Customize and Observe with VMware Spring Cloud Gateway for Kubernetes

VMware Spring Cloud Gateway for Kubernetes, the powerful distributed API gateway loved by application developers like you no matter what programming language you use, has been improved with some brand new capabilities. Spring Cloud Gateway for Kubernetes now supports the loading of your own extensions so you can customize them to your own specific needs. Capturing metrics and trace data into your observability tools of choice is also easier than ever before. And all of these new capabilities are built on the open source Spring libraries you’ve come to trust!

In this post, we’ll walk through how you can take advantage of them.

Custom extensions

Ever since the Spring Cloud Gateway open source project was released back in 2017, application developers have been taking advantage of its extensibility. Developing custom predicates and filters is a key part of production-grade API gateway implementations built on Spring Cloud Gateway. Now you can load these same custom extensions into Spring Cloud Gateway for Kubernetes API gateway instances.

First, let's take a look at how easy it is to develop your own extensions. Then we’ll show you how they are loaded into an API gateway instance.

To get started, you can create a new project based on your programming language of choice for the Java virtual machine. We’ll demonstrate how using Java along with Gradle to handle our project builds. 

Start by adding the following dependencies to your Gradle build file:

    implementation platform("org.springframework.boot:spring-boot-dependencies:${springBootVersion}")
    implementation platform("org.springframework.cloud:spring-cloud-dependencies:${springCloudVersion}")
    implementation 'org.springframework.cloud:spring-cloud-starter-gateway

Define springCLoudVersion and springBootVersion with your open source versions of choice. We will be using Hoxton.SR8 and 2.5.4, respectively. A working example can be found in our Acme Fitness sample application.

We will start by creating a filter that reverses the string value of a specific header named X-Reverse-Me into a new header named X-Reversed.

package com.vmware.scg.extensions;

import org.springframework.cloud.gateway.filter.GatewayFilter;
import org.springframework.cloud.gateway.filter.factory.AbstractGatewayFilterFactory;
import org.springframework.http.HttpHeaders;
import org.springframework.stereotype.Component;
import org.springframework.web.server.ServerWebExchange;

@Component
public class ReverseMyHeaderGatewayFilterFactory
  extends AbstractGatewayFilterFactory {

  @Override
  public GatewayFilter apply(Object config) {
     return (exchange, chain) ->
     {
        ServerWebExchange updatedExchange = exchange.mutate()
                                         .request(request -> request.headers(this::reverseHeader))
                                         .build();
        return chain.filter(updatedExchange);
     };
  }

  private void reverseHeader(HttpHeaders headers) {
     headers.getOrEmpty("X-Reverse-Me")
           .stream()
           .map(value -> new StringBuilder(value).reverse().toString())
           .forEach(reversed -> headers.add("X-Reversed", reversed));
  }
}

As you can see in the code:

  • The filter will be automatically detected when loaded into API gateway instances via @Component annotation

  • We are expecting the header X-Reverse-Me to be on every request and that it will always append the new header X-Reversed

Run the build to generate a jar file with the new custom filter ReverseMyHeader. You can now load the filter into your API gateway instance by creating a ConfigMap from the jar file:

$ kubectl create configmap reverse-my-header --from-file=path/to/reverse-my-header.jar -n gateway_namespace

Now configure your API gateway instance to load the reverse-my-header extension:

apiVersion: "tanzu.vmware.com/v1"
kind: SpringCloudGateway
metadata:
  name: my-api-gateway
spec:
  extensions:
    custom:
      - reverse-my-header
...

Application development teams can now add the filter in their API route configuration custom resources:

apiVersion: "tanzu.vmware.com/v1"
kind: SpringCloudGatewayRouteConfig
metadata:
  name: my-gateway-routes
spec:
  routes:
  - uri: https://httpbin.org
    predicates:
      - Path=/api/get
    filters:
      - ReverseMyHeader
...

Now you can access the /api/get endpoint on your API gateway instance using curl and the header that will be reversed:

