├── .github └── ISSUE_TEMPLATE.md ├── .gitignore ├── .travis.yml ├── CODE_OF_CONDUCT.md ├── CONTRIBUTING.md ├── LICENSE ├── NOTICE ├── README.md ├── aws-serverless-java-container-core ├── pom.xml └── src │ ├── main │ └── java │ │ └── com │ │ └── amazonaws │ │ └── serverless │ │ ├── exceptions │ │ ├── ContainerInitializationException.java │ │ ├── InvalidRequestEventException.java │ │ └── InvalidResponseObjectException.java │ │ └── proxy │ │ ├── AwsProxyExceptionHandler.java │ │ ├── AwsProxySecurityContextWriter.java │ │ ├── ExceptionHandler.java │ │ ├── LogFormatter.java │ │ ├── RequestReader.java │ │ ├── ResponseWriter.java │ │ ├── SecurityContextWriter.java │ │ ├── internal │ │ ├── LambdaContainerHandler.java │ │ ├── SecurityUtils.java │ │ ├── jaxrs │ │ │ └── AwsProxySecurityContext.java │ │ ├── servlet │ │ │ ├── ApacheCombinedServletLogFormatter.java │ │ │ ├── AwsFilterChainManager.java │ │ │ ├── AwsHttpServletRequest.java │ │ │ ├── AwsHttpServletResponse.java │ │ │ ├── AwsHttpSession.java │ │ │ ├── AwsLambdaServletContainerHandler.java │ │ │ ├── AwsProxyHttpServletRequest.java │ │ │ ├── AwsProxyHttpServletRequestReader.java │ │ │ ├── AwsProxyHttpServletResponseWriter.java │ │ │ ├── AwsProxyRequestDispatcher.java │ │ │ ├── AwsProxyRequestPart.java │ │ │ ├── AwsServletContext.java │ │ │ ├── FilterChainHolder.java │ │ │ ├── FilterChainManager.java │ │ │ ├── FilterHolder.java │ │ │ └── filters │ │ │ │ └── UrlPathValidator.java │ │ └── testutils │ │ │ ├── AwsProxyRequestBuilder.java │ │ │ ├── MockLambdaConsoleLogger.java │ │ │ ├── MockLambdaContext.java │ │ │ └── Timer.java │ │ └── model │ │ ├── AlbContext.java │ │ ├── ApiGatewayAuthorizerContext.java │ │ ├── ApiGatewayRequestIdentity.java │ │ ├── AwsProxyRequest.java │ │ ├── AwsProxyRequestContext.java │ │ ├── AwsProxyResponse.java │ │ ├── CognitoAuthorizerClaims.java │ │ ├── ContainerConfig.java │ │ ├── ErrorModel.java │ │ ├── Headers.java │ │ └── MultiValuedTreeMap.java │ └── test │ └── java │ └── com │ └── amazonaws │ └── serverless │ └── proxy │ ├── AwsProxyExceptionHandlerTest.java │ ├── AwsProxySecurityContextWriterTest.java │ ├── RequestReaderTest.java │ ├── internal │ ├── jaxrs │ │ └── AwsProxySecurityContextTest.java │ └── servlet │ │ ├── AwsFilterChainManagerTest.java │ │ ├── AwsHttpServletRequestTest.java │ │ ├── AwsHttpServletResponseTest.java │ │ ├── AwsProxyHttpServletRequestFormTest.java │ │ ├── AwsProxyHttpServletRequestReaderTest.java │ │ ├── AwsProxyHttpServletRequestTest.java │ │ ├── AwsServletContextTest.java │ │ └── FilterHolderTest.java │ └── model │ ├── ApiGatewayAuthorizerContextTest.java │ ├── AwsProxyRequestTest.java │ ├── CognitoAuthorizerClaimsTest.java │ └── MultiValuedTreeMapTest.java ├── aws-serverless-java-container-jersey ├── pom.xml └── src │ ├── main │ └── java │ │ └── com │ │ └── amazonaws │ │ └── serverless │ │ └── proxy │ │ └── jersey │ │ ├── JerseyHandlerFilter.java │ │ ├── JerseyLambdaContainerHandler.java │ │ ├── JerseyServletResponseWriter.java │ │ └── suppliers │ │ ├── AwsProxyServletContextSupplier.java │ │ ├── AwsProxyServletRequestSupplier.java │ │ └── AwsProxyServletResponseSupplier.java │ └── test │ └── java │ └── com │ └── amazonaws │ └── serverless │ └── proxy │ └── jersey │ ├── EchoJerseyResource.java │ ├── JerseyAwsProxyTest.java │ ├── JerseyInjectionTest.java │ ├── JerseyParamEncodingTest.java │ ├── model │ ├── MapResponseModel.java │ └── SingleValueModel.java │ └── providers │ ├── CustomExceptionMapper.java │ └── ServletRequestFilter.java ├── aws-serverless-java-container-spark ├── pom.xml └── src │ ├── main │ └── java │ │ └── com │ │ └── amazonaws │ │ └── serverless │ │ └── proxy │ │ └── spark │ │ ├── SparkLambdaContainerHandler.java │ │ └── embeddedserver │ │ ├── LambdaEmbeddedServer.java │ │ └── LambdaEmbeddedServerFactory.java │ └── test │ └── java │ └── com │ └── amazonaws │ └── serverless │ └── proxy │ └── spark │ ├── HelloWorldSparkStreamTest.java │ ├── HelloWorldSparkTest.java │ ├── InitExceptionHandlerTest.java │ ├── SparkLambdaContainerHandlerTest.java │ ├── embeddedserver │ └── LambdaEmbeddedServerTest.java │ └── filter │ ├── CustomHeaderFilter.java │ └── UnauthenticatedFilter.java ├── aws-serverless-java-container-spring ├── pom.xml └── src │ ├── main │ └── java │ │ └── com │ │ └── amazonaws │ │ └── serverless │ │ └── proxy │ │ └── spring │ │ ├── LambdaSpringApplicationInitializer.java │ │ ├── SpringBootLambdaContainerHandler.java │ │ └── SpringLambdaContainerHandler.java │ └── test │ ├── java │ └── com │ │ └── amazonaws │ │ └── serverless │ │ └── proxy │ │ └── spring │ │ ├── SpringAwsProxyTest.java │ │ ├── SpringBootAppTest.java │ │ ├── SpringServletContextTest.java │ │ ├── StaticAppProxyTest.java │ │ ├── echoapp │ │ ├── ContextResource.java │ │ ├── CustomHeaderFilter.java │ │ ├── EchoResource.java │ │ ├── EchoSpringAppConfig.java │ │ ├── ProfileOverrideConfig.java │ │ ├── RestControllerAdvice.java │ │ ├── UnauthenticatedFilter.java │ │ ├── model │ │ │ ├── MapResponseModel.java │ │ │ ├── SingleValueModel.java │ │ │ └── ValidatedUserModel.java │ │ └── profile │ │ │ ├── DefaultProfileConfiguration.java │ │ │ ├── DefaultProfileResource.java │ │ │ └── OverrideProfileConfiguration.java │ │ ├── profile │ │ └── SpringProfileTest.java │ │ ├── springbootapp │ │ ├── LambdaHandler.java │ │ ├── TestApplication.java │ │ └── TestController.java │ │ └── staticapp │ │ ├── LambdaHandler.java │ │ └── MyController.java │ └── resources │ ├── application-override.properties │ ├── application.properties │ ├── static │ └── static.html │ ├── staticAppContext.xml │ └── templates │ └── sample.html ├── aws-serverless-java-container-struts2 ├── pom.xml └── src │ ├── main │ └── java │ │ └── com │ │ └── amazonaws │ │ └── serverless │ │ └── proxy │ │ └── struts2 │ │ ├── Struts2LambdaContainerHandler.java │ │ └── Struts2LambdaHandler.java │ └── test │ ├── java │ └── com │ │ └── amazonaws │ │ └── serverless │ │ └── proxy │ │ └── struts2 │ │ ├── Struts2AwsProxyTest.java │ │ └── echoapp │ │ ├── EchoAction.java │ │ └── EchoRequestInfoAction.java │ └── resources │ └── struts.xml ├── aws-serverless-jersey-archetype ├── pom.xml └── src │ ├── main │ └── resources │ │ ├── META-INF │ │ └── maven │ │ │ └── archetype-metadata.xml │ │ └── archetype-resources │ │ ├── README.md │ │ ├── build.gradle │ │ ├── pom.xml │ │ ├── sam.yaml │ │ └── src │ │ ├── assembly │ │ └── bin.xml │ │ ├── main │ │ └── java │ │ │ ├── StreamLambdaHandler.java │ │ │ └── resource │ │ │ └── PingResource.java │ │ └── test │ │ └── java │ │ └── StreamLambdaHandlerTest.java │ └── test │ └── resources │ └── projects │ └── base │ ├── archetype.properties │ └── goal.txt ├── aws-serverless-spark-archetype ├── pom.xml └── src │ ├── main │ └── resources │ │ ├── META-INF │ │ └── maven │ │ │ └── archetype-metadata.xml │ │ └── archetype-resources │ │ ├── README.md │ │ ├── build.gradle │ │ ├── pom.xml │ │ ├── sam.yaml │ │ └── src │ │ ├── assembly │ │ └── bin.xml │ │ ├── main │ │ └── java │ │ │ ├── SparkResources.java │ │ │ ├── StreamLambdaHandler.java │ │ │ └── util │ │ │ └── JsonTransformer.java │ │ └── test │ │ └── java │ │ └── StreamLambdaHandlerTest.java │ └── test │ └── resources │ └── projects │ └── base │ ├── archetype.properties │ └── goal.txt ├── aws-serverless-spring-archetype ├── pom.xml └── src │ ├── main │ └── resources │ │ ├── META-INF │ │ └── maven │ │ │ └── archetype-metadata.xml │ │ └── archetype-resources │ │ ├── README.md │ │ ├── build.gradle │ │ ├── pom.xml │ │ ├── sam.yaml │ │ └── src │ │ ├── assembly │ │ └── bin.xml │ │ ├── main │ │ ├── java │ │ │ ├── SpringApiConfig.java │ │ │ ├── StreamLambdaHandler.java │ │ │ └── controller │ │ │ │ └── PingController.java │ │ └── resources │ │ │ └── log4j2.xml │ │ └── test │ │ └── java │ │ └── StreamLambdaHandlerTest.java │ └── test │ └── resources │ └── projects │ └── base │ ├── archetype.properties │ └── goal.txt ├── aws-serverless-springboot-archetype ├── pom.xml └── src │ ├── main │ └── resources │ │ ├── META-INF │ │ └── maven │ │ │ └── archetype-metadata.xml │ │ └── archetype-resources │ │ ├── README.md │ │ ├── build.gradle │ │ ├── pom.xml │ │ ├── sam.yaml │ │ └── src │ │ ├── assembly │ │ └── bin.xml │ │ ├── main │ │ ├── java │ │ │ ├── Application.java │ │ │ ├── StreamLambdaHandler.java │ │ │ └── controller │ │ │ │ └── PingController.java │ │ └── resources │ │ │ └── application.properties │ │ └── test │ │ └── java │ │ └── StreamLambdaHandlerTest.java │ └── test │ └── resources │ └── projects │ └── base │ ├── archetype.properties │ └── goal.txt ├── aws-serverless-springboot2-archetype ├── pom.xml └── src │ ├── main │ └── resources │ │ ├── META-INF │ │ └── maven │ │ │ └── archetype-metadata.xml │ │ └── archetype-resources │ │ ├── README.md │ │ ├── build.gradle │ │ ├── pom.xml │ │ ├── sam.yaml │ │ └── src │ │ ├── assembly │ │ └── bin.xml │ │ ├── main │ │ ├── java │ │ │ ├── Application.java │ │ │ ├── StreamLambdaHandler.java │ │ │ └── controller │ │ │ │ └── PingController.java │ │ └── resources │ │ │ └── application.properties │ │ └── test │ │ └── java │ │ └── StreamLambdaHandlerTest.java │ └── test │ └── resources │ └── projects │ └── base │ ├── archetype.properties │ └── goal.txt ├── aws-serverless-struts2-archetype ├── pom.xml └── src │ ├── main │ └── resources │ │ ├── META-INF │ │ └── maven │ │ │ └── archetype-metadata.xml │ │ └── archetype-resources │ │ ├── README.md │ │ ├── build.gradle │ │ ├── pom.xml │ │ ├── sam.yaml │ │ └── src │ │ ├── main │ │ ├── assembly │ │ │ └── dist.xml │ │ ├── java │ │ │ └── actions │ │ │ │ └── PingController.java │ │ └── resources │ │ │ ├── application.properties │ │ │ ├── log4j2.xml │ │ │ └── struts.xml │ │ └── test │ │ └── java │ │ └── StreamLambdaHandlerTest.java │ └── test │ └── resources │ └── projects │ └── base │ ├── archetype.properties │ └── goal.txt ├── owasp-suppression.xml ├── pom.xml ├── samples ├── jersey │ └── pet-store │ │ ├── README.md │ │ ├── build.gradle │ │ ├── pom.xml │ │ ├── sam.yaml │ │ └── src │ │ ├── assembly │ │ └── bin.xml │ │ └── main │ │ └── java │ │ └── com │ │ └── amazonaws │ │ └── serverless │ │ └── sample │ │ └── jersey │ │ ├── PetsResource.java │ │ ├── StreamLambdaHandler.java │ │ └── model │ │ ├── Error.java │ │ ├── Pet.java │ │ └── PetData.java ├── spark │ └── pet-store │ │ ├── README.md │ │ ├── build.gradle │ │ ├── pom.xml │ │ ├── sam.yaml │ │ └── src │ │ ├── assembly │ │ └── bin.xml │ │ └── main │ │ └── java │ │ └── com │ │ └── amazonaws │ │ └── serverless │ │ └── sample │ │ └── spark │ │ ├── JsonTransformer.java │ │ ├── SparkResources.java │ │ ├── StreamLambdaHandler.java │ │ ├── filter │ │ └── CognitoIdentityFilter.java │ │ └── model │ │ ├── Error.java │ │ ├── Pet.java │ │ └── PetData.java ├── spring │ └── pet-store │ │ ├── README.md │ │ ├── build.gradle │ │ ├── pom.xml │ │ ├── sam.yaml │ │ └── src │ │ ├── assembly │ │ └── bin.xml │ │ └── main │ │ └── java │ │ └── com │ │ └── amazonaws │ │ └── serverless │ │ └── sample │ │ └── spring │ │ ├── PetStoreSpringAppConfig.java │ │ ├── PetsController.java │ │ ├── StreamLambdaHandler.java │ │ ├── filter │ │ └── CognitoIdentityFilter.java │ │ └── model │ │ ├── Error.java │ │ ├── Pet.java │ │ └── PetData.java ├── springboot │ └── pet-store │ │ ├── README.md │ │ ├── build.gradle │ │ ├── pom.xml │ │ ├── serverless.yml │ │ └── src │ │ ├── assembly │ │ └── bin.xml │ │ └── main │ │ ├── java │ │ └── com │ │ │ └── amazonaws │ │ │ └── serverless │ │ │ └── sample │ │ │ └── springboot │ │ │ ├── Application.java │ │ │ ├── StreamLambdaHandler.java │ │ │ ├── controller │ │ │ └── PetsController.java │ │ │ ├── filter │ │ │ └── CognitoIdentityFilter.java │ │ │ └── model │ │ │ ├── Error.java │ │ │ ├── Pet.java │ │ │ └── PetData.java │ │ └── resources │ │ └── logback.xml ├── springboot2 │ └── pet-store │ │ ├── README.md │ │ ├── build.gradle │ │ ├── pom.xml │ │ ├── sam.yaml │ │ └── src │ │ ├── assembly │ │ └── bin.xml │ │ └── main │ │ ├── java │ │ └── com │ │ │ └── amazonaws │ │ │ └── serverless │ │ │ └── sample │ │ │ └── springboot2 │ │ │ ├── Application.java │ │ │ ├── StreamLambdaHandler.java │ │ │ ├── controller │ │ │ └── PetsController.java │ │ │ ├── filter │ │ │ └── CognitoIdentityFilter.java │ │ │ └── model │ │ │ ├── Error.java │ │ │ ├── Pet.java │ │ │ └── PetData.java │ │ └── resources │ │ └── logback.xml └── struts │ └── pet-store │ ├── README.md │ ├── build.gradle │ ├── pom.xml │ ├── sam.yaml │ └── src │ └── main │ ├── assembly │ └── dist.xml │ ├── java │ └── com │ │ └── amazonaws │ │ └── serverless │ │ └── sample │ │ └── struts │ │ ├── actions │ │ └── PetsController.java │ │ └── model │ │ ├── Pet.java │ │ └── PetData.java │ └── resources │ ├── log4j2.xml │ └── struts.xml └── travis.sh /.github/ISSUE_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | * Framework version: XX 2 | * Implementations: Jersey / Spring / Spring Boot / Spark 3 | 4 | ## Scenario 5 | 6 | ## Expected behavior 7 | 8 | ## Actual behavior 9 | 10 | ## Steps to reproduce 11 | 12 | ## Full log output 13 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *.class 2 | 3 | # Package Files # 4 | *.jar 5 | *.war 6 | *.ear 7 | 8 | # Idea project files 9 | .idea/ 10 | *.iml 11 | 12 | # virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml 13 | hs_err_pid* 14 | 15 | # output folder # 16 | target/ 17 | pom.xml.tag 18 | pom.xml.releaseBackup 19 | pom.xml.versionsBackup 20 | pom.xml.next 21 | release.properties 22 | dependency-reduced-pom.xml 23 | buildNumber.properties 24 | .mvn/timing.properties 25 | .gradle/ 26 | gradle/ 27 | build/ 28 | gradlew* 29 | 30 | # Exclude maven wrapper 31 | !/.mvn/wrapper/maven-wrapper.jar 32 | 33 | # Exclude compiled cloudformation 34 | .serverless -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: java 2 | dist: trusty 3 | jdk: 4 | - openjdk8 5 | addons: 6 | apt: 7 | update: true 8 | before_install: 9 | - wget https://services.gradle.org/distributions/gradle-5.0-bin.zip 10 | - mkdir /opt/gradle 11 | - unzip -d /opt/gradle gradle-5.0-bin.zip 12 | - export GRADLE=/opt/gradle/gradle-5.0/bin/gradle 13 | install: true 14 | script: ./travis.sh 15 | -------------------------------------------------------------------------------- /CODE_OF_CONDUCT.md: -------------------------------------------------------------------------------- 1 | ## Code of Conduct 2 | This project has adopted the [Amazon Open Source Code of Conduct](https://aws.github.io/code-of-conduct). 3 | For more information see the [Code of Conduct FAQ](https://aws.github.io/code-of-conduct-faq) or contact 4 | opensource-codeofconduct@amazon.com with any additional questions or comments. 5 | -------------------------------------------------------------------------------- /NOTICE: -------------------------------------------------------------------------------- 1 | AWS Serverless Java Container 2 | Copyright 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved. -------------------------------------------------------------------------------- /aws-serverless-java-container-core/src/main/java/com/amazonaws/serverless/exceptions/ContainerInitializationException.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016 Amazon.com, Inc. or its affiliates. All Rights Reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"). You may not use this file except in compliance 5 | * with the License. A copy of the License is located at 6 | * 7 | * http://aws.amazon.com/apache2.0/ 8 | * 9 | * or in the "license" file accompanying this file. This file is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES 10 | * OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions 11 | * and limitations under the License. 12 | */ 13 | package com.amazonaws.serverless.exceptions; 14 | 15 | 16 | import com.amazonaws.serverless.proxy.RequestReader; 17 | 18 | 19 | /** 20 | * This exception is thrown when the ContainerHandler fails to parse a request object or input stream into the 21 | * object required by the Container. The exception is thrown by implementing sub-classes of RequestReader 22 | * 23 | * @see RequestReader 24 | */ 25 | public class ContainerInitializationException extends Exception { 26 | public ContainerInitializationException(String message, Exception e) { 27 | super(message, e); 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /aws-serverless-java-container-core/src/main/java/com/amazonaws/serverless/exceptions/InvalidRequestEventException.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016 Amazon.com, Inc. or its affiliates. All Rights Reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"). You may not use this file except in compliance 5 | * with the License. A copy of the License is located at 6 | * 7 | * http://aws.amazon.com/apache2.0/ 8 | * 9 | * or in the "license" file accompanying this file. This file is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES 10 | * OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions 11 | * and limitations under the License. 12 | */ 13 | package com.amazonaws.serverless.exceptions; 14 | 15 | 16 | import com.amazonaws.serverless.proxy.RequestReader; 17 | 18 | 19 | /** 20 | * This exception is thrown when the ContainerHandler fails to parse a request object or input stream into the 21 | * object required by the Container. The exception is thrown by implementing sub-classes of RequestReader 22 | * 23 | * @see RequestReader 24 | */ 25 | public class InvalidRequestEventException extends Exception { 26 | public InvalidRequestEventException(String message, Exception e) { 27 | super(message, e); 28 | } 29 | 30 | public InvalidRequestEventException(String message) { 31 | super(message); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /aws-serverless-java-container-core/src/main/java/com/amazonaws/serverless/exceptions/InvalidResponseObjectException.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016 Amazon.com, Inc. or its affiliates. All Rights Reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"). You may not use this file except in compliance 5 | * with the License. A copy of the License is located at 6 | * 7 | * http://aws.amazon.com/apache2.0/ 8 | * 9 | * or in the "license" file accompanying this file. This file is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES 10 | * OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions 11 | * and limitations under the License. 12 | */ 13 | package com.amazonaws.serverless.exceptions; 14 | 15 | 16 | import com.amazonaws.serverless.proxy.ResponseWriter; 17 | 18 | 19 | /** 20 | * This exception is thrown when the ContainerHandler cannot transform the Container response into a valid return value 21 | * for the Lambda function. This exception is thrown by implementing sub-classes of ResponseWriter 22 | * 23 | * @see ResponseWriter 24 | */ 25 | public class InvalidResponseObjectException extends Exception { 26 | public InvalidResponseObjectException(String message, Exception e) { 27 | super(message, e); 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /aws-serverless-java-container-core/src/main/java/com/amazonaws/serverless/proxy/AwsProxySecurityContextWriter.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016 Amazon.com, Inc. or its affiliates. All Rights Reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"). You may not use this file except in compliance 5 | * with the License. A copy of the License is located at 6 | * 7 | * http://aws.amazon.com/apache2.0/ 8 | * 9 | * or in the "license" file accompanying this file. This file is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES 10 | * OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions 11 | * and limitations under the License. 12 | */ 13 | package com.amazonaws.serverless.proxy; 14 | 15 | import com.amazonaws.serverless.proxy.internal.jaxrs.AwsProxySecurityContext; 16 | import com.amazonaws.serverless.proxy.model.AwsProxyRequest; 17 | import com.amazonaws.services.lambda.runtime.Context; 18 | 19 | import javax.ws.rs.core.SecurityContext; 20 | 21 | /** 22 | * Default implementation of SecurityContextWriter. Creates a SecurityContext object based on an API Gateway 23 | * event and the Lambda context. This returns the default AwsProxySecurityContext instance. 24 | */ 25 | public class AwsProxySecurityContextWriter implements SecurityContextWriter { 26 | 27 | //------------------------------------------------------------- 28 | // Variables - Private - Static 29 | //------------------------------------------------------------- 30 | 31 | private AwsProxySecurityContext currentContext; 32 | 33 | 34 | //------------------------------------------------------------- 35 | // Implementation - SecurityContextWriter 36 | //------------------------------------------------------------- 37 | 38 | @Override 39 | public SecurityContext writeSecurityContext(AwsProxyRequest event, Context lambdaContext) { 40 | currentContext = new AwsProxySecurityContext(lambdaContext, event); 41 | 42 | return currentContext; 43 | } 44 | 45 | 46 | //------------------------------------------------------------- 47 | // Methods - Getter/Setter 48 | //------------------------------------------------------------- 49 | 50 | public AwsProxySecurityContext getCurrentContext() { 51 | return currentContext; 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /aws-serverless-java-container-core/src/main/java/com/amazonaws/serverless/proxy/ExceptionHandler.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016 Amazon.com, Inc. or its affiliates. All Rights Reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"). You may not use this file except in compliance 5 | * with the License. A copy of the License is located at 6 | * 7 | * http://aws.amazon.com/apache2.0/ 8 | * 9 | * or in the "license" file accompanying this file. This file is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES 10 | * OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions 11 | * and limitations under the License. 12 | */ 13 | package com.amazonaws.serverless.proxy; 14 | 15 | import java.io.IOException; 16 | import java.io.OutputStream; 17 | 18 | /** 19 | * Implementing sub-classes of this interface are used by container objects to handle exceptions. Normally, exceptions are 20 | * handled by the client applications directly within the container and a valid HTTP response is expected. This handler 21 | * is used for exceptions thrown by the library while marshalling and unmarshalling requests and responses. 22 | * 23 | * The interface declares two methods. A typed handle method for requests that are being proxied using a 24 | * request and response type LambdaContainerHandler, and a stream-based 25 | * handle method for 26 | * Lambda's RequestStreamHandler. 27 | * 28 | * @see com.amazonaws.serverless.proxy.internal.LambdaContainerHandler 29 | * 30 | * @param The type for the Lambda return value. Implementing sub-classes are required to return a valid 31 | * instance of the response type. 32 | */ 33 | public interface ExceptionHandler { 34 | /** 35 | * The handle method is called by the container object whenever an exception occurs in the proxy method 36 | * for typed calls 37 | * @param ex The exception thrown by the application 38 | * @return A valid response object 39 | */ 40 | ResponseType handle(Throwable ex); 41 | 42 | /** 43 | * This handle implementation is called whenever an exception occurs in the stream-based proxy method. 44 | * @param ex The exception thrown by the application 45 | * @param stream The OutputStream where the exception will be written 46 | * @throws IOException When the exception handler fails to write to the OutputStream 47 | */ 48 | void handle(Throwable ex, OutputStream stream) 49 | throws IOException; 50 | } 51 | -------------------------------------------------------------------------------- /aws-serverless-java-container-core/src/main/java/com/amazonaws/serverless/proxy/LogFormatter.java: -------------------------------------------------------------------------------- 1 | package com.amazonaws.serverless.proxy; 2 | 3 | 4 | import javax.ws.rs.core.SecurityContext; 5 | 6 | 7 | /** 8 | * Implementations of the log formatter interface are used by {@link com.amazonaws.serverless.proxy.internal.LambdaContainerHandler} class to log each request 9 | * processed in the container. You can set the log formatter using the {@link com.amazonaws.serverless.proxy.internal.LambdaContainerHandler#setLogFormatter(LogFormatter)} 10 | * method. The servlet implementation of the container ({@link com.amazonaws.serverless.proxy.internal.servlet.AwsLambdaServletContainerHandler} includes a 11 | * default log formatter that produces Apache combined logs. {@link com.amazonaws.serverless.proxy.internal.servlet.ApacheCombinedServletLogFormatter}. 12 | * @param The request type used by the underlying framework 13 | * @param The response type produced by the underlying framework 14 | */ 15 | public interface LogFormatter { 16 | /** 17 | * The format method is called by the container handler to produce the log line that should be written to the logs. 18 | * @param req The incoming request 19 | * @param res The completed response 20 | * @param ctx The security context produced based on the request 21 | * @return The log line 22 | */ 23 | String format(ContainerRequestType req, ContainerResponseType res, SecurityContext ctx); 24 | } 25 | -------------------------------------------------------------------------------- /aws-serverless-java-container-core/src/main/java/com/amazonaws/serverless/proxy/SecurityContextWriter.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016 Amazon.com, Inc. or its affiliates. All Rights Reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"). You may not use this file except in compliance 5 | * with the License. A copy of the License is located at 6 | * 7 | * http://aws.amazon.com/apache2.0/ 8 | * 9 | * or in the "license" file accompanying this file. This file is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES 10 | * OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions 11 | * and limitations under the License. 12 | */ 13 | package com.amazonaws.serverless.proxy; 14 | 15 | import com.amazonaws.serverless.proxy.model.AwsProxyRequest; 16 | import com.amazonaws.services.lambda.runtime.Context; 17 | 18 | import javax.ws.rs.core.SecurityContext; 19 | 20 | /** 21 | * This object is used by the container implementation to generated a Jax-Rs SecurityContext object from the 22 | * incoming AWS Lambda event. 23 | * @param The AWS Lambda event type 24 | */ 25 | public interface SecurityContextWriter { 26 | /** 27 | * Called by the container implementation to generate a SecurityContext given an incoming event. The 28 | * library includes a default implementation that reads from the AWS_PROXY integration events. 29 | * 30 | * @see AwsProxySecurityContextWriter 31 | * @see AwsProxyRequest 32 | * 33 | * @param event The incoming Lambda event 34 | * @param lambdaContext The context for the AWS Lambda function 35 | * @return A populated SecurityContext object 36 | */ 37 | SecurityContext writeSecurityContext(final RequestType event, final Context lambdaContext); 38 | } 39 | -------------------------------------------------------------------------------- /aws-serverless-java-container-core/src/main/java/com/amazonaws/serverless/proxy/internal/servlet/AwsFilterChainManager.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"). You may not use this file except in compliance 5 | * with the License. A copy of the License is located at 6 | * 7 | * http://aws.amazon.com/apache2.0/ 8 | * 9 | * or in the "license" file accompanying this file. This file is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES 10 | * OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions 11 | * and limitations under the License. 12 | */ 13 | package com.amazonaws.serverless.proxy.internal.servlet; 14 | 15 | import java.util.Map; 16 | 17 | /** 18 | * This implementation of the FilterChainManager object uses the AwsServletContext object 19 | * to extract a list of FilterHolders 20 | */ 21 | public class AwsFilterChainManager extends FilterChainManager { 22 | 23 | //------------------------------------------------------------- 24 | // Constructors 25 | //------------------------------------------------------------- 26 | 27 | /** 28 | * Creates a new FilterChainManager for the given servlet context 29 | * @param context An initialized AwsServletContext object 30 | */ 31 | AwsFilterChainManager(AwsServletContext context) { 32 | super(context); 33 | } 34 | 35 | //------------------------------------------------------------- 36 | // Implementation - FilterChainManager 37 | //------------------------------------------------------------- 38 | 39 | /** 40 | * Returns the filter holders stored in the AwsServletContext object 41 | * @return The map of filter holders 42 | */ 43 | @Override 44 | protected Map getFilterHolders() { 45 | return servletContext.getFilterHolders(); 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /aws-serverless-java-container-core/src/main/java/com/amazonaws/serverless/proxy/internal/testutils/MockLambdaConsoleLogger.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016 Amazon.com, Inc. or its affiliates. All Rights Reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"). You may not use this file except in compliance 5 | * with the License. A copy of the License is located at 6 | * 7 | * http://aws.amazon.com/apache2.0/ 8 | * 9 | * or in the "license" file accompanying this file. This file is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES 10 | * OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions 11 | * and limitations under the License. 12 | */ 13 | package com.amazonaws.serverless.proxy.internal.testutils; 14 | 15 | import com.amazonaws.services.lambda.runtime.LambdaLogger; 16 | 17 | import java.nio.charset.Charset; 18 | 19 | 20 | /** 21 | * Mock LambdaLogger object that prints output to the console 22 | */ 23 | public class MockLambdaConsoleLogger implements LambdaLogger { 24 | 25 | //------------------------------------------------------------- 26 | // Implementation - LambdaLogger 27 | //------------------------------------------------------------- 28 | 29 | @Override 30 | public void log(String s) { 31 | System.out.println(s); 32 | } 33 | 34 | 35 | @Override 36 | public void log(byte[] bytes) { 37 | System.out.println(new String(bytes, Charset.defaultCharset())); 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /aws-serverless-java-container-core/src/main/java/com/amazonaws/serverless/proxy/internal/testutils/MockLambdaContext.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016 Amazon.com, Inc. or its affiliates. All Rights Reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"). You may not use this file except in compliance 5 | * with the License. A copy of the License is located at 6 | * 7 | * http://aws.amazon.com/apache2.0/ 8 | * 9 | * or in the "license" file accompanying this file. This file is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES 10 | * OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions 11 | * and limitations under the License. 12 | */ 13 | package com.amazonaws.serverless.proxy.internal.testutils; 14 | 15 | import com.amazonaws.services.lambda.runtime.ClientContext; 16 | import com.amazonaws.services.lambda.runtime.CognitoIdentity; 17 | import com.amazonaws.services.lambda.runtime.Context; 18 | import com.amazonaws.services.lambda.runtime.LambdaLogger; 19 | 20 | /** 21 | * Mock Lambda context. 22 | */ 23 | public class MockLambdaContext implements Context { 24 | 25 | //------------------------------------------------------------- 26 | // Variables - Private - Static 27 | //------------------------------------------------------------- 28 | 29 | private static LambdaLogger logger = new MockLambdaConsoleLogger(); 30 | 31 | 32 | //------------------------------------------------------------- 33 | // Implementation - Context 34 | //------------------------------------------------------------- 35 | 36 | 37 | @Override 38 | public String getAwsRequestId() { 39 | return null; 40 | } 41 | 42 | 43 | @Override 44 | public String getLogGroupName() { 45 | return null; 46 | } 47 | 48 | 49 | @Override 50 | public String getLogStreamName() { 51 | return null; 52 | } 53 | 54 | 55 | @Override 56 | public String getFunctionName() { 57 | return null; 58 | } 59 | 60 | 61 | @Override 62 | public String getFunctionVersion() { 63 | return null; 64 | } 65 | 66 | 67 | @Override 68 | public String getInvokedFunctionArn() { 69 | return null; 70 | } 71 | 72 | 73 | @Override 74 | public CognitoIdentity getIdentity() { 75 | return null; 76 | } 77 | 78 | 79 | @Override 80 | public ClientContext getClientContext() { 81 | return null; 82 | } 83 | 84 | 85 | @Override 86 | public int getRemainingTimeInMillis() { 87 | return 0; 88 | } 89 | 90 | 91 | @Override 92 | public int getMemoryLimitInMB() { 93 | return 0; 94 | } 95 | 96 | 97 | @Override 98 | public LambdaLogger getLogger() { 99 | return logger; 100 | } 101 | } 102 | -------------------------------------------------------------------------------- /aws-serverless-java-container-core/src/main/java/com/amazonaws/serverless/proxy/internal/testutils/Timer.java: -------------------------------------------------------------------------------- 1 | package com.amazonaws.serverless.proxy.internal.testutils; 2 | 3 | 4 | import java.util.LinkedHashMap; 5 | import java.util.Map; 6 | 7 | 8 | public final class Timer { 9 | private volatile static Map timers = new LinkedHashMap<>(); 10 | private volatile static boolean enabled = false; 11 | 12 | public static void start(String timerName) { 13 | if (!enabled) { 14 | return; 15 | } 16 | 17 | timers.put(timerName, new TimerInfo(System.currentTimeMillis())); 18 | } 19 | 20 | public static long stop(String timerName) { 21 | if (!enabled) { 22 | return 0L; 23 | } 24 | 25 | TimerInfo info = timers.get(timerName); 26 | if (info == null) { 27 | throw new IllegalArgumentException("Could not find timer " + timerName); 28 | } 29 | 30 | long stopTime = System.currentTimeMillis(); 31 | info.stop(stopTime); 32 | 33 | return stopTime; 34 | } 35 | 36 | 37 | public static Map getTimers() { 38 | return timers; 39 | } 40 | 41 | public static TimerInfo getTimer(String timerName) { 42 | return timers.get(timerName); 43 | } 44 | 45 | public static void enable() { 46 | enabled = true; 47 | } 48 | 49 | public static void disable() { 50 | enabled = false; 51 | } 52 | 53 | private static class TimerInfo { 54 | private long startTime; 55 | private long stopTime; 56 | private long duration; 57 | 58 | public TimerInfo(long start) { 59 | startTime = start; 60 | } 61 | 62 | public void stop(long stop) { 63 | stopTime = stop; 64 | duration = stopTime - startTime; 65 | } 66 | 67 | public long getStartTime() { 68 | return startTime; 69 | } 70 | 71 | public long getStopTime() { 72 | return stopTime; 73 | } 74 | 75 | 76 | public long getDuration() { 77 | return duration; 78 | } 79 | } 80 | } 81 | -------------------------------------------------------------------------------- /aws-serverless-java-container-core/src/main/java/com/amazonaws/serverless/proxy/model/AlbContext.java: -------------------------------------------------------------------------------- 1 | package com.amazonaws.serverless.proxy.model; 2 | 3 | 4 | /*** 5 | * Context passed by ALB proxy events 6 | */ 7 | public class AlbContext { 8 | private String targetGroupArn; 9 | 10 | 11 | public String getTargetGroupArn() { 12 | return targetGroupArn; 13 | } 14 | 15 | 16 | public void setTargetGroupArn(String targetGroupArn) { 17 | this.targetGroupArn = targetGroupArn; 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /aws-serverless-java-container-core/src/main/java/com/amazonaws/serverless/proxy/model/ApiGatewayAuthorizerContext.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016 Amazon.com, Inc. or its affiliates. All Rights Reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"). You may not use this file except in compliance 5 | * with the License. A copy of the License is located at 6 | * 7 | * http://aws.amazon.com/apache2.0/ 8 | * 9 | * or in the "license" file accompanying this file. This file is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES 10 | * OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions 11 | * and limitations under the License. 12 | */ 13 | package com.amazonaws.serverless.proxy.model; 14 | 15 | import com.fasterxml.jackson.annotation.JsonAnyGetter; 16 | import com.fasterxml.jackson.annotation.JsonAnySetter; 17 | import com.fasterxml.jackson.annotation.JsonIgnoreProperties; 18 | 19 | import java.util.HashMap; 20 | import java.util.Map; 21 | 22 | 23 | /** 24 | * Context object used for custom authorizers and Cognito User Pool authorizers. 25 | * 26 | * Custom authorizers populate the principalId field. All other custom values 27 | * returned by the authorizer are accessible via the getContextValue method. 28 | * 29 | * Cognito User Pool authorizers populate the claims object. 30 | */ 31 | @JsonIgnoreProperties(ignoreUnknown = true) 32 | public class ApiGatewayAuthorizerContext { 33 | 34 | //------------------------------------------------------------- 35 | // Variables - Private 36 | //------------------------------------------------------------- 37 | 38 | private Map contextProperties = new HashMap<>(); 39 | private String principalId; 40 | private CognitoAuthorizerClaims claims; 41 | 42 | //------------------------------------------------------------- 43 | // Methods - Public 44 | //------------------------------------------------------------- 45 | 46 | @JsonAnyGetter 47 | public String getContextValue(String key) { 48 | return contextProperties.get(key); 49 | } 50 | 51 | 52 | @JsonAnySetter 53 | public void setContextValue(String key, String value) { 54 | contextProperties.put(key, value); 55 | } 56 | 57 | 58 | //------------------------------------------------------------- 59 | // Methods - Getter/Setter 60 | //------------------------------------------------------------- 61 | 62 | public String getPrincipalId() { 63 | return principalId; 64 | } 65 | 66 | 67 | public void setPrincipalId(String principalId) { 68 | this.principalId = principalId; 69 | } 70 | 71 | 72 | public CognitoAuthorizerClaims getClaims() { 73 | return claims; 74 | } 75 | 76 | 77 | public void setClaims(CognitoAuthorizerClaims claims) { 78 | this.claims = claims; 79 | } 80 | } 81 | -------------------------------------------------------------------------------- /aws-serverless-java-container-core/src/main/java/com/amazonaws/serverless/proxy/model/ErrorModel.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016 Amazon.com, Inc. or its affiliates. All Rights Reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"). You may not use this file except in compliance 5 | * with the License. A copy of the License is located at 6 | * 7 | * http://aws.amazon.com/apache2.0/ 8 | * 9 | * or in the "license" file accompanying this file. This file is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES 10 | * OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions 11 | * and limitations under the License. 12 | */ 13 | package com.amazonaws.serverless.proxy.model; 14 | 15 | /** 16 | * Default error response model. This object is used by the AwsProxyExceptionHandler object. 17 | */ 18 | public class ErrorModel { 19 | 20 | //------------------------------------------------------------- 21 | // Variables - Private 22 | //------------------------------------------------------------- 23 | 24 | private String message; 25 | 26 | 27 | //------------------------------------------------------------- 28 | // Constructors 29 | //------------------------------------------------------------- 30 | 31 | public ErrorModel() { 32 | this(null); 33 | } 34 | 35 | 36 | public ErrorModel(String message) { 37 | this.message = message; 38 | } 39 | 40 | 41 | //------------------------------------------------------------- 42 | // Methods - Getter/Setter 43 | //------------------------------------------------------------- 44 | 45 | public String getMessage() { 46 | return message; 47 | } 48 | 49 | 50 | public void setMessage(String message) { 51 | this.message = message; 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /aws-serverless-java-container-core/src/main/java/com/amazonaws/serverless/proxy/model/Headers.java: -------------------------------------------------------------------------------- 1 | package com.amazonaws.serverless.proxy.model; 2 | 3 | public class Headers extends MultiValuedTreeMap { 4 | 5 | private static final long serialVersionUID = 42L; 6 | 7 | public Headers() { 8 | super(String.CASE_INSENSITIVE_ORDER); 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /aws-serverless-java-container-core/src/test/java/com/amazonaws/serverless/proxy/AwsProxySecurityContextWriterTest.java: -------------------------------------------------------------------------------- 1 | package com.amazonaws.serverless.proxy; 2 | 3 | import com.amazonaws.serverless.proxy.model.AwsProxyRequest; 4 | import com.amazonaws.serverless.proxy.AwsProxySecurityContextWriter; 5 | import com.amazonaws.serverless.proxy.internal.testutils.AwsProxyRequestBuilder; 6 | import com.amazonaws.services.lambda.runtime.Context; 7 | import org.junit.Before; 8 | import org.junit.Test; 9 | 10 | import javax.ws.rs.core.SecurityContext; 11 | 12 | import java.lang.reflect.Method; 13 | 14 | import static org.junit.Assert.*; 15 | 16 | public class AwsProxySecurityContextWriterTest { 17 | private AwsProxySecurityContextWriter writer; 18 | 19 | @Before 20 | public void setUp() { 21 | writer = new AwsProxySecurityContextWriter(); 22 | } 23 | 24 | @Test 25 | public void write_returnClass_securityContext() 26 | throws NoSuchMethodException { 27 | Method writeMethod = writer.getClass().getMethod("writeSecurityContext", AwsProxyRequest.class, Context.class); 28 | assertEquals(SecurityContext.class, writeMethod.getReturnType()); 29 | } 30 | 31 | @Test 32 | public void write_noAuth_emptySecurityContext() { 33 | AwsProxyRequest request = new AwsProxyRequestBuilder("/test").build(); 34 | SecurityContext context = writer.writeSecurityContext(request, null); 35 | 36 | assertNotNull(context); 37 | assertNull(context.getAuthenticationScheme()); 38 | assertFalse(context.isSecure()); 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /aws-serverless-java-container-core/src/test/java/com/amazonaws/serverless/proxy/internal/servlet/FilterHolderTest.java: -------------------------------------------------------------------------------- 1 | package com.amazonaws.serverless.proxy.internal.servlet; 2 | 3 | import com.amazonaws.serverless.proxy.internal.servlet.filters.UrlPathValidator; 4 | import com.amazonaws.serverless.proxy.internal.testutils.MockLambdaContext; 5 | import com.amazonaws.services.lambda.runtime.Context; 6 | import org.junit.Test; 7 | 8 | import static org.junit.Assert.*; 9 | 10 | public class FilterHolderTest { 11 | private static Context lambdaContext = new MockLambdaContext(); 12 | 13 | @Test 14 | public void annotation_filterRegistration_pathValidator() { 15 | FilterHolder holder = new FilterHolder(new UrlPathValidator(), new AwsServletContext(null)); 16 | 17 | assertTrue(holder.isAnnotated()); 18 | assertNotEquals(UrlPathValidator.class.getName(), holder.getRegistration().getName()); 19 | assertEquals("UrlPathValidator", holder.getFilterName()); 20 | assertEquals("UrlPathValidator", holder.getRegistration().getName()); 21 | assertEquals(1, holder.getRegistration().getUrlPatternMappings().size()); 22 | assertEquals("/*", holder.getRegistration().getUrlPatternMappings().toArray()[0]); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /aws-serverless-java-container-core/src/test/java/com/amazonaws/serverless/proxy/model/MultiValuedTreeMapTest.java: -------------------------------------------------------------------------------- 1 | package com.amazonaws.serverless.proxy.model; 2 | 3 | 4 | import org.junit.Test; 5 | 6 | import static org.junit.Assert.assertEquals; 7 | import static org.junit.Assert.assertNotNull; 8 | import static org.junit.Assert.assertNull; 9 | 10 | 11 | public class MultiValuedTreeMapTest { 12 | 13 | @Test 14 | public void add_sameNameCaseSensitive_expectBothValues() { 15 | MultiValuedTreeMap map = new MultiValuedTreeMap<>(); 16 | map.add("Test", "test"); 17 | map.add("Test", "test2"); 18 | 19 | assertNotNull(map.get("Test")); 20 | assertEquals(2, map.get("Test").size()); 21 | assertEquals("test", map.getFirst("Test")); 22 | assertEquals("test2", map.get("Test").get(1)); 23 | assertNull(map.get("test")); 24 | 25 | map.add("test", "test"); 26 | assertNotNull(map.get("test")); 27 | assertEquals(1, map.get("test").size()); 28 | } 29 | 30 | @Test 31 | public void add_sameNameCaseInsensitive_expectOneValue() { 32 | Headers map = new Headers(); 33 | map.add("Test", "test"); 34 | assertNotNull(map.get("Test")); 35 | assertNotNull(map.get("test")); 36 | assertEquals(1, map.get("Test").size()); 37 | 38 | map.add("test", "test2"); 39 | assertNotNull(map.get("Test")); 40 | assertEquals(2, map.get("Test").size()); 41 | } 42 | 43 | @Test 44 | public void addFirst_sameNameKey_ExpectFirstReplaced() { 45 | MultiValuedTreeMap map = new MultiValuedTreeMap<>(); 46 | map.add("Test", "test1"); 47 | map.add("Test", "test2"); 48 | 49 | assertNotNull(map.get("Test")); 50 | assertEquals(2, map.get("Test").size()); 51 | assertEquals("test1", map.getFirst("Test")); 52 | 53 | map.addFirst("Test", "test3"); 54 | assertEquals(3, map.get("Test").size()); 55 | assertEquals("test3", map.getFirst("Test")); 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /aws-serverless-java-container-jersey/src/main/java/com/amazonaws/serverless/proxy/jersey/suppliers/AwsProxyServletContextSupplier.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016 Amazon.com, Inc. or its affiliates. All Rights Reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"). You may not use this file except in compliance 5 | * with the License. A copy of the License is located at 6 | * 7 | * http://aws.amazon.com/apache2.0/ 8 | * 9 | * or in the "license" file accompanying this file. This file is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES 10 | * OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions 11 | * and limitations under the License. 12 | */ 13 | package com.amazonaws.serverless.proxy.jersey.suppliers; 14 | 15 | 16 | import org.glassfish.jersey.server.ContainerRequest; 17 | 18 | import javax.servlet.ServletContext; 19 | import javax.servlet.http.HttpServletRequest; 20 | import javax.ws.rs.InternalServerErrorException; 21 | import javax.ws.rs.core.Context; 22 | 23 | import java.util.function.Supplier; 24 | 25 | import static com.amazonaws.serverless.proxy.jersey.JerseyHandlerFilter.JERSEY_SERVLET_REQUEST_PROPERTY; 26 | 27 | 28 | /** 29 | * Implementation of Jersey's Factory object for ServletContext objects. This can be used 30 | * by Jersey to generate a Servlet context given an AwsProxyRequest event. 31 | * 32 | *
33 |  * 
34 |  *     ResourceConfig app = new ResourceConfig().packages("my.app.package")
35 |  *         .register(new AbstractBinder() {
36 |  *             {@literal @}Override
37 |  *             protected void configure() {
38 |  *                 bindFactory(AwsProxyServletContextSupplier.class)
39 |  *                     .to(ServletContext.class)
40 |  *                     .in(RequestScoped.class);
41 |  *            }
42 |  *       });
43 |  * 
44 |  * 
45 | */ 46 | public class AwsProxyServletContextSupplier implements Supplier { 47 | @Context ContainerRequest currentRequest; 48 | 49 | @Override 50 | public ServletContext get() { 51 | return getServletContext(); 52 | } 53 | 54 | private ServletContext getServletContext() { 55 | HttpServletRequest req = (HttpServletRequest)currentRequest.getProperty(JERSEY_SERVLET_REQUEST_PROPERTY); 56 | 57 | if (req == null) { 58 | throw new InternalServerErrorException("Could not find servlet request in context"); 59 | } 60 | 61 | ServletContext ctx = req.getServletContext(); 62 | return ctx; 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /aws-serverless-java-container-jersey/src/main/java/com/amazonaws/serverless/proxy/jersey/suppliers/AwsProxyServletRequestSupplier.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016 Amazon.com, Inc. or its affiliates. All Rights Reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"). You may not use this file except in compliance 5 | * with the License. A copy of the License is located at 6 | * 7 | * http://aws.amazon.com/apache2.0/ 8 | * 9 | * or in the "license" file accompanying this file. This file is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES 10 | * OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions 11 | * and limitations under the License. 12 | */ 13 | package com.amazonaws.serverless.proxy.jersey.suppliers; 14 | 15 | 16 | import org.glassfish.jersey.server.ContainerRequest; 17 | 18 | import javax.servlet.http.HttpServletRequest; 19 | import javax.ws.rs.core.Context; 20 | 21 | import java.util.function.Supplier; 22 | 23 | import static com.amazonaws.serverless.proxy.jersey.JerseyHandlerFilter.JERSEY_SERVLET_REQUEST_PROPERTY; 24 | 25 | 26 | /** 27 | * Implementation of Jersey's Factory object for HttpServletRequest objects. This can be used 28 | * by Jersey to generate a Servlet request given an AwsProxyRequest event. 29 | * 30 | *
31 |  * 
32 |  *     ResourceConfig app = new ResourceConfig().packages("my.app.package")
33 |  *         .register(new AbstractBinder() {
34 |  *             {@literal @}Override
35 |  *             protected void configure() {
36 |  *                 bindFactory(AwsProxyServletRequestSupplier.class)
37 |  *                     .to(HttpServletRequest.class)
38 |  *                     .in(RequestScoped.class);
39 |  *            }
40 |  *       });
41 |  * 
42 |  * 
43 | */ 44 | public class AwsProxyServletRequestSupplier implements Supplier { 45 | 46 | @Context ContainerRequest currentRequest; 47 | 48 | //------------------------------------------------------------- 49 | // Implementation - Factory 50 | //------------------------------------------------------------- 51 | 52 | @Override 53 | public HttpServletRequest get() { 54 | return getServletRequest(); 55 | } 56 | 57 | private HttpServletRequest getServletRequest() { 58 | return (HttpServletRequest)currentRequest.getProperty(JERSEY_SERVLET_REQUEST_PROPERTY); 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /aws-serverless-java-container-jersey/src/main/java/com/amazonaws/serverless/proxy/jersey/suppliers/AwsProxyServletResponseSupplier.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016 Amazon.com, Inc. or its affiliates. All Rights Reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"). You may not use this file except in compliance 5 | * with the License. A copy of the License is located at 6 | * 7 | * http://aws.amazon.com/apache2.0/ 8 | * 9 | * or in the "license" file accompanying this file. This file is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES 10 | * OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions 11 | * and limitations under the License. 12 | */ 13 | package com.amazonaws.serverless.proxy.jersey.suppliers; 14 | 15 | 16 | import org.glassfish.jersey.server.ContainerRequest; 17 | 18 | import javax.servlet.http.HttpServletResponse; 19 | import javax.ws.rs.core.Context; 20 | 21 | import java.util.function.Supplier; 22 | 23 | import static com.amazonaws.serverless.proxy.jersey.JerseyHandlerFilter.JERSEY_SERVLET_RESPONSE_PROPERTY; 24 | 25 | 26 | /** 27 | * Implementation of Jersey's Factory object for HttpServletResponse objects. This can be used 28 | * to write data directly to the servlet response for the method, without using Jersey's ContainerResponse 29 | * 30 | *
31 |  * 
32 |  *     ResourceConfig app = new ResourceConfig().packages("my.app.package")
33 |  *         .register(new AbstractBinder() {
34 |  *             {@literal @}Override
35 |  *             protected void configure() {
36 |  *                 bindFactory(AwsProxyServletResponseSupplier.class)
37 |  *                     .to(HttpServletResponse.class)
38 |  *                     .in(RequestScoped.class);
39 |  *            }
40 |  *       });
41 |  * 
42 |  * 
43 | */ 44 | public class AwsProxyServletResponseSupplier implements Supplier { 45 | 46 | @Context ContainerRequest currentRequest; 47 | 48 | //------------------------------------------------------------- 49 | // Implementation - Factory 50 | //------------------------------------------------------------- 51 | 52 | @Override 53 | public HttpServletResponse get() { 54 | return getServletResponse(); 55 | } 56 | 57 | private HttpServletResponse getServletResponse() { 58 | return (HttpServletResponse)currentRequest.getProperty(JERSEY_SERVLET_RESPONSE_PROPERTY); 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /aws-serverless-java-container-jersey/src/test/java/com/amazonaws/serverless/proxy/jersey/JerseyInjectionTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016 Amazon.com, Inc. or its affiliates. All Rights Reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"). You may not use this file except in compliance 5 | * with the License. A copy of the License is located at 6 | * 7 | * http://aws.amazon.com/apache2.0/ 8 | * 9 | * or in the "license" file accompanying this file. This file is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES 10 | * OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions 11 | * and limitations under the License. 12 | */ 13 | package com.amazonaws.serverless.proxy.jersey; 14 | 15 | import static org.junit.Assert.assertEquals; 16 | import static org.junit.Assert.assertNotNull; 17 | 18 | import javax.inject.Singleton; 19 | 20 | import org.glassfish.jersey.internal.inject.AbstractBinder; 21 | import org.glassfish.jersey.media.multipart.MultiPartFeature; 22 | import org.glassfish.jersey.server.ResourceConfig; 23 | import org.junit.Test; 24 | 25 | import com.amazonaws.serverless.proxy.model.AwsProxyRequest; 26 | import com.amazonaws.serverless.proxy.model.AwsProxyResponse; 27 | 28 | /** 29 | * Test that one can access the Jersey injection manager 30 | */ 31 | public class JerseyInjectionTest { 32 | 33 | // Test ressource binder 34 | private static class ResourceBinder extends AbstractBinder { 35 | 36 | @Override 37 | protected void configure() { 38 | bind(new JerseyInjectionTest()).to(JerseyInjectionTest.class).in(Singleton.class); 39 | } 40 | 41 | } 42 | 43 | private static ResourceConfig app = new ResourceConfig().register(MultiPartFeature.class) 44 | .register(new ResourceBinder()); 45 | 46 | private static JerseyLambdaContainerHandler handler = JerseyLambdaContainerHandler.getAwsProxyHandler( 47 | app); 48 | 49 | @Test 50 | public void can_get_injected_resources() throws Exception { 51 | 52 | JerseyInjectionTest instance1 = handler.getInjectionManager().getInstance(JerseyInjectionTest.class); 53 | assertNotNull(instance1); 54 | 55 | JerseyInjectionTest instance2 = handler.getInjectionManager().getInstance(JerseyInjectionTest.class); 56 | assertEquals(instance1, instance2); 57 | 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /aws-serverless-java-container-jersey/src/test/java/com/amazonaws/serverless/proxy/jersey/model/MapResponseModel.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016 Amazon.com, Inc. or its affiliates. All Rights Reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"). You may not use this file except in compliance 5 | * with the License. A copy of the License is located at 6 | * 7 | * http://aws.amazon.com/apache2.0/ 8 | * 9 | * or in the "license" file accompanying this file. This file is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES 10 | * OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions 11 | * and limitations under the License. 12 | */ 13 | package com.amazonaws.serverless.proxy.jersey.model; 14 | 15 | import java.util.HashMap; 16 | import java.util.Map; 17 | 18 | /** 19 | * Request/response model 20 | */ 21 | public class MapResponseModel { 22 | private Map values; 23 | 24 | public MapResponseModel() { 25 | this.values = new HashMap<>(); 26 | } 27 | 28 | public void addValue(String key, String value) { 29 | this.values.put(key, value); 30 | } 31 | 32 | public Map getValues() { 33 | return values; 34 | } 35 | 36 | public void setValues(Map values) { 37 | this.values = values; 38 | } 39 | } -------------------------------------------------------------------------------- /aws-serverless-java-container-jersey/src/test/java/com/amazonaws/serverless/proxy/jersey/model/SingleValueModel.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016 Amazon.com, Inc. or its affiliates. All Rights Reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"). You may not use this file except in compliance 5 | * with the License. A copy of the License is located at 6 | * 7 | * http://aws.amazon.com/apache2.0/ 8 | * 9 | * or in the "license" file accompanying this file. This file is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES 10 | * OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions 11 | * and limitations under the License. 12 | */ 13 | package com.amazonaws.serverless.proxy.jersey.model; 14 | 15 | /** 16 | * Request/response model 17 | */ 18 | public class SingleValueModel { 19 | private String value; 20 | 21 | public String getValue() { 22 | return value; 23 | } 24 | 25 | public void setValue(String value) { 26 | this.value = value; 27 | } 28 | } -------------------------------------------------------------------------------- /aws-serverless-java-container-jersey/src/test/java/com/amazonaws/serverless/proxy/jersey/providers/CustomExceptionMapper.java: -------------------------------------------------------------------------------- 1 | package com.amazonaws.serverless.proxy.jersey.providers; 2 | 3 | 4 | import javax.inject.Inject; 5 | import javax.servlet.http.HttpServletRequest; 6 | import javax.ws.rs.core.Response; 7 | import javax.ws.rs.ext.ExceptionMapper; 8 | import javax.ws.rs.ext.Provider; 9 | 10 | 11 | @Provider 12 | public class CustomExceptionMapper implements ExceptionMapper { 13 | 14 | public CustomExceptionMapper() { 15 | System.out.println("Starting custom exception mapper"); 16 | } 17 | 18 | @Inject 19 | public javax.inject.Provider request; 20 | 21 | @Override 22 | public Response toResponse(UnsupportedOperationException throwable) { 23 | if (request == null) { 24 | return Response.status(Response.Status.NOT_FOUND).build(); 25 | } else { 26 | System.out.println("Request uri: " + request.get().getRequestURI()); 27 | return Response.ok(throwable.getMessage()).status(Response.Status.NOT_IMPLEMENTED).build(); 28 | } 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /aws-serverless-java-container-jersey/src/test/java/com/amazonaws/serverless/proxy/jersey/providers/ServletRequestFilter.java: -------------------------------------------------------------------------------- 1 | package com.amazonaws.serverless.proxy.jersey.providers; 2 | 3 | 4 | import javax.servlet.http.HttpServletRequest; 5 | import javax.ws.rs.container.ContainerRequestContext; 6 | import javax.ws.rs.container.ContainerRequestFilter; 7 | import javax.ws.rs.core.Context; 8 | 9 | import java.io.IOException; 10 | 11 | 12 | public class ServletRequestFilter implements ContainerRequestFilter { 13 | public static final String FILTER_ATTRIBUTE_NAME = "ServletFilter"; 14 | public static final String FILTER_ATTRIBUTE_VALUE = "done"; 15 | 16 | @Context HttpServletRequest request; 17 | 18 | public void filter(ContainerRequestContext ctx) throws IOException { 19 | request.setAttribute(FILTER_ATTRIBUTE_NAME, FILTER_ATTRIBUTE_VALUE); 20 | } 21 | 22 | } -------------------------------------------------------------------------------- /aws-serverless-java-container-spark/src/main/java/com/amazonaws/serverless/proxy/spark/embeddedserver/LambdaEmbeddedServerFactory.java: -------------------------------------------------------------------------------- 1 | package com.amazonaws.serverless.proxy.spark.embeddedserver; 2 | 3 | import com.amazonaws.serverless.proxy.internal.testutils.Timer; 4 | 5 | import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; 6 | import spark.ExceptionMapper; 7 | import spark.embeddedserver.EmbeddedServer; 8 | import spark.embeddedserver.EmbeddedServerFactory; 9 | import spark.route.Routes; 10 | import spark.staticfiles.StaticFilesConfiguration; 11 | 12 | public class LambdaEmbeddedServerFactory implements EmbeddedServerFactory { 13 | 14 | //------------------------------------------------------------- 15 | // Variables - Private - Static 16 | //------------------------------------------------------------- 17 | 18 | private static volatile LambdaEmbeddedServer embeddedServer; 19 | 20 | 21 | /** 22 | * Empty constructor, applications should always use this constructor. 23 | */ 24 | public LambdaEmbeddedServerFactory() {} 25 | 26 | 27 | /** 28 | * Constructor used in unit tests to inject a mocked embedded server 29 | * @param server The mocked server 30 | */ 31 | @SuppressFBWarnings("ST_WRITE_TO_STATIC_FROM_INSTANCE_METHOD") // suppressing the warning as this constructor is only used for unit tests 32 | public LambdaEmbeddedServerFactory(LambdaEmbeddedServer server) { 33 | LambdaEmbeddedServerFactory.embeddedServer = server; 34 | } 35 | 36 | 37 | //------------------------------------------------------------- 38 | // Implementation - EmbeddedServerFactory 39 | //------------------------------------------------------------- 40 | 41 | 42 | @Override 43 | public EmbeddedServer create(Routes routes, StaticFilesConfiguration staticFilesConfiguration, ExceptionMapper exceptionMapper, boolean multipleHandlers) { 44 | Timer.start("SPARK_SERVER_FACTORY_CREATE"); 45 | if (embeddedServer == null) { 46 | LambdaEmbeddedServerFactory.embeddedServer = new LambdaEmbeddedServer(routes, staticFilesConfiguration, exceptionMapper, multipleHandlers); 47 | } 48 | Timer.stop("SPARK_SERVER_FACTORY_CREATE"); 49 | return embeddedServer; 50 | } 51 | 52 | 53 | //------------------------------------------------------------- 54 | // Methods - Getter/Setter 55 | //------------------------------------------------------------- 56 | 57 | public LambdaEmbeddedServer getServerInstance() { 58 | return embeddedServer; 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /aws-serverless-java-container-spark/src/test/java/com/amazonaws/serverless/proxy/spark/embeddedserver/LambdaEmbeddedServerTest.java: -------------------------------------------------------------------------------- 1 | package com.amazonaws.serverless.proxy.spark.embeddedserver; 2 | 3 | 4 | import org.junit.Test; 5 | 6 | import java.util.Optional; 7 | 8 | import static org.junit.Assert.*; 9 | 10 | 11 | public class LambdaEmbeddedServerTest { 12 | private static LambdaEmbeddedServer server = new LambdaEmbeddedServer(null, null, null, false); 13 | 14 | @Test 15 | public void webSocket_configureWebSocket_noException() { 16 | try { 17 | server.configureWebSockets(null, Optional.of(0)); 18 | } catch (Exception e) { 19 | e.printStackTrace(); 20 | fail(); 21 | } 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /aws-serverless-java-container-spark/src/test/java/com/amazonaws/serverless/proxy/spark/filter/CustomHeaderFilter.java: -------------------------------------------------------------------------------- 1 | package com.amazonaws.serverless.proxy.spark.filter; 2 | 3 | 4 | import javax.servlet.Filter; 5 | import javax.servlet.FilterChain; 6 | import javax.servlet.FilterConfig; 7 | import javax.servlet.ServletException; 8 | import javax.servlet.ServletRequest; 9 | import javax.servlet.ServletResponse; 10 | import javax.servlet.http.HttpServletResponse; 11 | 12 | import java.io.IOException; 13 | 14 | 15 | public class CustomHeaderFilter implements Filter { 16 | public static final String HEADER_NAME = "X-Filter-Header"; 17 | public static final String HEADER_VALUE = "CustomHeaderFilter"; 18 | 19 | @Override 20 | public void init(FilterConfig filterConfig) throws ServletException { 21 | System.out.println("Called init on filter"); 22 | } 23 | 24 | @Override 25 | public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException { 26 | System.out.println("Called doFilter"); 27 | HttpServletResponse resp = (HttpServletResponse)servletResponse; 28 | resp.addHeader(HEADER_NAME, HEADER_VALUE); 29 | 30 | filterChain.doFilter(servletRequest, servletResponse); 31 | } 32 | 33 | 34 | @Override 35 | public void destroy() { 36 | System.out.println("Called destroy"); 37 | } 38 | } -------------------------------------------------------------------------------- /aws-serverless-java-container-spark/src/test/java/com/amazonaws/serverless/proxy/spark/filter/UnauthenticatedFilter.java: -------------------------------------------------------------------------------- 1 | package com.amazonaws.serverless.proxy.spark.filter; 2 | 3 | 4 | import javax.servlet.Filter; 5 | import javax.servlet.FilterChain; 6 | import javax.servlet.FilterConfig; 7 | import javax.servlet.ServletException; 8 | import javax.servlet.ServletRequest; 9 | import javax.servlet.ServletResponse; 10 | import javax.servlet.http.HttpServletRequest; 11 | import javax.servlet.http.HttpServletResponse; 12 | 13 | import java.io.IOException; 14 | 15 | 16 | public class UnauthenticatedFilter implements Filter { 17 | public static final String HEADER_NAME = "X-Unauthenticated-Response"; 18 | public static final int RESPONSE_STATUS = 401; 19 | 20 | @Override 21 | public void init(FilterConfig filterConfig) 22 | throws ServletException { 23 | 24 | } 25 | 26 | 27 | @Override 28 | public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) 29 | throws IOException, ServletException { 30 | System.out.println("Running unauth filter"); 31 | if (((HttpServletRequest)servletRequest).getHeader(HEADER_NAME) != null) { 32 | ((HttpServletResponse) servletResponse).setStatus(401); 33 | System.out.println("Returning 401"); 34 | return; 35 | } 36 | System.out.println("Continue chain"); 37 | filterChain.doFilter(servletRequest, servletResponse); 38 | } 39 | 40 | 41 | @Override 42 | public void destroy() { 43 | 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /aws-serverless-java-container-spring/src/test/java/com/amazonaws/serverless/proxy/spring/StaticAppProxyTest.java: -------------------------------------------------------------------------------- 1 | package com.amazonaws.serverless.proxy.spring; 2 | 3 | 4 | import com.amazonaws.serverless.proxy.internal.LambdaContainerHandler; 5 | import com.amazonaws.serverless.proxy.model.AwsProxyRequest; 6 | import com.amazonaws.serverless.proxy.model.AwsProxyResponse; 7 | import com.amazonaws.serverless.proxy.internal.testutils.AwsProxyRequestBuilder; 8 | import com.amazonaws.serverless.proxy.internal.testutils.MockLambdaContext; 9 | import com.amazonaws.serverless.proxy.spring.staticapp.LambdaHandler; 10 | 11 | import org.junit.Test; 12 | import org.springframework.http.HttpHeaders; 13 | 14 | import javax.ws.rs.core.MediaType; 15 | 16 | import static org.junit.Assert.*; 17 | 18 | 19 | public class StaticAppProxyTest { 20 | 21 | private LambdaHandler lambdaHandler = new LambdaHandler(); 22 | 23 | @Test 24 | public void staticPage() { 25 | AwsProxyRequest req = new AwsProxyRequestBuilder("/sample/page", "GET").build(); 26 | // we temporarily allow the container to read from any path 27 | LambdaContainerHandler.getContainerConfig().addValidFilePath("/"); 28 | AwsProxyResponse resp = lambdaHandler.handleRequest(req, new MockLambdaContext()); 29 | 30 | assertEquals(200, resp.getStatusCode()); 31 | assertTrue(resp.getBody().startsWith("")); 32 | assertTrue(resp.getMultiValueHeaders().containsKey(HttpHeaders.CONTENT_TYPE)); 33 | assertEquals(MediaType.TEXT_HTML, resp.getMultiValueHeaders().getFirst(HttpHeaders.CONTENT_TYPE)); 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /aws-serverless-java-container-spring/src/test/java/com/amazonaws/serverless/proxy/spring/echoapp/CustomHeaderFilter.java: -------------------------------------------------------------------------------- 1 | package com.amazonaws.serverless.proxy.spring.echoapp; 2 | 3 | 4 | import javax.servlet.Filter; 5 | import javax.servlet.FilterChain; 6 | import javax.servlet.FilterConfig; 7 | import javax.servlet.ServletException; 8 | import javax.servlet.ServletRequest; 9 | import javax.servlet.ServletResponse; 10 | import javax.servlet.http.HttpServletResponse; 11 | 12 | import java.io.IOException; 13 | 14 | 15 | public class CustomHeaderFilter implements Filter { 16 | public static final String HEADER_NAME = "X-Filter-Header"; 17 | public static final String HEADER_VALUE = "CustomHeaderFilter"; 18 | 19 | @Override 20 | public void init(FilterConfig filterConfig) throws ServletException { 21 | System.out.println("Called init on filter"); 22 | } 23 | 24 | @Override 25 | public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException { 26 | System.out.println("Called doFilter"); 27 | HttpServletResponse resp = (HttpServletResponse)servletResponse; 28 | resp.addHeader(HEADER_NAME, HEADER_VALUE); 29 | 30 | filterChain.doFilter(servletRequest, servletResponse); 31 | } 32 | 33 | 34 | @Override 35 | public void destroy() { 36 | System.out.println("Called destroy"); 37 | } 38 | } -------------------------------------------------------------------------------- /aws-serverless-java-container-spring/src/test/java/com/amazonaws/serverless/proxy/spring/echoapp/ProfileOverrideConfig.java: -------------------------------------------------------------------------------- 1 | package com.amazonaws.serverless.proxy.spring.echoapp; 2 | 3 | import org.springframework.context.annotation.Configuration; 4 | import org.springframework.context.annotation.Profile; 5 | import org.springframework.context.annotation.PropertySource; 6 | 7 | @Configuration 8 | @Profile("override") 9 | @PropertySource("classpath:/application-override.properties") 10 | public class ProfileOverrideConfig { 11 | } -------------------------------------------------------------------------------- /aws-serverless-java-container-spring/src/test/java/com/amazonaws/serverless/proxy/spring/echoapp/RestControllerAdvice.java: -------------------------------------------------------------------------------- 1 | package com.amazonaws.serverless.proxy.spring.echoapp; 2 | 3 | 4 | import com.amazonaws.serverless.proxy.spring.echoapp.model.SingleValueModel; 5 | 6 | import org.springframework.http.HttpStatus; 7 | import org.springframework.http.ResponseEntity; 8 | import org.springframework.web.bind.annotation.ControllerAdvice; 9 | import org.springframework.web.bind.annotation.ExceptionHandler; 10 | import org.springframework.web.bind.annotation.RequestMapping; 11 | import org.springframework.web.bind.annotation.ResponseBody; 12 | import org.springframework.web.servlet.NoHandlerFoundException; 13 | 14 | 15 | @ControllerAdvice 16 | @RequestMapping(produces = "application/json") 17 | @ResponseBody 18 | public class RestControllerAdvice { 19 | public static final String ERROR_MESSAGE = "UnhadledPath"; 20 | 21 | @ExceptionHandler(NoHandlerFoundException.class) 22 | public ResponseEntity unhandledPath(final NoHandlerFoundException e) { 23 | SingleValueModel model = new SingleValueModel(); 24 | model.setValue(ERROR_MESSAGE); 25 | return new ResponseEntity(model, HttpStatus.NOT_FOUND); 26 | } 27 | } -------------------------------------------------------------------------------- /aws-serverless-java-container-spring/src/test/java/com/amazonaws/serverless/proxy/spring/echoapp/UnauthenticatedFilter.java: -------------------------------------------------------------------------------- 1 | package com.amazonaws.serverless.proxy.spring.echoapp; 2 | 3 | 4 | import javax.servlet.Filter; 5 | import javax.servlet.FilterChain; 6 | import javax.servlet.FilterConfig; 7 | import javax.servlet.ServletException; 8 | import javax.servlet.ServletRequest; 9 | import javax.servlet.ServletResponse; 10 | import javax.servlet.http.HttpServletRequest; 11 | import javax.servlet.http.HttpServletResponse; 12 | 13 | import java.io.IOException; 14 | 15 | 16 | public class UnauthenticatedFilter implements Filter { 17 | public static final String HEADER_NAME = "X-Unauthenticated-Response"; 18 | public static final int RESPONSE_STATUS = 401; 19 | 20 | @Override 21 | public void init(FilterConfig filterConfig) 22 | throws ServletException { 23 | 24 | } 25 | 26 | 27 | @Override 28 | public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) 29 | throws IOException, ServletException { 30 | System.out.println("Running unauth filter"); 31 | if (((HttpServletRequest)servletRequest).getHeader(HEADER_NAME) != null) { 32 | ((HttpServletResponse) servletResponse).setStatus(401); 33 | System.out.println("Returning 401"); 34 | return; 35 | } 36 | System.out.println("Continue chain"); 37 | filterChain.doFilter(servletRequest, servletResponse); 38 | } 39 | 40 | 41 | @Override 42 | public void destroy() { 43 | 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /aws-serverless-java-container-spring/src/test/java/com/amazonaws/serverless/proxy/spring/echoapp/model/MapResponseModel.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016 Amazon.com, Inc. or its affiliates. All Rights Reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"). You may not use this file except in compliance 5 | * with the License. A copy of the License is located at 6 | * 7 | * http://aws.amazon.com/apache2.0/ 8 | * 9 | * or in the "license" file accompanying this file. This file is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES 10 | * OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions 11 | * and limitations under the License. 12 | */ 13 | package com.amazonaws.serverless.proxy.spring.echoapp.model; 14 | 15 | import java.util.HashMap; 16 | import java.util.Map; 17 | 18 | /** 19 | * Request/response model 20 | */ 21 | public class MapResponseModel { 22 | private Map values; 23 | 24 | public MapResponseModel() { 25 | this.values = new HashMap<>(); 26 | } 27 | 28 | public void addValue(String key, String value) { 29 | this.values.put(key, value); 30 | } 31 | 32 | public Map getValues() { 33 | return values; 34 | } 35 | 36 | public void setValues(Map values) { 37 | this.values = values; 38 | } 39 | } -------------------------------------------------------------------------------- /aws-serverless-java-container-spring/src/test/java/com/amazonaws/serverless/proxy/spring/echoapp/model/SingleValueModel.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016 Amazon.com, Inc. or its affiliates. All Rights Reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"). You may not use this file except in compliance 5 | * with the License. A copy of the License is located at 6 | * 7 | * http://aws.amazon.com/apache2.0/ 8 | * 9 | * or in the "license" file accompanying this file. This file is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES 10 | * OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions 11 | * and limitations under the License. 12 | */ 13 | package com.amazonaws.serverless.proxy.spring.echoapp.model; 14 | 15 | /** 16 | * Request/response model 17 | */ 18 | public class SingleValueModel { 19 | private String value; 20 | 21 | public String getValue() { 22 | return value; 23 | } 24 | 25 | public void setValue(String value) { 26 | this.value = value; 27 | } 28 | } -------------------------------------------------------------------------------- /aws-serverless-java-container-spring/src/test/java/com/amazonaws/serverless/proxy/spring/echoapp/model/ValidatedUserModel.java: -------------------------------------------------------------------------------- 1 | package com.amazonaws.serverless.proxy.spring.echoapp.model; 2 | 3 | import org.hibernate.validator.constraints.Email; 4 | import org.hibernate.validator.constraints.NotEmpty; 5 | 6 | import javax.validation.constraints.Size; 7 | 8 | public class ValidatedUserModel { 9 | @NotEmpty 10 | @Size(min=2, max=30) 11 | private String firstName; 12 | 13 | @NotEmpty 14 | @Size(min=2, max=30) 15 | private String lastName; 16 | 17 | @NotEmpty 18 | @Email 19 | private String email; 20 | 21 | public String getFirstName() { 22 | return firstName; 23 | } 24 | 25 | public void setFirstName(String firstName) { 26 | this.firstName = firstName; 27 | } 28 | 29 | public String getLastName() { 30 | return lastName; 31 | } 32 | 33 | public void setLastName(String lastName) { 34 | this.lastName = lastName; 35 | } 36 | 37 | public String getEmail() { 38 | return email; 39 | } 40 | 41 | public void setEmail(String email) { 42 | this.email = email; 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /aws-serverless-java-container-spring/src/test/java/com/amazonaws/serverless/proxy/spring/echoapp/profile/DefaultProfileConfiguration.java: -------------------------------------------------------------------------------- 1 | package com.amazonaws.serverless.proxy.spring.echoapp.profile; 2 | 3 | import org.springframework.context.annotation.Bean; 4 | import org.springframework.context.annotation.Configuration; 5 | 6 | @Configuration 7 | public class DefaultProfileConfiguration { 8 | @Bean 9 | public String beanInjectedValue() { 10 | return "default-profile-from-bean"; 11 | } 12 | } -------------------------------------------------------------------------------- /aws-serverless-java-container-spring/src/test/java/com/amazonaws/serverless/proxy/spring/echoapp/profile/DefaultProfileResource.java: -------------------------------------------------------------------------------- 1 | package com.amazonaws.serverless.proxy.spring.echoapp.profile; 2 | 3 | import com.amazonaws.serverless.proxy.spring.echoapp.model.MapResponseModel; 4 | import org.springframework.beans.factory.annotation.Autowired; 5 | import org.springframework.beans.factory.annotation.Value; 6 | import org.springframework.web.bind.annotation.RequestMapping; 7 | import org.springframework.web.bind.annotation.RequestMethod; 8 | import org.springframework.web.bind.annotation.RestController; 9 | 10 | @RestController 11 | @RequestMapping("/profile") 12 | public class DefaultProfileResource { 13 | @Value("${spring-proxy.profile-test}") 14 | private String profileTest; 15 | 16 | @Value("${spring-proxy.not-overridden-test}") 17 | private String noOverride; 18 | 19 | @Autowired 20 | private String beanInjectedValue; 21 | 22 | @RequestMapping(path = "/spring-properties", method = RequestMethod.GET) 23 | public MapResponseModel loadProperties() { 24 | MapResponseModel model = new MapResponseModel(); 25 | 26 | model.addValue("profileTest", profileTest); 27 | model.addValue("noOverride", noOverride); 28 | model.addValue("beanInjectedValue", beanInjectedValue); 29 | return model; 30 | } 31 | } -------------------------------------------------------------------------------- /aws-serverless-java-container-spring/src/test/java/com/amazonaws/serverless/proxy/spring/echoapp/profile/OverrideProfileConfiguration.java: -------------------------------------------------------------------------------- 1 | package com.amazonaws.serverless.proxy.spring.echoapp.profile; 2 | 3 | import org.springframework.context.annotation.Bean; 4 | import org.springframework.context.annotation.Configuration; 5 | import org.springframework.context.annotation.Profile; 6 | 7 | 8 | @Configuration 9 | @Profile("override") 10 | public class OverrideProfileConfiguration { 11 | @Bean 12 | public String beanInjectedValue() { 13 | return "override-profile-from-bean"; 14 | } 15 | } -------------------------------------------------------------------------------- /aws-serverless-java-container-spring/src/test/java/com/amazonaws/serverless/proxy/spring/springbootapp/LambdaHandler.java: -------------------------------------------------------------------------------- 1 | package com.amazonaws.serverless.proxy.spring.springbootapp; 2 | 3 | 4 | import com.amazonaws.serverless.exceptions.ContainerInitializationException; 5 | import com.amazonaws.serverless.proxy.model.AwsProxyRequest; 6 | import com.amazonaws.serverless.proxy.model.AwsProxyResponse; 7 | import com.amazonaws.serverless.proxy.spring.SpringBootLambdaContainerHandler; 8 | import com.amazonaws.serverless.proxy.spring.springbootapp.TestApplication; 9 | import com.amazonaws.services.lambda.runtime.Context; 10 | import com.amazonaws.services.lambda.runtime.RequestHandler; 11 | 12 | 13 | public class LambdaHandler 14 | implements RequestHandler 15 | { 16 | SpringBootLambdaContainerHandler handler; 17 | boolean isinitialized = false; 18 | 19 | public AwsProxyResponse handleRequest(AwsProxyRequest awsProxyRequest, Context context) 20 | { 21 | if (!isinitialized) { 22 | isinitialized = true; 23 | try { 24 | handler = SpringBootLambdaContainerHandler.getAwsProxyHandler(TestApplication.class); 25 | } catch (ContainerInitializationException e) { 26 | e.printStackTrace(); 27 | return null; 28 | } 29 | } 30 | AwsProxyResponse res = handler.proxy(awsProxyRequest, context); 31 | return res; 32 | } 33 | } 34 | 35 | -------------------------------------------------------------------------------- /aws-serverless-java-container-spring/src/test/java/com/amazonaws/serverless/proxy/spring/springbootapp/TestApplication.java: -------------------------------------------------------------------------------- 1 | package com.amazonaws.serverless.proxy.spring.springbootapp; 2 | 3 | 4 | import org.springframework.boot.autoconfigure.SpringBootApplication; 5 | import org.springframework.boot.web.support.SpringBootServletInitializer; 6 | import org.springframework.context.annotation.ComponentScan; 7 | 8 | 9 | @SpringBootApplication 10 | @ComponentScan(basePackages = "com.amazonaws.serverless.proxy.spring.springbootapp") 11 | public class TestApplication extends SpringBootServletInitializer { 12 | } 13 | -------------------------------------------------------------------------------- /aws-serverless-java-container-spring/src/test/java/com/amazonaws/serverless/proxy/spring/staticapp/LambdaHandler.java: -------------------------------------------------------------------------------- 1 | package com.amazonaws.serverless.proxy.spring.staticapp; 2 | 3 | 4 | import com.amazonaws.serverless.exceptions.ContainerInitializationException; 5 | import com.amazonaws.serverless.proxy.model.AwsProxyRequest; 6 | import com.amazonaws.serverless.proxy.model.AwsProxyResponse; 7 | import com.amazonaws.serverless.proxy.spring.SpringLambdaContainerHandler; 8 | import com.amazonaws.services.lambda.runtime.Context; 9 | import com.amazonaws.services.lambda.runtime.RequestHandler; 10 | 11 | import org.springframework.web.context.support.XmlWebApplicationContext; 12 | 13 | 14 | public class LambdaHandler 15 | implements RequestHandler 16 | { 17 | SpringLambdaContainerHandler handler; 18 | boolean isinitialized = false; 19 | 20 | public AwsProxyResponse handleRequest(AwsProxyRequest awsProxyRequest, Context context) 21 | { 22 | if (!isinitialized) { 23 | isinitialized = true; 24 | try { 25 | XmlWebApplicationContext wc = new XmlWebApplicationContext(); 26 | wc.setConfigLocation("classpath:/staticAppContext.xml"); 27 | handler = SpringLambdaContainerHandler.getAwsProxyHandler(wc); 28 | } catch (ContainerInitializationException e) { 29 | e.printStackTrace(); 30 | return null; 31 | } 32 | } 33 | AwsProxyResponse res = handler.proxy(awsProxyRequest, context); 34 | return res; 35 | } 36 | } 37 | 38 | -------------------------------------------------------------------------------- /aws-serverless-java-container-spring/src/test/java/com/amazonaws/serverless/proxy/spring/staticapp/MyController.java: -------------------------------------------------------------------------------- 1 | package com.amazonaws.serverless.proxy.spring.staticapp; 2 | 3 | import org.springframework.stereotype.Controller; 4 | import org.springframework.web.bind.annotation.RequestMapping; 5 | import org.springframework.web.servlet.config.annotation.EnableWebMvc; 6 | 7 | 8 | @EnableWebMvc 9 | @Controller 10 | public class MyController { 11 | @RequestMapping({ "/sample/page" }) 12 | public String showPage() { 13 | return "sample"; 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /aws-serverless-java-container-spring/src/test/resources/application-override.properties: -------------------------------------------------------------------------------- 1 | spring-proxy.profile-test=override-profile -------------------------------------------------------------------------------- /aws-serverless-java-container-spring/src/test/resources/application.properties: -------------------------------------------------------------------------------- 1 | spring-proxy.profile-test=default-profile 2 | spring-proxy.not-overridden-test=not-overridden -------------------------------------------------------------------------------- /aws-serverless-java-container-spring/src/test/resources/static/static.html: -------------------------------------------------------------------------------- 1 | 2 | 3 |

Static

4 | 5 | -------------------------------------------------------------------------------- /aws-serverless-java-container-spring/src/test/resources/staticAppContext.xml: -------------------------------------------------------------------------------- 1 | 2 | 10 | 11 | 12 | 14 | 15 | classpath:application.properties 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 26 | 27 | /templates/ 28 | 29 | 30 | .html 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | -------------------------------------------------------------------------------- /aws-serverless-java-container-spring/src/test/resources/templates/sample.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | hello world 4 | 5 | -------------------------------------------------------------------------------- /aws-serverless-java-container-struts2/src/main/java/com/amazonaws/serverless/proxy/struts2/Struts2LambdaHandler.java: -------------------------------------------------------------------------------- 1 | package com.amazonaws.serverless.proxy.struts2; 2 | 3 | import com.amazonaws.serverless.proxy.model.AwsProxyRequest; 4 | import com.amazonaws.serverless.proxy.model.AwsProxyResponse; 5 | import com.amazonaws.services.lambda.runtime.Context; 6 | import com.amazonaws.services.lambda.runtime.RequestStreamHandler; 7 | import org.slf4j.Logger; 8 | import org.slf4j.LoggerFactory; 9 | 10 | import java.io.IOException; 11 | import java.io.InputStream; 12 | import java.io.OutputStream; 13 | 14 | /** 15 | * The lambda handler to handle the requests. 16 | *

17 | * 18 | * com.amazonaws.serverless.proxy.struts2.Struts2LambdaHandler::handleRequest 19 | * 20 | */ 21 | public class Struts2LambdaHandler implements RequestStreamHandler { 22 | 23 | private static final Logger log = LoggerFactory.getLogger(Struts2LambdaHandler.class); 24 | 25 | private final Struts2LambdaContainerHandler handler = Struts2LambdaContainerHandler 26 | .getAwsProxyHandler(); 27 | 28 | @Override 29 | public void handleRequest(InputStream inputStream, OutputStream outputStream, Context context) 30 | throws IOException { 31 | handler.proxyStream(inputStream, outputStream, context); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /aws-serverless-java-container-struts2/src/test/java/com/amazonaws/serverless/proxy/struts2/echoapp/EchoAction.java: -------------------------------------------------------------------------------- 1 | package com.amazonaws.serverless.proxy.struts2.echoapp; 2 | 3 | import com.opensymphony.xwork2.ActionSupport; 4 | import org.apache.commons.io.IOUtils; 5 | import org.apache.struts2.ServletActionContext; 6 | 7 | import javax.servlet.http.HttpServletRequest; 8 | import javax.servlet.http.HttpServletResponse; 9 | import java.io.IOException; 10 | 11 | 12 | public class EchoAction extends ActionSupport { 13 | 14 | private String message; 15 | 16 | public String execute() throws IOException { 17 | HttpServletRequest request = ServletActionContext.getRequest(); 18 | 19 | if (message == null && requestHasBody(request)) { 20 | message = IOUtils.toString(request.getReader()); 21 | } 22 | 23 | return SUCCESS; 24 | } 25 | 26 | public String getMessage() { 27 | return message; 28 | } 29 | 30 | public void setMessage(String message) { 31 | this.message = message; 32 | } 33 | 34 | public void setCustomHeader(boolean customHeader) { 35 | if (customHeader) { 36 | HttpServletResponse response = ServletActionContext.getResponse(); 37 | response.setHeader("XX", "FOO"); 38 | } 39 | } 40 | 41 | 42 | public void setContentType(boolean contentType) { 43 | if (contentType) { 44 | HttpServletResponse response = ServletActionContext.getResponse(); 45 | response.setContentType("application/json"); 46 | } 47 | } 48 | 49 | private boolean requestHasBody(HttpServletRequest request) throws IOException { 50 | return ("POST".equalsIgnoreCase(request.getMethod()) || "PUT".equalsIgnoreCase(request.getMethod())) && request.getReader() != null; 51 | } 52 | 53 | } 54 | -------------------------------------------------------------------------------- /aws-serverless-java-container-struts2/src/test/resources/struts.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | message 14 | 15 | 16 | 17 | 18 | 20 | 21 | 22 | result 23 | 24 | 25 | 26 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /aws-serverless-jersey-archetype/src/main/resources/META-INF/maven/archetype-metadata.xml: -------------------------------------------------------------------------------- 1 | 5 | 6 | 7 | src/main/java 8 | 9 | **/*.java 10 | 11 | 12 | 13 | src/test/java 14 | 15 | **/*.java 16 | 17 | 18 | 19 | src/assembly 20 | 21 | * 22 | 23 | 24 | 25 | 26 | 27 | sam.yaml 28 | README.md 29 | build.gradle 30 | 31 | 32 | 33 | -------------------------------------------------------------------------------- /aws-serverless-jersey-archetype/src/main/resources/archetype-resources/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'java' 2 | 3 | repositories { 4 | mavenLocal() 5 | mavenCentral() 6 | } 7 | 8 | dependencies { 9 | compile ( 10 | 'com.amazonaws:aws-lambda-java-core:1.2.0', 11 | 'com.amazonaws.serverless:aws-serverless-java-container-jersey:[1.0,)', 12 | 'com.fasterxml.jackson.core:jackson-databind:2.9.8', 13 | 'io.symphonia:lambda-logging:1.0.1' 14 | ) 15 | 16 | compile("org.glassfish.jersey.media:jersey-media-json-jackson:2.27") { 17 | exclude group: 'com.fasterxml.jackson.core', module: "jackson-annotations" 18 | exclude group: 'com.fasterxml.jackson.core', module: "jackson-databind" 19 | exclude group: 'com.fasterxml.jackson.core', module: "jackson-core" 20 | } 21 | 22 | compile("org.glassfish.jersey.inject:jersey-hk2:2.27") { 23 | exclude group: 'javax.inject', module: "javax.inject" 24 | } 25 | 26 | testCompile("junit:junit:4.12") 27 | } 28 | 29 | task buildZip(type: Zip) { 30 | from compileJava 31 | from processResources 32 | into('lib') { 33 | from configurations.compileClasspath 34 | } 35 | } 36 | 37 | build.dependsOn buildZip 38 | -------------------------------------------------------------------------------- /aws-serverless-jersey-archetype/src/main/resources/archetype-resources/sam.yaml: -------------------------------------------------------------------------------- 1 | #set($resourceName = $artifactId) 2 | #macro(replaceChar $originalName, $char) 3 | #if($originalName.contains($char)) 4 | #set($tokens = $originalName.split($char)) 5 | #set($newResourceName = "") 6 | #foreach($token in $tokens) 7 | #set($newResourceName = $newResourceName + $token.substring(0,1).toUpperCase() + $token.substring(1).toLowerCase()) 8 | #end 9 | ${newResourceName} 10 | #else 11 | #set($newResourceName = $originalName.substring(0,1).toUpperCase() + $originalName.substring(1)) 12 | ${newResourceName} 13 | #end 14 | #end 15 | #set($resourceName = "#replaceChar($resourceName, '-')") 16 | #set($resourceName = "#replaceChar($resourceName, '.')") 17 | #set($resourceName = $resourceName.replaceAll("\n", "").trim()) 18 | #macro(regionVar) 19 | AWS::Region 20 | #end 21 | #set($awsRegion = "#regionVar()") 22 | #set($awsRegion = $awsRegion.replaceAll("\n", "").trim()) 23 | AWSTemplateFormatVersion: '2010-09-09' 24 | Transform: AWS::Serverless-2016-10-31 25 | Description: AWS Serverless Jersey API - ${groupId}::${artifactId} 26 | Globals: 27 | Api: 28 | EndpointConfiguration: REGIONAL 29 | 30 | Resources: 31 | ${resourceName}Function: 32 | Type: AWS::Serverless::Function 33 | Properties: 34 | Handler: ${groupId}.StreamLambdaHandler::handleRequest 35 | Runtime: java8 36 | CodeUri: target/${artifactId}-${version}-lambda-package.zip 37 | MemorySize: 512 38 | Policies: AWSLambdaBasicExecutionRole 39 | Timeout: 15 40 | Events: 41 | GetResource: 42 | Type: Api 43 | Properties: 44 | Path: /{proxy+} 45 | Method: any 46 | 47 | Outputs: 48 | ${resourceName}Api: 49 | Description: URL for application 50 | Value: !Sub 'https://${ServerlessRestApi}.execute-api.${${awsRegion}}.amazonaws.com/Prod/ping' 51 | Export: 52 | Name: ${resourceName}Api 53 | -------------------------------------------------------------------------------- /aws-serverless-jersey-archetype/src/main/resources/archetype-resources/src/assembly/bin.xml: -------------------------------------------------------------------------------- 1 | 4 | lambda-package 5 | 6 | zip 7 | 8 | false 9 | 10 | 11 | 12 | ${project.build.directory}${file.separator}lib 13 | lib 14 | 15 | 16 | 17 | ${project.build.directory}${file.separator}classes 18 | 19 | ** 20 | 21 | ${file.separator} 22 | 23 | 24 | -------------------------------------------------------------------------------- /aws-serverless-jersey-archetype/src/main/resources/archetype-resources/src/main/java/StreamLambdaHandler.java: -------------------------------------------------------------------------------- 1 | package ${groupId}; 2 | 3 | import com.amazonaws.serverless.proxy.jersey.JerseyLambdaContainerHandler; 4 | import com.amazonaws.serverless.proxy.model.AwsProxyRequest; 5 | import com.amazonaws.serverless.proxy.model.AwsProxyResponse; 6 | import com.amazonaws.services.lambda.runtime.Context; 7 | import com.amazonaws.services.lambda.runtime.RequestStreamHandler; 8 | 9 | import org.glassfish.jersey.jackson.JacksonFeature; 10 | import org.glassfish.jersey.server.ResourceConfig; 11 | 12 | import java.io.IOException; 13 | import java.io.InputStream; 14 | import java.io.OutputStream; 15 | 16 | import ${groupId}.resource.PingResource; 17 | 18 | 19 | public class StreamLambdaHandler implements RequestStreamHandler { 20 | private static final ResourceConfig jerseyApplication = new ResourceConfig() 21 | .register(PingResource.class) 22 | .register(JacksonFeature.class); 23 | private static final JerseyLambdaContainerHandler handler 24 | = JerseyLambdaContainerHandler.getAwsProxyHandler(jerseyApplication); 25 | 26 | @Override 27 | public void handleRequest(InputStream inputStream, OutputStream outputStream, Context context) 28 | throws IOException { 29 | handler.proxyStream(inputStream, outputStream, context); 30 | } 31 | } -------------------------------------------------------------------------------- /aws-serverless-jersey-archetype/src/main/resources/archetype-resources/src/main/java/resource/PingResource.java: -------------------------------------------------------------------------------- 1 | package ${groupId}.resource; 2 | 3 | 4 | import java.util.Map; 5 | import java.util.HashMap; 6 | 7 | import javax.ws.rs.Consumes; 8 | import javax.ws.rs.GET; 9 | import javax.ws.rs.Path; 10 | import javax.ws.rs.Produces; 11 | 12 | import javax.ws.rs.core.MediaType; 13 | import javax.ws.rs.core.Response; 14 | 15 | @Path("/ping") 16 | public class PingResource { 17 | 18 | @GET 19 | @Produces(MediaType.APPLICATION_JSON) 20 | @Consumes(MediaType.WILDCARD) 21 | public Response ping() { 22 | Map pong = new HashMap<>(); 23 | pong.put("pong", "Hello, World!"); 24 | return Response.status(200).entity(pong).build(); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /aws-serverless-jersey-archetype/src/test/resources/projects/base/archetype.properties: -------------------------------------------------------------------------------- 1 | groupId=test.service 2 | artifactId=jersey-archetype-test 3 | version=1.0-SNAPSHOT 4 | -------------------------------------------------------------------------------- /aws-serverless-jersey-archetype/src/test/resources/projects/base/goal.txt: -------------------------------------------------------------------------------- 1 | package -------------------------------------------------------------------------------- /aws-serverless-spark-archetype/src/main/resources/META-INF/maven/archetype-metadata.xml: -------------------------------------------------------------------------------- 1 | 5 | 6 | 7 | src/main/java 8 | 9 | **/*.java 10 | 11 | 12 | 13 | src/test/java 14 | 15 | **/*.java 16 | 17 | 18 | 19 | src/assembly 20 | 21 | * 22 | 23 | 24 | 25 | 26 | 27 | sam.yaml 28 | README.md 29 | build.gradle 30 | 31 | 32 | 33 | -------------------------------------------------------------------------------- /aws-serverless-spark-archetype/src/main/resources/archetype-resources/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'java' 2 | 3 | repositories { 4 | mavenLocal() 5 | mavenCentral() 6 | } 7 | 8 | dependencies { 9 | compile ( 10 | 'com.sparkjava:spark-core:2.8.0', 11 | 'com.amazonaws.serverless:aws-serverless-java-container-spark:[1.0,)', 12 | 'com.fasterxml.jackson.core:jackson-databind:2.9.8', 13 | 'io.symphonia:lambda-logging:1.0.1' 14 | ) 15 | 16 | testCompile("junit:junit:4.12") 17 | } 18 | 19 | task buildZip(type: Zip) { 20 | from compileJava 21 | from processResources 22 | into('lib') { 23 | from(configurations.compileClasspath) { 24 | exclude 'jetty-http*' 25 | exclude 'jetty-client*' 26 | exclude 'jetty-webapp*' 27 | exclude 'jetty-xml*' 28 | exclude 'jetty-io*' 29 | exclude 'websocket*' 30 | } 31 | } 32 | } 33 | 34 | build.dependsOn buildZip 35 | -------------------------------------------------------------------------------- /aws-serverless-spark-archetype/src/main/resources/archetype-resources/sam.yaml: -------------------------------------------------------------------------------- 1 | #set($resourceName = $artifactId) 2 | #macro(replaceChar $originalName, $char) 3 | #if($originalName.contains($char)) 4 | #set($tokens = $originalName.split($char)) 5 | #set($newResourceName = "") 6 | #foreach($token in $tokens) 7 | #set($newResourceName = $newResourceName + $token.substring(0,1).toUpperCase() + $token.substring(1).toLowerCase()) 8 | #end 9 | ${newResourceName} 10 | #else 11 | #set($newResourceName = $originalName.substring(0,1).toUpperCase() + $originalName.substring(1)) 12 | ${newResourceName} 13 | #end 14 | #end 15 | #set($resourceName = "#replaceChar($resourceName, '-')") 16 | #set($resourceName = "#replaceChar($resourceName, '.')") 17 | #set($resourceName = $resourceName.replaceAll("\n", "").trim()) 18 | #macro(regionVar) 19 | AWS::Region 20 | #end 21 | #set($awsRegion = "#regionVar()") 22 | #set($awsRegion = $awsRegion.replaceAll("\n", "").trim()) 23 | AWSTemplateFormatVersion: '2010-09-09' 24 | Transform: AWS::Serverless-2016-10-31 25 | Description: AWS Serverless Spark API - ${groupId}::${artifactId} 26 | Globals: 27 | Api: 28 | EndpointConfiguration: REGIONAL 29 | 30 | Resources: 31 | ${resourceName}Function: 32 | Type: AWS::Serverless::Function 33 | Properties: 34 | Handler: ${groupId}.StreamLambdaHandler::handleRequest 35 | Runtime: java8 36 | CodeUri: target/${artifactId}-${version}-lambda-package.zip 37 | MemorySize: 512 38 | Policies: AWSLambdaBasicExecutionRole 39 | Timeout: 15 40 | Events: 41 | GetResource: 42 | Type: Api 43 | Properties: 44 | Path: /{proxy+} 45 | Method: any 46 | 47 | Outputs: 48 | ${resourceName}Api: 49 | Description: URL for application 50 | Value: !Sub 'https://${ServerlessRestApi}.execute-api.${${awsRegion}}.amazonaws.com/Prod/ping' 51 | Export: 52 | Name: ${resourceName}Api 53 | -------------------------------------------------------------------------------- /aws-serverless-spark-archetype/src/main/resources/archetype-resources/src/assembly/bin.xml: -------------------------------------------------------------------------------- 1 | 4 | lambda-package 5 | 6 | zip 7 | 8 | false 9 | 10 | 11 | 12 | ${project.build.directory}${file.separator}lib 13 | 14 | websocket* 15 | jetty-http* 16 | jetty-client* 17 | jetty-webapp* 18 | jetty-xml* 19 | jetty-io* 20 | 21 | lib 22 | 23 | 24 | 25 | ${project.build.directory}${file.separator}classes 26 | 27 | ** 28 | 29 | ${file.separator} 30 | 31 | 32 | -------------------------------------------------------------------------------- /aws-serverless-spark-archetype/src/main/resources/archetype-resources/src/main/java/SparkResources.java: -------------------------------------------------------------------------------- 1 | package ${groupId}; 2 | 3 | 4 | import java.util.HashMap; 5 | import java.util.Map; 6 | 7 | import static spark.Spark.before; 8 | import static spark.Spark.get; 9 | 10 | import ${groupId}.util.JsonTransformer; 11 | 12 | 13 | public class SparkResources { 14 | 15 | public static void defineResources() { 16 | before((request, response) -> response.type("application/json")); 17 | 18 | get("/ping", (req, res) -> { 19 | Map pong = new HashMap<>(); 20 | pong.put("pong", "Hello, World!"); 21 | res.status(200); 22 | return pong; 23 | }, new JsonTransformer()); 24 | } 25 | } -------------------------------------------------------------------------------- /aws-serverless-spark-archetype/src/main/resources/archetype-resources/src/main/java/StreamLambdaHandler.java: -------------------------------------------------------------------------------- 1 | package ${groupId}; 2 | 3 | 4 | import com.amazonaws.serverless.exceptions.ContainerInitializationException; 5 | import com.amazonaws.serverless.proxy.model.AwsProxyRequest; 6 | import com.amazonaws.serverless.proxy.model.AwsProxyResponse; 7 | import com.amazonaws.serverless.proxy.spark.SparkLambdaContainerHandler; 8 | import com.amazonaws.services.lambda.runtime.Context; 9 | import com.amazonaws.services.lambda.runtime.RequestStreamHandler; 10 | 11 | import spark.Spark; 12 | 13 | import java.io.IOException; 14 | import java.io.InputStream; 15 | import java.io.OutputStream; 16 | 17 | 18 | public class StreamLambdaHandler implements RequestStreamHandler { 19 | private static SparkLambdaContainerHandler handler; 20 | static { 21 | try { 22 | handler = SparkLambdaContainerHandler.getAwsProxyHandler(); 23 | SparkResources.defineResources(); 24 | Spark.awaitInitialization(); 25 | } catch (ContainerInitializationException e) { 26 | // if we fail here. We re-throw the exception to force another cold start 27 | e.printStackTrace(); 28 | throw new RuntimeException("Could not initialize Spark container", e); 29 | } 30 | } 31 | 32 | @Override 33 | public void handleRequest(InputStream inputStream, OutputStream outputStream, Context context) 34 | throws IOException { 35 | handler.proxyStream(inputStream, outputStream, context); 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /aws-serverless-spark-archetype/src/main/resources/archetype-resources/src/main/java/util/JsonTransformer.java: -------------------------------------------------------------------------------- 1 | package ${groupId}.util; 2 | 3 | import com.fasterxml.jackson.core.JsonProcessingException; 4 | import com.fasterxml.jackson.databind.ObjectMapper; 5 | import org.slf4j.Logger; 6 | import org.slf4j.LoggerFactory; 7 | import spark.ResponseTransformer; 8 | 9 | public class JsonTransformer implements ResponseTransformer { 10 | 11 | private ObjectMapper mapper = new ObjectMapper(); 12 | private Logger log = LoggerFactory.getLogger(JsonTransformer.class); 13 | 14 | @Override 15 | public String render(Object model) { 16 | try { 17 | return mapper.writeValueAsString(model); 18 | } catch (JsonProcessingException e) { 19 | log.error("Cannot serialize object", e); 20 | return null; 21 | } 22 | } 23 | 24 | } -------------------------------------------------------------------------------- /aws-serverless-spark-archetype/src/test/resources/projects/base/archetype.properties: -------------------------------------------------------------------------------- 1 | groupId=test.service 2 | artifactId=spark-archetype-test 3 | version=1.0-SNAPSHOT 4 | -------------------------------------------------------------------------------- /aws-serverless-spark-archetype/src/test/resources/projects/base/goal.txt: -------------------------------------------------------------------------------- 1 | package -------------------------------------------------------------------------------- /aws-serverless-spring-archetype/src/main/resources/META-INF/maven/archetype-metadata.xml: -------------------------------------------------------------------------------- 1 | 5 | 6 | 7 | src/main/java 8 | 9 | **/*.java 10 | 11 | 12 | 13 | src/test/java 14 | 15 | **/*.java 16 | 17 | 18 | 19 | src/main/resources 20 | 21 | **/*.xml 22 | 23 | 24 | 25 | src/assembly 26 | 27 | * 28 | 29 | 30 | 31 | 32 | 33 | sam.yaml 34 | README.md 35 | build.gradle 36 | 37 | 38 | 39 | -------------------------------------------------------------------------------- /aws-serverless-spring-archetype/src/main/resources/archetype-resources/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'java' 2 | 3 | repositories { 4 | mavenLocal() 5 | mavenCentral() 6 | } 7 | 8 | dependencies { 9 | compile ( 10 | 'org.springframework:spring-webmvc:5.1.1.RELEASE', 11 | 'org.springframework:spring-context:5.1.1.RELEASE', 12 | 'com.amazonaws.serverless:aws-serverless-java-container-spring:[1.0,)', 13 | 'org.apache.logging.log4j:log4j-core:2.8.2', 14 | 'org.apache.logging.log4j:log4j-api:2.8.2', 15 | 'org.apache.logging.log4j:log4j-slf4j-impl:2.8.2', 16 | 'com.fasterxml.jackson.core:jackson-databind:2.9.8', 17 | 'com.amazonaws:aws-lambda-java-log4j2:1.1.0', 18 | ) 19 | 20 | testCompile("junit:junit:4.12") 21 | } 22 | 23 | task buildZip(type: Zip) { 24 | from compileJava 25 | from processResources 26 | into('lib') { 27 | from(configurations.compileClasspath) 28 | } 29 | } 30 | 31 | build.dependsOn buildZip 32 | -------------------------------------------------------------------------------- /aws-serverless-spring-archetype/src/main/resources/archetype-resources/sam.yaml: -------------------------------------------------------------------------------- 1 | #set($resourceName = $artifactId) 2 | #macro(replaceChar $originalName, $char) 3 | #if($originalName.contains($char)) 4 | #set($tokens = $originalName.split($char)) 5 | #set($newResourceName = "") 6 | #foreach($token in $tokens) 7 | #set($newResourceName = $newResourceName + $token.substring(0,1).toUpperCase() + $token.substring(1).toLowerCase()) 8 | #end 9 | ${newResourceName} 10 | #else 11 | #set($newResourceName = $originalName.substring(0,1).toUpperCase() + $originalName.substring(1)) 12 | ${newResourceName} 13 | #end 14 | #end 15 | #set($resourceName = "#replaceChar($resourceName, '-')") 16 | #set($resourceName = "#replaceChar($resourceName, '.')") 17 | #set($resourceName = $resourceName.replaceAll("\n", "").trim()) 18 | #macro(regionVar) 19 | AWS::Region 20 | #end 21 | #set($awsRegion = "#regionVar()") 22 | #set($awsRegion = $awsRegion.replaceAll("\n", "").trim()) 23 | AWSTemplateFormatVersion: '2010-09-09' 24 | Transform: AWS::Serverless-2016-10-31 25 | Description: AWS Serverless Spring API - ${groupId}::${artifactId} 26 | Globals: 27 | Api: 28 | EndpointConfiguration: REGIONAL 29 | 30 | Resources: 31 | ${resourceName}Function: 32 | Type: AWS::Serverless::Function 33 | Properties: 34 | Handler: ${groupId}.StreamLambdaHandler::handleRequest 35 | Runtime: java8 36 | CodeUri: target/${artifactId}-${version}-lambda-package.zip 37 | MemorySize: 512 38 | Policies: AWSLambdaBasicExecutionRole 39 | Timeout: 15 40 | Events: 41 | GetResource: 42 | Type: Api 43 | Properties: 44 | Path: /{proxy+} 45 | Method: any 46 | 47 | Outputs: 48 | ${resourceName}Api: 49 | Description: URL for application 50 | Value: !Sub 'https://${ServerlessRestApi}.execute-api.${${awsRegion}}.amazonaws.com/Prod/ping' 51 | Export: 52 | Name: ${resourceName}Api 53 | -------------------------------------------------------------------------------- /aws-serverless-spring-archetype/src/main/resources/archetype-resources/src/assembly/bin.xml: -------------------------------------------------------------------------------- 1 | 4 | lambda-package 5 | 6 | zip 7 | 8 | false 9 | 10 | 11 | 12 | ${project.build.directory}${file.separator}lib 13 | lib 14 | 15 | 16 | 17 | ${project.build.directory}${file.separator}classes 18 | 19 | ** 20 | 21 | ${file.separator} 22 | 23 | 24 | -------------------------------------------------------------------------------- /aws-serverless-spring-archetype/src/main/resources/archetype-resources/src/main/java/SpringApiConfig.java: -------------------------------------------------------------------------------- 1 | package ${groupId}; 2 | 3 | import org.springframework.context.annotation.Bean; 4 | import org.springframework.context.annotation.ComponentScan; 5 | import org.springframework.context.annotation.Configuration; 6 | import org.springframework.context.annotation.Import; 7 | import org.springframework.web.servlet.HandlerAdapter; 8 | import org.springframework.web.servlet.HandlerExceptionResolver; 9 | import org.springframework.web.servlet.HandlerMapping; 10 | import org.springframework.web.servlet.ModelAndView; 11 | import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter; 12 | import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping; 13 | 14 | import javax.servlet.http.HttpServletRequest; 15 | import javax.servlet.http.HttpServletResponse; 16 | 17 | import ${groupId}.controller.PingController; 18 | 19 | 20 | @Configuration 21 | // We use direct @Import instead of @ComponentScan to speed up cold starts 22 | // @ComponentScan("${groupId}.controller") 23 | @Import({ PingController.class }) 24 | public class SpringApiConfig { 25 | /* 26 | * Create required HandlerMapping, to avoid several default HandlerMapping instances being created 27 | */ 28 | @Bean 29 | public HandlerMapping handlerMapping() { 30 | return new RequestMappingHandlerMapping(); 31 | } 32 | 33 | /* 34 | * Create required HandlerAdapter, to avoid several default HandlerAdapter instances being created 35 | */ 36 | @Bean 37 | public HandlerAdapter handlerAdapter() { 38 | return new RequestMappingHandlerAdapter(); 39 | } 40 | 41 | /* 42 | * optimization - avoids creating default exception resolvers; not required as the serverless container handles 43 | * all exceptions 44 | * 45 | * By default, an ExceptionHandlerExceptionResolver is created which creates many dependent object, including 46 | * an expensive ObjectMapper instance. 47 | * 48 | * To enable custom @ControllerAdvice classes remove this bean. 49 | */ 50 | @Bean 51 | public HandlerExceptionResolver handlerExceptionResolver() { 52 | return new HandlerExceptionResolver() { 53 | 54 | @Override 55 | public ModelAndView resolveException(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) { 56 | return null; 57 | } 58 | }; 59 | } 60 | } -------------------------------------------------------------------------------- /aws-serverless-spring-archetype/src/main/resources/archetype-resources/src/main/java/StreamLambdaHandler.java: -------------------------------------------------------------------------------- 1 | package ${groupId}; 2 | 3 | 4 | import com.amazonaws.serverless.exceptions.ContainerInitializationException; 5 | import com.amazonaws.serverless.proxy.model.AwsProxyRequest; 6 | import com.amazonaws.serverless.proxy.model.AwsProxyResponse; 7 | import com.amazonaws.serverless.proxy.spring.SpringLambdaContainerHandler; 8 | import com.amazonaws.services.lambda.runtime.Context; 9 | import com.amazonaws.services.lambda.runtime.RequestStreamHandler; 10 | 11 | import java.io.IOException; 12 | import java.io.InputStream; 13 | import java.io.OutputStream; 14 | 15 | 16 | public class StreamLambdaHandler implements RequestStreamHandler { 17 | private static SpringLambdaContainerHandler handler; 18 | static { 19 | try { 20 | handler = SpringLambdaContainerHandler.getAwsProxyHandler(SpringApiConfig.class); 21 | } catch (ContainerInitializationException e) { 22 | // if we fail here. We re-throw the exception to force another cold start 23 | e.printStackTrace(); 24 | throw new RuntimeException("Could not initialize Spring framework", e); 25 | } 26 | } 27 | 28 | @Override 29 | public void handleRequest(InputStream inputStream, OutputStream outputStream, Context context) 30 | throws IOException { 31 | handler.proxyStream(inputStream, outputStream, context); 32 | } 33 | } -------------------------------------------------------------------------------- /aws-serverless-spring-archetype/src/main/resources/archetype-resources/src/main/java/controller/PingController.java: -------------------------------------------------------------------------------- 1 | package ${groupId}.controller; 2 | 3 | 4 | import org.springframework.web.bind.annotation.*; 5 | import org.springframework.web.servlet.config.annotation.EnableWebMvc; 6 | 7 | import java.util.HashMap; 8 | import java.util.Map; 9 | 10 | 11 | @RestController 12 | @EnableWebMvc 13 | public class PingController { 14 | @RequestMapping(path = "/ping", method = RequestMethod.GET) 15 | public Map ping() { 16 | Map pong = new HashMap<>(); 17 | pong.put("pong", "Hello, World!"); 18 | return pong; 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /aws-serverless-spring-archetype/src/main/resources/archetype-resources/src/main/resources/log4j2.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | %d{yyyy-MM-dd HH:mm:ss} %X{AWSRequestId} %-5p %c{1}:%L - %m%n 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /aws-serverless-spring-archetype/src/test/resources/projects/base/archetype.properties: -------------------------------------------------------------------------------- 1 | groupId=test.service 2 | artifactId=spring-archetype-test 3 | version=1.0-SNAPSHOT 4 | -------------------------------------------------------------------------------- /aws-serverless-spring-archetype/src/test/resources/projects/base/goal.txt: -------------------------------------------------------------------------------- 1 | package -------------------------------------------------------------------------------- /aws-serverless-springboot-archetype/src/main/resources/META-INF/maven/archetype-metadata.xml: -------------------------------------------------------------------------------- 1 | 5 | 6 | 7 | src/main/java 8 | 9 | **/*.java 10 | 11 | 12 | 13 | src/main/resources 14 | 15 | **/*.properties 16 | 17 | 18 | 19 | src/test/java 20 | 21 | **/*.java 22 | 23 | 24 | 25 | src/assembly 26 | 27 | * 28 | 29 | 30 | 31 | 32 | 33 | sam.yaml 34 | README.md 35 | build.gradle 36 | 37 | 38 | 39 | -------------------------------------------------------------------------------- /aws-serverless-springboot-archetype/src/main/resources/archetype-resources/build.gradle: -------------------------------------------------------------------------------- 1 | plugins { 2 | id 'org.springframework.boot' version '1.5.17.RELEASE' 3 | } 4 | apply plugin: 'java' 5 | 6 | repositories { 7 | jcenter() 8 | mavenLocal() 9 | mavenCentral() 10 | } 11 | 12 | dependencies { 13 | compile ( 14 | 'org.springframework.boot:spring-boot-starter-web', 15 | 'com.amazonaws.serverless:aws-serverless-java-container-spring:[1.0,)', 16 | 'io.symphonia:lambda-logging:1.0.1' 17 | ) 18 | 19 | testCompile("junit:junit:4.12") 20 | } 21 | 22 | task buildZip(type: Zip) { 23 | from compileJava 24 | from processResources 25 | into('lib') { 26 | from(configurations.compileClasspath) { 27 | exclude 'tomcat-embed-*' 28 | } 29 | } 30 | } 31 | 32 | build.dependsOn buildZip 33 | -------------------------------------------------------------------------------- /aws-serverless-springboot-archetype/src/main/resources/archetype-resources/sam.yaml: -------------------------------------------------------------------------------- 1 | #set($resourceName = $artifactId) 2 | #macro(replaceChar $originalName, $char) 3 | #if($originalName.contains($char)) 4 | #set($tokens = $originalName.split($char)) 5 | #set($newResourceName = "") 6 | #foreach($token in $tokens) 7 | #set($newResourceName = $newResourceName + $token.substring(0,1).toUpperCase() + $token.substring(1).toLowerCase()) 8 | #end 9 | ${newResourceName} 10 | #else 11 | #set($newResourceName = $originalName.substring(0,1).toUpperCase() + $originalName.substring(1)) 12 | ${newResourceName} 13 | #end 14 | #end 15 | #set($resourceName = "#replaceChar($resourceName, '-')") 16 | #set($resourceName = "#replaceChar($resourceName, '.')") 17 | #set($resourceName = $resourceName.replaceAll("\n", "").trim()) 18 | #macro(regionVar) 19 | AWS::Region 20 | #end 21 | #set($awsRegion = "#regionVar()") 22 | #set($awsRegion = $awsRegion.replaceAll("\n", "").trim()) 23 | AWSTemplateFormatVersion: '2010-09-09' 24 | Transform: AWS::Serverless-2016-10-31 25 | Description: AWS Serverless Spring Boot API - ${groupId}::${artifactId} 26 | Globals: 27 | Api: 28 | EndpointConfiguration: REGIONAL 29 | 30 | Resources: 31 | ${resourceName}Function: 32 | Type: AWS::Serverless::Function 33 | Properties: 34 | Handler: ${groupId}.StreamLambdaHandler::handleRequest 35 | Runtime: java8 36 | CodeUri: target/${artifactId}-${version}-lambda-package.zip 37 | MemorySize: 512 38 | Policies: AWSLambdaBasicExecutionRole 39 | Timeout: 30 40 | Events: 41 | GetResource: 42 | Type: Api 43 | Properties: 44 | Path: /{proxy+} 45 | Method: any 46 | 47 | Outputs: 48 | ${resourceName}Api: 49 | Description: URL for application 50 | Value: !Sub 'https://${ServerlessRestApi}.execute-api.${${awsRegion}}.amazonaws.com/Prod/ping' 51 | Export: 52 | Name: ${resourceName}Api 53 | -------------------------------------------------------------------------------- /aws-serverless-springboot-archetype/src/main/resources/archetype-resources/src/assembly/bin.xml: -------------------------------------------------------------------------------- 1 | 4 | lambda-package 5 | 6 | zip 7 | 8 | false 9 | 10 | 11 | 12 | ${project.build.directory}${file.separator}lib 13 | lib 14 | 15 | tomcat-embed* 16 | 17 | 18 | 19 | 20 | ${project.build.directory}${file.separator}classes 21 | 22 | ** 23 | 24 | ${file.separator} 25 | 26 | 27 | -------------------------------------------------------------------------------- /aws-serverless-springboot-archetype/src/main/resources/archetype-resources/src/main/java/StreamLambdaHandler.java: -------------------------------------------------------------------------------- 1 | package ${groupId}; 2 | 3 | 4 | import com.amazonaws.serverless.exceptions.ContainerInitializationException; 5 | import com.amazonaws.serverless.proxy.model.AwsProxyRequest; 6 | import com.amazonaws.serverless.proxy.model.AwsProxyResponse; 7 | import com.amazonaws.serverless.proxy.spring.SpringBootLambdaContainerHandler; 8 | import com.amazonaws.services.lambda.runtime.Context; 9 | import com.amazonaws.services.lambda.runtime.RequestStreamHandler; 10 | 11 | import java.io.IOException; 12 | import java.io.InputStream; 13 | import java.io.OutputStream; 14 | 15 | 16 | public class StreamLambdaHandler implements RequestStreamHandler { 17 | private static SpringBootLambdaContainerHandler handler; 18 | static { 19 | try { 20 | handler = SpringBootLambdaContainerHandler.getAwsProxyHandler(Application.class); 21 | } catch (ContainerInitializationException e) { 22 | // if we fail here. We re-throw the exception to force another cold start 23 | e.printStackTrace(); 24 | throw new RuntimeException("Could not initialize Spring Boot application", e); 25 | } 26 | } 27 | 28 | @Override 29 | public void handleRequest(InputStream inputStream, OutputStream outputStream, Context context) 30 | throws IOException { 31 | handler.proxyStream(inputStream, outputStream, context); 32 | } 33 | } -------------------------------------------------------------------------------- /aws-serverless-springboot-archetype/src/main/resources/archetype-resources/src/main/java/controller/PingController.java: -------------------------------------------------------------------------------- 1 | package ${groupId}.controller; 2 | 3 | 4 | import org.springframework.web.bind.annotation.*; 5 | import org.springframework.web.servlet.config.annotation.EnableWebMvc; 6 | 7 | import java.util.HashMap; 8 | import java.util.Map; 9 | 10 | 11 | @RestController 12 | @EnableWebMvc 13 | public class PingController { 14 | @RequestMapping(path = "/ping", method = RequestMethod.GET) 15 | public Map ping() { 16 | Map pong = new HashMap<>(); 17 | pong.put("pong", "Hello, World!"); 18 | return pong; 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /aws-serverless-springboot-archetype/src/main/resources/archetype-resources/src/main/resources/application.properties: -------------------------------------------------------------------------------- 1 | # Reduce logging level to make sure the application works with SAM local 2 | # https://github.com/awslabs/aws-serverless-java-container/issues/134 3 | logging.level.root=WARN -------------------------------------------------------------------------------- /aws-serverless-springboot-archetype/src/test/resources/projects/base/archetype.properties: -------------------------------------------------------------------------------- 1 | groupId=test.service 2 | artifactId=springboot-archetype-test 3 | version=1.0-SNAPSHOT 4 | -------------------------------------------------------------------------------- /aws-serverless-springboot-archetype/src/test/resources/projects/base/goal.txt: -------------------------------------------------------------------------------- 1 | package -------------------------------------------------------------------------------- /aws-serverless-springboot2-archetype/src/main/resources/META-INF/maven/archetype-metadata.xml: -------------------------------------------------------------------------------- 1 | 5 | 6 | 7 | src/main/java 8 | 9 | **/*.java 10 | 11 | 12 | 13 | src/main/resources 14 | 15 | **/*.properties 16 | 17 | 18 | 19 | src/test/java 20 | 21 | **/*.java 22 | 23 | 24 | 25 | src/assembly 26 | 27 | * 28 | 29 | 30 | 31 | 32 | 33 | sam.yaml 34 | README.md 35 | build.gradle 36 | 37 | 38 | 39 | -------------------------------------------------------------------------------- /aws-serverless-springboot2-archetype/src/main/resources/archetype-resources/build.gradle: -------------------------------------------------------------------------------- 1 | plugins { 2 | id 'org.springframework.boot' version '2.1.1.RELEASE' 3 | } 4 | apply plugin: 'java' 5 | 6 | repositories { 7 | jcenter() 8 | mavenLocal() 9 | mavenCentral() 10 | } 11 | 12 | dependencies { 13 | compile ( 14 | 'org.springframework.boot:spring-boot-starter-web:2.1.1.RELEASE', 15 | 'com.amazonaws.serverless:aws-serverless-java-container-spring:[1.0,)', 16 | 'io.symphonia:lambda-logging:1.0.1' 17 | ) 18 | 19 | testCompile("junit:junit:4.12") 20 | } 21 | 22 | task buildZip(type: Zip) { 23 | from compileJava 24 | from processResources 25 | into('lib') { 26 | from(configurations.compileClasspath) { 27 | exclude 'tomcat-embed-*' 28 | } 29 | } 30 | } 31 | 32 | build.dependsOn buildZip 33 | -------------------------------------------------------------------------------- /aws-serverless-springboot2-archetype/src/main/resources/archetype-resources/sam.yaml: -------------------------------------------------------------------------------- 1 | #set($resourceName = $artifactId) 2 | #macro(replaceChar $originalName, $char) 3 | #if($originalName.contains($char)) 4 | #set($tokens = $originalName.split($char)) 5 | #set($newResourceName = "") 6 | #foreach($token in $tokens) 7 | #set($newResourceName = $newResourceName + $token.substring(0,1).toUpperCase() + $token.substring(1).toLowerCase()) 8 | #end 9 | ${newResourceName} 10 | #else 11 | #set($newResourceName = $originalName.substring(0,1).toUpperCase() + $originalName.substring(1)) 12 | ${newResourceName} 13 | #end 14 | #end 15 | #set($resourceName = "#replaceChar($resourceName, '-')") 16 | #set($resourceName = "#replaceChar($resourceName, '.')") 17 | #set($resourceName = $resourceName.replaceAll("\n", "").trim()) 18 | #macro(regionVar) 19 | AWS::Region 20 | #end 21 | #set($awsRegion = "#regionVar()") 22 | #set($awsRegion = $awsRegion.replaceAll("\n", "").trim()) 23 | AWSTemplateFormatVersion: '2010-09-09' 24 | Transform: AWS::Serverless-2016-10-31 25 | Description: AWS Serverless Spring Boot 2 API - ${groupId}::${artifactId} 26 | Globals: 27 | Api: 28 | EndpointConfiguration: REGIONAL 29 | 30 | Resources: 31 | ${resourceName}Function: 32 | Type: AWS::Serverless::Function 33 | Properties: 34 | Handler: ${groupId}.StreamLambdaHandler::handleRequest 35 | Runtime: java8 36 | CodeUri: target/${artifactId}-${version}-lambda-package.zip 37 | MemorySize: 512 38 | Policies: AWSLambdaBasicExecutionRole 39 | Timeout: 30 40 | Events: 41 | GetResource: 42 | Type: Api 43 | Properties: 44 | Path: /{proxy+} 45 | Method: any 46 | 47 | Outputs: 48 | ${resourceName}Api: 49 | Description: URL for application 50 | Value: !Sub 'https://${ServerlessRestApi}.execute-api.${${awsRegion}}.amazonaws.com/Prod/ping' 51 | Export: 52 | Name: ${resourceName}Api 53 | -------------------------------------------------------------------------------- /aws-serverless-springboot2-archetype/src/main/resources/archetype-resources/src/assembly/bin.xml: -------------------------------------------------------------------------------- 1 | 4 | lambda-package 5 | 6 | zip 7 | 8 | false 9 | 10 | 11 | 12 | ${project.build.directory}${file.separator}lib 13 | lib 14 | 15 | tomcat-embed* 16 | 17 | 18 | 19 | 20 | ${project.build.directory}${file.separator}classes 21 | 22 | ** 23 | 24 | ${file.separator} 25 | 26 | 27 | -------------------------------------------------------------------------------- /aws-serverless-springboot2-archetype/src/main/resources/archetype-resources/src/main/java/Application.java: -------------------------------------------------------------------------------- 1 | #macro(loggingOff) 2 | logging.level.root:OFF 3 | #end 4 | #set($logging = "#loggingOff()") 5 | #set($logging = $logging.replaceAll("\n", "").trim()) 6 | package ${groupId}; 7 | 8 | import org.springframework.beans.factory.annotation.Value; 9 | import org.springframework.boot.SpringApplication; 10 | import org.springframework.boot.autoconfigure.SpringBootApplication; 11 | import org.springframework.boot.web.servlet.support.SpringBootServletInitializer; 12 | import org.springframework.context.annotation.Bean; 13 | import org.springframework.context.annotation.Import; 14 | import org.springframework.web.servlet.HandlerAdapter; 15 | import org.springframework.web.servlet.HandlerExceptionResolver; 16 | import org.springframework.web.servlet.HandlerMapping; 17 | import org.springframework.web.servlet.ModelAndView; 18 | import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter; 19 | import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping; 20 | 21 | import javax.servlet.http.HttpServletRequest; 22 | import javax.servlet.http.HttpServletResponse; 23 | 24 | import ${groupId}.controller.PingController; 25 | 26 | 27 | @SpringBootApplication 28 | // We use direct @Import instead of @ComponentScan to speed up cold starts 29 | // @ComponentScan(basePackages = "${groupId}.controller") 30 | @Import({ PingController.class }) 31 | public class Application extends SpringBootServletInitializer { 32 | 33 | /* 34 | * Create required HandlerMapping, to avoid several default HandlerMapping instances being created 35 | */ 36 | @Bean 37 | public HandlerMapping handlerMapping() { 38 | return new RequestMappingHandlerMapping(); 39 | } 40 | 41 | /* 42 | * Create required HandlerAdapter, to avoid several default HandlerAdapter instances being created 43 | */ 44 | @Bean 45 | public HandlerAdapter handlerAdapter() { 46 | return new RequestMappingHandlerAdapter(); 47 | } 48 | 49 | public static void main(String[] args) { 50 | SpringApplication.run(Application.class, args); 51 | } 52 | } -------------------------------------------------------------------------------- /aws-serverless-springboot2-archetype/src/main/resources/archetype-resources/src/main/java/StreamLambdaHandler.java: -------------------------------------------------------------------------------- 1 | package ${groupId}; 2 | 3 | 4 | import com.amazonaws.serverless.exceptions.ContainerInitializationException; 5 | import com.amazonaws.serverless.proxy.model.AwsProxyRequest; 6 | import com.amazonaws.serverless.proxy.model.AwsProxyResponse; 7 | import com.amazonaws.serverless.proxy.spring.SpringBootLambdaContainerHandler; 8 | import com.amazonaws.services.lambda.runtime.Context; 9 | import com.amazonaws.services.lambda.runtime.RequestStreamHandler; 10 | 11 | import java.io.IOException; 12 | import java.io.InputStream; 13 | import java.io.OutputStream; 14 | 15 | 16 | public class StreamLambdaHandler implements RequestStreamHandler { 17 | private static SpringBootLambdaContainerHandler handler; 18 | static { 19 | try { 20 | handler = SpringBootLambdaContainerHandler.getAwsProxyHandler(Application.class); 21 | } catch (ContainerInitializationException e) { 22 | // if we fail here. We re-throw the exception to force another cold start 23 | e.printStackTrace(); 24 | throw new RuntimeException("Could not initialize Spring Boot application", e); 25 | } 26 | } 27 | 28 | @Override 29 | public void handleRequest(InputStream inputStream, OutputStream outputStream, Context context) 30 | throws IOException { 31 | handler.proxyStream(inputStream, outputStream, context); 32 | } 33 | } -------------------------------------------------------------------------------- /aws-serverless-springboot2-archetype/src/main/resources/archetype-resources/src/main/java/controller/PingController.java: -------------------------------------------------------------------------------- 1 | package ${groupId}.controller; 2 | 3 | 4 | import org.springframework.web.bind.annotation.*; 5 | import org.springframework.web.servlet.config.annotation.EnableWebMvc; 6 | 7 | import java.util.HashMap; 8 | import java.util.Map; 9 | 10 | 11 | @RestController 12 | @EnableWebMvc 13 | public class PingController { 14 | @RequestMapping(path = "/ping", method = RequestMethod.GET) 15 | public Map ping() { 16 | Map pong = new HashMap<>(); 17 | pong.put("pong", "Hello, World!"); 18 | return pong; 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /aws-serverless-springboot2-archetype/src/main/resources/archetype-resources/src/main/resources/application.properties: -------------------------------------------------------------------------------- 1 | # Reduce logging level to make sure the application works with SAM local 2 | # https://github.com/awslabs/aws-serverless-java-container/issues/134 3 | logging.level.root=WARN -------------------------------------------------------------------------------- /aws-serverless-springboot2-archetype/src/test/resources/projects/base/archetype.properties: -------------------------------------------------------------------------------- 1 | groupId=test.service 2 | artifactId=springboot-archetype-test 3 | version=1.0-SNAPSHOT 4 | -------------------------------------------------------------------------------- /aws-serverless-springboot2-archetype/src/test/resources/projects/base/goal.txt: -------------------------------------------------------------------------------- 1 | package -------------------------------------------------------------------------------- /aws-serverless-struts2-archetype/src/main/resources/META-INF/maven/archetype-metadata.xml: -------------------------------------------------------------------------------- 1 | 5 | 6 | 7 | src/main/java 8 | 9 | **/*.java 10 | 11 | 12 | 13 | src/test/java 14 | 15 | **/*.java 16 | 17 | 18 | 19 | src/main/resources 20 | 21 | **/*.properties 22 | **/*.xml 23 | 24 | 25 | 26 | src/main/assembly 27 | 28 | **/*.xml 29 | 30 | 31 | 32 | 33 | 34 | sam.yaml 35 | README.md 36 | build.gradle 37 | 38 | 39 | 40 | -------------------------------------------------------------------------------- /aws-serverless-struts2-archetype/src/main/resources/archetype-resources/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'java' 2 | 3 | repositories { 4 | mavenLocal() 5 | mavenCentral() 6 | } 7 | 8 | dependencies { 9 | compile ( 10 | 'com.amazonaws.serverless:aws-serverless-java-container-struts2:[1.0,)', 11 | 'org.apache.struts:struts2-convention-plugin:2.5.17', 12 | 'org.apache.struts:struts2-rest-plugin:2.5.17', 13 | 'org.apache.struts:struts2-bean-validation-plugin:2.5.17', 14 | 'org.apache.struts:struts2-junit-plugin:2.5.17', 15 | 'com.jgeppert.struts2:struts2-aws-lambda-support-plugin:1.0.0', 16 | 'org.hibernate:hibernate-validator:4.3.2.Final', 17 | 'com.fasterxml.jackson.core:jackson-databind:2.9.8', 18 | 'org.apache.logging.log4j:log4j-core:2.8.2', 19 | 'org.apache.logging.log4j:log4j-api:2.8.2', 20 | 'org.apache.logging.log4j:log4j-slf4j-impl:2.8.2', 21 | 'com.amazonaws:aws-lambda-java-log4j2:1.1.0', 22 | ) 23 | 24 | testCompile("junit:junit:4.12") 25 | } 26 | 27 | task buildZip(type: Zip) { 28 | from compileJava 29 | from processResources 30 | into('lib') { 31 | from(configurations.compileClasspath) 32 | } 33 | } 34 | 35 | build.dependsOn buildZip 36 | -------------------------------------------------------------------------------- /aws-serverless-struts2-archetype/src/main/resources/archetype-resources/sam.yaml: -------------------------------------------------------------------------------- 1 | #set($resourceName = $artifactId) 2 | #macro(replaceChar $originalName, $char) 3 | #if($originalName.contains($char)) 4 | #set($tokens = $originalName.split($char)) 5 | #set($newResourceName = "") 6 | #foreach($token in $tokens) 7 | #set($newResourceName = $newResourceName + $token.substring(0,1).toUpperCase() + $token.substring(1).toLowerCase()) 8 | #end 9 | ${newResourceName} 10 | #else 11 | #set($newResourceName = $originalName.substring(0,1).toUpperCase() + $originalName.substring(1)) 12 | ${newResourceName} 13 | #end 14 | #end 15 | #set($resourceName = "#replaceChar($resourceName, '-')") 16 | #set($resourceName = "#replaceChar($resourceName, '.')") 17 | #set($resourceName = $resourceName.replaceAll("\n", "").trim()) 18 | #macro(regionVar) 19 | AWS::Region 20 | #end 21 | #set($awsRegion = "#regionVar()") 22 | #set($awsRegion = $awsRegion.replaceAll("\n", "").trim()) 23 | AWSTemplateFormatVersion: '2010-09-09' 24 | Transform: AWS::Serverless-2016-10-31 25 | Description: AWS Serverless Apache Struts2 API - ${groupId}::${artifactId} 26 | Globals: 27 | Api: 28 | EndpointConfiguration: REGIONAL 29 | 30 | Resources: 31 | ${resourceName}Function: 32 | Type: AWS::Serverless::Function 33 | Properties: 34 | Handler: com.amazonaws.serverless.proxy.struts2.Struts2LambdaHandler::handleRequest 35 | Runtime: java8 36 | CodeUri: target/${artifactId}-${version}-lambda.zip 37 | MemorySize: 512 38 | Policies: AWSLambdaBasicExecutionRole 39 | Timeout: 30 40 | Events: 41 | GetResource: 42 | Type: Api 43 | Properties: 44 | Path: /{proxy+} 45 | Method: any 46 | 47 | Outputs: 48 | ${resourceName}Api: 49 | Description: URL for application 50 | Value: !Sub 'https://${ServerlessRestApi}.execute-api.${${awsRegion}}.amazonaws.com/Prod/ping' 51 | Export: 52 | Name: ${resourceName}Api 53 | -------------------------------------------------------------------------------- /aws-serverless-struts2-archetype/src/main/resources/archetype-resources/src/main/assembly/dist.xml: -------------------------------------------------------------------------------- 1 | 4 | lambda 5 | 6 | zip 7 | 8 | false 9 | 10 | 11 | lib 12 | false 13 | 14 | 15 | 16 | 17 | ${basedir}/src/main/resources 18 | 19 | 20 | * 21 | 22 | 23 | 24 | ${project.build.directory}/classes 25 | 26 | 27 | **/*.class 28 | 29 | 30 | 31 | -------------------------------------------------------------------------------- /aws-serverless-struts2-archetype/src/main/resources/archetype-resources/src/main/java/actions/PingController.java: -------------------------------------------------------------------------------- 1 | package ${groupId}.actions; 2 | 3 | 4 | import com.opensymphony.xwork2.ModelDriven; 5 | import org.apache.struts2.rest.DefaultHttpHeaders; 6 | import org.apache.struts2.rest.HttpHeaders; 7 | import org.apache.struts2.rest.RestActionSupport; 8 | 9 | 10 | import java.util.Collection; 11 | import java.util.UUID; 12 | 13 | 14 | public class PingController extends RestActionSupport implements ModelDriven { 15 | 16 | private String model = new String(); 17 | private String id; 18 | private Collection list = null; 19 | 20 | 21 | // GET /ping/1 22 | public HttpHeaders show() { 23 | return new DefaultHttpHeaders("show"); 24 | } 25 | 26 | // GET /ping 27 | public HttpHeaders index() { 28 | this.model = "Hello, World!"; 29 | return new DefaultHttpHeaders("index") 30 | .disableCaching(); 31 | } 32 | 33 | // POST /ping 34 | public HttpHeaders create() { 35 | this.model = UUID.randomUUID().toString(); 36 | return new DefaultHttpHeaders("success") 37 | .setLocationId(model); 38 | 39 | } 40 | 41 | // PUT /ping/1 42 | public String update() { 43 | //TODO: UPDATE LOGIC 44 | return SUCCESS; 45 | } 46 | 47 | // DELETE /ping/1 48 | public String destroy() { 49 | //TODO: DELETE LOGIC 50 | return SUCCESS; 51 | } 52 | 53 | public void setId(String id) { 54 | if (id != null) { 55 | this.model = "New model instance"; 56 | } 57 | this.id = id; 58 | } 59 | 60 | public Object getModel() { 61 | if (list != null) { 62 | return list; 63 | } else { 64 | if (model == null) { 65 | model = "Pong"; 66 | } 67 | return model; 68 | } 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /aws-serverless-struts2-archetype/src/main/resources/archetype-resources/src/main/resources/application.properties: -------------------------------------------------------------------------------- 1 | # Reduce logging level to make sure the application works with SAM local 2 | # https://github.com/awslabs/aws-serverless-java-container/issues/134 3 | logging.level.root=WARN -------------------------------------------------------------------------------- /aws-serverless-struts2-archetype/src/main/resources/archetype-resources/src/main/resources/log4j2.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | %d{yyyy-MM-dd HH:mm:ss} %X{AWSRequestId} %-5p %c{1}:%L - %m%n 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /aws-serverless-struts2-archetype/src/main/resources/archetype-resources/src/main/resources/struts.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | -------------------------------------------------------------------------------- /aws-serverless-struts2-archetype/src/test/resources/projects/base/archetype.properties: -------------------------------------------------------------------------------- 1 | groupId=test.service 2 | artifactId=struts2-archetype-test 3 | version=1.0-SNAPSHOT 4 | -------------------------------------------------------------------------------- /aws-serverless-struts2-archetype/src/test/resources/projects/base/goal.txt: -------------------------------------------------------------------------------- 1 | package -------------------------------------------------------------------------------- /owasp-suppression.xml: -------------------------------------------------------------------------------- 1 | 2 | 20 | 21 | 22 | 23 | 24 | cpe:/a:amazon_aws_project:amazon_aws:7.x-1.2::~~~drupal~~ 25 | 26 | 27 | 28 | cpe:/a:restful_web_services_project:restful_web_services:7.x-2.1::~~~drupal~~ 29 | 30 | 31 | 34 | 35 | 36 | 37 | cpe:/a:slf4j:slf4j:1.8.0 38 | 39 | 40 | 41 | 42 | cpe:/a:fasterxml:jackson-databind:2.9.9 43 | 44 | 45 | -------------------------------------------------------------------------------- /samples/jersey/pet-store/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'java' 2 | 3 | repositories { 4 | mavenLocal() 5 | mavenCentral() 6 | } 7 | 8 | dependencies { 9 | compile ( 10 | 'com.amazonaws:aws-lambda-java-core:1.2.0', 11 | 'com.amazonaws.serverless:aws-serverless-java-container-jersey:[1.0,)', 12 | 'com.fasterxml.jackson.core:jackson-databind:2.9.8', 13 | 'io.symphonia:lambda-logging:1.0.1' 14 | ) 15 | 16 | compile("org.glassfish.jersey.media:jersey-media-json-jackson:2.27") { 17 | exclude group: 'com.fasterxml.jackson.core', module: "jackson-annotations" 18 | exclude group: 'com.fasterxml.jackson.core', module: "jackson-databind" 19 | exclude group: 'com.fasterxml.jackson.core', module: "jackson-core" 20 | } 21 | 22 | compile("org.glassfish.jersey.inject:jersey-hk2:2.27") { 23 | exclude group: 'javax.inject', module: "javax.inject" 24 | } 25 | } 26 | 27 | task buildZip(type: Zip) { 28 | from compileJava 29 | from processResources 30 | into('lib') { 31 | from configurations.compileClasspath 32 | } 33 | } 34 | 35 | build.dependsOn buildZip 36 | -------------------------------------------------------------------------------- /samples/jersey/pet-store/sam.yaml: -------------------------------------------------------------------------------- 1 | AWSTemplateFormatVersion: '2010-09-09' 2 | Transform: AWS::Serverless-2016-10-31 3 | Description: Example Pet Store API written in jersey with the aws-serverless-java-container library 4 | 5 | Globals: 6 | Api: 7 | # API Gateway regional endpoints 8 | EndpointConfiguration: REGIONAL 9 | 10 | Resources: 11 | PetStoreFunction: 12 | Type: AWS::Serverless::Function 13 | Properties: 14 | Handler: com.amazonaws.serverless.sample.jersey.StreamLambdaHandler::handleRequest 15 | Runtime: java8 16 | CodeUri: target/serverless-jersey-example-1.0-SNAPSHOT-lambda-package.zip 17 | MemorySize: 512 18 | Policies: AWSLambdaBasicExecutionRole 19 | Timeout: 20 20 | Events: 21 | GetResource: 22 | Type: Api 23 | Properties: 24 | Path: /{proxy+} 25 | Method: any 26 | 27 | Outputs: 28 | JerseyPetStoreApi: 29 | Description: URL for application 30 | Value: !Sub 'https://${ServerlessRestApi}.execute-api.${AWS::Region}.amazonaws.com/Prod/pets' 31 | Export: 32 | Name: JerseyPetStoreApi 33 | -------------------------------------------------------------------------------- /samples/jersey/pet-store/src/assembly/bin.xml: -------------------------------------------------------------------------------- 1 | 4 | lambda-package 5 | 6 | zip 7 | 8 | false 9 | 10 | 11 | 12 | ${project.build.directory}${file.separator}lib 13 | lib 14 | 15 | 16 | 17 | ${project.build.directory}${file.separator}classes 18 | 19 | ** 20 | 21 | ${file.separator} 22 | 23 | 24 | -------------------------------------------------------------------------------- /samples/jersey/pet-store/src/main/java/com/amazonaws/serverless/sample/jersey/PetsResource.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016 Amazon.com, Inc. or its affiliates. All Rights Reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"). You may not use this file except in compliance 5 | * with the License. A copy of the License is located at 6 | * 7 | * http://aws.amazon.com/apache2.0/ 8 | * 9 | * or in the "license" file accompanying this file. This file is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES 10 | * OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions 11 | * and limitations under the License. 12 | */ 13 | package com.amazonaws.serverless.sample.jersey; 14 | 15 | import com.amazonaws.serverless.sample.jersey.model.Pet; 16 | import com.amazonaws.serverless.sample.jersey.model.PetData; 17 | 18 | import javax.ws.rs.*; 19 | import javax.ws.rs.core.MediaType; 20 | import javax.ws.rs.core.Response; 21 | import java.util.UUID; 22 | 23 | @Path("/pets") 24 | public class PetsResource { 25 | 26 | @POST 27 | @Produces(MediaType.APPLICATION_JSON) 28 | @Consumes(MediaType.APPLICATION_JSON) 29 | public Response createPet(final Pet newPet) { 30 | if (newPet.getName() == null || newPet.getBreed() == null) { 31 | return Response.status(400).entity(new Error("Invalid name or breed")).build(); 32 | } 33 | 34 | Pet dbPet = newPet; 35 | dbPet.setId(UUID.randomUUID().toString()); 36 | return Response.status(200).entity(dbPet).build(); 37 | } 38 | 39 | @GET 40 | @Produces(MediaType.APPLICATION_JSON) 41 | public Pet[] listPets(@QueryParam("limit") int limit) { 42 | if (limit < 1) { 43 | limit = 10; 44 | } 45 | 46 | Pet[] outputPets = new Pet[limit]; 47 | 48 | for (int i = 0; i < limit; i++) { 49 | Pet newPet = new Pet(); 50 | newPet.setId(UUID.randomUUID().toString()); 51 | newPet.setName(PetData.getRandomName()); 52 | newPet.setBreed(PetData.getRandomBreed()); 53 | newPet.setDateOfBirth(PetData.getRandomDoB()); 54 | outputPets[i] = newPet; 55 | } 56 | 57 | return outputPets; 58 | } 59 | 60 | @Path("/{petId}") @GET 61 | @Produces(MediaType.APPLICATION_JSON) 62 | public Pet getPetDetails() { 63 | Pet newPet = new Pet(); 64 | newPet.setId(UUID.randomUUID().toString()); 65 | newPet.setBreed(PetData.getRandomBreed()); 66 | newPet.setDateOfBirth(PetData.getRandomDoB()); 67 | newPet.setName(PetData.getRandomName()); 68 | return newPet; 69 | } 70 | } -------------------------------------------------------------------------------- /samples/jersey/pet-store/src/main/java/com/amazonaws/serverless/sample/jersey/StreamLambdaHandler.java: -------------------------------------------------------------------------------- 1 | package com.amazonaws.serverless.sample.jersey; 2 | 3 | 4 | import com.amazonaws.serverless.proxy.internal.LambdaContainerHandler; 5 | import com.amazonaws.serverless.proxy.internal.testutils.Timer; 6 | import com.amazonaws.serverless.proxy.jersey.JerseyLambdaContainerHandler; 7 | import com.amazonaws.serverless.proxy.model.AwsProxyRequest; 8 | import com.amazonaws.serverless.proxy.model.AwsProxyResponse; 9 | import com.amazonaws.services.lambda.runtime.Context; 10 | import com.amazonaws.services.lambda.runtime.RequestStreamHandler; 11 | 12 | import org.glassfish.jersey.jackson.JacksonFeature; 13 | import org.glassfish.jersey.server.ResourceConfig; 14 | 15 | import java.io.IOException; 16 | import java.io.InputStream; 17 | import java.io.OutputStream; 18 | 19 | 20 | public class StreamLambdaHandler implements RequestStreamHandler { 21 | private static final ResourceConfig jerseyApplication = new ResourceConfig() 22 | .packages("com.amazonaws.serverless.sample.jersey") 23 | .register(JacksonFeature.class); 24 | private static final JerseyLambdaContainerHandler handler 25 | = JerseyLambdaContainerHandler.getAwsProxyHandler(jerseyApplication); 26 | 27 | public StreamLambdaHandler() { 28 | // we enable the timer for debugging. This SHOULD NOT be enabled in production. 29 | Timer.enable(); 30 | } 31 | 32 | @Override 33 | public void handleRequest(InputStream inputStream, OutputStream outputStream, Context context) 34 | throws IOException { 35 | handler.proxyStream(inputStream, outputStream, context); 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /samples/jersey/pet-store/src/main/java/com/amazonaws/serverless/sample/jersey/model/Error.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016 Amazon.com, Inc. or its affiliates. All Rights Reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"). You may not use this file except in compliance 5 | * with the License. A copy of the License is located at 6 | * 7 | * http://aws.amazon.com/apache2.0/ 8 | * 9 | * or in the "license" file accompanying this file. This file is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES 10 | * OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions 11 | * and limitations under the License. 12 | */ 13 | package com.amazonaws.serverless.sample.jersey.model; 14 | 15 | public class Error { 16 | private String message; 17 | 18 | public Error(String errorMessage) { 19 | message = errorMessage; 20 | } 21 | 22 | public String getMessage() { 23 | return message; 24 | } 25 | 26 | public void setMessage(String message) { 27 | this.message = message; 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /samples/jersey/pet-store/src/main/java/com/amazonaws/serverless/sample/jersey/model/Pet.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016 Amazon.com, Inc. or its affiliates. All Rights Reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"). You may not use this file except in compliance 5 | * with the License. A copy of the License is located at 6 | * 7 | * http://aws.amazon.com/apache2.0/ 8 | * 9 | * or in the "license" file accompanying this file. This file is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES 10 | * OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions 11 | * and limitations under the License. 12 | */ 13 | package com.amazonaws.serverless.sample.jersey.model; 14 | 15 | import java.util.Date; 16 | 17 | public class Pet { 18 | private String id; 19 | private String breed; 20 | private String name; 21 | private Date dateOfBirth; 22 | 23 | public String getId() { 24 | return id; 25 | } 26 | 27 | public void setId(String id) { 28 | this.id = id; 29 | } 30 | 31 | public String getBreed() { 32 | return breed; 33 | } 34 | 35 | public void setBreed(String breed) { 36 | this.breed = breed; 37 | } 38 | 39 | public String getName() { 40 | return name; 41 | } 42 | 43 | public void setName(String name) { 44 | this.name = name; 45 | } 46 | 47 | public Date getDateOfBirth() { 48 | return dateOfBirth; 49 | } 50 | 51 | public void setDateOfBirth(Date dateOfBirth) { 52 | this.dateOfBirth = dateOfBirth; 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /samples/spark/pet-store/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'java' 2 | 3 | repositories { 4 | mavenLocal() 5 | mavenCentral() 6 | } 7 | 8 | dependencies { 9 | compile ( 10 | 'com.sparkjava:spark-core:2.8.0', 11 | 'com.amazonaws.serverless:aws-serverless-java-container-spark:[1.0,)', 12 | 'com.fasterxml.jackson.core:jackson-databind:2.9.8', 13 | 'io.symphonia:lambda-logging:1.0.1' 14 | ) 15 | } 16 | 17 | task buildZip(type: Zip) { 18 | from compileJava 19 | from processResources 20 | into('lib') { 21 | from(configurations.compileClasspath) { 22 | exclude 'jetty-http*' 23 | exclude 'jetty-client*' 24 | exclude 'jetty-webapp*' 25 | exclude 'jetty-xml*' 26 | exclude 'jetty-io*' 27 | exclude 'websocket*' 28 | } 29 | } 30 | } 31 | 32 | build.dependsOn buildZip 33 | -------------------------------------------------------------------------------- /samples/spark/pet-store/sam.yaml: -------------------------------------------------------------------------------- 1 | AWSTemplateFormatVersion: '2010-09-09' 2 | Transform: AWS::Serverless-2016-10-31 3 | Description: Example Pet Store API written with spark with the aws-serverless-java-container library 4 | 5 | Globals: 6 | Api: 7 | # API Gateway regional endpoints 8 | EndpointConfiguration: REGIONAL 9 | 10 | Resources: 11 | PetStoreFunction: 12 | Type: AWS::Serverless::Function 13 | Properties: 14 | Handler: com.amazonaws.serverless.sample.spark.StreamLambdaHandler::handleRequest 15 | Runtime: java8 16 | CodeUri: target/serverless-spark-example-1.0-SNAPSHOT-lambda-package.zip 17 | MemorySize: 512 18 | Policies: AWSLambdaBasicExecutionRole 19 | Timeout: 20 20 | Events: 21 | GetResource: 22 | Type: Api 23 | Properties: 24 | Path: /{proxy+} 25 | Method: any 26 | 27 | Outputs: 28 | SparkPetStoreApi: 29 | Description: URL for application 30 | Value: !Sub 'https://${ServerlessRestApi}.execute-api.${AWS::Region}.amazonaws.com/Prod/pets' 31 | Export: 32 | Name: SparkPetStoreApi 33 | -------------------------------------------------------------------------------- /samples/spark/pet-store/src/assembly/bin.xml: -------------------------------------------------------------------------------- 1 | 4 | lambda-package 5 | 6 | zip 7 | 8 | false 9 | 10 | 11 | 12 | ${project.build.directory}${file.separator}lib 13 | 14 | websocket* 15 | jetty-http* 16 | jetty-client* 17 | jetty-webapp* 18 | jetty-xml* 19 | jetty-io* 20 | 21 | lib 22 | 23 | 24 | 25 | ${project.build.directory}${file.separator}classes 26 | 27 | ** 28 | 29 | ${file.separator} 30 | 31 | 32 | -------------------------------------------------------------------------------- /samples/spark/pet-store/src/main/java/com/amazonaws/serverless/sample/spark/JsonTransformer.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016 Amazon.com, Inc. or its affiliates. All Rights Reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"). You may not use this file except in compliance 5 | * with the License. A copy of the License is located at 6 | * 7 | * http://aws.amazon.com/apache2.0/ 8 | * 9 | * or in the "license" file accompanying this file. This file is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES 10 | * OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions 11 | * and limitations under the License. 12 | */ 13 | package com.amazonaws.serverless.sample.spark; 14 | 15 | import com.fasterxml.jackson.core.JsonProcessingException; 16 | import com.fasterxml.jackson.databind.ObjectMapper; 17 | import org.slf4j.Logger; 18 | import org.slf4j.LoggerFactory; 19 | import spark.ResponseTransformer; 20 | 21 | public class JsonTransformer implements ResponseTransformer { 22 | 23 | private ObjectMapper mapper = new ObjectMapper(); 24 | private Logger log = LoggerFactory.getLogger(JsonTransformer.class); 25 | 26 | @Override 27 | public String render(Object model) { 28 | try { 29 | return mapper.writeValueAsString(model); 30 | } catch (JsonProcessingException e) { 31 | log.error("Cannot serialize object", e); 32 | return null; 33 | } 34 | } 35 | 36 | } -------------------------------------------------------------------------------- /samples/spark/pet-store/src/main/java/com/amazonaws/serverless/sample/spark/SparkResources.java: -------------------------------------------------------------------------------- 1 | package com.amazonaws.serverless.sample.spark; 2 | 3 | 4 | import com.amazonaws.serverless.proxy.internal.LambdaContainerHandler; 5 | import com.amazonaws.serverless.sample.spark.model.Pet; 6 | import com.amazonaws.serverless.sample.spark.model.PetData; 7 | 8 | import javax.ws.rs.core.Response; 9 | 10 | import java.util.UUID; 11 | 12 | import static spark.Spark.before; 13 | import static spark.Spark.get; 14 | import static spark.Spark.post; 15 | 16 | 17 | public class SparkResources { 18 | 19 | public static void defineResources() { 20 | before((request, response) -> response.type("application/json")); 21 | 22 | post("/pets", (req, res) -> { 23 | Pet newPet = LambdaContainerHandler.getObjectMapper().readValue(req.body(), Pet.class); 24 | if (newPet.getName() == null || newPet.getBreed() == null) { 25 | return Response.status(400).entity(new Error("Invalid name or breed")).build(); 26 | } 27 | 28 | Pet dbPet = newPet; 29 | dbPet.setId(UUID.randomUUID().toString()); 30 | 31 | res.status(200); 32 | return dbPet; 33 | }, new JsonTransformer()); 34 | 35 | get("/pets", (req, res) -> { 36 | int limit = 10; 37 | if (req.queryParams("limit") != null) { 38 | limit = Integer.parseInt(req.queryParams("limit")); 39 | } 40 | 41 | Pet[] outputPets = new Pet[limit]; 42 | 43 | for (int i = 0; i < limit; i++) { 44 | Pet newPet = new Pet(); 45 | newPet.setId(UUID.randomUUID().toString()); 46 | newPet.setName(PetData.getRandomName()); 47 | newPet.setBreed(PetData.getRandomBreed()); 48 | newPet.setDateOfBirth(PetData.getRandomDoB()); 49 | outputPets[i] = newPet; 50 | } 51 | 52 | res.status(200); 53 | return outputPets; 54 | }, new JsonTransformer()); 55 | 56 | get("/pets/:petId", (req, res) -> { 57 | Pet newPet = new Pet(); 58 | newPet.setId(UUID.randomUUID().toString()); 59 | newPet.setBreed(PetData.getRandomBreed()); 60 | newPet.setDateOfBirth(PetData.getRandomDoB()); 61 | newPet.setName(PetData.getRandomName()); 62 | res.status(200); 63 | return newPet; 64 | }, new JsonTransformer()); 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /samples/spark/pet-store/src/main/java/com/amazonaws/serverless/sample/spark/StreamLambdaHandler.java: -------------------------------------------------------------------------------- 1 | package com.amazonaws.serverless.sample.spark; 2 | 3 | 4 | import com.amazonaws.serverless.exceptions.ContainerInitializationException; 5 | import com.amazonaws.serverless.proxy.internal.testutils.Timer; 6 | import com.amazonaws.serverless.proxy.model.AwsProxyRequest; 7 | import com.amazonaws.serverless.proxy.model.AwsProxyResponse; 8 | import com.amazonaws.serverless.proxy.spark.SparkLambdaContainerHandler; 9 | import com.amazonaws.serverless.sample.spark.filter.CognitoIdentityFilter; 10 | import com.amazonaws.services.lambda.runtime.Context; 11 | import com.amazonaws.services.lambda.runtime.RequestStreamHandler; 12 | 13 | import spark.Spark; 14 | 15 | import javax.servlet.DispatcherType; 16 | import javax.servlet.FilterRegistration; 17 | 18 | import java.io.IOException; 19 | import java.io.InputStream; 20 | import java.io.OutputStream; 21 | import java.util.EnumSet; 22 | 23 | 24 | public class StreamLambdaHandler implements RequestStreamHandler { 25 | private static SparkLambdaContainerHandler handler; 26 | static { 27 | try { 28 | handler = SparkLambdaContainerHandler.getAwsProxyHandler(); 29 | SparkResources.defineResources(); 30 | Spark.awaitInitialization(); 31 | 32 | // we use the onStartup method of the handler to register our custom filter 33 | handler.onStartup(servletContext -> { 34 | FilterRegistration.Dynamic registration = servletContext.addFilter("CognitoIdentityFilter", CognitoIdentityFilter.class); 35 | registration.addMappingForUrlPatterns(EnumSet.of(DispatcherType.REQUEST), false, "/*"); 36 | }); 37 | } catch (ContainerInitializationException e) { 38 | // if we fail here. We re-throw the exception to force another cold start 39 | e.printStackTrace(); 40 | throw new RuntimeException("Could not initialize Spark container", e); 41 | } 42 | } 43 | 44 | public StreamLambdaHandler() { 45 | // we enable the timer for debugging. This SHOULD NOT be enabled in production. 46 | Timer.enable(); 47 | } 48 | 49 | @Override 50 | public void handleRequest(InputStream inputStream, OutputStream outputStream, Context context) 51 | throws IOException { 52 | handler.proxyStream(inputStream, outputStream, context); 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /samples/spark/pet-store/src/main/java/com/amazonaws/serverless/sample/spark/filter/CognitoIdentityFilter.java: -------------------------------------------------------------------------------- 1 | package com.amazonaws.serverless.sample.spark.filter; 2 | 3 | 4 | import com.amazonaws.serverless.proxy.RequestReader; 5 | import com.amazonaws.serverless.proxy.model.AwsProxyRequestContext; 6 | 7 | import org.slf4j.Logger; 8 | import org.slf4j.LoggerFactory; 9 | 10 | import javax.servlet.Filter; 11 | import javax.servlet.FilterChain; 12 | import javax.servlet.FilterConfig; 13 | import javax.servlet.ServletException; 14 | import javax.servlet.ServletRequest; 15 | import javax.servlet.ServletResponse; 16 | 17 | import java.io.IOException; 18 | 19 | 20 | /** 21 | * Simple Filter implementation that looks for a Cognito identity id in the API Gateway request context 22 | * and stores the value in a request attribute. The filter is registered with aws-serverless-java-container 23 | * in the onStartup method from the {@link com.amazonaws.serverless.sample.spring.StreamLambdaHandler} class. 24 | */ 25 | public class CognitoIdentityFilter implements Filter { 26 | public static final String COGNITO_IDENTITY_ATTRIBUTE = "com.amazonaws.serverless.cognitoId"; 27 | 28 | private static Logger log = LoggerFactory.getLogger(CognitoIdentityFilter.class); 29 | 30 | @Override 31 | public void init(FilterConfig filterConfig) 32 | throws ServletException { 33 | // nothing to do in init 34 | } 35 | 36 | 37 | @Override 38 | public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) 39 | throws IOException, ServletException { 40 | Object apiGwContext = servletRequest.getAttribute(RequestReader.API_GATEWAY_CONTEXT_PROPERTY); 41 | if (apiGwContext == null) { 42 | log.warn("API Gateway context is null"); 43 | filterChain.doFilter(servletRequest, servletResponse); 44 | } 45 | if (!AwsProxyRequestContext.class.isAssignableFrom(apiGwContext.getClass())) { 46 | log.warn("API Gateway context object is not of valid type"); 47 | filterChain.doFilter(servletRequest, servletResponse); 48 | } 49 | 50 | AwsProxyRequestContext ctx = (AwsProxyRequestContext)apiGwContext; 51 | if (ctx.getIdentity() == null) { 52 | log.warn("Identity context is null"); 53 | filterChain.doFilter(servletRequest, servletResponse); 54 | } 55 | String cognitoIdentityId = ctx.getIdentity().getCognitoIdentityId(); 56 | if (cognitoIdentityId == null || "".equals(cognitoIdentityId.trim())) { 57 | log.warn("Cognito identity id in request is null"); 58 | } 59 | servletRequest.setAttribute(COGNITO_IDENTITY_ATTRIBUTE, cognitoIdentityId); 60 | filterChain.doFilter(servletRequest, servletResponse); 61 | } 62 | 63 | 64 | @Override 65 | public void destroy() { 66 | // nothing to do in destroy 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /samples/spark/pet-store/src/main/java/com/amazonaws/serverless/sample/spark/model/Error.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016 Amazon.com, Inc. or its affiliates. All Rights Reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"). You may not use this file except in compliance 5 | * with the License. A copy of the License is located at 6 | * 7 | * http://aws.amazon.com/apache2.0/ 8 | * 9 | * or in the "license" file accompanying this file. This file is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES 10 | * OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions 11 | * and limitations under the License. 12 | */ 13 | package com.amazonaws.serverless.sample.spark.model; 14 | 15 | public class Error { 16 | private String message; 17 | 18 | public Error(String errorMessage) { 19 | message = errorMessage; 20 | } 21 | 22 | public String getMessage() { 23 | return message; 24 | } 25 | 26 | public void setMessage(String message) { 27 | this.message = message; 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /samples/spark/pet-store/src/main/java/com/amazonaws/serverless/sample/spark/model/Pet.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016 Amazon.com, Inc. or its affiliates. All Rights Reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"). You may not use this file except in compliance 5 | * with the License. A copy of the License is located at 6 | * 7 | * http://aws.amazon.com/apache2.0/ 8 | * 9 | * or in the "license" file accompanying this file. This file is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES 10 | * OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions 11 | * and limitations under the License. 12 | */ 13 | package com.amazonaws.serverless.sample.spark.model; 14 | 15 | import java.util.Date; 16 | 17 | public class Pet { 18 | private String id; 19 | private String breed; 20 | private String name; 21 | private Date dateOfBirth; 22 | 23 | public String getId() { 24 | return id; 25 | } 26 | 27 | public void setId(String id) { 28 | this.id = id; 29 | } 30 | 31 | public String getBreed() { 32 | return breed; 33 | } 34 | 35 | public void setBreed(String breed) { 36 | this.breed = breed; 37 | } 38 | 39 | public String getName() { 40 | return name; 41 | } 42 | 43 | public void setName(String name) { 44 | this.name = name; 45 | } 46 | 47 | public Date getDateOfBirth() { 48 | return dateOfBirth; 49 | } 50 | 51 | public void setDateOfBirth(Date dateOfBirth) { 52 | this.dateOfBirth = dateOfBirth; 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /samples/spring/pet-store/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'java' 2 | 3 | repositories { 4 | mavenLocal() 5 | mavenCentral() 6 | } 7 | 8 | dependencies { 9 | compile ( 10 | 'org.springframework:spring-webmvc:5.1.1.RELEASE', 11 | 'org.springframework:spring-context:5.1.1.RELEASE', 12 | 'com.amazonaws.serverless:aws-serverless-java-container-spring:[1.0,)', 13 | 'org.apache.logging.log4j:log4j-core:2.8.2', 14 | 'org.apache.logging.log4j:log4j-api:2.8.2', 15 | 'org.apache.logging.log4j:log4j-slf4j-impl:2.8.2', 16 | 'com.fasterxml.jackson.core:jackson-databind:2.9.8', 17 | 'com.amazonaws:aws-lambda-java-log4j2:1.1.0', 18 | ) 19 | } 20 | 21 | task buildZip(type: Zip) { 22 | from compileJava 23 | from processResources 24 | into('lib') { 25 | from(configurations.compileClasspath) 26 | } 27 | } 28 | 29 | build.dependsOn buildZip 30 | -------------------------------------------------------------------------------- /samples/spring/pet-store/sam.yaml: -------------------------------------------------------------------------------- 1 | AWSTemplateFormatVersion: '2010-09-09' 2 | Transform: AWS::Serverless-2016-10-31 3 | Description: Example Pet Store API written with spring with the aws-serverless-java-container library 4 | 5 | Globals: 6 | Api: 7 | # API Gateway regional endpoints 8 | EndpointConfiguration: REGIONAL 9 | 10 | Resources: 11 | PetStoreFunction: 12 | Type: AWS::Serverless::Function 13 | Properties: 14 | Handler: com.amazonaws.serverless.sample.spring.StreamLambdaHandler::handleRequest 15 | Runtime: java8 16 | CodeUri: target/serverless-spring-example-1.0-SNAPSHOT-lambda-package.zip 17 | MemorySize: 512 18 | Policies: AWSLambdaBasicExecutionRole 19 | Timeout: 30 20 | Events: 21 | GetResource: 22 | Type: Api 23 | Properties: 24 | Path: /{proxy+} 25 | Method: any 26 | 27 | Outputs: 28 | SpringPetStoreApi: 29 | Description: URL for application 30 | Value: !Sub 'https://${ServerlessRestApi}.execute-api.${AWS::Region}.amazonaws.com/Prod/pets' 31 | Export: 32 | Name: SpringPetStoreApi 33 | -------------------------------------------------------------------------------- /samples/spring/pet-store/src/assembly/bin.xml: -------------------------------------------------------------------------------- 1 | 4 | lambda-package 5 | 6 | zip 7 | 8 | false 9 | 10 | 11 | 12 | ${project.build.directory}${file.separator}lib 13 | lib 14 | 15 | 16 | 17 | ${project.build.directory}${file.separator}classes 18 | 19 | ** 20 | 21 | ${file.separator} 22 | 23 | 24 | -------------------------------------------------------------------------------- /samples/spring/pet-store/src/main/java/com/amazonaws/serverless/sample/spring/PetStoreSpringAppConfig.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016 Amazon.com, Inc. or its affiliates. All Rights Reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"). You may not use this file except in compliance 5 | * with the License. A copy of the License is located at 6 | * 7 | * http://aws.amazon.com/apache2.0/ 8 | * 9 | * or in the "license" file accompanying this file. This file is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES 10 | * OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions 11 | * and limitations under the License. 12 | */ 13 | package com.amazonaws.serverless.sample.spring; 14 | 15 | import org.springframework.context.annotation.Bean; 16 | import org.springframework.context.annotation.Configuration; 17 | import org.springframework.context.annotation.Import; 18 | import org.springframework.web.servlet.HandlerAdapter; 19 | import org.springframework.web.servlet.HandlerExceptionResolver; 20 | import org.springframework.web.servlet.HandlerMapping; 21 | import org.springframework.web.servlet.ModelAndView; 22 | import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter; 23 | import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping; 24 | 25 | import javax.servlet.http.HttpServletRequest; 26 | import javax.servlet.http.HttpServletResponse; 27 | 28 | 29 | @Configuration 30 | @Import({ PetsController.class }) 31 | public class PetStoreSpringAppConfig { 32 | /* 33 | * Create required HandlerMapping, to avoid several default HandlerMapping instances being created 34 | */ 35 | @Bean 36 | public HandlerMapping handlerMapping() { 37 | return new RequestMappingHandlerMapping(); 38 | } 39 | 40 | /* 41 | * Create required HandlerAdapter, to avoid several default HandlerAdapter instances being created 42 | */ 43 | @Bean 44 | public HandlerAdapter handlerAdapter() { 45 | return new RequestMappingHandlerAdapter(); 46 | } 47 | 48 | /* 49 | * optimization - avoids creating default exception resolvers; not required as the serverless container handles 50 | * all exceptions 51 | * 52 | * By default, an ExceptionHandlerExceptionResolver is created which creates many dependent object, including 53 | * an expensive ObjectMapper instance. 54 | * 55 | * To enable custom @ControllerAdvice classes remove this bean. 56 | */ 57 | @Bean 58 | public HandlerExceptionResolver handlerExceptionResolver() { 59 | return new HandlerExceptionResolver() { 60 | 61 | @Override 62 | public ModelAndView resolveException(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) { 63 | return null; 64 | } 65 | }; 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /samples/spring/pet-store/src/main/java/com/amazonaws/serverless/sample/spring/PetsController.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016 Amazon.com, Inc. or its affiliates. All Rights Reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"). You may not use this file except in compliance 5 | * with the License. A copy of the License is located at 6 | * 7 | * http://aws.amazon.com/apache2.0/ 8 | * 9 | * or in the "license" file accompanying this file. This file is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES 10 | * OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions 11 | * and limitations under the License. 12 | */ 13 | package com.amazonaws.serverless.sample.spring; 14 | 15 | import com.amazonaws.serverless.sample.spring.model.Pet; 16 | import com.amazonaws.serverless.sample.spring.model.PetData; 17 | import org.springframework.web.bind.annotation.*; 18 | import org.springframework.web.servlet.config.annotation.EnableWebMvc; 19 | 20 | import java.security.Principal; 21 | import java.util.Optional; 22 | import java.util.UUID; 23 | 24 | @RestController 25 | @EnableWebMvc 26 | public class PetsController { 27 | @RequestMapping(path = "/pets", method = RequestMethod.POST) 28 | public Pet createPet(@RequestBody Pet newPet) { 29 | if (newPet.getName() == null || newPet.getBreed() == null) { 30 | return null; 31 | } 32 | 33 | Pet dbPet = newPet; 34 | dbPet.setId(UUID.randomUUID().toString()); 35 | return dbPet; 36 | } 37 | 38 | @RequestMapping(path = "/pets", method = RequestMethod.GET) 39 | public Pet[] listPets(@RequestParam("limit") Optional limit, Principal principal) { 40 | int queryLimit = 10; 41 | if (limit.isPresent()) { 42 | queryLimit = limit.get(); 43 | } 44 | 45 | Pet[] outputPets = new Pet[queryLimit]; 46 | 47 | for (int i = 0; i < queryLimit; i++) { 48 | Pet newPet = new Pet(); 49 | newPet.setId(UUID.randomUUID().toString()); 50 | newPet.setName(PetData.getRandomName()); 51 | newPet.setBreed(PetData.getRandomBreed()); 52 | newPet.setDateOfBirth(PetData.getRandomDoB()); 53 | outputPets[i] = newPet; 54 | } 55 | 56 | return outputPets; 57 | } 58 | 59 | @RequestMapping(path = "/pets/{petId}", method = RequestMethod.GET) 60 | public Pet listPets() { 61 | Pet newPet = new Pet(); 62 | newPet.setId(UUID.randomUUID().toString()); 63 | newPet.setBreed(PetData.getRandomBreed()); 64 | newPet.setDateOfBirth(PetData.getRandomDoB()); 65 | newPet.setName(PetData.getRandomName()); 66 | return newPet; 67 | } 68 | 69 | } 70 | -------------------------------------------------------------------------------- /samples/spring/pet-store/src/main/java/com/amazonaws/serverless/sample/spring/StreamLambdaHandler.java: -------------------------------------------------------------------------------- 1 | package com.amazonaws.serverless.sample.spring; 2 | 3 | 4 | import com.amazonaws.serverless.exceptions.ContainerInitializationException; 5 | import com.amazonaws.serverless.proxy.internal.testutils.Timer; 6 | import com.amazonaws.serverless.proxy.model.AwsProxyRequest; 7 | import com.amazonaws.serverless.proxy.model.AwsProxyResponse; 8 | import com.amazonaws.serverless.proxy.spring.SpringLambdaContainerHandler; 9 | import com.amazonaws.serverless.sample.spring.filter.CognitoIdentityFilter; 10 | import com.amazonaws.services.lambda.runtime.Context; 11 | import com.amazonaws.services.lambda.runtime.RequestStreamHandler; 12 | 13 | import javax.servlet.DispatcherType; 14 | import javax.servlet.FilterRegistration; 15 | 16 | import java.io.IOException; 17 | import java.io.InputStream; 18 | import java.io.OutputStream; 19 | import java.util.EnumSet; 20 | 21 | 22 | public class StreamLambdaHandler implements RequestStreamHandler { 23 | private static SpringLambdaContainerHandler handler; 24 | static { 25 | try { 26 | handler = SpringLambdaContainerHandler.getAwsProxyHandler(PetStoreSpringAppConfig.class); 27 | 28 | // we use the onStartup method of the handler to register our custom filter 29 | handler.onStartup(servletContext -> { 30 | FilterRegistration.Dynamic registration = servletContext.addFilter("CognitoIdentityFilter", CognitoIdentityFilter.class); 31 | registration.addMappingForUrlPatterns(EnumSet.of(DispatcherType.REQUEST), false, "/*"); 32 | }); 33 | 34 | } catch (ContainerInitializationException e) { 35 | // if we fail here. We re-throw the exception to force another cold start 36 | e.printStackTrace(); 37 | throw new RuntimeException("Could not initialize Spring framework", e); 38 | } 39 | } 40 | 41 | public StreamLambdaHandler() { 42 | // we enable the timer for debugging. This SHOULD NOT be enabled in production. 43 | Timer.enable(); 44 | } 45 | 46 | @Override 47 | public void handleRequest(InputStream inputStream, OutputStream outputStream, Context context) 48 | throws IOException { 49 | handler.proxyStream(inputStream, outputStream, context); 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /samples/spring/pet-store/src/main/java/com/amazonaws/serverless/sample/spring/model/Error.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016 Amazon.com, Inc. or its affiliates. All Rights Reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"). You may not use this file except in compliance 5 | * with the License. A copy of the License is located at 6 | * 7 | * http://aws.amazon.com/apache2.0/ 8 | * 9 | * or in the "license" file accompanying this file. This file is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES 10 | * OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions 11 | * and limitations under the License. 12 | */ 13 | package com.amazonaws.serverless.sample.spring.model; 14 | 15 | public class Error { 16 | private String message; 17 | 18 | public Error(String errorMessage) { 19 | message = errorMessage; 20 | } 21 | 22 | public String getMessage() { 23 | return message; 24 | } 25 | 26 | public void setMessage(String message) { 27 | this.message = message; 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /samples/spring/pet-store/src/main/java/com/amazonaws/serverless/sample/spring/model/Pet.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016 Amazon.com, Inc. or its affiliates. All Rights Reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"). You may not use this file except in compliance 5 | * with the License. A copy of the License is located at 6 | * 7 | * http://aws.amazon.com/apache2.0/ 8 | * 9 | * or in the "license" file accompanying this file. This file is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES 10 | * OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions 11 | * and limitations under the License. 12 | */ 13 | package com.amazonaws.serverless.sample.spring.model; 14 | 15 | import java.util.Date; 16 | 17 | public class Pet { 18 | private String id; 19 | private String breed; 20 | private String name; 21 | private Date dateOfBirth; 22 | 23 | public String getId() { 24 | return id; 25 | } 26 | 27 | public void setId(String id) { 28 | this.id = id; 29 | } 30 | 31 | public String getBreed() { 32 | return breed; 33 | } 34 | 35 | public void setBreed(String breed) { 36 | this.breed = breed; 37 | } 38 | 39 | public String getName() { 40 | return name; 41 | } 42 | 43 | public void setName(String name) { 44 | this.name = name; 45 | } 46 | 47 | public Date getDateOfBirth() { 48 | return dateOfBirth; 49 | } 50 | 51 | public void setDateOfBirth(Date dateOfBirth) { 52 | this.dateOfBirth = dateOfBirth; 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /samples/springboot/pet-store/README.md: -------------------------------------------------------------------------------- 1 | # Serverless Spring Boot example 2 | A basic pet store written with the [Spring Boot framework](https://projects.spring.io/spring-boot/). The `LambdaHandler` object is the main entry point for Lambda. 3 | 4 | The application can be deployed in an AWS account using the [Serverless Framework](https://github.com/serverless/serverless). The `serverless.yml` file in the root folder contains the application definition 5 | 6 | ## Installation 7 | To build and install the sample application you will need [Maven](https://maven.apache.org/) and the [`sls` CLI installed](https://serverless.com/framework/docs/providers/aws/guide/installation/) on your computer. 8 | 9 | In a shell, navigate to the sample's folder and use maven to build a deployable jar. 10 | ``` 11 | $ mvn package 12 | ``` 13 | 14 | This command should generate a `serverless-spring-boot-example-1.0-SNAPSHOT.jar` in the `target` folder. Now that we have generated the jar file, we can use the SLS CLI to package the template for deployment, deploy it, and version control it in S3. 15 | 16 | If you already [set up AWS credentials](https://serverless.com/framework/docs/providers/aws/guide/credentials/), run the following command from the sample's folder: 17 | 18 | ``` 19 | $ sls deploy 20 | ``` 21 | 22 | Once the deployment is complete you'll get information like this in the terminal: 23 | ``` 24 | Service Information 25 | service: petstore 26 | stage: dev 27 | region: us-west-2 28 | stack: petstore-dev 29 | resources: 11 30 | api keys: 31 | None 32 | endpoints: 33 | ANY - https://rbzh9fj8q1.execute-api.us-west-2.amazonaws.com/dev/ 34 | ANY - https://rbzh9fj8q1.execute-api.us-west-2.amazonaws.com/dev/{proxy+} 35 | functions: 36 | SpringBootPetStoreApi: petstore-dev-SpringBootPetStoreApi 37 | layers: 38 | None 39 | ``` 40 | 41 | Copy the `endpoints` URL into a browser, and add `pets` at the end of it to test a first request: https://rbzh9fj8q1.execute-api.us-west-2.amazonaws.com/dev/pets 42 | 43 | To remove all AWS resources related to this project, including the Lambda function, the API endpoint, and the S3 bucket containing the infrastructure configuration and the source code, run the following: 44 | 45 | ``` 46 | $ sls remove 47 | ``` -------------------------------------------------------------------------------- /samples/springboot/pet-store/build.gradle: -------------------------------------------------------------------------------- 1 | plugins { 2 | id 'org.springframework.boot' version '1.5.17.RELEASE' 3 | } 4 | apply plugin: 'java' 5 | 6 | repositories { 7 | jcenter() 8 | mavenLocal() 9 | mavenCentral() 10 | } 11 | 12 | dependencies { 13 | compile ( 14 | 'org.springframework.boot:spring-boot-starter-web', 15 | 'com.amazonaws.serverless:aws-serverless-java-container-spring:[1.0,)', 16 | 'io.symphonia:lambda-logging:1.0.1' 17 | ) 18 | testCompile("junit:junit") 19 | } 20 | 21 | task buildZip(type: Zip) { 22 | from compileJava 23 | from processResources 24 | into('lib') { 25 | from(configurations.compileClasspath) { 26 | exclude 'tomcat-embed-*' 27 | } 28 | } 29 | } 30 | 31 | build.dependsOn buildZip 32 | -------------------------------------------------------------------------------- /samples/springboot/pet-store/serverless.yml: -------------------------------------------------------------------------------- 1 | service: petstore 2 | 3 | provider: 4 | name: aws 5 | runtime: java8 6 | memorySize: 1512 7 | timeout: 60 8 | stage: ${opt:stage,'dev'} 9 | region: ${opt:region, 'us-west-2'} 10 | profile: ${opt:profile, "default"} 11 | endpointType: REGIONAL 12 | 13 | resources: 14 | Description: Example Pet Store API written with SpringBoot with the aws-serverless-java-container library 15 | 16 | package: 17 | individually: true 18 | 19 | functions: 20 | SpringBootPetStoreApi: 21 | package: 22 | artifact: target/serverless-spring-boot-example-1.0-SNAPSHOT-lambda-package.zip 23 | handler: com.amazonaws.serverless.sample.springboot.StreamLambdaHandler::handleRequest 24 | events: 25 | - http: 26 | path: /{proxy+} 27 | method: ANY -------------------------------------------------------------------------------- /samples/springboot/pet-store/src/assembly/bin.xml: -------------------------------------------------------------------------------- 1 | 4 | lambda-package 5 | 6 | zip 7 | 8 | false 9 | 10 | 11 | 12 | ${project.build.directory}${file.separator}lib 13 | lib 14 | 15 | tomcat-embed* 16 | 17 | 18 | 19 | 20 | ${project.build.directory}${file.separator}classes 21 | 22 | ** 23 | 24 | ${file.separator} 25 | 26 | 27 | -------------------------------------------------------------------------------- /samples/springboot/pet-store/src/main/java/com/amazonaws/serverless/sample/springboot/Application.java: -------------------------------------------------------------------------------- 1 | package com.amazonaws.serverless.sample.springboot; 2 | 3 | import com.amazonaws.serverless.sample.springboot.controller.PetsController; 4 | 5 | import org.springframework.beans.factory.annotation.Value; 6 | import org.springframework.boot.SpringApplication; 7 | import org.springframework.boot.autoconfigure.SpringBootApplication; 8 | import org.springframework.boot.web.support.SpringBootServletInitializer; 9 | import org.springframework.context.annotation.Bean; 10 | import org.springframework.context.annotation.Import; 11 | import org.springframework.web.servlet.HandlerAdapter; 12 | import org.springframework.web.servlet.HandlerExceptionResolver; 13 | import org.springframework.web.servlet.HandlerMapping; 14 | import org.springframework.web.servlet.ModelAndView; 15 | import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter; 16 | import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping; 17 | 18 | import javax.servlet.http.HttpServletRequest; 19 | import javax.servlet.http.HttpServletResponse; 20 | 21 | 22 | @SpringBootApplication 23 | @Import({ PetsController.class }) 24 | public class Application extends SpringBootServletInitializer { 25 | 26 | // silence console logging 27 | @Value("${logging.level.root:OFF}") 28 | String message = ""; 29 | 30 | /* 31 | * Create required HandlerMapping, to avoid several default HandlerMapping instances being created 32 | */ 33 | @Bean 34 | public HandlerMapping handlerMapping() { 35 | return new RequestMappingHandlerMapping(); 36 | } 37 | 38 | /* 39 | * Create required HandlerAdapter, to avoid several default HandlerAdapter instances being created 40 | */ 41 | @Bean 42 | public HandlerAdapter handlerAdapter() { 43 | return new RequestMappingHandlerAdapter(); 44 | } 45 | 46 | /* 47 | * optimization - avoids creating default exception resolvers; not required as the serverless container handles 48 | * all exceptions 49 | * 50 | * By default, an ExceptionHandlerExceptionResolver is created which creates many dependent object, including 51 | * an expensive ObjectMapper instance. 52 | * 53 | * To enable custom @ControllerAdvice classes remove this bean. 54 | */ 55 | @Bean 56 | public HandlerExceptionResolver handlerExceptionResolver() { 57 | return new HandlerExceptionResolver() { 58 | 59 | @Override 60 | public ModelAndView resolveException(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) { 61 | return null; 62 | } 63 | }; 64 | } 65 | 66 | public static void main(String[] args) { 67 | SpringApplication.run(Application.class, args); 68 | } 69 | } -------------------------------------------------------------------------------- /samples/springboot/pet-store/src/main/java/com/amazonaws/serverless/sample/springboot/StreamLambdaHandler.java: -------------------------------------------------------------------------------- 1 | package com.amazonaws.serverless.sample.springboot; 2 | 3 | 4 | import com.amazonaws.serverless.exceptions.ContainerInitializationException; 5 | import com.amazonaws.serverless.proxy.internal.testutils.Timer; 6 | import com.amazonaws.serverless.proxy.model.AwsProxyRequest; 7 | import com.amazonaws.serverless.proxy.model.AwsProxyResponse; 8 | import com.amazonaws.serverless.proxy.spring.SpringBootLambdaContainerHandler; 9 | import com.amazonaws.serverless.sample.springboot.filter.CognitoIdentityFilter; 10 | import com.amazonaws.services.lambda.runtime.Context; 11 | import com.amazonaws.services.lambda.runtime.RequestStreamHandler; 12 | 13 | import javax.servlet.DispatcherType; 14 | import javax.servlet.FilterRegistration; 15 | 16 | import java.io.IOException; 17 | import java.io.InputStream; 18 | import java.io.OutputStream; 19 | import java.util.EnumSet; 20 | 21 | 22 | public class StreamLambdaHandler implements RequestStreamHandler { 23 | private static SpringBootLambdaContainerHandler handler; 24 | static { 25 | try { 26 | handler = SpringBootLambdaContainerHandler.getAwsProxyHandler(Application.class); 27 | 28 | // we use the onStartup method of the handler to register our custom filter 29 | handler.onStartup(servletContext -> { 30 | FilterRegistration.Dynamic registration = servletContext.addFilter("CognitoIdentityFilter", CognitoIdentityFilter.class); 31 | registration.addMappingForUrlPatterns(EnumSet.of(DispatcherType.REQUEST), true, "/*"); 32 | }); 33 | } catch (ContainerInitializationException e) { 34 | // if we fail here. We re-throw the exception to force another cold start 35 | e.printStackTrace(); 36 | throw new RuntimeException("Could not initialize Spring Boot application", e); 37 | } 38 | } 39 | 40 | public StreamLambdaHandler() { 41 | // we enable the timer for debugging. This SHOULD NOT be enabled in production. 42 | Timer.enable(); 43 | } 44 | 45 | @Override 46 | public void handleRequest(InputStream inputStream, OutputStream outputStream, Context context) 47 | throws IOException { 48 | handler.proxyStream(inputStream, outputStream, context); 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /samples/springboot/pet-store/src/main/java/com/amazonaws/serverless/sample/springboot/model/Error.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016 Amazon.com, Inc. or its affiliates. All Rights Reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"). You may not use this file except in compliance 5 | * with the License. A copy of the License is located at 6 | * 7 | * http://aws.amazon.com/apache2.0/ 8 | * 9 | * or in the "license" file accompanying this file. This file is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES 10 | * OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions 11 | * and limitations under the License. 12 | */ 13 | package com.amazonaws.serverless.sample.springboot.model; 14 | 15 | public class Error { 16 | private String message; 17 | 18 | public Error(String errorMessage) { 19 | message = errorMessage; 20 | } 21 | 22 | public String getMessage() { 23 | return message; 24 | } 25 | 26 | public void setMessage(String message) { 27 | this.message = message; 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /samples/springboot/pet-store/src/main/java/com/amazonaws/serverless/sample/springboot/model/Pet.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016 Amazon.com, Inc. or its affiliates. All Rights Reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"). You may not use this file except in compliance 5 | * with the License. A copy of the License is located at 6 | * 7 | * http://aws.amazon.com/apache2.0/ 8 | * 9 | * or in the "license" file accompanying this file. This file is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES 10 | * OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions 11 | * and limitations under the License. 12 | */ 13 | package com.amazonaws.serverless.sample.springboot.model; 14 | 15 | import java.util.Date; 16 | 17 | 18 | public class Pet { 19 | private String id; 20 | private String breed; 21 | private String name; 22 | private Date dateOfBirth; 23 | 24 | public String getId() { 25 | return id; 26 | } 27 | 28 | public void setId(String id) { 29 | this.id = id; 30 | } 31 | 32 | public String getBreed() { 33 | return breed; 34 | } 35 | 36 | public void setBreed(String breed) { 37 | this.breed = breed; 38 | } 39 | 40 | public String getName() { 41 | return name; 42 | } 43 | 44 | public void setName(String name) { 45 | this.name = name; 46 | } 47 | 48 | public Date getDateOfBirth() { 49 | return dateOfBirth; 50 | } 51 | 52 | public void setDateOfBirth(Date dateOfBirth) { 53 | this.dateOfBirth = dateOfBirth; 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /samples/springboot/pet-store/src/main/resources/logback.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /samples/springboot2/pet-store/build.gradle: -------------------------------------------------------------------------------- 1 | plugins { 2 | id 'org.springframework.boot' version '2.1.1.RELEASE' 3 | } 4 | apply plugin: 'java' 5 | 6 | repositories { 7 | jcenter() 8 | mavenLocal() 9 | mavenCentral() 10 | } 11 | 12 | dependencies { 13 | compile ( 14 | 'org.springframework.boot:spring-boot-starter-web:2.1.1.RELEASE', 15 | 'com.amazonaws.serverless:aws-serverless-java-container-spring:[1.0,)', 16 | 'io.symphonia:lambda-logging:1.0.1' 17 | ) 18 | testCompile("junit:junit") 19 | } 20 | 21 | task buildZip(type: Zip) { 22 | from compileJava 23 | from processResources 24 | into('lib') { 25 | from(configurations.compileClasspath) { 26 | exclude 'tomcat-embed-*' 27 | } 28 | } 29 | } 30 | 31 | build.dependsOn buildZip 32 | -------------------------------------------------------------------------------- /samples/springboot2/pet-store/sam.yaml: -------------------------------------------------------------------------------- 1 | AWSTemplateFormatVersion: '2010-09-09' 2 | Transform: AWS::Serverless-2016-10-31 3 | Description: Example Pet Store API written with SpringBoot with the aws-serverless-java-container library 4 | 5 | Globals: 6 | Api: 7 | # API Gateway regional endpoints 8 | EndpointConfiguration: REGIONAL 9 | 10 | Resources: 11 | PetStoreFunction: 12 | Type: AWS::Serverless::Function 13 | Properties: 14 | Handler: com.amazonaws.serverless.sample.springboot2.StreamLambdaHandler::handleRequest 15 | Runtime: java8 16 | CodeUri: target/serverless-springboot2-example-1.0-SNAPSHOT-lambda-package.zip 17 | MemorySize: 1512 18 | Policies: AWSLambdaBasicExecutionRole 19 | Timeout: 60 20 | Events: 21 | GetResource: 22 | Type: Api 23 | Properties: 24 | Path: /{proxy+} 25 | Method: any 26 | 27 | Outputs: 28 | SpringBootPetStoreApi: 29 | Description: URL for application 30 | Value: !Sub 'https://${ServerlessRestApi}.execute-api.${AWS::Region}.amazonaws.com/Prod/pets' 31 | Export: 32 | Name: SpringBootPetStoreApi 33 | -------------------------------------------------------------------------------- /samples/springboot2/pet-store/src/assembly/bin.xml: -------------------------------------------------------------------------------- 1 | 4 | lambda-package 5 | 6 | zip 7 | 8 | false 9 | 10 | 11 | 12 | ${project.build.directory}${file.separator}lib 13 | lib 14 | 15 | tomcat-embed* 16 | 17 | 18 | 19 | 20 | ${project.build.directory}${file.separator}classes 21 | 22 | ** 23 | 24 | ${file.separator} 25 | 26 | 27 | -------------------------------------------------------------------------------- /samples/springboot2/pet-store/src/main/java/com/amazonaws/serverless/sample/springboot2/Application.java: -------------------------------------------------------------------------------- 1 | package com.amazonaws.serverless.sample.springboot2; 2 | 3 | import com.amazonaws.serverless.sample.springboot2.controller.PetsController; 4 | 5 | import org.springframework.beans.factory.annotation.Value; 6 | import org.springframework.boot.SpringApplication; 7 | import org.springframework.boot.autoconfigure.SpringBootApplication; 8 | import org.springframework.boot.web.servlet.support.SpringBootServletInitializer; 9 | import org.springframework.context.annotation.Bean; 10 | import org.springframework.context.annotation.Import; 11 | import org.springframework.web.servlet.HandlerAdapter; 12 | import org.springframework.web.servlet.HandlerExceptionResolver; 13 | import org.springframework.web.servlet.HandlerMapping; 14 | import org.springframework.web.servlet.ModelAndView; 15 | import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter; 16 | import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping; 17 | 18 | import javax.servlet.http.HttpServletRequest; 19 | import javax.servlet.http.HttpServletResponse; 20 | 21 | 22 | @SpringBootApplication 23 | @Import({ PetsController.class }) 24 | public class Application extends SpringBootServletInitializer { 25 | 26 | // silence console logging 27 | @Value("${logging.level.root:OFF}") 28 | String message = ""; 29 | 30 | /* 31 | * Create required HandlerMapping, to avoid several default HandlerMapping instances being created 32 | */ 33 | @Bean 34 | public HandlerMapping handlerMapping() { 35 | return new RequestMappingHandlerMapping(); 36 | } 37 | 38 | /* 39 | * Create required HandlerAdapter, to avoid several default HandlerAdapter instances being created 40 | */ 41 | @Bean 42 | public HandlerAdapter handlerAdapter() { 43 | return new RequestMappingHandlerAdapter(); 44 | } 45 | 46 | public static void main(String[] args) { 47 | SpringApplication.run(Application.class, args); 48 | } 49 | } -------------------------------------------------------------------------------- /samples/springboot2/pet-store/src/main/java/com/amazonaws/serverless/sample/springboot2/StreamLambdaHandler.java: -------------------------------------------------------------------------------- 1 | package com.amazonaws.serverless.sample.springboot2; 2 | 3 | 4 | import com.amazonaws.serverless.exceptions.ContainerInitializationException; 5 | import com.amazonaws.serverless.proxy.internal.testutils.Timer; 6 | import com.amazonaws.serverless.proxy.model.AwsProxyRequest; 7 | import com.amazonaws.serverless.proxy.model.AwsProxyResponse; 8 | import com.amazonaws.serverless.proxy.spring.SpringBootLambdaContainerHandler; 9 | import com.amazonaws.serverless.sample.springboot2.filter.CognitoIdentityFilter; 10 | import com.amazonaws.services.lambda.runtime.Context; 11 | import com.amazonaws.services.lambda.runtime.RequestStreamHandler; 12 | 13 | import javax.servlet.DispatcherType; 14 | import javax.servlet.FilterRegistration; 15 | 16 | import java.io.IOException; 17 | import java.io.InputStream; 18 | import java.io.OutputStream; 19 | import java.util.EnumSet; 20 | 21 | 22 | public class StreamLambdaHandler implements RequestStreamHandler { 23 | private static SpringBootLambdaContainerHandler handler; 24 | static { 25 | try { 26 | handler = SpringBootLambdaContainerHandler.getAwsProxyHandler(Application.class); 27 | 28 | // we use the onStartup method of the handler to register our custom filter 29 | handler.onStartup(servletContext -> { 30 | FilterRegistration.Dynamic registration = servletContext.addFilter("CognitoIdentityFilter", CognitoIdentityFilter.class); 31 | registration.addMappingForUrlPatterns(EnumSet.of(DispatcherType.REQUEST), true, "/*"); 32 | }); 33 | } catch (ContainerInitializationException e) { 34 | // if we fail here. We re-throw the exception to force another cold start 35 | e.printStackTrace(); 36 | throw new RuntimeException("Could not initialize Spring Boot application", e); 37 | } 38 | } 39 | 40 | public StreamLambdaHandler() { 41 | // we enable the timer for debugging. This SHOULD NOT be enabled in production. 42 | Timer.enable(); 43 | } 44 | 45 | @Override 46 | public void handleRequest(InputStream inputStream, OutputStream outputStream, Context context) 47 | throws IOException { 48 | handler.proxyStream(inputStream, outputStream, context); 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /samples/springboot2/pet-store/src/main/java/com/amazonaws/serverless/sample/springboot2/model/Error.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016 Amazon.com, Inc. or its affiliates. All Rights Reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"). You may not use this file except in compliance 5 | * with the License. A copy of the License is located at 6 | * 7 | * http://aws.amazon.com/apache2.0/ 8 | * 9 | * or in the "license" file accompanying this file. This file is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES 10 | * OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions 11 | * and limitations under the License. 12 | */ 13 | package com.amazonaws.serverless.sample.springboot2.model; 14 | 15 | public class Error { 16 | private String message; 17 | 18 | public Error(String errorMessage) { 19 | message = errorMessage; 20 | } 21 | 22 | public String getMessage() { 23 | return message; 24 | } 25 | 26 | public void setMessage(String message) { 27 | this.message = message; 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /samples/springboot2/pet-store/src/main/java/com/amazonaws/serverless/sample/springboot2/model/Pet.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016 Amazon.com, Inc. or its affiliates. All Rights Reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"). You may not use this file except in compliance 5 | * with the License. A copy of the License is located at 6 | * 7 | * http://aws.amazon.com/apache2.0/ 8 | * 9 | * or in the "license" file accompanying this file. This file is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES 10 | * OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions 11 | * and limitations under the License. 12 | */ 13 | package com.amazonaws.serverless.sample.springboot2.model; 14 | 15 | import java.util.Date; 16 | 17 | 18 | public class Pet { 19 | private String id; 20 | private String breed; 21 | private String name; 22 | private Date dateOfBirth; 23 | 24 | public String getId() { 25 | return id; 26 | } 27 | 28 | public void setId(String id) { 29 | this.id = id; 30 | } 31 | 32 | public String getBreed() { 33 | return breed; 34 | } 35 | 36 | public void setBreed(String breed) { 37 | this.breed = breed; 38 | } 39 | 40 | public String getName() { 41 | return name; 42 | } 43 | 44 | public void setName(String name) { 45 | this.name = name; 46 | } 47 | 48 | public Date getDateOfBirth() { 49 | return dateOfBirth; 50 | } 51 | 52 | public void setDateOfBirth(Date dateOfBirth) { 53 | this.dateOfBirth = dateOfBirth; 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /samples/springboot2/pet-store/src/main/resources/logback.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /samples/struts/pet-store/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'java' 2 | 3 | repositories { 4 | mavenLocal() 5 | mavenCentral() 6 | } 7 | 8 | dependencies { 9 | compile ( 10 | 'com.amazonaws.serverless:aws-serverless-java-container-struts2:[1.0,)', 11 | 'org.apache.struts:struts2-convention-plugin:2.5.20', 12 | 'org.apache.struts:struts2-rest-plugin:2.5.20', 13 | 'org.apache.struts:struts2-bean-validation-plugin:2.5.20', 14 | 'org.apache.struts:struts2-junit-plugin:2.5.20', 15 | 'com.jgeppert.struts2:struts2-aws-lambda-support-plugin:1.1.0', 16 | 'org.hibernate:hibernate-validator:4.3.2.Final', 17 | 'com.fasterxml.jackson.core:jackson-databind:2.9.8', 18 | 'org.apache.logging.log4j:log4j-core:2.8.2', 19 | 'org.apache.logging.log4j:log4j-api:2.8.2', 20 | 'org.apache.logging.log4j:log4j-slf4j-impl:2.8.2', 21 | 'com.amazonaws:aws-lambda-java-log4j2:1.1.0', 22 | ) 23 | } 24 | 25 | task buildZip(type: Zip) { 26 | from compileJava 27 | from processResources 28 | into('lib') { 29 | from(configurations.compileClasspath) 30 | } 31 | } 32 | 33 | build.dependsOn buildZip 34 | -------------------------------------------------------------------------------- /samples/struts/pet-store/sam.yaml: -------------------------------------------------------------------------------- 1 | AWSTemplateFormatVersion: '2010-09-09' 2 | Transform: AWS::Serverless-2016-10-31 3 | Description: Example Pet Store API written with Apache Struts based on the aws-serverless-java-container library 4 | 5 | Globals: 6 | Api: 7 | # API Gateway regional endpoints 8 | EndpointConfiguration: REGIONAL 9 | 10 | Resources: 11 | PetStoreFunction: 12 | Type: AWS::Serverless::Function 13 | Properties: 14 | Handler: com.amazonaws.serverless.proxy.struts2.Struts2LambdaHandler::handleRequest 15 | Runtime: java8 16 | CodeUri: target/serverless-struts-example-1.0-SNAPSHOT-lambda.zip 17 | MemorySize: 256 18 | Policies: AWSLambdaBasicExecutionRole 19 | Timeout: 30 20 | Events: 21 | GetResource: 22 | Type: Api 23 | Properties: 24 | Path: /{proxy+} 25 | Method: any 26 | 27 | Outputs: 28 | SpringPetStoreApi: 29 | Description: URL for application 30 | Value: !Sub 'https://${ServerlessRestApi}.execute-api.${AWS::Region}.amazonaws.com/Prod/pets' 31 | Export: 32 | Name: Struts2PetStoreApi 33 | -------------------------------------------------------------------------------- /samples/struts/pet-store/src/main/assembly/dist.xml: -------------------------------------------------------------------------------- 1 | 4 | lambda 5 | 6 | zip 7 | 8 | false 9 | 10 | 11 | lib 12 | false 13 | 14 | 15 | 16 | 17 | ${basedir}/src/main/resources 18 | / 19 | 20 | * 21 | 22 | 23 | 24 | ${project.build.directory}/classes 25 | / 26 | 27 | **/*.class 28 | 29 | 30 | 31 | -------------------------------------------------------------------------------- /samples/struts/pet-store/src/main/java/com/amazonaws/serverless/sample/struts/model/Pet.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016 Amazon.com, Inc. or its affiliates. All Rights Reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"). You may not use this file except in compliance 5 | * with the License. A copy of the License is located at 6 | * 7 | * http://aws.amazon.com/apache2.0/ 8 | * 9 | * or in the "license" file accompanying this file. This file is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES 10 | * OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions 11 | * and limitations under the License. 12 | */ 13 | package com.amazonaws.serverless.sample.struts.model; 14 | 15 | import org.hibernate.validator.constraints.NotBlank; 16 | 17 | import java.util.Date; 18 | 19 | public class Pet { 20 | 21 | private String id; 22 | private String breed; 23 | 24 | @NotBlank 25 | private String name; 26 | private Date dateOfBirth; 27 | 28 | public Pet() { 29 | } 30 | 31 | public Pet(String id, String breed, String name, Date dateOfBirth) { 32 | this.id = id; 33 | this.breed = breed; 34 | this.name = name; 35 | this.dateOfBirth = dateOfBirth; 36 | } 37 | 38 | public String getId() { 39 | return id; 40 | } 41 | 42 | public void setId(String id) { 43 | this.id = id; 44 | } 45 | 46 | public String getBreed() { 47 | return breed; 48 | } 49 | 50 | public void setBreed(String breed) { 51 | this.breed = breed; 52 | } 53 | 54 | public String getName() { 55 | return name; 56 | } 57 | 58 | public void setName(String name) { 59 | this.name = name; 60 | } 61 | 62 | public Date getDateOfBirth() { 63 | return dateOfBirth; 64 | } 65 | 66 | public void setDateOfBirth(Date dateOfBirth) { 67 | this.dateOfBirth = dateOfBirth; 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /samples/struts/pet-store/src/main/resources/log4j2.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | %d{yyyy-MM-dd HH:mm:ss} %X{AWSRequestId} %-5p %c{1}:%L - %m%n 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /samples/struts/pet-store/src/main/resources/struts.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | --------------------------------------------------------------------------------