Skip to content

Commit 875970f

Browse files
authored
Replace migrate-managed-gateway
1 parent 9e406a8 commit 875970f

File tree

2 files changed

+160
-361
lines changed

2 files changed

+160
-361
lines changed

articles/spring-apps/migration/migrate-to-azure-container-apps-components-gateway.md

Lines changed: 160 additions & 130 deletions
Original file line numberDiff line numberDiff line change
@@ -10,112 +10,94 @@ ms.date: 01/29/2025
1010
ms.custom: devx-track-java, devx-track-extended-java
1111
---
1212

13-
# Migrate Spring Cloud Gateway for Tanzu to managed Gateway for Spring in Azure Container Apps
13+
# Migrate Spring Cloud Gateway for Tanzu to self-hosted gateway application in Azure Container Apps
1414

1515
[!INCLUDE [deprecation-note](../includes/deprecation-note.md)]
1616

1717
**This article applies to:** ❎ Basic/Standard ✅ Enterprise
1818

19-
This article shows you how to migrate VMware Spring Cloud Gateway in Azure Spring Apps Enterprise plan to managed Gateway for Spring in Azure Container Apps using the Azure CLI.
19+
This article shows you how to migrate Spring Cloud Gateway for Tanzu in Azure Spring Apps Enterprise plan to self-hosted Open Source Spring Cloud Gateway (OSS Gateway) running as an Azure Container Apps application.
2020

2121
## Prerequisites
2222

