This tutorial demonstrates running within AWS Serverless.
AWS SAM is supported by OfficeFloor through the following plugin:
<dependency> <groupId>net.officefloor.server</groupId> <artifactId>officeserver_sam</artifactId> </dependency>
The only additional configuration is AWS SAM requiring the application be shaded as follows:
<build> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-shade-plugin</artifactId> <configuration> <transformers> <transformer implementation="org.apache.maven.plugins.shade.resource.ServicesResourceTransformer" /> </transformers> </configuration> <executions> <execution> <phase>package</phase> <goals> <goal>shade</goal> </goals> </execution> </executions> </plugin> </plugins> </build>
Running the AWS SAM application locally typically requires setting up a docker network, running DynamoDB and then starting SAM locally. To ease running and testing the application, the following plugin is available:
<plugin> <groupId>net.officefloor.maven</groupId> <artifactId>officefloor-sam-maven-plugin</artifactId> <configuration> <samPort>8381</samPort> <dynamodbPort>8382</dynamodbPort> </configuration> <executions> <execution> <id>start</id> <phase>pre-integration-test</phase> <goals> <goal>start</goal> </goals> </execution> <execution> <id>stop</id> <phase>post-integration-test</phase> <goals> <goal>stop</goal> </goals> </execution> </executions> </plugin> <!-- Run integration tests against locally started AWS SAM --> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-failsafe-plugin</artifactId> <executions> <execution> <goals> <goal>integration-test</goal> <goal>verify</goal> </goals> </execution> </executions> </plugin>
Note that the SAM template.yaml file is created by the plugin if it does not exist. Hence, once the file is generated, it is possible to make manual alterations and check it into source control.
The application may then be manually started with the following:
mvn officefloor-sam:run
The AWS provided SAM CLI may be used for deploying the application to AWS. In this case:
sam deploy --guided
The functionality can be tested just like any other Web on OfficeFloor (WoOF) application:
public static final @Order(1) @RegisterExtension DynamoDbExtension dynamo = new DynamoDbExtension(); public static final @Order(2) @RegisterExtension MockWoofServerExtension server = new MockWoofServerExtension(); @Test public void createPost() { // Create the entity MockWoofResponse response = server .send(MockWoofServer.mockJsonRequest(HttpMethod.POST, "/posts", new Post("TEST"))); PostEntity entity = response.getJson(200, PostEntity.class); // Ensure in store PostEntity stored = dynamo.getDynamoDbMapper().load(PostEntity.class, entity.getId()); assertNotNull(stored, "Should find entity in DynamoDB " + entity.getId()); assertEquals("TEST", stored.getMessage(), "Incorrent entity"); }
To test within the SAM local server, use integration testing. The officefloor-sam-maven-plugin above sets up the application running within a SAM local server. It also sets up a local DynamoDB. This enables the following integration testing:
public static final @RegisterExtension HttpClientExtension serverClient = new HttpClientExtension(false, 8381) .timeout(30_000); public static final @RegisterExtension DynamoDbConnectExtension dynamoClient = new DynamoDbConnectExtension( new Configuration().port(8382)); private static final ObjectMapper mapper = new ObjectMapper(); @Test public void createPost() throws IOException { // Create the entity HttpPost request = new HttpPost(serverClient.url("/posts")); request.setHeader("Accept", "application/json"); // Provide Accept header due to AWS SAM requiring it request.setHeader("Content-Type", "application/json"); request.setEntity(new StringEntity(mapper.writeValueAsString(new Post("TEST")))); HttpResponse response = serverClient.execute(request); String responseBody = EntityUtils.toString(response.getEntity()); assertEquals(200, response.getStatusLine().getStatusCode(), "Should be successful: " + responseBody); PostEntity entity = mapper.readValue(responseBody, PostEntity.class); // Ensure in store PostEntity stored = dynamoClient.getDynamoDbMapper().load(PostEntity.class, entity.getId()); assertNotNull(stored, "Should find entity in DynamoDB " + entity.getId()); assertEquals("TEST", stored.getMessage(), "Incorrent entity"); }
Note that a different DynamoDB extension is used for each type of testing:
The next tutorial covers the CosmosDB client.