SnoopDougg
SnoopDougg

Reputation: 1609

How can I write a Maven Java Azure Function that reads a MongoDB database?

Can anyone please help me figure out an Azure function in a Maven Java project to read a MongoDB database?

I am struggling to find any useful examples on github or in Microsoft's Azure documentation.

Here's what I have so far - although it fails to compile because it can't access a class I've defined in a separate library I mean to include.

My pom.xml:

<?xml version="1.0" encoding="UTF-8"?>
<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>
    <name>CRUD Azure Functions</name>
    <version>1.0.0</version>
    <artifactId>crud-azure-functions</artifactId>
    <description>Experimenting with Azure Functions</description>
    <packaging>jar</packaging>

    <parent>
        <artifactId>my-parent-module</artifactId>
        <groupId>com.snoop.dougg</groupId>
        <version>1.0.0</version>
    </parent>

    <properties>
        <start-class>com.snoop.dougg.azure</start-class>
    </properties>

    <dependencies>
        <dependency>
            <groupId>com.microsoft.azure</groupId>
            <artifactId>azure-functions-java-core</artifactId>
            <version>1.0.0-beta-2</version>
        </dependency>
        <dependency>
            <groupId>com.snoop.dougg</groupId>
            <artifactId>my-common-lib</artifactId>
        </dependency>
    </dependencies>

    <build>
        <pluginManagement>
            <plugins>
                <plugin>
                    <artifactId>maven-resources-plugin</artifactId>
                    <version>3.0.2</version>
                </plugin>
                <plugin>
                    <groupId>com.microsoft.azure</groupId>
                    <artifactId>azure-functions-maven-plugin</artifactId>
                    <version>0.1.7</version>
                </plugin>
                <plugin>
                    <groupId>org.apache.maven.plugins</groupId>
                    <artifactId>maven-shade-plugin</artifactId>
                    <version>3.1.0</version>
                </plugin>
            </plugins>
        </pluginManagement>
        <plugins>
            <plugin>
                <groupId>com.microsoft.azure</groupId>
                <artifactId>azure-functions-maven-plugin</artifactId>
                <configuration>
                    <resourceGroup>java-functions-group</resourceGroup>
                    <appName>crud-azure-functions</appName>
                    <region>Central US</region>
                    <appSettings>
                        <property>
                            <name>FUNCTIONS_EXTENSION_VERSION</name>
                            <value>beta</value>
                        </property>
                    </appSettings>
                </configuration>
                <executions>
                    <execution>
                        <id>package-functions</id>
                        <goals>
                            <goal>package</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
            <plugin>
                <artifactId>maven-resources-plugin</artifactId>
                <executions>
                    <execution>
                        <id>copy-resources</id>
                        <phase>package</phase>
                        <goals>
                            <goal>copy-resources</goal>
                        </goals>
                        <configuration>
                            <overwrite>true</overwrite>
                            <outputDirectory>${project.basedir}</outputDirectory>
                            <resources>
                                <resource>
                                    <directory>${project.basedir}</directory>
                                    <includes>
                                        <include>**/*jar</include>
                                    </includes>
                                </resource>
                            </resources>
                        </configuration>
                    </execution>
                </executions>
            </plugin>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-shade-plugin</artifactId>
                <configuration>
                    <outputFile>${project.basedir}/${project.artifactId}-${project.version}.jar</outputFile>
                    <shadedArtifactAttached>false</shadedArtifactAttached>
                </configuration>
                <executions>
                    <execution>
                        <phase>package</phase>
                        <goals>
                            <goal>shade</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>
</project>

And then here's my Java code:

package com.snoop.dougg.azure;

import com.snoop.dougg.common.model.mongodb.Item;
import com.microsoft.azure.serverless.functions.ExecutionContext;
import com.microsoft.azure.serverless.functions.HttpRequestMessage;
import com.microsoft.azure.serverless.functions.HttpResponseMessage;
import com.microsoft.azure.serverless.functions.annotation.AuthorizationLevel;
import com.microsoft.azure.serverless.functions.annotation.FunctionName;
import com.microsoft.azure.serverless.functions.annotation.HttpTrigger;
import com.microsoft.azure.serverless.functions.annotation.TableInput;

import javax.servlet.http.HttpServletResponse;
import java.util.Optional;

public class ItemCrudFunctions {

    public static void main() {}

    @FunctionName("DouggHelloWorld")
    public HttpResponseMessage<String> helloWorld(
            @HttpTrigger(name = "req", methods = {"get"}, authLevel = AuthorizationLevel.ANONYMOUS)
                 HttpRequestMessage<Optional<String>> request,
            final ExecutionContext context) {
        return request.createResponse(HttpServletResponse.SC_OK, "Good news everyone!");
    }

    @FunctionName("ItemRetrieval")
    public HttpResponseMessage<Item> retrieveItem(
            @HttpTrigger(name = "retrieveItem",
                    route = "/item/{itemId}",
                    methods = {"get"},
                    authLevel = AuthorizationLevel.FUNCTION)
                HttpRequestMessage<Optional<String>> requestMessage,
            @TableInput(name = "itemTableInput",
                    tableName = "item",
                    connection = "AzureWebJobsStorage",
                    rowKey = "{itemId}") Item item) {
        return requestMessage.createResponse(HttpServletResponse.SC_OK, item);
    }
}

But I'm getting an error: cannot find symbol: class Item, and on top of that, I have no idea if this would even work if it did compile. I've been completely unable to find any good examples of Maven Java Azure Functions so far...

Upvotes: 1

Views: 1004

Answers (1)

Jay Gong
Jay Gong

Reputation: 23782

I tried to access my azure mongo database in my java azure function. On my side, I used mongo-java-driver lib instead of the com.snoop.dougg lib you used.Please see my sample code as below:

Function Class:

package com.fabrikam.functions;

import com.microsoft.azure.serverless.functions.annotation.*;
import com.microsoft.azure.serverless.functions.ExecutionContext;

import com.mongodb.MongoClient;
import com.mongodb.MongoClientURI;
import com.mongodb.client.MongoDatabase;

public class Function {
    @FunctionName("mongo")
    public String mongo(@HttpTrigger(name = "req", methods = {"get", "post"}, authLevel = AuthorizationLevel.ANONYMOUS) String req,
                    ExecutionContext context) {

    try {
        MongoClientURI uri = new MongoClientURI("***");
        MongoClient mongoClient = new MongoClient(uri);
        MongoDatabase database = mongoClient.getDatabase("db");
        return String.format("Hello, I get database name : %s!", database.getName());

    } catch (Exception e) {
        e.printStackTrace();
        return "Access Error!";
    }
}

pom.xml:

<?xml version="1.0" encoding="UTF-8"?>

<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.fabrikam.functions</groupId>
    <artifactId>fabrikam-functions</artifactId>
    <version>1.0-SNAPSHOT</version>
    <packaging>jar</packaging>

    <name>Azure Java Functions</name>

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <maven.compiler.source>1.8</maven.compiler.source>
        <maven.compiler.target>1.8</maven.compiler.target>
        <functionAppName>fabrikam-functions-20171017112209094</functionAppName>
    </properties>

    <dependencies>
        <dependency>
            <groupId>com.microsoft.azure</groupId>
            <artifactId>azure-functions-java-core</artifactId>
            <version>1.0.0-beta-1</version>
        </dependency>
        <!-- https://mvnrepository.com/artifact/org.mongodb/mongo-java-driver -->
        <dependency>
            <groupId>org.mongodb</groupId>
            <artifactId>mongo-java-driver</artifactId>
            <version>3.6.3</version>
        </dependency>


        <!-- Test -->
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.12</version>
            <scope>test</scope>
        </dependency>
    </dependencies>

    <build>
        <pluginManagement>
            <plugins>
                <plugin>
                    <artifactId>maven-resources-plugin</artifactId>
                    <version>3.0.2</version>
                </plugin>
                <plugin>
                    <groupId>com.microsoft.azure</groupId>
                    <artifactId>azure-functions-maven-plugin</artifactId>
                    <version>0.1.5</version>
                </plugin>
            </plugins>
        </pluginManagement>

        <plugins>
            <plugin>
                <groupId>com.microsoft.azure</groupId>
                <artifactId>azure-functions-maven-plugin</artifactId>
                <configuration>
                    <resourceGroup>java-functions-group</resourceGroup>
                    <appName>${functionAppName}</appName>
                    <region>westus2</region>
                    <appSettings>
                        <property>
                            <name>FUNCTIONS_EXTENSION_VERSION</name>
                            <value>beta</value>
                        </property>
                    </appSettings>
                </configuration>
                <executions>
                    <execution>
                        <id>package-functions</id>
                        <goals>
                            <goal>package</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
            <plugin>
                <artifactId>maven-resources-plugin</artifactId>
                <executions>
                    <execution>
                        <id>copy-resources</id>
                        <phase>package</phase>
                        <goals>
                            <goal>copy-resources</goal>
                        </goals>
                        <configuration>
                            <overwrite>true</overwrite>
                            <outputDirectory>${project.build.directory}/azure-functions/${functionAppName}
                            </outputDirectory>
                            <resources>
                                <resource>
                                    <directory>${project.basedir}</directory>
                                    <includes>
                                        <include>host.json</include>
                                        <include>local.settings.json</include>
                                    </includes>
                                </resource>
                            </resources>
                        </configuration>
                    </execution>
                </executions>
            </plugin>
            <plugin>
                <artifactId>maven-assembly-plugin</artifactId>
                <configuration>
                    <descriptorRefs>
                        <descriptorRef>jar-with-dependencies</descriptorRef>
                    </descriptorRefs>
                    <archive>
                        <manifest>
                            <mainClass>com.fabrikam.functions.Function</mainClass>
                        </manifest>
                    </archive>
                </configuration>
                <executions>
                    <execution>
                        <id>make-assembly</id>
                        <phase>package</phase>
                        <goals>
                            <goal>single</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>

</project>

Then please use command mvn-clean-package and you will see two jar files generated.

enter image description here

One is that it does not contain dependent jar packages, and the second one contains dependent jar packages.

Move the fabrikam-functions-1.0-SNAPSHOT-jar-with-dependencies jar into the path:${project.basedir}/target/azure-functions/${function-app-name}/

For me ,it looks like E:\TestAzureFunction\fabrikam-functions\target\azure-functions\fabrikam-functions-20171017112209094.

enter image description here

Don't forget rename the jar to fabrikam-functions-1.0-SNAPSHOT.

Finally, I run the azure function successfully and get the output result.

enter image description here

In addition, you could refer to this github doc for more configuration details about azure function maven plugin.

Hope it helps you.

Upvotes: 2

Related Questions