Skip to content

Commit 379a825

Browse files
authored
Merge pull request iluwatar#714 from dheeraj-mummareddy/master
iluwatar#473 serveless implementation using aws compute engine and serverless fram…
2 parents 1c0e0cd + 522fbc0 commit 379a825

23 files changed

+1558
-0
lines changed

pom.xml

+6
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,11 @@
4848
<mongo-java-driver.version>3.3.0</mongo-java-driver.version>
4949
<slf4j.version>1.7.21</slf4j.version>
5050
<logback.version>1.1.7</logback.version>
51+
<aws-lambda-core.version>1.1.0</aws-lambda-core.version>
52+
<aws-java-sdk-dynamodb.version>1.11.289</aws-java-sdk-dynamodb.version>
53+
<aws-lambda-log4j.version>1.0.0</aws-lambda-log4j.version>
54+
<aws-lambda-java-events.version>2.0.1</aws-lambda-java-events.version>
55+
<jackson.version>2.8.5</jackson.version>
5156
</properties>
5257
<modules>
5358
<module>abstract-factory</module>
@@ -154,6 +159,7 @@
154159
<module>eip-aggregator</module>
155160
<module>retry</module>
156161
<module>trampoline</module>
162+
<module>serverless</module>
157163
</modules>
158164

159165
<repositories>

serverless/README.md

