Add build file setup documentation

Resolves #377
This commit is contained in:
Olga Maciaszek-Sharma
2019-06-19 22:10:34 +02:00
committed by Oleg Zhurakousky
parent cf5cd49b72
commit b0ef7b19d1
2 changed files with 177 additions and 3 deletions

View File

@@ -1,3 +1,5 @@
:branch: master
The adapter has a couple of generic request handlers that you can use. The most generic is `SpringBootStreamHandler`, which uses a Jackson `ObjectMapper` provided by Spring Boot to serialize and deserialize the objects in the function. There is also a `SpringBootRequestHandler` which you can extend, and provide the input and output types as type parameters (enabling AWS to inspect the class and do the JSON conversions itself).
If your app has more than one `@Bean` of type `Function` etc. then you can choose the one to use by configuring `function.name` (e.g. as `FUNCTION_NAME` environment variable in AWS). The functions are extracted from the Spring Cloud `FunctionCatalog` (searching first for `Function` then `Consumer` and finally `Supplier`).
@@ -8,7 +10,7 @@ You don't need the Spring Cloud Function Web or Stream adapter at runtime in Lam
need to exclude those before you create the JAR you send to AWS. A Lambda application 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). The sample app creates 2 jar files, one with an `aws`
classifier for deploying in Lambda, and one executable (thin) jar that includes `spring-cloud-function-web`
classifier for deploying in Lambda, and one [[thin-jar,thin jar]] executable (thin) jar that includes `spring-cloud-function-web`
at runtime. Spring Cloud Function will try and locate a "main class" for you from the JAR file
manifest, using the `Start-Class` attribute (which will be added for you by the Spring Boot
tooling if you use the starter parent). If there is no `Start-Class` in your manifest you can
@@ -17,6 +19,7 @@ use an environment variable or system property `MAIN_CLASS` when you deploy the
If you are not using the functional bean definitions but relying on Spring Boot's auto-configuration,
then additional transformers must be configured as part of the maven-shade-plugin execution.
[[shade-plugin-setup]]
[source, xml]
----
<plugin>
@@ -47,6 +50,116 @@ then additional transformers must be configured as part of the maven-shade-plugi
</plugin>
----
== Build file setup
In order to run Spring Cloud Function applications on AWS Lambda, you can leverage Maven or Gradle
plugins offered by the cloud platform provider.
=== Maven
In order to use the adapter plugin for Maven, add the plugin dependency to your `pom.xml`
file:
[source,xml]
----
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-function-adapter-aws</artifactId>
</dependency>
</dependencies>
----
As pointed out in the <<Notes on JAR Layout>>, you wil need a shaded jar in order to upload it
to AWS Lambda. You can use the https://maven.apache.org/plugins/maven-shade-plugin/[Maven Shade Plugin] for that.
The example of the <<shade-plugin-setup,setup>> can be found above.
You can use theSpring Boot Maven Plugin to generate the <<thin-jar>>.
[source,xml]
----
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<dependencies>
<dependency>
<groupId>org.springframework.boot.experimental</groupId>
<artifactId>spring-boot-thin-layout</artifactId>
<version>${wrapper.version}</version>
</dependency>
</dependencies>
</plugin>
----
You can find the entire sample `pom.xml` file for deploying Spring Cloud Function
applications to AWS Lambda with Maven https://github.com/spring-cloud/spring-cloud-function/blob/{branch}/spring-cloud-function-samples/function-sample-aws/pom.xml[here].
=== Gradle
In order to use the adapter plugin for Gradle, add the dependency to your `build.gradle` file:
[source,groovy]
----
dependencies {
compile("org.springframework.cloud:spring-cloud-function-adapter-aws:${version}")
}
----
As pointed out in <<Notes on JAR Layout>>, you wil need a shaded jar in order to upload it
to AWS Lambda. You can use the https://plugins.gradle.org/plugin/com.github.johnrengelman.shadow/[Gradle Shadow Plugin] for that:
[source,groovy]
----
buildscript {
dependencies {
classpath "com.github.jengelman.gradle.plugins:shadow:${shadowPluginVersion}"
}
}
apply plugin: 'com.github.johnrengelman.shadow'
assemble.dependsOn = [shadowJar]
import com.github.jengelman.gradle.plugins.shadow.transformers.*
shadowJar {
classifier = 'aws'
dependencies {
exclude(
dependency("org.springframework.cloud:spring-cloud-function-web:${springCloudFunctionVersion}"))
}
// Required for Spring
mergeServiceFiles()
append 'META-INF/spring.handlers'
append 'META-INF/spring.schemas'
append 'META-INF/spring.tooling'
transform(PropertiesFileTransformer) {
paths = ['META-INF/spring.factories']
mergeStrategy = "append"
}
}
----
You can use the Spring Boot Gradle Plugin and Spring Boot Thin Gradle Plugin to generate
the <<thin-jar>>.
[source,groovy]
----
buildscript {
dependencies {
classpath("org.springframework.boot.experimental:spring-boot-thin-gradle-plugin:${wrapperVersion}")
classpath("org.springframework.boot:spring-boot-gradle-plugin:${springBootVersion}")
}
}
apply plugin: 'org.springframework.boot'
apply plugin: 'org.springframework.boot.experimental.thin-launcher'
assemble.dependsOn = [thinJar]
----
You can find the entire sample `build.gradle` file for deploying Spring Cloud Function
applications to AWS Lambda with Gradle https://github.com/spring-cloud/spring-cloud-function/blob/{branch}/spring-cloud-function-samples/function-sample-aws/build.gradle[here].
== Upload
Build the sample under `spring-cloud-function-samples/function-sample-aws` and upload the `-aws` jar file to Lambda. The handler can be `example.Handler` or `org.springframework.cloud.function.adapter.aws.SpringBootStreamHandler` (FQN of the class, _not_ a method reference, although Lambda does accept method references).

