Spring Cloud Function as Multi Cloud Framework (Azure Function + AWS Lambda + Gradle)
As the title mentioned, this post is about creating a Gradle Spring Boot project that can deploy to both Azure Functions and AWS Lambda.
SpringBootConfiguration
Before we get into the multicloud project, a bit exploration on the Spring Boot and Spring Cloud Function. Spring Cloud Function provides a faster way to load the Spring Boot application thereby reducing the notorious cold start time experienced in AWS Lam
With Spring Boot @SpringBootApplication and @Bean
With Spring Boot @SpringBootConfiguration and Java Function<>
Few things to note:
ShadowJar or uber jar equivalent is needed
AWS Lambda Java Cold Start Duration: 4814.89 ms@SpringBootApplication
public class MulticloudApplication {
@Bean
public Function<String, String> uppercase() {
return value -> value.toUpperCase();
}
public static void main(String[] args) {
SpringApplication.run(MulticloudApplication.class, args);
}
}
With Spring Boot @SpringBootConfiguration and Java Function<>
@SpringBootConfiguration
public class MulticloudApplication implements Function<String, String> {
public static void main(String[] args) {
FunctionalSpringApplication.run(MulticloudApplication.class, args);
}
@Override
public String apply(String value) {
return value.toUpperCase();
}
}
AWS Lambda Java Cold Start Duration: 2792.52 ms
Few things to note:
ShadowJar or uber jar equivalent is needed
plugins {
id 'com.github.johnrengelman.shadow' version '5.1.0'
}
shadowJar {No Spring-boot-starter library, it is too heavy (over 100mb)
archiveClassifier = null
dependencies {
exclude(
dependency("org.springframework.cloud:spring-cloud-function-web:${springCloudVersion}"))
}
// 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"
}
}
compile("org.springframework.cloud:spring-cloud-function-adapter-aws") compile("org.springframework.cloud:spring-cloud-starter-function-webflux") compile("org.springframework.boot:spring-boot-configuration-processor")
Now that's out of the way, and we have a 3s Spring Boot Function, its time we delve into the Multicloud deployment
Note: actual code is in this github: https://github.com/overtakerx/function_multicloud_demo
AWS Lambda Deployment
Deploying to AWS Lambda is rather straight forward, create the uber jar, and upload it directly to AWS Lambda (if below 10mb) or to S3 and then to AWS Lambda via S3 url.
After that there is no further configuration needed. The next step is to test that your lambda is working correctly by executing the test functionality provided by AWS Lambda.
Azure Function Deployment
Deploying to Azure Lambda is trickier. As usual, we create the uber jar with gradlew clean build.
Unlike AWS Lambda, Azure require a handler:
public class UppercaseHandler extends AzureSpringBootRequestHandler<String, String> {In addition, it also need Azure gradle plugin and its configurations:
@FunctionName("uppercase")
public String execute(@HttpTrigger(name = "req",
methods = {HttpMethod.GET, HttpMethod.POST},
authLevel = AuthorizationLevel.ANONYMOUS)
HttpRequestMessage<Optional<String>> request,
ExecutionContext context) {
return handleRequest(request.getBody().get(), context);
}
}
plugins {
id "com.microsoft.azure.azurefunctions" version "1.3.0"
}
azurefunctions {
resourceGroup = 'java-functions-group'
appName = 'function-uppercase-multicloud'
pricingTier = 'Consumption'
region = 'australiasoutheast'
appSettings {
WEBSITE_RUN_FROM_PACKAGE = '1'
FUNCTIONS_EXTENSION_VERSION = '~2'
FUNCTIONS_WORKER_RUNTIME = 'java'
MAIN_CLASS = 'com.sevnis.serverlesspoc.multicloud.MulticloudApplication'
}
runtime {
os = 'windows'
}
deployment {
type = 'run_from_blob'
}
}
With all the above configurations taken care of, we can call gradlew azureFunctionsDeploy, which will execute for a while and produce output like as follow:
Next, we can verify in the Azure Functions dashboard:
There we go, we have a single Gradle Project that can deploy seamlessly to both Cloud Services.
References:
Comments
Post a Comment