Spring Cloud Gateway 4.0.0-RC2 native example with Testcontainers
Tags: springcloud, testcontainers, buildpack, springboot
Published: 2022-12-09 01:24:19

---
series: spring boot 3 native
---

# Spring Cloud Gateway 4.0.0-RC2 native example with Testcontainers

[This example repository is on GitHub](https://github.com/dashaun/dev.dashaun.service.gateway)

There are 3 goals I have for this example:

- Deliver Spring Cloud Gateway as a graalvm-native-image with Spring Boot 3
- Get feedback on the multi-architecture buildpack that includes ARM64 support
- Demonstrate a pattern for building and testing buildpack images using Testcontainers

## [Spring Cloud Gateway](https://spring.io/projects/spring-cloud-gateway)

From the [Spring.io](https://spring.io/projects/spring-cloud-gateway) website:

```text
Spring Cloud Gateway aims to provide a simple,
yet effective way to route to APIs and provide
cross cutting concerns to them such as:
security, monitoring/metrics, and resiliency.
```

It is very popular, and even more valuable than it is popular!

Spring Framework 6 and Spring Boot 3.0.0 have recently gone GA. My favorite feature of these new releases is hands down the AOT processing. The AOT processing, provided by [GraalVM](https://graalvm.org), creates statically linked binary images. These images are optimized, ahead of time, for the operating system and architecture. For many modern workloads they can provide smaller image sizes, smaller memory footprint, and a much faster startup time.

[In a recent experiment](https://dashaun.com/posts/k3s-knative-ubuntu-raspberry-pi/), I was able to expose Spring Cloud Gateway to the public, and have it route to other Spring Boot 3 native image workloads. 

In that experiment Spring Cloud Gateway provided:
- Single service for SSL and ingress integration
- YAML configured routing
- Circuit Breaker capabilities with Resilience4j
- Request Rate Limiting with Redis

In the experiment, I left the Spring Cloud Gateway running, by setting the `min-scale` value to 1.

```yaml
metadata:
  name: spring-cloud-gateway
  namespace: default
spec:
  template:
    metadata:
      annotations:
        autoscaling.knative.dev/initial-scale: "1"
        autoscaling.knative.dev/min-scale: "1"
        autoscaling.knative.dev/max-scale: "2"
    spec:
      containers:
        - image: dashaun/dev.dashaun.service.gateway:latest
```

The other Spring Boot applications, being routed to by the gateway, were allowed to scale-to-zero when they weren't used.

[The experiment was on a cluster of Raspberry Pi](https://dashaun.com/posts/k3s-knative-ubuntu-raspberry-pi/) devices which are ARM64 cpus.

The Spring Cloud Gateway, native image, typically starts up between 0.600s and 0.650s, on a Raspberry Pi.

[![SCG native image Raspberry Pi startup](https://dashaun.com/posts/spring-cloud-gateway-4-0-0-rc2-native-example-with-testcontainers/images/scg-startup-rpi.png)](https://dashaun.com/posts/spring-cloud-gateway-4-0-0-rc2-native-example-with-testcontainers/images/scg-startup-rpi.png)

Today, the buildpack delivered by [Spring Initializr at start.spring.io](https://start.spring.io), is unable to create native images on ARM64.

## Multi-architecture buildpack

Earlier this year, I started working on a buildpack to use with the experimental project, `Spring Native`, and ARM64, for my Raspberry Pi devices. Later the M1/M2 Apple Silicon community, also ARM64, began showing interest in using this buildpack. [I have delivered a few versions to date](https://hub.docker.com/r/dashaun/java-native-builder-arm64). I've also created some automation to improve my process for creating these buildpacks.

Recently, I created a [multi-architecture buildpack](https://hub.docker.com/r/dashaun/java-native-builder-multiarch) that can be used with Spring Boot 3, to create native images on both Intel/AMD64 and ARM64 architectures. This example repository is configured with this multi-architecture buildpack.

I'm still working to improve this builder, in an effort to get ARM64 support upstream to [Paketo](https://paketo.io). I have a long way to go, but with your help, I can discover gaps and continue this effort. One of the known, and frustrating gaps today, is that UPX compression does not work on ARM64, it does work with AMD64.  I really want to get this figured out, and it is a high priority for me.

## Building and testing native images

One of the most common concerns I have heard from the community this year has been around validating that the native image artifacts are delivering the same results as the JIT/JVM based artifacts. This is a very valid concern.  This is also why I feel, that organizations with mature testing capabilities today, will be able to move forward with native images faster.

This repository provides a `BuildImageTest` that uses the buildpack to create a native image.  It then tests the native image, using [Testcontainers](https://testcontainers.org) and [JUnit](https://junit.org). Building the native image with AOT processing, as part of a test, takes minutes not seconds, and should not be part of normal "inner loop" development.  So the `BuildImageTest` is in a separate `sourceSet` and can be executed independently. This is a very powerful pattern, that I'm just getting started with. I would love to hear your thoughts on this pattern or other alternatives to it.

To build and validate the native image:

```bash
./gradlew integrationTest
```
> You can also execute the `BuildImageTest` directly in your IDE.

## Thanks

I am having so much fun with all of these new capabilities and challenges. I want to thank the Spring team, for all of their amazing work bring Spring Framework 6 and Spring Boot 3 to GA. I also want to thank Daniel Mikusa and the Paketo community for being amazing to work with. I want to thank Sergei Egorov for [sharing the testing pattern](https://bsideup.github.io/posts/spring_boot_in_container/) and supporting my Testcontainers journey. Finally, I would like to thank [Dan Vega](https://danvega.dev), my [Spring Office Hours](http://bit.ly/spring-office-hours) cohost, for being an amazing teammate, and having the JUICE.

## Keep Learning

- [Spring Boot Gateway](https://spring.io/projects/spring-cloud-gateway)
- [Spring Cloud 2022.0.0-RC2](https://spring.io/projects/spring-cloud)
- [Spring Boot 3.0.0](https://spring.io/projects/spring-boot)
- [Testcontainers](https://testcontainers.org)
- [Spring Boot 3 buildpacks with Testcontainers Cloud](https://dashaun.com/posts/spring-boot-3-buildpacks-with-testcontainers-cloud/)
- [Cloud Native Buildpack for ARM64 and AMD64](https://dashaun.com/posts/java-native-builder-multiarch-7-41-0/)
- [First attempt at a multi-architecture buildpack](https://dashaun.com/posts/multiarch-builder-poc/)
- [K3s Knative Ubuntu Raspberry Pi](https://dashaun.com/posts/k3s-knative-ubuntu-raspberry-pi/)