$ curl http://my.gateway.domain.io/api/get -H "X-Reverse-Me: test"
{
...
  "headers": {
...
    "X-Reverse-Me": "test",
    "X-Reversed": "tset"
  },
  ...
}

And that’s it! That’s all it takes for Spring Cloud Gateway for Kubernetes to be extended for all of your custom API use case needs!

API metrics at your fingertips

The Spring Cloud Gateway open source library has been emitting metrics since its initial release via the Spring Boot metrics actuator. Spring Cloud Gateway for Kubernetes not only leverages this underlying capability, but it has now added more API metrics, making it simple to configure transmission to your observability tool of choice: VMware Tanzu Observability by Wavefront or Prometheus and Grafana.

Let's take a look at the Tanzu Observability dashboard that gets generated.

The dashboard provides insights into API usage, performance, and error rate data. All of this can be yours with some simple Tanzu Observability configuration on your API gateway instance:

apiVersion: "tanzu.vmware.com/v1"
kind: SpringCloudGateway
metadata:
  name: my-api-gateway
spec:
  observability
    metrics:
      wavefront:
        enabled: true
    wavefront:
      secret: tanzu-observability-credentials-secret
      application: my-business-domain

The tanzu-observability-credentials-secret reference is to a Kubernetes Secret that has the following configuration contents:

apiVersion: v1
kind: Secret
metadata:
  name: tanzu-observability-credentials-secret
data:
  wavefront.api-token: "***"
  wavefront.uri: "***"

And that's it! You can now check out your generated API dashboard.

Trace API calls

Imagine that you’re asked to troubleshoot a problem in your complex mesh of API calls and microservices interactions. How do you figure out where the problem lies? Spring Cloud Gateway for Kubernetes leverages Spring Cloud Sleuth to enable the propagation of trace data for API routes to downstream application services. And as with metrics observability configuration, it is as easy as adding a tracing configuration:

apiVersion: "tanzu.vmware.com/v1"
kind: SpringCloudGateway
metadata:
  name: test-gateway-tracing
spec:
  observability:
    tracing:
      wavefront:
        enabled: true
    wavefront:
      secret: tanzu-observability-credentials-secret
      application: my-business-domain

Now you can troubleshoot your API calls like a pro!

Try Spring Cloud Gateway for Kubernetes today!

So where can you use Spring Cloud Gateway for Kubernetes? The following Kubernetes environments are supported:

  • VMware Tanzu Kubernetes Grid

  • Microsoft Azure Kubernetes Service

  • Google Kubernetes Engine

  • Amazon Elastic Kubernetes Service

  • Kubernetes versions 1.17+

To find out how you can get started:

You could also check out some of these talks from SpringOne that dive deeper into API management:

About the Author

Chris Sterling

Chris Sterling is Product Line Manager focused on API management at VMware. He has held multiple high-level roles in his 25+ years in the software industry. Chris published the book Managing Software Debt: Building for Inevitable Change with Addison-Wesley in 2010 to provide a framework for teams and organizations to assess and manage debt in their software systems. Chris has successfully supported organizational transformation across multiple verticals with organizations of 10 up to 800 people. After a successful entrepreneurial endeavor as co-founder of Agile Advantage, Chris has brought his diverse experience and deep passion for technology when presenting on topics such as Continuous Delivery, Cloud Native architecture, DevOps, Lean, and Agile to the products he helps bring to market.

Follow on Twitter Follow on Linkedin More Content by Chris Sterling
Previous
SpringOne 2021: Day 1 Recap and Highlights
SpringOne 2021: Day 1 Recap and Highlights

We’ve put together this roundup of some of the most interesting and insightful moments from Day 1 to give y...

Next
Simplifying the Deployment of Backing Services in Kubernetes with Helm Charts and VMware Tanzu Application Catalog
Simplifying the Deployment of Backing Services in Kubernetes with Helm Charts and VMware Tanzu Application Catalog

How to customize, deploy, and manage open source software at scale in a secure, reliable, and consistent way.