Skip to content

Commit

Permalink
initial commit
Browse files Browse the repository at this point in the history
  • Loading branch information
susaurabh-git committed Aug 23, 2021
1 parent 180cd2c commit decde08
Show file tree
Hide file tree
Showing 13 changed files with 379 additions and 1 deletion.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ hs_err_pid*
*.iml
*.ipr
out/
target/

# macOS
*.DD_Store
Expand Down
8 changes: 7 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1 +1,7 @@
# aws-serverless-springboot-crud
# aws-serverless-springboot-crud

This is sample Springboot implementation with AWS Lambda and serverless framework.

#### References:

- https://github.com/awslabs/aws-serverless-java-container
27 changes: 27 additions & 0 deletions serverless.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
service: crud

provider:
name: aws
runtime: java11
memorySize: 1024
timeout: 60
stage: ${opt:stage, 'dev'}
region: ${opt:region, 'us-east-1'}
profile: ${opt:profile, 'default'}
endpointType: REGIONAL

resources:
Description: This is sample Springboot implementation with AWS Lambda and serverless framework.

package:
individually: true

functions:
crud-api:
package:
artifact: target/aws-serverless-springboot-crud-1.0.0-SNAPSHOT-lambda-package.zip
handler: us.innodea.aws.serverless.springboot.crud.StreamLambdaHandler::handleRequest
events:
- http:
path: /{proxy+}
method: ANY
24 changes: 24 additions & 0 deletions src/assembly/bin.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
<assembly xmlns="http://maven.apache.org/ASSEMBLY/2.1.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/ASSEMBLY/2.1.0 http://maven.apache.org/xsd/assembly-2.1.0.xsd">
<id>lambda-package</id>
<formats>
<format>zip</format>
</formats>
<includeBaseDirectory>false</includeBaseDirectory>
<fileSets>
<fileSet>
<directory>${project.build.directory}${file.separator}lib</directory>
<outputDirectory>lib</outputDirectory>
<excludes>
<exclude>tomcat-embed*</exclude>
</excludes>
</fileSet>
<fileSet>
<directory>${project.build.directory}${file.separator}classes</directory>
<includes>
<include>**</include>
</includes>
<outputDirectory>${file.separator}</outputDirectory>
</fileSet>
</fileSets>
</assembly>
11 changes: 11 additions & 0 deletions src/main/java/us/innodea/aws/serverless/springboot/crud/Main.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package us.innodea.aws.serverless.springboot.crud;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class Main {
public static void main(String[] args) {
SpringApplication.run(Main.class, args);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
package us.innodea.aws.serverless.springboot.crud;

import com.amazonaws.serverless.exceptions.ContainerInitializationException;
import com.amazonaws.serverless.proxy.model.AwsProxyRequest;
import com.amazonaws.serverless.proxy.model.AwsProxyResponse;
import com.amazonaws.serverless.proxy.spring.SpringBootLambdaContainerHandler;
import com.amazonaws.services.lambda.runtime.Context;
import com.amazonaws.services.lambda.runtime.RequestStreamHandler;

import javax.ws.rs.core.Application;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;

public class StreamLambdaHandler implements RequestStreamHandler {
private static SpringBootLambdaContainerHandler<AwsProxyRequest, AwsProxyResponse> handler;

static {
try {
handler = SpringBootLambdaContainerHandler.getAwsProxyHandler(Application.class);
// If you are using HTTP APIs with the version 2.0 of the proxy model, use the getHttpApiV2ProxyHandler
// method: handler = SpringBootLambdaContainerHandler.getHttpApiV2ProxyHandler(Application.class);
} catch (ContainerInitializationException e) {
e.printStackTrace();
throw new RuntimeException("Could not initialize Spring Boot application", e);
}
}

@Override
public void handleRequest(InputStream inputStream, OutputStream outputStream, Context context)
throws IOException {
handler.proxyStream(inputStream, outputStream, context);
}
}


Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
package us.innodea.aws.serverless.springboot.crud.controller;

import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import us.innodea.aws.serverless.springboot.crud.model.CreateUserRequest;
import us.innodea.aws.serverless.springboot.crud.model.User;

import java.util.*;

@Slf4j
@RestController
@EnableWebMvc
public class UserController {

private static final String RESOURCE_PATH = "/users";
private final Map<String, User> users = dummyUserRepo();

@PostMapping(RESOURCE_PATH)
public User createUser(@RequestBody CreateUserRequest request){
log.info("Create User: {}", request);
User user =createUserService(request);
return user;
}

@GetMapping(RESOURCE_PATH)
public List<User> getAllUsers(){
log.info("Get All User!!");
List<User> users =getAllUsersService();
return users;
}

@GetMapping(RESOURCE_PATH+"/{id}")
public User getUser(@PathVariable String id){
log.info("Get User: {}", id);
User user =getUserService(id);
return user;
}

@DeleteMapping(RESOURCE_PATH+"/{id}")
public User deleteUser(@PathVariable String id){
log.info("delete User: {}", id);
User user =deleteUserService(id);
return user;
}

@PostMapping(RESOURCE_PATH+"/{id}")
public User updateUser(@RequestBody CreateUserRequest request){
log.info("Update User: {}", request);
User user =updateUserService(request);
return user;
}

private User createUserService(CreateUserRequest request) {
User newUser =
User.builder()
.id(UUID.randomUUID().toString())
.firstName(request.getFirstName())
.lastName(request.getLastName())
.build();
users.put(newUser.getId(), newUser);
return newUser;
}

private User getUserService(String id) {
return users.get(id);
}

private List<User> getAllUsersService() {
return new ArrayList<>(users.values());
}

private User deleteUserService(String id) {
return users.remove(id);
}

private User updateUserService(CreateUserRequest request) {
User updatedUser =
User.builder()
.id(request.getId())
.firstName(request.getFirstName())
.lastName(request.getLastName())
.build();
users.put(updatedUser.getId(), updatedUser);
return updatedUser;
}

private Map<String, User> dummyUserRepo() {
Map<String, User> users = new HashMap<>();
String id = UUID.randomUUID().toString();
users.put(id, User.builder().id(id).firstName("Amie").lastName("Apple").build());
id = UUID.randomUUID().toString();
users.put(id, User.builder().id(id).firstName("Bouncy").lastName("Ben").build());
id = UUID.randomUUID().toString();
users.put(id, User.builder().id(id).firstName("Clever").lastName("Cat").build());
id = UUID.randomUUID().toString();
users.put(id, User.builder().id(id).firstName("Dippy").lastName("Duck").build());
return users;
}

}

Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
package us.innodea.aws.serverless.springboot.crud.filter;

import com.amazonaws.serverless.proxy.RequestReader;
import com.amazonaws.serverless.proxy.model.AwsProxyRequestContext;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;

import java.io.IOException;


/**
* Simple Filter implementation that looks for a Cognito identity id in the API Gateway request context
* and stores the value in a request attribute. The filter is registered with aws-serverless-java-container
* in the onStartup method from the {com.amazonaws.serverless.sample.spring.StreamLambdaHandler} class.
*/
public class CognitoIdentityFilter implements Filter {
public static final String COGNITO_IDENTITY_ATTRIBUTE = "com.amazonaws.serverless.cognitoId";

private static Logger log = LoggerFactory.getLogger(CognitoIdentityFilter.class);

@Override
public void init(FilterConfig filterConfig)
throws ServletException {
// nothing to do in init
}


@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain)
throws IOException, ServletException {
Object apiGwContext = servletRequest.getAttribute(RequestReader.API_GATEWAY_CONTEXT_PROPERTY);
if (apiGwContext == null) {
log.warn("API Gateway context is null");
filterChain.doFilter(servletRequest, servletResponse);
}
if (!AwsProxyRequestContext.class.isAssignableFrom(apiGwContext.getClass())) {
log.warn("API Gateway context object is not of valid type");
filterChain.doFilter(servletRequest, servletResponse);
}

AwsProxyRequestContext ctx = (AwsProxyRequestContext)apiGwContext;
if (ctx.getIdentity() == null) {
log.warn("Identity context is null");
filterChain.doFilter(servletRequest, servletResponse);
}
String cognitoIdentityId = ctx.getIdentity().getCognitoIdentityId();
if (cognitoIdentityId == null || "".equals(cognitoIdentityId.trim())) {
log.warn("Cognito identity id in request is null");
}
servletRequest.setAttribute(COGNITO_IDENTITY_ATTRIBUTE, cognitoIdentityId);
filterChain.doFilter(servletRequest, servletResponse);
}


@Override
public void destroy() {
// nothing to do in destroy
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package us.innodea.aws.serverless.springboot.crud.model;

import lombok.Getter;

import java.io.Serializable;

@Getter
public class CreateUserRequest implements Serializable {
private static final long serialVersionUID = -1802739462080006423L;
private String id;
private String firstName;
private String lastName;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package us.innodea.aws.serverless.springboot.crud.model;

import lombok.Builder;
import lombok.Data;

import java.io.Serial;
import java.io.Serializable;

@Data
@Builder
public class User implements Serializable {
@Serial
private static final long serialVersionUID = 8166913065696134416L;
private String id;
private String firstName;
private String lastName;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
package us.innodea.aws.serverless.springboot.crud.service;

import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import us.innodea.aws.serverless.springboot.crud.model.CreateUserRequest;
import us.innodea.aws.serverless.springboot.crud.model.User;

import java.util.*;
@Slf4j
@Service
public class UserService {

private final Map<String, User> users = dummyUserRepo();

public User createUser(CreateUserRequest request) {
User newUser =
User.builder()
.id(UUID.randomUUID().toString())
.firstName(request.getFirstName())
.lastName(request.getLastName())
.build();
users.put(newUser.getId(), newUser);
return newUser;
}

public User getUser(String id) {
return users.get(id);
}

public List<User> getAllUsers() {
return new ArrayList<>(users.values());
}

public User deleteUser(String id) {
return users.remove(id);
}

public User updateUser(CreateUserRequest request) {
User updatedUser =
User.builder()
.id(request.getId())
.firstName(request.getFirstName())
.lastName(request.getLastName())
.build();
users.put(updatedUser.getId(), updatedUser);
return updatedUser;
}

private Map<String, User> dummyUserRepo() {
Map<String, User> users = new HashMap<>();
String id = UUID.randomUUID().toString();
users.put(id, User.builder().id(id).firstName("Amie").lastName("Apple").build());
id = UUID.randomUUID().toString();
users.put(id, User.builder().id(id).firstName("Bouncy").lastName("Ben").build());
id = UUID.randomUUID().toString();
users.put(id, User.builder().id(id).firstName("Clever").lastName("Cat").build());
id = UUID.randomUUID().toString();
users.put(id, User.builder().id(id).firstName("Dippy").lastName("Duck").build());
return users;
}
}
8 changes: 8 additions & 0 deletions src/main/resources/application.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
logging:
level:
root: info

spring:
jackson:
serialization:
write_dates_as_timestamps: false
Loading

0 comments on commit decde08

Please sign in to comment.