+199
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,199 @@
1+
---
2+
layout: pattern
3+
title: serverless
4+
folder: serverless
5+
permalink: /patterns/serverless/
6+
categories: Architectural
7+
tags:
8+
- Java
9+
- Difficulty-Intermediate
10+
---
11+
12+
## Serverless
13+
14+
Serverless eliminates the need to plan for infrastructure and let's you focus on your
15+
application.
16+
17+
Following are optimization katas you should be aware of while building a serverless
18+
applications
19+
20+
* The Lean function
21+
* Concise logic - Use functions to transform, not transport (utilize some of the
22+
integration available from the provider to transport), and make sure you read only
23+
what you need
24+
* Efficient/single purpose code - avoid conditional/routing logic and break down
25+
into individual functions, avoid "fat"/monolithic functions and control the
26+
dependencies in the function deployment package to reduce the load time for your
27+
function
28+
* ephemeral environment - Utilize container start for expensive initializations
29+
* Eventful Invocations
30+
* Succinct payloads - Scrutinize the event as much as possible, and watch for
31+
payload constraints (async - 128K)
32+
* resilient routing - Understand retry policies and leverage dead letter queues
33+
(SQS or SNS for replays) and remember retries count as invocations
34+
* concurrent execution - lambda thinks of it's scale in terms of concurrency and
35+
its not request based/duration based. Lambda will spin up the number of instances
36+
based on the request.
37+
* Coordinated calls
38+
* Decoupled via APIs - best practice to setup your application is to have API's as
39+
contracts that ensures separation of concerns
40+
* scale-matched downstream - make sure when Lambda is calling downstream
41+
components, you are matching scale configuration to it (by specifying max
42+
concurrency based on downstream services)
43+
* secured - Always ask a question, do I need a VPC?
44+
* Serviceful operations
45+
* Automated - use automated tools to manage and maintain the stack
46+
* monitored applications - use monitoring services to get holistic view of your
47+
serverless applications
48+
49+
## Intent
50+
51+
Whether to reduce your infrastructure costs, shrink the time you spend on ops tasks,
52+
simplify your deployment processes, reach infinite scalability, serverless cuts time
53+
to market in half.
54+
55+
## Explanation
56+
57+
Serverless computing is a cloud computing execution model in which the cloud provider
58+
dynamically manages the allocation of machine resources. Pricing is based on the
59+
actual amount of resources consumed by an application, rather than on pre-purchased
60+
units of capacity.
61+
62+
## Serverless framework
63+
64+
[Serverless](https://serverless.com/) is a toolkit for deploying and operating serverless architectures.
65+
66+
## (Function as a Service or "FaaS")
67+
68+
The term ‘Serverless’ is confusing since with such applications there are both server
69+
hardware and server processes running somewhere, but the difference to normal
70+
approaches is that the organization building and supporting a ‘Serverless’ application
71+
is not looking after the hardware or the processes - they are outsourcing this to a vendor.
72+
73+
Some of the Serverless Cloud Providers are
74+
75+
![https://serverless.com/framework/docs/providers/aws/](./etc/aws-black.png "aws")
76+
![https://serverless.com/framework/docs/providers/azure/](./etc/azure-black.png "azure")
77+
![https://serverless.com/framework/docs/providers/openwhisk/](./etc/openwhisk-black.png "openwhisk")
78+
![https://serverless.com/framework/docs/providers/google/](./etc/gcf-black.png "google")
79+
![https://serverless.com/framework/docs/providers/kubeless/](./etc/kubeless-logos-black.png "kubeless")
80+
![https://serverless.com/framework/docs/providers/spotinst/](./etc/spotinst-logos-black-small.png "spotinst")
81+
![https://serverless.com/framework/docs/providers/webtasks/](./etc/webtask-small-grayscale.png "webtask")
82+
...
83+
84+
Anything that triggers an Lambda Function to execute is regarded by the Framework as
85+
an Event. Most of the Serverless Cloud Providers support following Events
86+
- Http
87+
- PubSub Events
88+
- scheduled
89+
90+
AWS supports processing event generated from AWS Services (S3/Cloudwatch/etc) and
91+
using aws as a compute engine is our first choice.
92+
93+
## (Backend as a Service or "BaaS")
94+
This example creates a backend for ‘persons’ collection which uses DynamoDB NoSQL
95+
database service also provided by Amazon.
96+
97+
## AWS lambda function implementation
98+
99+
[AWS Lambda SDK](https://aws.amazon.com/sdk-for-java/) provides pre-defined interface
100+
`com.amazonaws.services.lambda.runtime
101+
.RequestHandler` to implement our lambda function.
102+
103+
```java
104+
public class LambdaInfoApiHandler implements RequestHandler<Map<String, Object>, ApiGatewayResponse> {
105+
106+
private static final Logger LOG = Logger.getLogger(LambdaInfoApiHandler.class);
107+
private static final Integer SUCCESS_STATUS_CODE = 200;
108+
109+
110+
@Override
111+
public ApiGatewayResponse handleRequest(Map<String, Object> input, Context context) {
112+
113+
}
114+
}
115+
```
116+
handleRequest method is where the function code is implemented. Context provides
117+
useful information about Lambda execution environment. AWS Lambda function needs a
118+
deployment package. This package is either a .zip or .jar file that contains all the
119+
dependencies of the function.
120+
121+
`serverless.yml` contains configuration to manage deployments for your functions.
122+
123+
## Run example in local
124+
125+
# Pre-requisites
126+
* Node.js v6.5.0 or later.
127+
* Serverless CLI v1.9.0 or later. You can run npm install -g serverless to install it.
128+
* An AWS account. If you don't already have one, you can sign up for a free trial that includes 1 million free Lambda requests per month.
129+
* [Set-up](https://serverless.com/framework/docs/providers/aws/guide/credentials/) your Provider Credentials. Watch the video on setting up credentials
130+
131+
# build and deploy
132+
133+
* `cd serverless`
134+
* `mvn clean package`
135+
* `serverless deploy --stage=dev --verbose`
136+
137+
Based on the configuration in `serverless.yml` serverless framework creates following
138+
resources
139+
* CloudFormation stack for S3 (ServerlessDeploymentBucket)
140+
* IAM Role (IamRoleLambdaExecution)
141+
* CloudWatch (log groups)
142+
* API Gateway (ApiGatewayRestApi)
143+
* Lambda function
144+
* DynamoDB collection
145+
146+
The command will print out Stack Outputs which looks something like this
147+
148+
```yaml
149+
endpoints:
150+
GET - https://xxxxxxxxx.execute-api.us-east-1.amazonaws.com/dev/info
151+
POST - https://xxxxxxxxx.execute-api.us-east-1.amazonaws.com/dev/api/person
152+
GET - https://xxxxxxxxx.execute-api.us-east-1.amazonaws.com/dev/api/person/{id}
153+
154+
```
155+
156+
```yaml
157+
CurrentTimeLambdaFunctionQualifiedArn: arn:aws:lambda:us-east-1:xxxxxxxxxxx:function:lambda-info-http-endpoint-dev-currentTime:4
158+
ServiceEndpoint: https://xxxxxxxxx.execute-api.us-east-1.amazonaws.com/dev
159+
ServerlessDeploymentBucketName: lambda-info-http-endpoin-serverlessdeploymentbuck-2u8uz2i7cap2
160+
```
161+
access the endpoint to invoke the function.
162+
163+
Use the following cURL commands to test the endpoints
164+
165+
```cURL
166+
curl -X GET \
167+
https://xxxxxxxxx.execute-api.us-east-1.amazonaws.com/dev/info \
168+
-H 'cache-control: no-cache'
169+
```
170+
171+
```cURL
172+
curl -X POST \
173+
https://xxxxxxxxx.execute-api.us-east-1.amazonaws.com/dev/api/person \
174+
-H 'cache-control: no-cache' \
175+
-H 'content-type: application/json' \
176+
-d '{
177+
"firstName": "Thor",
178+
"lastName": "Odinson",
179+
"address": {
180+
"addressLineOne": "1 Odin ln",
181+
"addressLineTwo": "100",
182+
"city": "Asgard",
183+
"state": "country of the Gods",
184+
"zipCode": "00001"
185+
}
186+
}'
187+
```
188+
189+
```cURL
190+
curl -X GET \
191+
https://xxxxxxxxx.execute-api.us-east-1.amazonaws.com/dev/api/person/{id} \
192+
-H 'cache-control: no-cache'
193+
```
194+
195+
## Credits
196+
197+
* [serverless docs](https://serverless.com/framework/docs/)
198+
* [Serverless Architectures](https://martinfowler.com/articles/serverless.html)
199+
* [Serverless Black Belt](https://youtu.be/oQFORsso2go)

serverless/etc/aws-black.png

9.04 KB
Loading

serverless/etc/azure-black.png

4.6 KB
Loading

serverless/etc/gcf-black.png

7.47 KB
Loading
8.73 KB
Loading

serverless/etc/openwhisk-black.png

5.59 KB
Loading
5.29 KB
Loading
8.22 KB
Loading

serverless/pom.xml

+133
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,133 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<!--
3+
The MIT License
4+
Copyright (c) 2014-2017 Ilkka Seppälä
5+
Permission is hereby granted, free of charge, to any person obtaining a copy
6+
of this software and associated documentation files (the "Software"), to deal
7+
in the Software without restriction, including without limitation the rights
8+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
copies of the Software, and to permit persons to whom the Software is
10+
furnished to do so, subject to the following conditions:
11+
The above copyright notice and this permission notice shall be included in
12+
all copies or substantial portions of the Software.
13+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19+
THE SOFTWARE.
20+
-->
21+
<project xmlns="http://maven.apache.org/POM/4.0.0"
22+
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
23+
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
24+
<modelVersion>4.0.0</modelVersion>
25+
<artifactId>serverless</artifactId>
26+
<parent>
27+
<groupId>com.iluwatar</groupId>
28+
<artifactId>java-design-patterns</artifactId>
29+
<version>1.20.0-SNAPSHOT</version>
30+
</parent>
31+
32+
<dependencies>
33+
<dependency>
34+
<groupId>com.amazonaws</groupId>
35+
<artifactId>aws-lambda-java-core</artifactId>
36+
<version>${aws-lambda-core.version}</version>
37+
</dependency>
38+
<dependency>
39+
<groupId>com.amazonaws</groupId>
40+
<artifactId>aws-java-sdk-dynamodb</artifactId>
41+
<version>${aws-java-sdk-dynamodb.version}</version>
42+
<exclusions>
43+
<exclusion>
44+
<groupId>com.amazonaws</groupId>
45+
<artifactId>aws-java-sdk-s3</artifactId>
46+
</exclusion>
47+
<exclusion>
48+
<groupId>com.amazonaws</groupId>
49+
<artifactId>aws-java-sdk-kms</artifactId>
50+
</exclusion>
51+
</exclusions>
52+
</dependency>
53+
<dependency>
54+
<groupId>com.amazonaws</groupId>
55+
<artifactId>aws-lambda-java-events</artifactId>
56+
<version>${aws-lambda-java-events.version}</version>
57+
</dependency>
58+
<dependency>
59+
<groupId>com.amazonaws</groupId>
60+
<artifactId>aws-lambda-java-log4j</artifactId>
61+
<version>${aws-lambda-log4j.version}</version>
62+
</dependency>
63+
<dependency>
64+
<groupId>com.fasterxml.jackson.core</groupId>
65+
<artifactId>jackson-core</artifactId>
66+
<version>${jackson.version}</version>
67+
</dependency>
68+
<dependency>
69+
<groupId>com.fasterxml.jackson.core</groupId>
70+
<artifactId>jackson-databind</artifactId>
71+
<version>${jackson.version}</version>
72+
</dependency>
73+
<dependency>
74+
<groupId>com.fasterxml.jackson.core</groupId>
75+
<artifactId>jackson-annotations</artifactId>
76+
<version>${jackson.version}</version>
77+
</dependency>
78+
<dependency>
79+
<groupId>org.junit.jupiter</groupId>
80+
<artifactId>junit-jupiter-api</artifactId>
81+
<scope>test</scope>
82+
</dependency>
83+
<dependency>
84+
<groupId>org.junit.jupiter</groupId>
85+
<artifactId>junit-jupiter-engine</artifactId>
86+
<scope>test</scope>
87+
</dependency>
88+
<dependency>
89+
<groupId>org.mockito</groupId>
90+
<artifactId>mockito-core</artifactId>
91+
<scope>test</scope>
92+
</dependency>
93+
<dependency>
94+
<groupId>junit</groupId>
95+
<artifactId>junit</artifactId>
96+
<scope>test</scope>
97+
</dependency>
98+
</dependencies>
99+
100+
<build>
101+
<plugins>
102+
<!--
103+
Using the Apache Maven Shade plugin to package the jar
104+
105+
"This plugin provides the capability to package the artifact
106+
in an uber-jar, including its dependencies and to shade - i.e. rename -
107+
the packages of some of the dependencies."
108+
109+
Link: https://maven.apache.org/plugins/maven-shade-plugin/
110+
-->
111+
<plugin>
112+
<groupId>org.apache.maven.plugins</groupId>
113+
<artifactId>maven-shade-plugin</artifactId>
114+
<version>2.3</version>
115+
<configuration>
116+
<createDependencyReducedPom>false</createDependencyReducedPom>
117+
</configuration>
118+
<executions>
119+
<execution>
120+
<phase>package</phase>
121+
<goals>
122+
<goal>shade</goal>
123+
</goals>
124+
<configuration>
125+
<finalName>${project.artifactId}</finalName>
126+
</configuration>
127+
</execution>
128+
</executions>
129+
</plugin>
130+
</plugins>
131+
</build>
132+
133+
</project>

0 commit comments

Comments
 (0)