Java in Azure Functions
Check out this example of developing and executing a Java-based application running in Azure Functions.
Join the DZone community and get the full member experience.
Join For FreeAzure Functions is the serverless computing in Azure architecture that provides a programming model for event-driven applications
Back in February, Microsoft announced Java support in Azure Functions 2.0. This is good news to Java developers accessing Azure as a cloud-based provider and leveraging Azure Functions as computing components.
In this article, we will study an example of developing and executing a Java-based application running in Azure Functions.
Create Function App From Azure Portal
First, you need to provide the function name and other details like subscription, resource group, and OS details to provision Azure Functions
Select the hosting plan. Azure Functions runs on two plans:
Consumption Plan: In this plan, instances of Azure Functions host are dynamically added or removed based on the number of incoming events. Billing is based on the number of executions, memory used, and execution time. Maximum memory in this plan is 1.5 GB per instance
App Service Plan: In this plan, Azure Functions runs on dedicated VM's as other App Service Apps. Memory in this plan goes from 1.75 GB to 14 GB per instance
There is one more plan: "Premium," which is in the preview stage. Choose any of the above plans, depending on the business requirements and usage.
Then, choose a runtime stack for the execution environment. In this requirement, we select Java:
Select Storage Account and Application Insights as logging of Azure Functions is directly integrated with Application Insights:
With the above details, the Function App is provisioned in the given usage plan. With this simple example, we can see how we can implement a Java service published and hosted in Azure Functions.
Create a Maven project in your local system with the Maven archetype for an Azure Functions environment.
Below is the command to create a Maven project:
mvn archetype:generate ".microsoft.azure" "-functions-archetype"
Import the Maven project in your favorite IDE, like Eclipse or Visual Studio Code. Then, open the generated pom.xml and update the following details:
<functionAppName></functionAppName>
<functionAppRegion></functionAppRegion>
<functionResourceGroup></functionResourceGroup>
These details are obtained when you have provisioned Azure Functions from the portal.
Also, add any other third-party libraries as dependencies in the Maven project required for your Java application
In our example, we create a simple Java service with two methods — one serving HTTP GET requests and another serving HTTP POST requests.
The code below is for a POST request that creates order. In our example, we are creating a dummy order and there is no interaction with any back-end system. The purpose of this example is to show how we can build a POST request in Java published to the Azure Function environment:
@FunctionName("createorder")
public String createOrder(
@HttpTrigger(name = "req", methods = {HttpMethod.POST},
authLevel = AuthorizationLevel.FUNCTION)
HttpRequestMessage<Optional<String>> request,
final ExecutionContext context) {
String orderDetails = request.getBody().get();
context.getLogger().info("order details "+orderDetails);
return "order created o-8976";
}
The above function is annotated with functionName
, which is CreateOrder
and takes the object of HttpRequestMessage
and ExecutionContext
object as parameters.
The request body passed in POST request can be obtained using getBody
method of HttpRequestMessage
object.
ExecutionContext
has methods that get function-related configurations like invocation id, function name, and logger object that logs messages to Application Insights.
Similarly, an example for a GET request service is shown below and provides order details by passing order Id as a query parameter in the URL:
@FunctionName("listorder")
public HttpResponseMessage listOrder(
@HttpTrigger(name = "req", methods = {HttpMethod.GET},
authLevel = AuthorizationLevel.FUNCTION)
HttpRequestMessage<Optional<String>> request,
final ExecutionContext context) {
context.getLogger().info("In list order");
// Parse query parameter
String orderRequest = request.getQueryParameters().get("orderId");
String orderId = request.getBody().orElse(orderRequest);
if (orderRequest == null) {
return request.createResponseBuilder(HttpStatus.BAD_REQUEST)
.body("Please pass orderId").build();
} else {
return request.createResponseBuilder(HttpStatus.OK)
.body("this order "+orderId+" belongs to mobile order").build();
}
}
The above function is annotated with the function name ListOrder
. This function is accessed by GET request with "orderId
" parameter passed as a query parameter in the URL
The query parameter passed in the URL can be obtained by getQueryParameters
method of HttpRequestMessage
.
The required classes for Java code to run in Azure Functions are from the Java package "com.microsoft.azure.functions."
The host.json file is also generated in the Maven project; then you can add the below entry:
{
"version": "2.0",
"extensionBundle": {
"id": "Microsoft.Azure.Functions.ExtensionBundle",
"version": "[1.*, 2.0.0)"
}
}
When you enable bundles, a predefined set of extension packages is automatically installed.
Now, run the Maven project locally:
mvn clean package
mvn azure-functions:run
When functions run as locally (first-time setup), we get this exception:
Caused by: java.lang.Exception: Azure Functions Core Tools not found. Please go to https://aka.ms/azfunc-install to install Azure Functions Core Tools first. at
Solution: Install Azure Function-core tools using npm (Node Package Manager) with the following command:
npm i -g azure-functions-core-tools --unsafe-perm true
Test the function in the local environment, and once everything is fine, then start publishing to Azure.
To start publishing to Azure, log into the Azure portal using the below command:
az login
Once login is a success, publish and deploy the Java project to Azure Functions:
mvn azure-functions:deploy
Once the project is deployed, two functions can be visualized in the portal from the Azure Function resource:
The functions createorder
and listorder
, where we have annotated with the function name in the Java code for POST service and GET service, are being seen as separate individual functions with the same name as the one annotated.
To get the URL for createorder
, click on the createorder
function and get the URL by clicking the Get function URL
The format is as below:
https://mybrandorderservice.azurewebsites.net/api/createorder?code=<code>
mybrandorderservice
is the function app name we provided during provisioning of Azure Functions, createorder
is the function name we provided in the Java method, and code query parameter is the security code generated at the Azure Functions level.
Similarly, for the GET request in our example, the URL format is shown below:
https://mybrandorderservice.azurewebsites.net/api/listorder?orderId=8976&code=<codeid>
orderId
is the query parameter we defined for passing custom value (in this example, the orderId
value).
The URL pattern starts with /api
for the function and gets published and hosted as Azure Functions.
If we can test our example POST service from the REST client:
We get the following response from the createorder
service:
To view the logs, navigate to the Monitor section of the particular function in the Azure portal and see the logs for the createorder
function
Click on the following log generated:
The detailed log will be presented from the Application Insights. We can see the info log from the Java code that got logged for the createorder
function, as shown below.
In this way, we can monitor any errors, debug, and collect info traces from the Java project.
Conclusion
We hope you enjoyed this overview of running a Java-based Maven project and publishing it to Azure Functions. We have seen how we can develop services for POST and GET request methods in Java, and then host it in Azure Functions with monitoring enabled by tracing the logger details from the Application Insights.
Further Reading
Opinions expressed by DZone contributors are their own.
Comments