Skip to content

Commit d816d4d

Browse files
bnusunnysapessi
authored andcommitted
add Quarkus pet store sample. (#309)
* add Quarkus pet store sample. * update source code package structure
1 parent 67abc3e commit d816d4d

File tree

8 files changed

+481
-0
lines changed

8 files changed

+481
-0
lines changed
Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
# Quarkus Native Pet store example
2+
3+
The [Quarkus framework](https://quarkus.io/) is compatible with Spring's annotations and makes it easy to use [GraalVM](https://www.graalvm.org/) to build application images into native binaries. Further, Micronaut includes builtin support for AWS Lambda.
4+
5+
This demo application shows how to use Quarkus to compile our standard pet store example, using Spring annotations, into a native binary with GraalVM and execute it in AWS Lambda. To run this demo, you will need to have [Maven](https://maven.apache.org/) installed as well as [Docker](https://www.docker.com/) to build GraalVM native image.
6+
7+
With all the pre-requisites installed including:
8+
9+
* JDK 8 or above
10+
* Maven 3.5.x
11+
12+
You should be able to build a native image of the application by running mvn from the repository's root.
13+
14+
```bash
15+
$ mvn clean install -Pnative
16+
```
17+
18+
The output of the build is a deployable zip called `function.zip` in the `target` folder.
19+
20+
To run the lambda locally, you can utilize the SAM cli. This should start up the listeners in the `PetsController`, and you can test locally with your preferred http client.
21+
22+
```bash
23+
sam local start-api -t sam.native.yaml
24+
```
25+
26+
For example, to test the GET /pets endpoint via curl:
27+
```bash
28+
curl localhost:3000/pets
29+
```
30+
31+
You should see JSON output of pets.
32+
33+
To deploy the application to AWS Lambda you can use the pre-configured `sam-native.yaml` file included in the repo. Using the AWS or SAM CLI, run the following commands:
34+
35+
```bash
36+
sam deploy -g -t sam.native.yaml
37+
```
38+
39+
You should see the stack deployed successfully:
40+
41+
```bash
42+
Stack quarkus-sample-pet-store outputs:
43+
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
44+
OutputKey-Description OutputValue
45+
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
46+
PetStoreNativeApi - URL for application https://xxxxxxxxxx.execute-api.xx-xxxx-1.amazonaws.com/Prod/
47+
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
48+
49+
Successfully created/updated stack - quarkus-sample-pet-store in xx-xxxx-1
50+
51+
```
52+
53+
Make a test request to the API endpoint using curl or your preferred http client.
54+
55+
For example, to check the GET /pets endpoint via curl:
56+
```bash
57+
curl https://xxxxxxxxxx.execute-api.xx-xxxx-1.amazonaws.com/Prod/pets
58+
```
59+
60+
Finally, there’s an environment variable that must be set for native GraalVM deployments. If you look at sam.native.yaml you’ll see this:
61+
62+
```bash
63+
Environment:
64+
Variables:
65+
DISABLE_SIGNAL_HANDLERS: true
66+
```
67+
68+
This environment variable resolves some incompatibilites between GraalVM and the Amazon Lambda Custom Runtime environment.

samples/quarkus/pet-store/pom.xml

Lines changed: 141 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,141 @@
1+
<?xml version="1.0"?>
2+
<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns="http://maven.apache.org/POM/4.0.0"
3+
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
4+
<modelVersion>4.0.0</modelVersion>
5+
<groupId>com.amazonaws.serverless.sample</groupId>
6+
<artifactId>serverless-quarkus-example</artifactId>
7+
<version>1.0-SNAPSHOT</version>
8+
<properties>
9+
<compiler-plugin.version>3.8.1</compiler-plugin.version>
10+
<maven.compiler.parameters>true</maven.compiler.parameters>
11+
<maven.compiler.source>1.8</maven.compiler.source>
12+
<maven.compiler.target>1.8</maven.compiler.target>
13+
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
14+
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
15+
<quarkus-plugin.version>1.0.1.Final</quarkus-plugin.version>
16+
<quarkus.platform.artifact-id>quarkus-universe-bom</quarkus.platform.artifact-id>
17+
<quarkus.platform.group-id>io.quarkus</quarkus.platform.group-id>
18+
<quarkus.platform.version>1.0.1.Final</quarkus.platform.version>
19+
<surefire-plugin.version>2.22.1</surefire-plugin.version>
20+
</properties>
21+
<dependencyManagement>
22+
<dependencies>
23+
<dependency>
24+
<groupId>${quarkus.platform.group-id}</groupId>
25+
<artifactId>${quarkus.platform.artifact-id}</artifactId>
26+
<version>${quarkus.platform.version}</version>
27+
<type>pom</type>
28+
<scope>import</scope>
29+
</dependency>
30+
</dependencies>
31+
</dependencyManagement>
32+
<dependencies>
33+
<dependency>
34+
<groupId>io.quarkus</groupId>
35+
<artifactId>quarkus-resteasy</artifactId>
36+
</dependency>
37+
<dependency>
38+
<groupId>io.quarkus</groupId>
39+
<artifactId>quarkus-amazon-lambda-http</artifactId>
40+
</dependency>
41+
<dependency>
42+
<groupId>io.quarkus</groupId>
43+
<artifactId>quarkus-spring-web</artifactId>
44+
</dependency>
45+
<dependency>
46+
<groupId>io.quarkus</groupId>
47+
<artifactId>quarkus-junit5</artifactId>
48+
<scope>test</scope>
49+
</dependency>
50+
<dependency>
51+
<groupId>io.rest-assured</groupId>
52+
<artifactId>rest-assured</artifactId>
53+
<scope>test</scope>
54+
</dependency>
55+
</dependencies>
56+
<build>
57+
<plugins>
58+
<plugin>
59+
<groupId>io.quarkus</groupId>
60+
<artifactId>quarkus-maven-plugin</artifactId>
61+
<version>${quarkus-plugin.version}</version>
62+
<executions>
63+
<execution>
64+
<goals>
65+
<goal>build</goal>
66+
</goals>
67+
</execution>
68+
</executions>
69+
</plugin>
70+
<plugin>
71+
<artifactId>maven-compiler-plugin</artifactId>
72+
<version>${compiler-plugin.version}</version>
73+
</plugin>
74+
<plugin>
75+
<artifactId>maven-surefire-plugin</artifactId>
76+
<version>${surefire-plugin.version}</version>
77+
<configuration>
78+
<systemProperties>
79+
<java.util.logging.manager>org.jboss.logmanager.LogManager</java.util.logging.manager>
80+
</systemProperties>
81+
</configuration>
82+
</plugin>
83+
</plugins>
84+
</build>
85+
<profiles>
86+
<profile>
87+
<id>native</id>
88+
<activation>
89+
<property>
90+
<name>native</name>
91+
</property>
92+
</activation>
93+
<build>
94+
<plugins>
95+
<plugin>
96+
<artifactId>maven-failsafe-plugin</artifactId>
97+
<version>${surefire-plugin.version}</version>
98+
<executions>
99+
<execution>
100+
<goals>
101+
<goal>integration-test</goal>
102+
<goal>verify</goal>
103+
</goals>
104+
<configuration>
105+
<systemProperties>
106+
<native.image.path>${project.build.directory}/${project.build.finalName}-runner</native.image.path>
107+
</systemProperties>
108+
</configuration>
109+
</execution>
110+
</executions>
111+
</plugin>
112+
<plugin>
113+
<groupId>org.apache.maven.plugins</groupId>
114+
<artifactId>maven-assembly-plugin</artifactId>
115+
<version>3.1.0</version>
116+
<executions>
117+
<execution>
118+
<id>zip-assembly</id>
119+
<phase>package</phase>
120+
<goals>
121+
<goal>single</goal>
122+
</goals>
123+
<configuration>
124+
<finalName>function</finalName>
125+
<descriptors>
126+
<descriptor>src/assembly/zip.xml</descriptor>
127+
</descriptors>
128+
<attach>false</attach>
129+
<appendAssemblyId>false</appendAssemblyId>
130+
</configuration>
131+
</execution>
132+
</executions>
133+
</plugin>
134+
</plugins>
135+
</build>
136+
<properties>
137+
<quarkus.package.type>native</quarkus.package.type>
138+
</properties>
139+
</profile>
140+
</profiles>
141+
</project>
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
AWSTemplateFormatVersion: '2010-09-09'
2+
Transform: AWS::Serverless-2016-10-31
3+
Description: AWS Serverless Quarkus HTTP - com.amazon.quarkus.demo::pet-store
4+
Globals:
5+
Api:
6+
EndpointConfiguration: REGIONAL
7+
BinaryMediaTypes:
8+
- "*/*"
9+
10+
Resources:
11+
PetStoreNativeFunction:
12+
Type: AWS::Serverless::Function
13+
Properties:
14+
Handler: not.used.in.provided.runtime
15+
Runtime: provided
16+
CodeUri: target/function.zip
17+
MemorySize: 128
18+
Policies: AWSLambdaBasicExecutionRole
19+
Tracing: Active
20+
Timeout: 15
21+
Environment:
22+
Variables:
23+
DISABLE_SIGNAL_HANDLERS: true
24+
Events:
25+
GetResource:
26+
Type: Api
27+
Properties:
28+
Path: /{proxy+}
29+
Method: any
30+
31+
Outputs:
32+
PetStoreNativeApi:
33+
Description: URL for application
34+
Value: !Sub 'https://${ServerlessRestApi}.execute-api.${AWS::Region}.amazonaws.com/Prod/'
35+
Export:
36+
Name: PetStoreNativeApi
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
<assembly xmlns="http://maven.apache.org/ASSEMBLY/2.0.0"
2+
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
3+
xsi:schemaLocation="http://maven.apache.org/ASSEMBLY/2.0.0 http://maven.apache.org/xsd/assembly-2.0.0.xsd">
4+
<id>lambda-package</id>
5+
<formats>
6+
<format>zip</format>
7+
</formats>
8+
<includeBaseDirectory>false</includeBaseDirectory>
9+
<files>
10+
<file>
11+
<source>${project.build.directory}${file.separator}${artifactId}-${version}-runner</source>
12+
<outputDirectory>/</outputDirectory>
13+
<destName>bootstrap</destName>
14+
<fileMode>755</fileMode>
15+
</file>
16+
</files>
17+
</assembly>
Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
package com.amazonaws.serverless.sample.quarkus;
2+
3+
import com.amazonaws.serverless.sample.quarkus.model.Pet;
4+
import com.amazonaws.serverless.sample.quarkus.model.PetData;
5+
import org.springframework.beans.factory.annotation.Autowired;
6+
import org.springframework.web.bind.annotation.*;
7+
8+
import java.util.Optional;
9+
import java.util.UUID;
10+
11+
@RestController
12+
public class PetsController {
13+
14+
private PetData petData;
15+
16+
@Autowired
17+
public PetsController(PetData data) {
18+
petData = data;
19+
}
20+
21+
@RequestMapping(path = "/pets", method = RequestMethod.POST)
22+
public Pet createPet(@RequestBody Pet newPet) {
23+
if (newPet.getName() == null || newPet.getBreed() == null) {
24+
return null;
25+
}
26+
27+
Pet dbPet = newPet;
28+
dbPet.setId(UUID.randomUUID().toString());
29+
return dbPet;
30+
}
31+
32+
@RequestMapping(path = "/pets", method = RequestMethod.GET)
33+
public Pet[] listPets(@RequestParam("limit") Optional<Integer> limit) {
34+
int queryLimit = 10;
35+
if (limit.isPresent()) {
36+
queryLimit = limit.get();
37+
}
38+
39+
Pet[] outputPets = new Pet[queryLimit];
40+
41+
for (int i = 0; i < queryLimit; i++) {
42+
Pet newPet = new Pet();
43+
newPet.setId(UUID.randomUUID().toString());
44+
newPet.setName(petData.getRandomName());
45+
newPet.setBreed(petData.getRandomBreed());
46+
newPet.setDateOfBirth(petData.getRandomDoB());
47+
outputPets[i] = newPet;
48+
}
49+
50+
return outputPets;
51+
}
52+
53+
@RequestMapping(path = "/pets/{petId}", method = RequestMethod.GET)
54+
public Pet getPet(@RequestParam("petId") String petId) {
55+
Pet newPet = new Pet();
56+
newPet.setId(UUID.randomUUID().toString());
57+
newPet.setBreed(petData.getRandomBreed());
58+
newPet.setDateOfBirth(petData.getRandomDoB());
59+
newPet.setName(petData.getRandomName());
60+
return newPet;
61+
}
62+
63+
}
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
package com.amazonaws.serverless.sample.quarkus.model;
2+
3+
import com.fasterxml.jackson.annotation.JsonFormat;
4+
import com.fasterxml.jackson.annotation.JsonProperty;
5+
import io.quarkus.runtime.annotations.RegisterForReflection;
6+
7+
import java.util.Date;
8+
9+
@RegisterForReflection
10+
public class Pet {
11+
private String id;
12+
private String breed;
13+
private String name;
14+
private Date dateOfBirth;
15+
16+
@JsonProperty("petId")
17+
public String getId() {
18+
return id;
19+
}
20+
21+
public void setId(String id) {
22+
this.id = id;
23+
}
24+
25+
public String getBreed() {
26+
return breed;
27+
}
28+
29+
public void setBreed(String breed) {
30+
this.breed = breed;
31+
}
32+
33+
public String getName() {
34+
return name;
35+
}
36+
37+
public void setName(String name) {
38+
this.name = name;
39+
}
40+
41+
@JsonFormat(pattern = "YYYY-mm-dd")
42+
public Date getDateOfBirth() {
43+
return dateOfBirth;
44+
}
45+
46+
public void setDateOfBirth(Date dateOfBirth) {
47+
this.dateOfBirth = dateOfBirth;
48+
}
49+
50+
}

0 commit comments

Comments
 (0)