# Create and deploy an HTTP Cloud Run function by using Java (1st gen)

This guide takes you through the process of writing a Cloud Run function
using the Java runtime. There are two types of Cloud Run functions:

- An HTTP function, which you invoke from standard HTTP requests.
- An event-driven function, which you use to handle events from your Cloud infrastructure, such as messages on a Pub/Sub topic, or changes in a Cloud Storage bucket.

The document shows how to create a simple HTTP function and build it using
either [Maven](https://maven.apache.org) or
[Gradle](https://gradle.org/).

> [!IMPORTANT]
> **Learn more** : For more details, read about [HTTP functions](https://docs.cloud.google.com/functions/1stgendocs/writing/write-http-functions.md.txt) and [event-driven functions](https://docs.cloud.google.com/functions/1stgendocs/writing/write-event-driven-functions.md.txt).

## Before you begin

1. Prepare your development environment.
   [Go to the Java setup guide](https://docs.cloud.google.com/java/docs/setup.md.txt)

<br />

## Create a function

This section describes how to create a function.

### Maven

1. Create a directory on your local system for the function code:

   **Linux or Mac OS X:**

   ```java
    mkdir ~/helloworld
    cd ~/helloworld
   ```

   **Windows:**

   ```java
    mkdir %HOMEPATH%\helloworld
    cd %HOMEPATH%\helloworld
   ```
2. Create the project structure to contain the source directory and source file.

   ```java
   mkdir -p src/main/java/functions
   touch src/main/java/functions/HelloWorld.java
   ```
3. Add the following contents to the `HelloWorld.java` file:

   ```java

   package functions;

   import com.google.cloud.functions.HttpFunction;
   import com.google.cloud.functions.HttpRequest;
   import com.google.cloud.functions.HttpResponse;
   import java.io.BufferedWriter;
   import java.io.IOException;

   public class HelloWorld implements HttpFunction {
     // Simple function to return "Hello World"
     @Override
     public void service(HttpRequest request, HttpResponse response)
         throws IOException {
       BufferedWriter writer = response.getWriter();
       writer.write("Hello World!");
     }
   }
   ```

   This example function outputs the greeting "Hello World!"

### Gradle

1. Create a directory on your local system for the function code:

   **Linux or Mac OS X:**

   ```java
    mkdir ~/helloworld-gradle
    cd ~/helloworld-gradle
   ```

   **Windows:**

   ```java
    mkdir %HOMEPATH%\helloworld-gradle
    cd %HOMEPATH%\helloworld-gradle
   ```
2. Create the project structure to contain the source directory and source file.

   ```java
    mkdir -p src/main/java/functions
    touch src/main/java/functions/HelloWorld.java
   ```
3. Add the following contents to the `HelloWorld.java` file:

   ```java

   package functions;

   import com.google.cloud.functions.HttpFunction;
   import com.google.cloud.functions.HttpRequest;
   import com.google.cloud.functions.HttpResponse;
   import java.io.BufferedWriter;
   import java.io.IOException;

   public class HelloWorld implements HttpFunction {
     // Simple function to return "Hello World"
     @Override
     public void service(HttpRequest request, HttpResponse response)
         throws IOException {
       BufferedWriter writer = response.getWriter();
       writer.write("Hello World!");
     }
   }
   ```

   This example function outputs the greeting "Hello World!"

## Specify dependencies

The next step is to set up dependencies:

### Maven

Change directory to the `helloworld` directory you created above, and create
a `pom.xml` file:

```java
 cd ~/helloworld
 touch pom.xml
```

To manage dependencies using Maven, specify the dependencies in
the `<dependencies>` section inside the [pom.xml](http://maven.apache.org/guides/introduction/introduction-to-the-pom.html) file
of your project. For this exercise, copy the following contents
into your `pom.xml` file.

```java
<project xmlns="http://maven.apache.org/POM/4.0.0"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>

  <groupId>com.example.functions</groupId>
  <artifactId>functions-hello-world</artifactId>
  <version>1.0.0-SNAPSHOT</version>
  <properties>
    <maven.compiler.target>11</maven.compiler.target>
    <maven.compiler.source>11</maven.compiler.source>
  </properties>

  <dependencies>
    <!-- Required for Function primitives -->
    <dependency>
      <groupId>com.google.cloud.functions</groupId>
      <artifactId>functions-framework-api</artifactId>
      <version>1.1.0</version>
      <scope>provided</scope>
    </dependency>
  </dependencies>

  <build>
    <plugins>
      <plugin>
        <!--
          Google Cloud Functions Framework Maven plugin

          This plugin allows you to run Cloud Functions Java code
          locally. Use the following terminal command to run a
          given function locally:

          mvn function:run -Drun.functionTarget=your.package.yourFunction
        -->
        <groupId>com.google.cloud.functions</groupId>
        <artifactId>function-maven-plugin</artifactId>
        <version>0.11.0</version>
        <configuration>
          <functionTarget>functions.HelloWorld</functionTarget>
        </configuration>
      </plugin>
    </plugins>
  </build>
</project>
```

See [helloworld](https://github.com/GoogleCloudPlatform/java-docs-samples/tree/master/functions/helloworld/helloworld)
for a complete sample based on Maven.

### Gradle

Change directory to the `helloworld-gradle` directory you created above, and
create a `build.gradle` file:

```java
 cd ~/helloworld-gradle
 touch build.gradle
```

To manage dependencies using Gradle, specify the dependencies in
the [build.gradle](https://docs.gradle.org/current/userguide/tutorial_using_tasks.html) file
of your project. For this exercise, copy the following contents
into your `build.gradle` file. Note that this `build.gradle` file includes a
custom task to help you run functions [locally](https://docs.cloud.google.com/functions/1stgendocs/create-deploy-http-java-1st-gen.md.txt#building_and_testing_locally).

```java
apply plugin: 'java'

repositories {
  jcenter()
  mavenCentral()
}
configurations {
    invoker
}

dependencies {
  // Every function needs this dependency to get the Functions Framework API.
  compileOnly 'com.google.cloud.functions:functions-framework-api:1.1.0'

  // To run function locally using Functions Framework's local invoker
  invoker 'com.google.cloud.functions.invoker:java-function-invoker:1.3.1'

  // These dependencies are only used by the tests.
  testImplementation 'com.google.cloud.functions:functions-framework-api:1.1.0'
  testImplementation 'junit:junit:4.13.2'
  testImplementation 'com.google.truth:truth:1.4.0'
  testImplementation 'org.mockito:mockito-core:5.10.0'

}

// Register a "runFunction" task to run the function locally
tasks.register("runFunction", JavaExec) {
  main = 'com.google.cloud.functions.invoker.runner.Invoker'
  classpath(configurations.invoker)
  inputs.files(configurations.runtimeClasspath, sourceSets.main.output)
  args(
    '--target', project.findProperty('run.functionTarget') ?: '',
    '--port', project.findProperty('run.port') ?: 8080
  )
  doFirst {
    args('--classpath', files(configurations.runtimeClasspath, sourceSets.main.output).asPath)
  }
}
```

See [helloworld-gradle](https://github.com/GoogleCloudPlatform/java-docs-samples/tree/master/functions/helloworld/helloworld-gradle)
for a complete sample based on Gradle.

> [!IMPORTANT]
> **Learn more** : For more details, read about [specifying dependencies](https://docs.cloud.google.com/functions/1stgendocs/writing/specifying-dependencies-java.md.txt).

## Build and test locally

Before deploying the function, you can build and test it locally:

### Maven

Run the following command to confirm that your function builds:

```java
mvn compile
```

Another option is to use the `mvn package` command to compile your Java
code, run any tests, and package the code up in a JAR file within the target
directory. You can learn more about the Maven build lifecycle
[here](https://maven.apache.org/guides/introduction/introduction-to-the-lifecycle.html).

To test the function, run the following command:

```java
mvn function:run
```

### Gradle

Run the following command to confirm that your function builds:

```java
gradle build
```

To test the function, run the following command:

```java
gradle runFunction -Prun.functionTarget=functions.HelloWorld
```

If testing completes successfully, it displays the URL you can visit in your web
browser to see the function in action:
`http://localhost:8080/`. You should see a `Hello World!` message.

Alternatively, you can send requests to this function using `curl` from another
terminal window:

```java
curl localhost:8080
# Output: Hello World!
```

## Deploy the function

### Maven

To deploy the function with an HTTP trigger, run the following
command in the `helloworld` directory:

```bash
gcloud functions deploy my-first-function --no-gen2 --entry-point functions.HelloWorld --runtime java17 --trigger-http --memory 512MB --allow-unauthenticated
```
where `my-first-function` is the registered name by which your function will be identified in the Google Cloud console, and `--entry-point` specifies your function's fully qualified class name (FQN).

<br />

### Gradle

To deploy the function with an HTTP trigger, run the following
command in the `helloworld-gradle` directory:

```bash
gcloud functions deploy my-first-function --no-gen2 --entry-point functions.HelloWorld --runtime java17 --trigger-http --memory 512MB --allow-unauthenticated
```
where `my-first-function` is the registered name by which your function will be identified in the Google Cloud console, and `--entry-point` specifies your function's fully qualified class name (FQN).

<br />

> [!IMPORTANT]
> **Learn more** : For more details, read about [deploying Cloud Run functions](https://docs.cloud.google.com/functions/1stgendocs/deploy.md.txt#basics).

## Test the deployed function

1. When the function finishes deploying, take note of the `httpsTrigger.url`
   property or find it using the following command:

   ```bash
   gcloud functions describe my-first-function
   ```
   It should look like this:

   <br />

   ```
   https://GCP_REGION-PROJECT_ID.cloudfunctions.net/my-first-function
   ```
2. Visit this URL in your browser. You should see a `Hello World!` message.

> [!NOTE]
> **Note:** You can also find this URL in Google Cloud console. Go to the [Cloud Run functions Overview page](https://console.cloud.google.com/functions/list), and click the name of your function to open its **Function details** page. Open the **TRIGGER** tab to see your function's URL.

## View logs

Logs for Cloud Run functions are viewable using the Google Cloud CLI, and in the
Cloud Logging UI.

### Use the command-line tool

To view logs for your function with the gcloud CLI, use the
[`logs read`](https://docs.cloud.google.com/sdk/gcloud/reference/functions/logs/read) command, followed by
the name of the function:

```bash
gcloud functions logs read my-first-function
```

The output should resemble the following:

```bash
LEVEL  NAME               EXECUTION_ID  TIME_UTC                 LOG
D      my-first-function  k2bqgroszo4u  2020-07-24 18:18:01.791  Function execution started
D      my-first-function  k2bqgroszo4u  2020-07-24 18:18:01.958  Function execution took 168 ms, finished with status code: 200
...
```

> [!NOTE]
> **Note:** There is typically a slight delay between when log entries are created and when they show up in Cloud Logging.

### Use the Logging dashboard

You can also view logs for Cloud Run functions from the
[Google Cloud console](https://console.cloud.google.com/project/_/logs?service=cloudfunctions.googleapis.com).

> [!IMPORTANT]
> **Learn more** : For more details, read about [writing, viewing, and responding to logs](https://docs.cloud.google.com/functions/1stgendocs/monitoring/logging.md.txt).