From b0ef7b19d15b2de3f1ee371aa0a9446403ca3d6c Mon Sep 17 00:00:00 2001 From: Olga Maciaszek-Sharma Date: Wed, 19 Jun 2019 22:10:34 +0200 Subject: [PATCH] Add build file setup documentation Resolves #377 --- .../src/main/asciidoc/adapters/aws-intro.adoc | 115 +++++++++++++++++- .../main/asciidoc/adapters/azure-intro.adoc | 65 +++++++++- 2 files changed, 177 insertions(+), 3 deletions(-) diff --git a/docs/src/main/asciidoc/adapters/aws-intro.adoc b/docs/src/main/asciidoc/adapters/aws-intro.adoc index 33da52407..af2616b79 100644 --- a/docs/src/main/asciidoc/adapters/aws-intro.adoc +++ b/docs/src/main/asciidoc/adapters/aws-intro.adoc @@ -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] ---- @@ -47,6 +50,116 @@ then additional transformers must be configured as part of the maven-shade-plugi ---- +== 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] +---- + + + org.springframework.cloud + spring-cloud-function-adapter-aws + + +---- + +As pointed out in the <>, 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 <> can be found above. + +You can use theSpring Boot Maven Plugin to generate the <>. +[source,xml] +---- + + org.springframework.boot + spring-boot-maven-plugin + + + org.springframework.boot.experimental + spring-boot-thin-layout + ${wrapper.version} + + + +---- + +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 <>, 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 <>. + +[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). diff --git a/docs/src/main/asciidoc/adapters/azure-intro.adoc b/docs/src/main/asciidoc/adapters/azure-intro.adoc index fa46f7b81..e98a00ddb 100644 --- a/docs/src/main/asciidoc/adapters/azure-intro.adoc +++ b/docs/src/main/asciidoc/adapters/azure-intro.adoc @@ -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] +---- + + + org.springframework.cloud + spring-cloud-function-adapter-azure + + +---- + +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] +---- + + com.microsoft.azure + azure-functions-maven-plugin + + ${functionResourceGroup} + ${functionAppName} + + + + package-functions + + package + + + + +---- + +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. \ No newline at end of file +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.