Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Spring Boot On Amazon Web services with Spring Cloud AWS

Spring Boot On Amazon Web services with Spring Cloud AWS

Spring Cloud AWS is a community project that helps developers use the rich ecosystem of AWS-managed services within a Spring Boot application in a familiar, idiomatic way.

In this talk, you'll learn how to speed up the development process using Spring Cloud AWS features, latest additions to the framework, and plans for the future.

Maciej Walkowiak

September 02, 2021
Tweet

More Decks by Maciej Walkowiak

Other Decks in Programming

Transcript

  1. SPRING BOOT
    ON AMAZON WEB SERVICES
    WITH SPRING CLOUD AWS
    MACIEJ
    WALKOWIAK
    MATEJ
    NEDIC

    View Slide

  2. @maciejwalkowiak @matejnedic1

    View Slide

  3. @maciejwalkowiak @matejnedic1

    View Slide

  4. @maciejwalkowiak @matejnedic1
    MACIEJ WALKOWIAK
    - independent consultant
    - Spring Cloud AWS Lead
    - working with

    View Slide

  5. @maciejwalkowiak @matejnedic1
    https://youtube.com/springacademy

    View Slide

  6. @maciejwalkowiak @matejnedic1
    MATEJ NEDIC
    - Software Engineer
    - Spring Cloud AWS Core team member
    - working at

    View Slide

  7. @maciejwalkowiak @matejnedic1
    SPRING CLOUD AWS

    View Slide

  8. @maciejwalkowiak @matejnedic1
    SPRING CLOUD AWS
    •Created by Agim Emruli and Alain Shall
    •First commit in February 2011
    •Community project
    •April 2020 - not a part of Spring
    Cloud release train
    •May 2020 - new maintainers

    View Slide

  9. @maciejwalkowiak @matejnedic1
    SPRING CLOUD AWS
    MACIEJ
    WALKOWIAK
    MATEJ
    NEDIC
    EDDU
    MELENDEZ

    View Slide

  10. @maciejwalkowiak @matejnedic1
    SPRING CLOUD AWS
    https://github.com/awspring/spring-cloud-aws

    View Slide

  11. @maciejwalkowiak @matejnedic1
    SPRING CLOUD AWS
    https://github.com/awspring/spring-cloud-aws

    View Slide

  12. @maciejwalkowiak @matejnedic1

    View Slide

  13. @maciejwalkowiak @matejnedic1
    SPRING BOOT
    ON AMAZON WEB
    SERVICES
    WITH SPRING CLOUD AWS

    View Slide

  14. @maciejwalkowiak @matejnedic1
    Application RDBMS

    View Slide

  15. @maciejwalkowiak @matejnedic1
    EC2
    •Updates
    •Backups
    •Security
    •Scaling
    •High Availability
    RDS
    •Updates
    •Backups
    •Security
    •Scaling
    •High Availability

    View Slide

  16. @maciejwalkowiak @matejnedic1
    EC2
    •! Updates
    •! Backups
    •! Security
    •! Scaling
    •! High Availability
    RDS
    •✅ Updates
    •✅ Backups
    •✅ Security
    •✅ Scaling
    •✅ High Availability

    View Slide

  17. @maciejwalkowiak @matejnedic1
    EC2
    •! Updates
    •! Backups
    •! Security
    •! Scaling
    •! High Availability
    RDS
    •✅ Updates
    •✅ Backups
    •✅ Security
    •✅ Scaling
    •✅ High Availability
    #

    View Slide

  18. @maciejwalkowiak @matejnedic1

    View Slide

  19. @maciejwalkowiak @matejnedic1
    Application RDS

    View Slide

  20. @maciejwalkowiak @matejnedic1
    Application
    RDS - Primary

    View Slide

  21. @maciejwalkowiak @matejnedic1
    Application
    RDS - Primary
    RDS - Read Replica

    View Slide

  22. @maciejwalkowiak @matejnedic1
    Application
    RDS - Primary
    RDS - Read Replica
    Asynchronous
    Replication

    View Slide

  23. @maciejwalkowiak @matejnedic1
    Application
    RDS - Primary
    RDS - Read Replica
    Asynchronous
    Replication

    View Slide

  24. @maciejwalkowiak @matejnedic1
    Application
    RDS - Primary
    RDS - Read Replica
    Asynchronous
    Replication

    View Slide

  25. @maciejwalkowiak @matejnedic1
    Application
    RDS - Primary
    RDS - Read Replica
    Asynchronous
    Replication
    Write
    Read

    View Slide

  26. @maciejwalkowiak @matejnedic1
    Application
    RDS - Primary
    RDS - Read Replica #1
    Asynchronous
    Replication
    Write
    Read
    RDS - Read Replica #2
    RDS - Read Replica #3
    Read
    Read

    View Slide

  27. @maciejwalkowiak @matejnedic1
    spring:
    datasource:
    url: jdbc:postgresql://springone.c0x5be2ybrmz.eu-west-2.rds.amazonaws.com:5432/postgres
    username: postgres
    password: postgres

    View Slide

  28. @maciejwalkowiak @matejnedic1
    cloud:
    aws:
    rds:
    instances:
    -
    db-instance-identifier: springone
    database-name: postgres
    username: postgres
    password: postgres

    View Slide

  29. @maciejwalkowiak @matejnedic1
    cloud:
    aws:
    rds:
    instances:
    -
    db-instance-identifier: springone
    database-name: postgres
    username: postgres
    password: postgres
    read-replica-support: true

    View Slide

  30. @maciejwalkowiak @matejnedic1
    @Service
    class UserService {
    @Transactional
    void registerUser(User user) {
    ...
    }
    @Transactional(readOnly=true)
    User findUser(Long id) {
    ...
    }
    }

    View Slide

  31. @maciejwalkowiak @matejnedic1
    https://vladmihalcea.com/read-write-read-only-transaction-routing-spring/

    View Slide

  32. @maciejwalkowiak @matejnedic1
    •Only Tomcat connection pool supported (will change
    in 3.0)
    •No Aurora support (will change in 3.0)
    WHAT IS MISSING?

    View Slide

  33. @maciejwalkowiak @matejnedic1
    •Aurora support
    •IAM Authentication
    •RDS Proxy Support
    •Secrets Manager JDBC authentication (?)
    WHAT IS COMING?

    View Slide

  34. @maciejwalkowiak @matejnedic1
    MESSAGING ON AWS

    View Slide

  35. @maciejwalkowiak @matejnedic1
    Service A Service B
    HTTP

    View Slide

  36. @maciejwalkowiak @matejnedic1
    Service A Service B

    View Slide

  37. @maciejwalkowiak @matejnedic1
    Service A Service B

    View Slide

  38. @maciejwalkowiak @matejnedic1
    Service A Service B

    View Slide

  39. @maciejwalkowiak @matejnedic1
    Service A Service B

    View Slide

  40. @maciejwalkowiak @matejnedic1
    Service A Service B

    View Slide

  41. @maciejwalkowiak @matejnedic1

    View Slide

  42. @maciejwalkowiak @matejnedic1

    View Slide

  43. @maciejwalkowiak @matejnedic1
    https://docs.aws.amazon.com/AWSSimpleQueueService/latest/SQSDeveloperGuide/sqs-basic-architecture.html

    View Slide

  44. @maciejwalkowiak @matejnedic1
    @Service
    public class RegistrationService {
    void register(Attendee attendee) {
    // persist attendee, send confirmation email
    }
    }

    View Slide

  45. @maciejwalkowiak @matejnedic1
    @Service
    public class RegistrationService {
    private final QueueMessagingTemplate queueMessagingTemplate;
    public RegistrationService(QueueMessagingTemplate queueMessagingTemplate)
    this.queueMessagingTemplate = queueMessagingTemplate;
    }
    void register(Attendee attendee) {
    // persist attendee, send confirmation email
    queueMessagingTemplate.convertAndSend("springone-queue", attendee);
    }
    }

    View Slide

  46. @maciejwalkowiak @matejnedic1
    @Component
    public class AttendeeListener {
    private AttendeeRepository attendeeRepository;
    public AttendeeListener(AttendeeRepository attendeeRepository) {
    this.attendeeRepository = attendeeRepository;
    }
    @SqsListener("springone-queue")
    void handle(Attendee attendee) {
    attendeeRepository.save(attendee);
    }
    }

    View Slide

  47. @maciejwalkowiak @matejnedic1
    @Component
    public class AttendeeListener {
    private AttendeeRepository attendeeRepository;
    public AttendeeListener(AttendeeRepository attendeeRepository) {
    this.attendeeRepository = attendeeRepository;
    }
    @SqsListener("springone-queue")
    void handle(Attendee attendee, @Header("header-name") String header) {
    attendeeRepository.save(attendee);
    }
    }

    View Slide

  48. @maciejwalkowiak @matejnedic1
    @Component
    public class AttendeeListener {
    private AttendeeRepository attendeeRepository;
    public AttendeeListener(AttendeeRepository attendeeRepository) {
    this.attendeeRepository = attendeeRepository;
    }
    @SqsListener("springone-queue")
    void handle(Attendee attendee, Acknowledgment acknowledgment) {
    if (...) {
    acknowledgment.acknowledge();
    }
    }
    }

    View Slide

  49. @maciejwalkowiak @matejnedic1
    @Component
    public class AttendeeListener {
    private AttendeeRepository attendeeRepository;
    public AttendeeListener(AttendeeRepository attendeeRepository) {
    this.attendeeRepository = attendeeRepository;
    }
    @SqsListener("springone-queue")
    void handle(Attendee attendee, Visibility visibility) {
    if (...) {
    visibility.extend(2);
    }
    }
    }

    View Slide

  50. @maciejwalkowiak @matejnedic1
    @Component
    public class AttendeeListener {
    private AttendeeRepository attendeeRepository;
    public AttendeeListener(AttendeeRepository attendeeRepository) {
    this.attendeeRepository = attendeeRepository;
    }
    @SqsListener("springone-queue")
    @SendTo("tickets-queue")
    Ticket handle(Attendee attendee) {
    attendeeRepository.save(attendee);
    // return ticket
    }
    }

    View Slide

  51. @maciejwalkowiak @matejnedic1
    Service A Service C
    Service B
    SNS

    View Slide

  52. @maciejwalkowiak @matejnedic1
    Service A Service C
    Service B
    SNS

    View Slide

  53. @maciejwalkowiak @matejnedic1
    Service A Service C
    Service B
    SNS

    View Slide

  54. @maciejwalkowiak @matejnedic1
    Service A Service C
    Service B
    SNS

    View Slide

  55. @maciejwalkowiak @matejnedic1
    Service A Service C
    Service B
    SNS

    View Slide

  56. @maciejwalkowiak @matejnedic1
    Service A Service C
    Service B
    SNS

    View Slide

  57. @maciejwalkowiak @matejnedic1
    Service A Service C
    Service B
    SNS

    View Slide

  58. @maciejwalkowiak @matejnedic1
    Service A Service C
    Service B
    SNS
    HTTP
    HTTP
    HTTP

    View Slide

  59. @maciejwalkowiak @matejnedic1
    @Component
    public class SnsNotificationSender {
    private final NotificationMessagingTemplate
    notificationMessagingTemplate;
    public SnsNotificationSender(
    NotificationMessagingTemplate notificationMessagingTemplate)
    {
    this.notificationMessagingTemplate =
    notificationMessagingTemplate;
    }
    public void send(String subject, String message) {
    this.notificationMessagingTemplate.sendNotification(
    "physicalTopicName", message, subject);
    }
    }

    View Slide

  60. @maciejwalkowiak @matejnedic1
    @Controller
    @RequestMapping("/springone-topic")
    public class NotificationController {
    @NotificationSubscriptionMapping
    public void handleSubscriptionMessage(NotificationStatus status) {
    //We subscribe to start receive the message
    status.confirmSubscription();
    }
    @NotificationMessageMapping
    public void handleNotificationMessage(@NotificationSubject String subject,
    @NotificationMessage String message) {
    // ...
    }
    @NotificationUnsubscribeConfirmationMapping
    public void handleUnsubscribeMessage(NotificationStatus status) {
    //e.g. the client has been unsubscribed and we want to "re-subscribe"
    status.confirmSubscription();
    }
    }

    View Slide

  61. @maciejwalkowiak @matejnedic1
    •Performance …
    •Reactive support
    •Spring Cloud Stream SQS (?)
    WHAT IS COMING?

    View Slide

  62. @maciejwalkowiak @matejnedic1
    •Performance …
    •Reactive support
    •Spring Cloud Stream SQS (?)
    WHAT IS COMING?

    View Slide

  63. @maciejwalkowiak @matejnedic1
    STORING CONFIGURATION WITH
    SECRETS MANAGER
    AND
    PARAMETER STORE

    View Slide

  64. @maciejwalkowiak @matejnedic1
    https://cloud.spring.io/spring-cloud-config/reference/html/
    Service A
    Service B
    Service C

    View Slide

  65. @maciejwalkowiak @matejnedic1
    https://cloud.spring.io/spring-cloud-config/reference/html/
    Service A
    Service B
    Service C
    Spring Cloud Config

    View Slide

  66. @maciejwalkowiak @matejnedic1
    https://cloud.spring.io/spring-cloud-config/reference/html/
    Service A
    Service B
    Service C
    Spring Cloud Config
    DB
    File
    System
    Vault
    Git

    View Slide

  67. @maciejwalkowiak @matejnedic1
    But what if your
    storage for properties
    goes down?

    View Slide

  68. @maciejwalkowiak @matejnedic1
    AWS PARAMETER STORE

    View Slide

  69. @maciejwalkowiak @matejnedic1

    View Slide

  70. @maciejwalkowiak @matejnedic1
    Service A Service B
    Parameter store

    View Slide

  71. View Slide

  72. @maciejwalkowiak @matejnedic1
    spring.config.import=aws-parameterstore:/config/spring/
    spring.config.import=optional:aws-parameterstore:/config/common/;/config/urls/
    spring:
    config:
    import:
    - aws-parameterstore:/config/spring/
    - optional:aws-parameterstore:/config/common/;/config/urls/

    View Slide

  73. @maciejwalkowiak @matejnedic1
    @Value("${message}") String message;
    spring.cloud.config.server.git.refreshRate=${refresh}

    View Slide

  74. @maciejwalkowiak @matejnedic1
    AWS SECRETS MANAGER

    View Slide

  75. Parameter store
    Secret Manager

    View Slide

  76. Service A
    Parameter store
    Secret Manager

    View Slide

  77. Service A
    RDS
    Parameter store
    Secret Manager

    View Slide

  78. @maciejwalkowiak @matejnedic1
    spring.config.import=aws-secretmanager:/secret/db/prod/url
    spring.config.import=optional:aws-secretmanager:/secret/common
    spring.datasoruce.url=${url}

    View Slide

  79. @maciejwalkowiak @matejnedic1
    Parameter Store
    • Type: Supports
    StringList,String,
    SecureString.
    • 4KB char max
    • Can’t be referenced cross
    account
    • Can’t rotate secrets
    • Cheaper
    Secret manager
    • Can be referenced cross
    account
    • Automatic Secret rotation
    • More expensive
    • Can store more characters 10kb
    • Built in password generator
    • Supports secret cross region
    replication

    View Slide

  80. @maciejwalkowiak @matejnedic1
    •Secret rotation support
    •Refreshing context on parameter and secret change
    WHAT IS COMING?

    View Slide

  81. @maciejwalkowiak @matejnedic1
    OTHER SUPPORTED SERVICES
    •S3
    •EC2 metadata
    •Cloud Watch
    •ElastiCache (Redis & Memcached)
    •SES (Simple Email Service)
    •Cloud Formation

    View Slide

  82. @maciejwalkowiak @matejnedic1

    View Slide

  83. @maciejwalkowiak @matejnedic1
    WHEN SPRING CLOUD AWS IS NOT ENOUGH
    •Spring Cloud Stream Kinesis Binder
    https://github.com/spring-cloud/spring-cloud-stream-binder-aws-kinesis
    •Spring Integration AWS
    https://github.com/spring-projects/spring-integration-aws
    •Spring Cloud Config Server
    https://github.com/spring-cloud/spring-cloud-config
    •Spring Data DynamoDB
    https://github.com/boostchicken/spring-data-dynamodb

    View Slide

  84. @maciejwalkowiak @matejnedic1
    •AWS SDK:
    •AWS SDK v1
    •AWS SDK v2
    WHEN SPRING CLOUD AWS IS NOT ENOUGH

    View Slide

  85. @maciejwalkowiak @matejnedic1
    •AWS SDK v2
    •$ GraalVM Native Image compatible
    •$ Non Blocking - Spring WebFlux friendly!
    •$ Pluggable HTTP client
    •$ Does not conflict with SDK v1
    •% Still no feature parity with 1.x
    WHEN SPRING CLOUD AWS IS NOT ENOUGH

    View Slide

  86. @maciejwalkowiak @matejnedic1
    TESTING

    View Slide

  87. @maciejwalkowiak @matejnedic1
    TESTING WITH LOCALSTACK

    View Slide

  88. @maciejwalkowiak @matejnedic1
    version: '3.1'
    services:
    localstack:
    image: localstack/localstack:latest
    environment:
    - SERVICES=sqs,s3
    ports:
    - ‘4566:4566'
    - ‘4571:4571’
    volumes:
    - "${TEMPDIR:-/tmp/localstack}:/tmp/localstack"
    - "/var/run/docker.sock:/var/run/docker.sock"
    LOCALSTACK

    View Slide

  89. @maciejwalkowiak @matejnedic1
    $ docker-compose up
    localstack_1 |
    localstack_1 | __ _______ __ __
    localstack_1 | / / ____ _________ _/ / ___// /_____ ______/ /__
    localstack_1 | / / / __ \/ ___/ __ `/ /\__ \/ __/ __ `/ ___/ //_/
    localstack_1 | / /___/ /_/ / /__/ /_/ / /___/ / /_/ /_/ / /__/ ,<
    localstack_1 | /_____/\____/\___/\__,_/_//____/\__/\__,_/\___/_/|_|
    localstack_1 |
    localstack_1 | & LocalStack CLI 0.12.17.3
    localstack_1 |
    localstack_1 | [16:23:49] starting LocalStack in host mode & localstack.py:101
    localstack_1 | ──────────────── LocalStack Runtime Log (press CTRL-C to quit) ─────────────────
    localstack_1 | 2021-09-01 16:23:50,722 INFO success: infra entered RUNNING state, process has stayed up for > than 1 seconds (startsecs)
    localstack_1 |
    localstack_1 | LocalStack version: 0.12.17.3
    localstack_1 | LocalStack Docker container id: 67fb82278492
    localstack_1 | LocalStack build date: 2021-09-01
    localstack_1 | LocalStack build git hash: 637d9bfa
    localstack_1 |
    localstack_1 | Starting edge router (https port 4566)...
    localstack_1 | Starting mock S3 service on http port 4566 ...
    localstack_1 | 2021-09-01T16:23:54:INFO:localstack.multiserver: Starting multi API server process on port 44089
    localstack_1 | [2021-09-01 16:23:54 +0000] [21] [INFO] Running on https://0.0.0.0:4566 (CTRL + C to quit)
    localstack_1 | 2021-09-01T16:23:54:INFO:hypercorn.error: Running on https://0.0.0.0:4566 (CTRL + C to quit)
    localstack_1 | [2021-09-01 16:23:54 +0000] [21] [INFO] Running on http://0.0.0.0:44089 (CTRL + C to quit)
    localstack_1 | 2021-09-01T16:23:54:INFO:hypercorn.error: Running on http://0.0.0.0:44089 (CTRL + C to quit)
    localstack_1 | Waiting for all LocalStack services to be ready
    localstack_1 | Starting mock SQS service on http port 4566 ...
    localstack_1 | Ready.
    LOCALSTACK

    View Slide

  90. @maciejwalkowiak @matejnedic1
    $ aws sqs create-queue --queue-name “hello-springone" --endpoint-url http://localhost:4566
    LOCALSTACK

    View Slide

  91. @maciejwalkowiak @matejnedic1
    $ aws sqs create-queue --queue-name “hello-springone" --endpoint-url http://localhost:4566
    LOCALSTACK
    {
    "QueueUrl": "http://localhost:4566/000000000000/hello-springone"
    }

    View Slide

  92. @maciejwalkowiak @matejnedic1
    $ aws sqs create-queue --queue-name “hello-springone" --endpoint-url http://localhost:4566
    LOCALSTACK
    {
    "QueueUrl": "http://localhost:4566/000000000000/hello-springone"
    }
    $ aws sqs list-queues --endpoint-url http://localhost:4566

    View Slide

  93. @maciejwalkowiak @matejnedic1
    $ aws sqs create-queue --queue-name “hello-springone" --endpoint-url http://localhost:4566
    LOCALSTACK
    {
    "QueueUrl": "http://localhost:4566/000000000000/hello-springone"
    }
    $ aws sqs list-queues --endpoint-url http://localhost:4566
    {
    "QueueUrls": [
    "http://localhost:4566/000000000000/testqueue",
    "http://localhost:4566/000000000000/hello-springone"
    ]
    }

    View Slide

  94. @maciejwalkowiak @matejnedic1
    cloud.aws.sqs.endpoint: http://localhost:4566
    LOCALSTACK
    cloud.aws.sns.endpoint: http://localhost:4566

    View Slide

  95. @maciejwalkowiak @matejnedic1
    @SpringBootTest
    @Testcontainers
    class DemoApplicationTests {
    @Container
    static LocalStackContainer localstack =
    new LocalStackContainer(DockerImageName.parse("localstack/localstack:0.12.17"))
    .withServices(LocalStackContainer.Service.SQS);
    @DynamicPropertySource
    static void localstackProperties(DynamicPropertyRegistry registry) {
    registry.add("clous.aws.sqs.endpoint",
    () -> localstack.getEndpointOverride(LocalStackContainer.Service.SQS));
    }
    // ..
    }
    LOCALSTACK

    View Slide

  96. @maciejwalkowiak @matejnedic1
    LOCALSTACK
    • ACM
    • API Gateway
    • CloudFormation
    • CloudWatch
    • CloudWatch Logs
    • DynamoDB
    • DynamoDB Streams
    • EC2
    • Elasticsearch Service
    • EventBridge
    (CloudWatch Events)
    • Firehose
    • IAM
    • Kinesis
    • KMS
    • Lambda
    • Redshift
    • STS
    • Route53
    • S3
    • SecretsManager
    • SES
    • SNS
    • SQS
    • SSM
    • StepFunctions

    View Slide

  97. @maciejwalkowiak @matejnedic1
    LOCALSTACK
    • Amplify
    • API Gateway V2
    (WebSockets support)
    • AppConfig
    • Application
    AutoScaling
    • AppSync
    • Athena
    • Backup
    • Batch
    • CloudFront
    • CloudTrail
    • CodeCommit
    • Cognito
    • CostExplorer
    • DocumentDB
    • ECR/ECS/EKS
    • ElastiCache
    • ElasticBeanstalk
    • ELB/ELBv2
    • EMR
    • Glacier / S3 Select
    • Glue
    • IAM Security Policy
    Enforcement
    • IoT
    • Kinesis Data Analytics
    • Lambda Layers &
    Container Images

    View Slide

  98. @maciejwalkowiak @matejnedic1
    LOCALSTACK
    https://localstack.dev

    View Slide

  99. @maciejwalkowiak @matejnedic1
    FUTURE

    View Slide

  100. @maciejwalkowiak @matejnedic1
    •Migrate from AWS SDK v1 to AWS SDK v2
    •CloudMap integration (PR ready)
    •Spring Data Dynamo DB (?)
    •Drop support for: ElastiCache, CloudFormation
    •Improve startup times
    •GraalVM Native Image compatibility
    FUTURE  SPRING CLOUD AWS 3.X

    View Slide

  101. @maciejwalkowiak @matejnedic1
    SPRING CLOUD AWS
    SAMPLES

    View Slide

  102. @maciejwalkowiak @matejnedic1
    https://github.com/awspring/spring-cloud-aws/tree/2.3.x/spring-cloud-aws-samples

    View Slide

  103. https://awspring.io/

    View Slide

  104. https://stratospheric.dev/
    BJÖRN WILMSMANN
    PHILIP RIECKS
    TOM HOMBERGS

    View Slide

  105. @maciejwalkowiak @matejnedic1
    THANK YOU!

    View Slide