Attempt to write JSON by hand

This commit is contained in:
Dave Syer
2018-01-19 09:28:26 +00:00
parent 308e4d5514
commit 7604de3ca7
10 changed files with 224 additions and 182 deletions

View File

@@ -48,7 +48,7 @@ public class SpringBootRequestHandler<E, O> extends SpringFunctionInitializer
}
private Object result(Object input, Flux<?> output) {
List<Object> result = new ArrayList<>();
List<O> result = new ArrayList<>();
for (Object value : output.toIterable()) {
result.add(convertOutput(value));
}

View File

@@ -14,6 +14,30 @@ You don't need the Spring Cloud Function Web at runtime in Azure, so you need to
A function application on Azure has to be shaded, but a Spring Boot standalone application does not, so you can run the same app using 2 separate jars (as per the sample here).
The sample app creates the shaded jar file, with an `azure` classifier for deploying in Azure.
=== JSON Configuration
The Azure tooling needs to find some JSON configuration files to tell it how to deploy and intergrate the function (e.g. which Java class to use as the entry point, and which triggers to use). Those files can be created with the Maven plugin for a non-Spring function, but the tooling doesn't work yet with the adapter in its current form. There is an example `function.json` in the sample which hooks the function up as an HTTP endpoint:
```
{
"scriptFile" : "../function-sample-azure-1.0.0.BUILD-SNAPSHOT-azure.jar",
"entryPoint" : "example.FooHandler.handleRequest",
"bindings" : [ {
"type" : "httpTrigger",
"name" : "req",
"direction" : "in",
"authLevel" : "anonymous",
"methods" : [ "get", "post" ]
}, {
"type" : "http",
"name" : "$return",
"direction" : "out"
} ],
"disabled" : false
}
```
== Build
----
@@ -22,50 +46,25 @@ The sample app creates the shaded jar file, with an `azure` classifier for deplo
== Running the sample
Before running the sample, we need to install a custom azure maven plugin.
Checkout this fork: https://github.com/sobychacko/azure-maven-plugins/tree/for-spring-boot-apps
----
cd azure-functions-maven-plugin
mvn clean install -Dcheckstyle.skip=true -DskipTests -Dfindbugs.skip=true
----
You can run the sample locally, just like the other Spring Cloud Function samples:
Build the sample under `spring-cloud-function-samples/function-sample-azure`.
---
./mvnw spring-boot:run
---
and `curl -H "Content-Type: text/plain" localhost:8080/function -d '{"value": "hello foobar"}'`.
You will need the `az` CLI app and some node.js fu (see https://docs.microsoft.com/en-us/azure/azure-functions/functions-create-first-java-maven for more detail). To deploy the function on Azure runtime:
----
mvn clean package
----
Running Azure function locally.
----
mvn azure-functions:run
On another terminal try this: curl localhost:7071/api/uppercase -d '{"value": "hello foobar"}'
----
Deploying the function that ran locally on Azure runtime.
----
az login
mvn azure-functions:deploy
$ az login
$ mvn azure-functions:deploy
On another terminal try this: curl https://<azure-function-url-from-the-log>/api/uppercase -d '{"value": "hello foobar!"}'
Please ensure that you use the right URL for the function above.
----
Running the function as a standalone Spring Boot app
Go to the samples project and uncomment `spring-cloud-function-web` dependency and `spring-boot-maven-plugin`.
----
mvn clean package
java -jar target/<spring boot uber jar>
On another terminal: curl -H "Content-Type: text/plain" localhost:8080/function -d '{"value": "hello foobar"}'
----
The input type for the function in the Azure sample is a Foo with a single property called "value". So you would need this to test it with something as below.
----

View File

@@ -21,12 +21,13 @@ import java.util.Collection;
import java.util.List;
import com.microsoft.azure.serverless.functions.ExecutionContext;
import reactor.core.publisher.Flux;
/**
* @author Soby Chacko
*/
public class AzureSpringBootRequestHandler<I,O> extends AzureSpringFunctionInitializer {
public class AzureSpringBootRequestHandler<I, O> extends AzureSpringFunctionInitializer {
public Object handleRequest(I foo, ExecutionContext context) {
context.getLogger().info("Handler Java HTTP trigger processed a request.");
@@ -51,9 +52,9 @@ public class AzureSpringBootRequestHandler<I,O> extends AzureSpringFunctionIniti
private Object result(Object input, Flux<?> output) {
List<Object> result = new ArrayList<>();
for (Object value : output.toIterable()) {
result.add(value);
result.add(convertOutput(value));
}
if (isSingleValue(input) && result.size()==1) {
if (isSingleValue(input) && result.size() == 1) {
return result.get(0);
}
return result;
@@ -63,5 +64,8 @@ public class AzureSpringBootRequestHandler<I,O> extends AzureSpringFunctionIniti
return !(input instanceof Collection);
}
@SuppressWarnings("unchecked")
protected O convertOutput(Object output) {
return (O) output;
}
}

View File

@@ -0,0 +1,6 @@
lib/
node/
package-lock.json
node_modules/
etc/

View File

@@ -0,0 +1,4 @@
#!/bin/sh
cd $(dirname $0)
PATH="$PWD/node/":$PATH
node "node/node_modules/npm/bin/npm-cli.js" "$@"

View File

@@ -1,153 +1,162 @@
<?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>
<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>io.spring.sample</groupId>
<artifactId>function-sample-azure</artifactId>
<version>1.0.0.BUILD-SNAPSHOT</version>
<packaging>jar</packaging>
<groupId>io.spring.sample</groupId>
<artifactId>function-sample-azure</artifactId>
<version>1.0.0.BUILD-SNAPSHOT</version>
<packaging>jar</packaging>
<name>Azure Java Functions</name>
<name>Azure Java Functions</name>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.5.8.RELEASE</version>
<relativePath /> <!-- lookup parent from repository -->
</parent>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.5.8.RELEASE</version>
<relativePath /> <!-- lookup parent from repository -->
</parent>
<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>function-sample-azure-11262017190909</functionAppName>
<functionAppRegion>westus</functionAppRegion>
<start-class>example.FooConfig</start-class>
</properties>
<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>function-sample-azure</functionAppName>
<functionAppRegion>westus</functionAppRegion>
<start-class>example.FooConfig</start-class>
</properties>
<dependencies>
<dependency>
<groupId>com.microsoft.azure</groupId>
<artifactId>azure-functions-java-core</artifactId>
<version>[1.0.0-beta-1,1.0.0)</version>
</dependency>
<!--<dependency>-->
<!--<groupId>org.springframework.cloud</groupId>-->
<!--<artifactId>spring-cloud-function-web</artifactId>-->
<!--<version>1.0.0.BUILD-SNAPSHOT</version>-->
<!--</dependency>-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-function-adapter-azure</artifactId>
<version>1.0.0.BUILD-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>io.projectreactor</groupId>
<artifactId>reactor-core</artifactId>
<version>3.0.7.RELEASE</version>
</dependency>
<dependencies>
<dependency>
<groupId>com.microsoft.azure</groupId>
<artifactId>azure-functions-java-core</artifactId>
<version>1.0.0-beta-2</version>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-function-web</artifactId>
<version>1.0.0.BUILD-SNAPSHOT</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-function-adapter-azure</artifactId>
<version>1.0.0.BUILD-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>io.projectreactor</groupId>
<artifactId>reactor-core</artifactId>
<version>3.1.2.RELEASE</version>
</dependency>
<!-- Test -->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-core</artifactId>
<version>2.4.0</version>
<scope>test</scope>
</dependency>
</dependencies>
<!-- Test -->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-core</artifactId>
<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.7-SNAPSHOT</version>
</plugin>
</plugins>
</pluginManagement>
<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.6</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>${functionAppRegion}</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>-->
<!--<groupId>org.springframework.boot</groupId>-->
<!--<artifactId>spring-boot-maven-plugin</artifactId>-->
<!--</plugin>-->
<plugins>
<plugin>
<groupId>com.github.eirslett</groupId>
<artifactId>frontend-maven-plugin</artifactId>
<version>1.6</version>
<configuration>
<nodeVersion>v8.8.1</nodeVersion>
</configuration>
<executions>
<execution>
<id>install-npm</id>
<goals>
<goal>install-node-and-npm</goal>
</goals>
</execution>
<execution>
<id>npm-install</id>
<goals>
<goal>npm</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>com.microsoft.azure</groupId>
<artifactId>azure-functions-maven-plugin</artifactId>
<configuration>
<resourceGroup>java-functions-group</resourceGroup>
<appName>${functionAppName}</appName>
<region>${functionAppRegion}</region>
<appSettings>
<property>
<name>FUNCTIONS_EXTENSION_VERSION</name>
<value>beta</value>
</property>
</appSettings>
</configuration>
</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}/src/main/azure</directory>
<includes>
<include>uppercase/**</include>
<include>host.json</include>
<include>local.settings.json</include>
</includes>
</resource>
</resources>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<configuration>
<createDependencyReducedPom>false</createDependencyReducedPom>
<shadedArtifactAttached>true</shadedArtifactAttached>
<shadedClassifierName>azure</shadedClassifierName>
<outputDirectory>${project.build.directory}/azure-functions/${functionAppName}</outputDirectory>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<configuration>
<createDependencyReducedPom>false</createDependencyReducedPom>
<shadedArtifactAttached>true</shadedArtifactAttached>
<shadedClassifierName>azure</shadedClassifierName>
<outputDirectory>${project.build.directory}/azure-functions/${functionAppName}</outputDirectory>
</configuration>
</plugin>
</plugins>
</plugins>
</build>
</build>

View File

@@ -0,0 +1,16 @@
{
"scriptFile" : "../function-sample-azure-1.0.0.BUILD-SNAPSHOT-azure.jar",
"entryPoint" : "example.FooHandler.handleRequest",
"bindings" : [ {
"type" : "httpTrigger",
"name" : "foo",
"direction" : "in",
"authLevel" : "anonymous",
"methods" : [ "get", "post" ]
}, {
"type" : "http",
"name" : "$return",
"direction" : "out"
} ],
"disabled" : false
}

View File

@@ -17,18 +17,22 @@
package example;
import com.microsoft.azure.serverless.functions.ExecutionContext;
import com.microsoft.azure.serverless.functions.annotation.HttpOutput;
import com.microsoft.azure.serverless.functions.annotation.HttpTrigger;
import org.springframework.cloud.function.adapter.azure.AzureSpringBootRequestHandler;
/**
* @author Soby Chacko
*/
public class FooHandler extends AzureSpringBootRequestHandler {
public class FooHandler extends AzureSpringBootRequestHandler<Foo, Bar> {
@SuppressWarnings("unchecked")
public Bar handleRequest(Foo foo, ExecutionContext context) {
@Override
public @HttpOutput(name = "bar") Bar handleRequest(
@HttpTrigger(name = "foo", methods = { "get", "post" }) Foo foo,
ExecutionContext context) {
context.getLogger().info("Invoking entry point method");
return (Bar)super.handleRequest(foo,context);
return (Bar) super.handleRequest(foo, context);
}
}