View File

@@ -1,3 +1,5 @@
:branch: master
This project provides an adapter layer for a Spring Cloud Function application onto Azure.
You can write an app with a single `@Bean` of type `Function` and it will be deployable in Azure if you get the JAR file laid out right.
@@ -43,7 +45,66 @@ Normally type-based injection should suffice, however if need to you can also ut
=== Notes on JAR Layout
You don't need the Spring Cloud Function Web at runtime in Azure, so you can exclude this before you create the JAR you deploy to Azure, but it won't be used if you include it so it doesn't hurt to leave it in. A function application on Azure is an archive generated by the Maven plugin. The function lives in the JAR file generated by this project. The sample creates it as an executable jar, using the thin layout, so that Azure can find the handler classes. If you prefer you can just use a regular flat JAR file. The dependencies should *not* be included.
You don't need the Spring Cloud Function Web at runtime in Azure, so you can exclude this
before you create the JAR you deploy to Azure, but it won't be used if you include it, so
it doesn't hurt to leave it in. A function application on Azure is an archive generated by
the Maven plugin. The function lives in the JAR file generated by this project.
The sample creates it as an executable jar, using the thin layout, so that Azure can find
the handler classes. If you prefer you can just use a regular flat JAR file.
The dependencies should *not* be included.
== Build file setup
In order to run Spring Cloud Function applications on Microsoft Azure, you can leverage the Maven
plugin offered by the cloud platform provider.
In order to use the adapter plugin for Maven, add the plugin dependency to your `pom.xml`
file:
[source,xml]
----
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-function-adapter-azure</artifactId>
</dependency>
</dependencies>
----
Then, configure the plugin. You will need to provide Azure-specific configuration for your
application, specifying the `resourceGroup`, `appName` and other optional properties, and
add the `package` goal execution so that the `function.json` file required by Azure is
generated for you. Full plugin documentation can be found in the https://github.com/microsoft/azure-maven-plugins[plugin repository].
[source,xml]
----
<plugin>
<groupId>com.microsoft.azure</groupId>
<artifactId>azure-functions-maven-plugin</artifactId>
<configuration>
<resourceGroup>${functionResourceGroup}</resourceGroup>
<appName>${functionAppName}</appName>
</configuration>
<executions>
<execution>
<id>package-functions</id>
<goals>
<goal>package</goal>
</goals>
</execution>
</executions>
</plugin>
----
You will also have to ensure that the files to be scanned by the plugin can be found in the
Azure functions staging directory (see the https://github.com/microsoft/azure-maven-plugins[plugin repository]
for more details on the staging directory and it's default location).
You can find the entire sample `pom.xml` file for deploying Spring Cloud Function
applications to Microsoft Azure with Maven https://github.com/spring-cloud/spring-cloud-function/blob/{branch}/spring-cloud-function-samples/function-sample-azure/pom.xml[here].
NOTE: As of yet, only Maven plugin is available. Gradle plugin has not been created by
the cloud platform provider.
== Build
@@ -78,4 +139,4 @@ The input type for the function in the Azure sample is a Foo with a single prope
}
----
NOTE: The Azure sample app is written in the "non-functional" style (using `@Bean`). The functional style (with just `Function` or `ApplicationContextInitializer`) is much faster on startup in Azure than the traditional `@Bean` style, so if you don't need `@Beans` (or `@EnableAutoConfiguration`) it's a good choice. Warm starts are not affected.
NOTE: The Azure sample app is written in the "non-functional" style (using `@Bean`). The functional style (with just `Function` or `ApplicationContextInitializer`) is much faster on startup in Azure than the traditional `@Bean` style, so if you don't need `@Beans` (or `@EnableAutoConfiguration`) it's a good choice. Warm starts are not affected.