23-
- An existing Azure Spring Apps Enterprise plan instance with Spring Cloud Gateway enabled.
24-
- An existing Azure container app. For more information, see [Quickstart: Deploy your first container app using the Azure portal](../../container-apps/quickstart-portal.md).
23+
- An Azure Spring Apps Enterprise plan instance with Spring Cloud Gateway enabled.
24+
- An Azure Container Apps. For more information, see [Quickstart: Deploy your first container app using the Azure portal](../../container-apps/quickstart-portal.md).
2525
- [Azure CLI](/cli/azure/install-azure-cli).
26+
- An Azure Container Registry with sufficient permissions to build and push Docker images, see [Create A Container Registry](../../container-registry/container-registry-get-started-azure-cli#create-a-container-registry)
2627

27-
## Provision managed Gateway for Spring
28+
## Prepare the code of self-hosted OSS Gateway application
2829

29-
Use the following command to provision the Gateway for Spring Java component in the Azure Container Apps environment that you created in the prerequisites:
30+
To get the code of the OSS Gateway:
31+
1. Navigate to https://start.spring.io.
32+
1. Update the project metadata by setting the `Group` to your orgnization's name. Change the `Artifact` and `Name` to `gateway`.
33+
1. Add dependencies `Reactive Gateway` and `Spring Boot Actuator`.
34+
1. Leave the other properties at their default values.
35+
1. Click `Generate` to download the project.
3036

31-
```azurecli
32-
az containerapp env java-component gateway-for-spring create \
33-
--resource-group <resource-group-name> \
34-
--name <gateway-name> \
35-
--environment <azure-container-app-environment-name>
36-
```
37-
38-
After you successfully create the component, you can see that the **Provisioning State** value for Spring Cloud Gateway is **Succeeded**.
39-
40-
### Resource management
41-
42-
The container resource allocation for the Gateway for Spring in Azure Container Apps is fixed to the following values:
43-
44-
- **CPU**: 0.5 vCPU
45-
- **Memory**: 1 Gi
37+
Extract the project when it's downloaded.
4638

47-
To configure the instance count for Gateway for Spring, use the parameters `--min-replicas` and `--max-replicas`, setting both to the same value. This configuration ensures that the instance count remains fixed. The system currently doesn't support dynamic autoscaling configurations.
39+
## Configure the OSS Gateway
40+
Once the OSS Gateway code is ready, navigate to the `gateway/src/main/resources` directory of the project. Rename the `application.properties` file with `application.yml`. You can migrate from Spring Cloud Gateway for Tanzu by configuring the `application.yml`.
4841

49-
## Configure Gateway for Spring
42+
The example of `application.yml` is like:
5043

51-
After you provision the gateway, the next step is to configure it for smooth migration.
52-
53-
You can update the configuration and routes of the Gateway for Spring component by using the `update` command, as shown in the following example:
54-
55-
```azurecli
56-
az containerapp env java-component gateway-for-spring update \
57-
--resource-group <resource-group-name> \
58-
--name <gateway-name> \
59-
--environment <azure-container-app-environment-name> \
60-
--configuration <configuration-key>="<configuration-value>" \
61-
--route-yaml <path-to-route-YAML-file>
44+
```yaml
45+
spring:
46+
application:
47+
name: gateway
48+
cloud:
49+
gateway:
50+
globalcors:
51+
corsConfigurations:
52+
'[/**]':
53+
allowedOriginPatterns: "*"
54+
allowedMethods:
55+
- GET
56+
- POST
57+
- PUT
58+
- DELETE
59+
allowedHeaders:
60+
- "*"
61+
allowCredentials: true
62+
maxAge: 3600
63+
routes:
64+
- id: front
65+
uri: http://front-app
66+
predicates:
67+
- Path=/**
68+
- Method=GET
69+
order: 1000
70+
filters:
71+
- StripPrefix=0
72+
tags:
73+
- front
6274
```
6375
6476
### CORS configuration
6577
66-
To migrate the global Cross-Origin Resource Sharing (CORS) configuration of VMware Spring Cloud Gateway, you need to map properties into the format `<configuration-key>="<configuration-value>"`. The mapping relation is shown in the following table:
78+
To migrate the Cross-Origin Resource Sharing (CORS) configuration of Spring Cloud Gateway for Tanzu, you can refer to [CORS Configuration for OSS Gateway](https://docs.spring.io/spring-cloud-gateway/docs/current/reference/html/#cors-configuration) for global CORS configuration and route CORS configuration.
6779
68-
| Property name in VMware Spring Cloud Gateway | Configuration in Gateway for Spring |
69-
|----------------------------------------------|-----------------------------------------------------------------------------------------|
70-
| Allowed origins | `spring.cloud.gateway.globalcors.cors-configurations.[/**].allowedOrigins[<id>]` |
71-
| Allowed origin patterns | `spring.cloud.gateway.globalcors.cors-configurations.[/**].allowedOriginPatterns[<id>]` |
72-
| Allowed methods | `spring.cloud.gateway.globalcors.cors-configurations.[/**].allowedMethods[<id>]` |
73-
| Allowed headers | `spring.cloud.gateway.globalcors.cors-configurations.[/**].allowedHeaders[<id>]` |
74-
| Max age | `spring.cloud.gateway.globalcors.cors-configurations.[/**].maxAge` |
75-
| Allow credentials | `spring.cloud.gateway.globalcors.cors-configurations.[/**].allowCredentials` |
76-
| Exposed headers | `spring.cloud.gateway.globalcors.cors-configurations.[/**].exposedHeaders[<id>]` |
80+
### Scale
81+
When migrating to OSS Gateway application in Azure Container Apps, the scaling behavior should align with Azure Container Apps' model. The instance count from Spring Cloud Gateway for Tanzu maps to `min-replica` and `max-replica` in Azure Container Apps. You can configure automatic scaling for the gateway application by defining scaling rules. For more details, refer to [Set scaling rules in Azure Container Apps](../../container-apps/scale-app).
7782

78-
For example, if you have a configuration like `allowedOrigins:["https://example.com","https://example1.com"]` in VMware Spring Cloud Gateway, you should update Gateway for Spring with the following parameter:
83+
The CPU and memory combinations available in Azure Spring Apps may differ from those in Azure Container Apps. When mapping resource allocations, ensure that the selected CPU and memory configurations in Azure Container Apps fit both performance needs and supported options.
7984

80-
```azurecli
81-
--configuration spring.cloud.gateway.globalcors.cors-configurations.[/**].allowedOrigins[0]=https://example.com spring.cloud.gateway.globalcors.cors-configurations.[/**].allowedOrigins[1]=https://example1.com
82-
```
83-
84-
For per route CORS configuration, you need to replace the "/**" in the configuration key as the route path. For example, if you have a route with path `/v1/**`, you should configure `spring.cloud.gateway.globalcors.cors-configurations.[/v1/**].allowedOrigins[<id>]`.
85+
### Custom domain & certificates
86+
Azure Container Apps supports custom domains and certificates, you can refer to [Domains & certificates](../../container-apps/certificates-overview) to migrate custom domains configured on Spring Cloud Gateway for Tanzu.
8587

8688
### Routes
8789

88-
The Gateway for Spring component supports defining routes through the `id`, `uri`, `predicates`, and `filters` properties, as shown in the following example:
89-
90-
```yaml
91-
springCloudGatewayRoutes:
92-
- id: "route1"
93-
uri: "https://otherjavacomponent.myenvironment.test.net"
94-
predicates:
95-
- "Path=/v1/{path}"
96-
- "After=2024-01-01T00:00:00.000-00:00[America/Denver]"
97-
filters:
98-
- "SetPath=/{path}"
99-
- id: "route2"
100-
uri: "https://otherjavacomponent.myenvironment.test.net"
101-
predicates:
102-
- "Path=/v2/{path}"
103-
- "After=2024-01-01T00:00:00.000-00:00[America/Denver]"
104-
filters:
105-
- "SetPath=/{path}"
106-
```
107-
108-
The following list describes the mapping relationship between routes of VMware Spring Cloud Gateway and routes of Gateway for Spring:
90+
You can migrate the routes in Spring Cloud Gatewy for Tanzu to OSS Gateway as the example of `application.yml` shows. The following list describes the mapping relationship between routes of Spring Cloud Gateway for Tanzu and routes of OSS Gateway:
10991

11092
- The `name` of the route is mapped to `id`.
111-
- The `appName` and `protocol` are mapped to the URI of the route, which should be the accessible URI for the Azure Container Apps instance.
112-
- Spring Cloud Gateway predicates and filters are mapped to Gateway for Spring predicates and filters.
93+
- The `appName` and `protocol` are mapped to the URI of the route, which should be the accessible URI for the Azure Container Apps instance, make sure that the Azure Container Apps applications enable the ingress.
94+
- Predicates and filters of Spring Cloud Gateway for Tanzu are mapped to that of OSS Gateway. Commercial predicates and filters are not supported, refer to [the document](https://techdocs.broadcom.com/us/en/vmware-tanzu/spring/spring-cloud-gateway-for-kubernetes/2-2/scg-k8s/developer-filters.html) for more details.
11395

114-
For example, suppose the following route config json file, called **test-api.json** is created for VMware Spring Cloud Gateway:
96+
For example, consider the following route config JSON file, `test-api.json`, which defines the `test-api` route in Spring Cloud Gateway for Tanzu for the `test` app:
11597

11698
```json
11799
{
118-
"protocol": "HTTP",
100+
"protocol": "HTTP",
119101
"routes": [
120102
{
121103
"title": "Test API",
@@ -124,90 +106,138 @@ For example, suppose the following route config json file, called **test-api.jso
124106
"Method=GET"
125107
],
126108
"filters": [
127-
"AddResponseHeader=X-Response-Red, Blue"
109+
"AddRequestHeader=X-Request-red, blue"
128110
]
129111
}
130112
]
131113
}
132114
```
133115

134-
And, suppose you use the following command to apply the rule to the Azure Spring Apps app `test-app`:
116+
Then, the following yaml shows the corresponding route configuration for OSS Gateway:
135117

136-
```azurecli
137-
az spring gateway route-config create \
138-
--resource-group <resource-group-name> \
139-
--service <Azure-Spring-Apps-instance-name> \
140-
--name test-api \
141-
--app-name test-app \
142-
--routes-file test-api.json
118+
```yaml
119+
spring:
120+
cloud:
121+
gateway:
122+
routes:
123+
- id: test-api
124+
uri: http://test
125+
predicates:
126+
- Path=/test/api/healthcheck
127+
- Method=GET
128+
filters:
129+
- AddRequestHeader=X-Request-red, blue
130+
- StripPrefix=1
143131
```
144132

145-
Then, the following example shows the corresponding route YAML file **test-api.yml** for Gateway for Spring on Azure Container Apps:
133+
Spring Cloud Gateway for Tanzu sets `StripPrefix=1` by default on every route. To migrate to OSS Gateway, you need to explicitly set `StripPrefix=1` in the filter configuration.
134+
135+
To allow your OSS Gateway application to access other applications through the app name, you need to enable ingress for your Azure Container App applications. You can also use for the accessible FQDN of Azure Container Apps application as the uri of the route, following the format: `https://<app-name>.<container-app-env-name>.<region>.azurecontainerapps.io`.
136+
137+
There are some [commercial predicates](https://docs.vmware.com/en/VMware-Spring-Cloud-Gateway-for-Kubernetes/2.2/scg-k8s/GUID-guides-predicates.html) and [commercial filters](https://docs.vmware.com/en/VMware-Spring-Cloud-Gateway-for-Kubernetes/2.2/scg-k8s/GUID-guides-filters.html) that aren't supported on OSS Gateway.
138+
139+
### Response cache
146140

141+
If you enable the response cache globally in Spring Cloud Gateway for Tanzu, use the following configuration in OSS Gateway and see [local cache response global filter](https://docs.spring.io/spring-cloud-gateway/docs/current/reference/html/#local-cache-response-global-filter) for more details:
147142
```yaml
148-
springCloudGatewayRoutes:
149-
- id: "test-api"
150-
uri: "<app-fqdn-in-Container-Apps>"
151-
predicates:
152-
- Path=/test/api/healthcheck
153-
- Method=GET
154-
filters:
155-
- AddResponseHeader=X-Response-Red, Blue
143+
spring:
144+
cloud:
145+
gateway:
146+
filter:
147+
local-response-cache:
148+
enabled: true
149+
time-to-live: <response-cache-ttl>
150+
size: <response-cache-size>
156151
```
157152

158-
And, you would use the following command to update the container app:
153+
If you enable the response cache for the route, you can use the [`LocalResponseCache`](https://docs.spring.io/spring-cloud-gateway/docs/current/reference/html/#local-cache-response-filter) filter in the routing rule configuration of managed Gateway for Spring as the following YAML:
159154

160-
```azurecli
161-
az containerapp env java-component gateway-for-spring update \
162-
--route-yaml test-api.yml
155+
```yaml
156+
spring:
157+
cloud:
158+
gateway:
159+
routes:
160+
- id: test-api
161+
uri: http://test
162+
predicates:
163+
- Path=/resource
164+
filters:
165+
- LocalResponseCache=30m,500MB
163166
```
164167

165-
You need to enable ingress for your Azure Container App application to obtain its fully qualified domain name (FQDN). Then, replace `<app-FQDN-in-Azure-Container-Apps>` in the route's URI with the app's accessible endpoint. The URI format is `https://<app-name>.<container-app-env-name>.<region>.azurecontainerapps.io`.
168+
### Integrate with APM
166169

167-
There are some [commercial predicates](https://docs.vmware.com/en/VMware-Spring-Cloud-Gateway-for-Kubernetes/2.2/scg-k8s/GUID-guides-predicates.html) and [commercial filters](https://docs.vmware.com/en/VMware-Spring-Cloud-Gateway-for-Kubernetes/2.2/scg-k8s/GUID-guides-filters.html) that aren't supported on Gateway for Spring on Azure Container Apps.
170+
To enable application performance monitoring (APM) for OSS Gateway application, refer to [Integrate application performance monitoring into container images](./migrate-to-azure-container-apps-build-application-performance-monitoring.md).
168171

169-
### Response cache
172+
## Deploy to Azure Continer Apps
173+
174+
Once the OSS Gateway configuration is ready, build the image using Azure Container Registry and deploy it to Azure Container Apps.
175+
176+
### Build and Push the Docker Image
177+
178+
In the OSS Gateway project directory, create a `Dockerfile` with the following contents:
179+
180+
```dockerfile
181+
FROM mcr.microsoft.com/openjdk/jdk:17-mariner as build
182+
WORKDIR /staging
183+
# Install gradle
184+
RUN tdnf install -y wget unzip
185+
186+
RUN wget https://services.gradle.org/distributions/gradle-8.8-bin.zip && \
187+
unzip -d /opt/gradle gradle-8.8-bin.zip && \
188+
chmod +x /opt/gradle/gradle-8.8/bin/gradle
189+
190+
ENV GRADLE_HOME=/opt/gradle/gradle-8.8
191+
ENV PATH=$PATH:$GRADLE_HOME/bin
192+
193+
COPY . .
194+
195+
# Compile with gradle
196+
RUN gradle build -x test
197+
198+
FROM mcr.microsoft.com/openjdk/jdk:17-mariner as runtime
170199
171-
If you enable the response cache globally, you can update the managed Gateway for Spring with the following configuration:
200+
WORKDIR /app
172201
173-
```properties
174-
spring.cloud.gateway.filter.local-response-cache.enabled=true
175-
spring.cloud.gateway.filter.local-response-cache.time-to-live=<response-cache-ttl>
176-
spring.cloud.gateway.filter.local-response-cache.size=<response-cache-size>
202+
COPY --from=build /staging/build/libs/gateway-0.0.1-SNAPSHOT.jar .
203+
204+
ENTRYPOINT ["java", "-jar", "gateway-0.0.1-SNAPSHOT.jar"]
177205
```
178206

179-
If you enable the response cache for the route, you can use the `LocalResponseCache` filter in the routing rule configuration of managed Gateway for Spring as the following YAML:
207+
Alternatively, you can refer to the sample [Dockerfile](https://github.com/Azure-Samples/acme-fitness-store/blob/Azure/azure-kubernetes-service/resources/gateway/gateway/Dockerfile) for guidance.
180208

181-
```yaml
182-
springCloudGatewayRoutes:
183-
- id: "test-api"
184-
uri: "<app-fqdn-in-Container-Apps>"
185-
predicates:
186-
- Path=/v1/**
187-
- Method=GET
188-
filters:
189-
- LocalResponseCache=3m, 1MB
209+
Run the following command to build the image of gateway using your Azure Container Registry:
210+
211+
```azurecli
212+
az acr login --name <azure-container-registry-name>
213+
az acr build --image gateway:acrbuild-spring-cloud-gateway-0.0.1-SNAPSHOT --registry <azure-container-registry-name> --file Dockerfile . --resource-group <resource-group-name>
190214
```
191215

192-
## Troubleshooting
216+
Ensure the gateway image is created and get the image tag, which follows the format: `<azure-container-registry-name>.azurecr.io/gateway:acrbuild-spring-cloud-gateway-0.0.1-SNAPSHOT`.
193217

194-
You can view logs of Gateway for Spring in Azure Container Apps using `Log Analytics` by using the following steps:
218+
### Deploy the image in Azure Container Apps
195219

196-
1. In the Azure portal, navigate to your Azure Container Apps environment.
197-
1. In the navigation pane, select **Monitoring** > **Logs**.
198-
1. To view logs, query the `ContainerAppSystemLogs_CL` table using the query editor, as shown in the following example:
220+
Once your gateway application image is ready, deploy it as an Azure Container Apps application `gateway`. Replace the <container-image-of-gateway> with the image tag retrieved in the previous step:
199221

200-
```kusto
201-
ContainerAppSystemLogs_CL
202-
| where ComponentType_s == "SpringCloudGateway"
203-
| project Time=TimeGenerated, ComponentName=ComponentName_s, Message=Log_s
204-
| take 100
205-
```
222+
```azurecli
223+
az containerapp up \
224+
--name gateway \
225+
--resource-group <resource-group-name> \
226+
--environment <azure-container-app-environment-name> \
227+
--image <container-image-of-gateway> \
228+
--target-port 8080 \
229+
--ingress external
230+
```
206231

207-
For more information about querying logs, see [Observability of managed Java components in Azure Container Apps](../../container-apps/java-component-logs.md).
232+
Access the FQDN of the OSS Gateway application to verify that it is running.
208233

209-
## Known limitation
234+
## Troubleshooting
235+
236+
If you encounter issues when running the OSS Gateway application, you can view real time and historical logs of the application `gateway` in Azure Container Apps following [Application Logging in Azure Container Apps](../../container-apps/logging).
210237

211-
For now, Gateway for Spring on Azure Container Apps doesn't support certain commercial features, including metadata used to generate OpenAPI documentation, single sign-on (SSO), and application performance monitoring (APM) integration.
238+
To monitor gateway application's metrics, refer to [Monitor Azure Container Apps metrics](../../container-apps/metrics)
212239

213-
There's a known issue where enabling Gateway for Spring prevents the **Services** section from opening in the Azure portal. We expect to resolve this issue soon.
240+
## Known limitation
241+
OSS Gateway does not support the following commercial features:
242+
- Metadata used to generate OpenAPI documentation
243+
- Single sign-on (SSO) functionality

0 commit comments

Comments
 (0)