Skip to content

Commit 4317abf

Browse files
authored
Merge pull request #226638 from CaihuaRui/caihua/nginx
Add How to use gRPC in Azure Spring Apps
2 parents 8c80000 + 41d290b commit 4317abf

File tree

2 files changed

+320
-0
lines changed

2 files changed

+320
-0
lines changed
Lines changed: 316 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,316 @@
1+
---
2+
title: How to use gRPC in Azure Spring Apps
3+
description: Shows you how to use gRPC in Azure Spring Apps.
4+
author: KarlErickson
5+
ms.author: caihuarui
6+
ms.service: spring-apps
7+
ms.topic: how-to
8+
ms.date: 5/24/2023
9+
ms.custom: devx-track-java
10+
---
11+
12+
# How to use gRPC in Azure Spring Apps
13+
14+
> [!NOTE]
15+
> Azure Spring Apps is the new name for the Azure Spring Cloud service. Although the service has a new name, you'll see the old name in some places for a while as we work to update assets such as screenshots, videos, and diagrams.
16+
17+
**This article applies to:** ✔️ Basic/Standard ✔️ Enterprise
18+
19+
This article shows you how to use gRPC in Azure Spring Apps.
20+
21+
In this article, you modify and redeploy the [Spring Boot Pet Clinic](https://github.com/Azure-Samples/spring-petclinic-microservices) sample application. From your local environment, you create a gRPC service by modifying the `customers-service` microservice, deploy the modified sample to Azure Spring Apps, and then use `grpcurl` commands to test the service by making calls to gRPC methods.
22+
23+
For a demonstration of this process, see the following video:
24+
25+
<br>
26+
27+
> [!VIDEO https://www.youtube.com/embed/yNvoQ4YIDCI]
28+
29+
## Prerequisites
30+
31+
- An Azure subscription. If you don't have a subscription, create a [free account](https://azure.microsoft.com/free/) before you begin.
32+
- [Azure CLI](/cli/azure/install-azure-cli).
33+
- Use the following command to install the Azure Spring Apps extension: `az extension add --name spring`
34+
- [Git](https://git-scm.com/downloads).
35+
- [Microsoft Build of OpenJDK](/java/openjdk/download#openjdk-17) Version 17.
36+
- [Maven](https://maven.apache.org/download.cgi).
37+
- An Azure Spring Apps instance. For more information, see [Quickstart: Provision an Azure Spring Apps service instance](quickstart-provision-service-instance.md).
38+
- A built and deployed Pet Clinic sample application. For more information, see [Quickstart: Build and deploy apps to Azure Spring Apps](quickstart-deploy-apps.md).
39+
40+
## Assign a public endpoint
41+
42+
To facilitate testing, assign a public endpoint. The public endpoint is used in the `grpcurl` commands as the hostname. For more information, see [fullstorydev/grpcurl](https://github.com/fullstorydev/grpcurl).
43+
44+
Use the following command to assign a public endpoint. Be sure to replace the placeholders with the resource group name, service instance name, and app name that you used when you fulfilled the prerequisites.
45+
46+
```azurecli
47+
az spring app update \
48+
--resource-group <resource-group-name> \
49+
--service <Azure-Spring-Apps-instance-name> \
50+
--name <app-name> \
51+
--assign-public-endpoint true
52+
```
53+
54+
You can also use the Azure portal to assign a public endpoint. For more information, see [Expose applications on Azure Spring Apps to the internet from a public network](how-to-access-app-from-internet-virtual-network.md).
55+
56+
## Modify an existing service to be a gRPC service
57+
58+
Before the service is changed into a gRPC server, look at the Owners page of the deployed PetClinic instance application to examine the current pet owners data. You can also list all owners by adding `/owners` to the URL path, which you can get from the Overview page for the `customers-service` page in the Azure portal.
59+
60+
Use the following steps to change `customers-service` into a gRPC server:
61+
62+
1. Locate *pom.xml* in the *spring-petclinic-customers-service* folder.
63+
64+
1. In the *pom.xml* file, delete the following element that defines the `spring-boot-starter-web` dependency:
65+
66+
```xml
67+
<dependency>
68+
<groupId>org.springframework.boot</groupId>
69+
<artifactId>spring-boot-starter-web</artifactId>
70+
</dependency>
71+
```
72+
73+
If you don't remove this dependency, the application starts both a web server and a gRPC server. Azure Spring Apps then rewrites the server port to 1025, which prevents gRPC from being routed correctly with a static server address.
74+
75+
1. Add the following elements to the *pom.xml* file. These elements define the dependency and build plugins required for gRPC.
76+
77+
```xml
78+
<dependencies>
79+
<!-- For both gRPC server and client -->
80+
<dependency>
81+
<groupId>net.devh</groupId>
82+
<artifactId>grpc-spring-boot-starter</artifactId>
83+
<version>2.5.1.RELEASE</version>
84+
<exclusions>
85+
<exclusion>
86+
<groupId>io.grpc</groupId>
87+
<artifactId>grpc-netty-shaded</artifactId>
88+
</exclusion>
89+
</exclusions>
90+
</dependency>
91+
<!-- For the gRPC server (only) -->
92+
<dependency>
93+
<groupId>net.devh</groupId>
94+
<artifactId>grpc-server-spring-boot-starter</artifactId>
95+
<version>2.5.1.RELEASE</version>
96+
<exclusions>
97+
<exclusion>
98+
<groupId>io.grpc</groupId>
99+
<artifactId>grpc-netty-shaded</artifactId>
100+
</exclusion>
101+
</exclusions>
102+
</dependency>
103+
<dependency>
104+
<groupId>net.devh</groupId>
105+
<artifactId>grpc-client-spring-boot-autoconfigure</artifactId>
106+
<version>2.5.1.RELEASE</version>
107+
<type>pom</type>
108+
</dependency>
109+
</dependencies>
110+
<build>
111+
<extensions>
112+
<extension>
113+
<groupId>kr.motd.maven</groupId>
114+
<artifactId>os-maven-plugin</artifactId>
115+
<version>1.6.1</version>
116+
</extension>
117+
</extensions>
118+
<plugins>
119+
<plugin>
120+
<groupId>org.springframework.boot</groupId>
121+
<artifactId>spring-boot-maven-plugin</artifactId>
122+
</plugin>
123+
<plugin>
124+
<groupId>org.xolstice.maven.plugins</groupId>
125+
<artifactId>protobuf-maven-plugin</artifactId>
126+
<version>0.6.1</version>
127+
<configuration>
128+
<protocArtifact>
129+
com.google.protobuf:protoc:3.3.0:exe:${os.detected.lassifier}
130+
</protocArtifact>
131+
<pluginId>grpc-java</pluginId>
132+
<pluginArtifact>
133+
io.grpc:protoc-gen-grpc-java:1.4.0:exe:${os.detected.classifier}
134+
</pluginArtifact>
135+
</configuration>
136+
<executions>
137+
<execution>
138+
<goals>
139+
<goal>compile</goal>
140+
<goal>compile-custom</goal>
141+
</goals>
142+
</execution>
143+
</executions>
144+
</plugin>
145+
</plugins>
146+
</build>
147+
```
148+
149+
## Build the gRPC service
150+
151+
Use the following steps to create and run a *.proto* file that defines the message types and RPC interface methods:
152+
153+
1. Create a new file with the *.proto* extension in the source code folder that has the following content:
154+
155+
```protobuf
156+
syntax = "proto3";
157+
option java_multiple_files = true;
158+
package org.springframework.samples.petclinic.customers.grpc;
159+
import "google/protobuf/empty.proto";
160+
161+
message OwnerRequest {
162+
int32 ownerId = 1;
163+
}
164+
165+
message PetRequest {
166+
int32 petId = 1;
167+
}
168+
169+
message OwnerResponse {
170+
int32 id = 1;
171+
string firstName = 2;
172+
string lastName = 3;
173+
string address = 4;
174+
string city = 5;
175+
string telephone = 6;
176+
repeated PetResponse pets = 7;
177+
}
178+
179+
message PetResponse {
180+
int32 id = 1;
181+
string name = 2;
182+
string birthDate = 3;
183+
PetType type = 4;
184+
OwnerResponse owner = 5;
185+
}
186+
187+
message PetType {
188+
int32 id = 1;
189+
string name = 2;
190+
}
191+
192+
message PetTypes {
193+
repeated PetType ele = 1;
194+
}
195+
196+
message Owners {
197+
repeated OwnerResponse ele = 1;
198+
}
199+
200+
service CustomersService {
201+
rpc createOwner(OwnerResponse) returns (OwnerResponse);
202+
rpc findOwner(OwnerRequest) returns (OwnerResponse);
203+
rpc findAll(google.protobuf.Empty) returns (Owners);
204+
rpc updateOwner(OwnerResponse) returns (google.protobuf.Empty);
205+
rpc getPetTypes(google.protobuf.Empty) returns (PetTypes);
206+
rpc createPet(PetResponse) returns (PetResponse);
207+
rpc updatePet(PetResponse) returns (google.protobuf.Empty);
208+
rpc findPet(PetRequest) returns (PetResponse);
209+
}
210+
```
211+
212+
1. Use the following command to generate the gRPC service files:
213+
214+
```bash
215+
mvn package
216+
```
217+
218+
You can implement the gRPC service with the RPC methods defined in the *.proto* file. In the sample application, the generated files include *CustomersServiceGrpc.java*, as defined by the gRPC `proto` plugin.
219+
220+
## Implement the gRPC service
221+
222+
In your development environment, create a Java class file for the project with the following content that implements the RPC methods defined in the *.proto* file. Use the annotation `@GrpcService` to extend the autogenerated gRPC service base class to implement its methods. The following example shows an implementation of some of the methods:
223+
224+
```java
225+
@GrpcService
226+
@Slf4j
227+
public class CustomersServiceImpl extends CustomersServiceGrpc.CustomersServiceImplBase {
228+
@Autowired
229+
private OwnerRepository ownerRepository;
230+
231+
@Autowired
232+
private PetRepository petRepository;
233+
234+
@Override
235+
public void createOwner(OwnerResponse request, StreamObserver<OwnerResponse> responseObserver) {
236+
Owner owner = new Owner();
237+
BeanUtils.copyProperties(request, owner);
238+
ownerRepository.save(owner);
239+
240+
responseObserver.onNext(request);
241+
responseObserver.onCompleted();
242+
}
243+
}
244+
```
245+
246+
## Configure the server port to 1025
247+
248+
Next, configure the server port to 1025 so that the ingress rule works correctly. Add the following line to the *application.properties* file in the *spring-petclinic-customers-service/src/main/resources* folder.
249+
250+
```properties
251+
grpc.server.port=1025
252+
```
253+
254+
## Build the service JAR file
255+
256+
Use the following command to build the gRPC server JAR file:
257+
258+
```bash
259+
mvn package
260+
```
261+
262+
The modification of `customers-service` is now complete, and it's now a gRPC service.
263+
264+
## Deploy the application to Azure Spring Apps
265+
266+
You can now configure the server and deploy the application.
267+
268+
Use the following command to deploy the newly built JAR file to your Azure Spring Apps instance.
269+
270+
```azurecli
271+
az spring app deploy \
272+
--name ${CUSTOMERS_SERVICE} \
273+
--jar-path ${CUSTOMERS_SERVICE_JAR} \
274+
--jvm-options='-Xms2048m -Xmx2048m -Dspring.profiles.active=mysql' \
275+
--env MYSQL_SERVER_FULL_NAME=${MYSQL_SERVER_FULL_NAME} \
276+
MYSQL_DATABASE_NAME=${MYSQL_DATABASE_NAME} \
277+
MYSQL_SERVER_ADMIN_LOGIN_NAME=${MYSQL_SERVER_ADMIN_LOGIN_NAME} \
278+
MYSQL_SERVER_ADMIN_PASSWORD=${MYSQL_SERVER_ADMIN_PASSWORD}
279+
```
280+
281+
The deployment can take a few minutes to complete.
282+
283+
Now that the application is deployed in Azure Spring Apps, call a gRPC service from outside the Azure Spring Apps service instance. As you did earlier, test the `customers-service` endpoint to attempt to list all pet owners by adding `/owners` to the URL path. This time, the test fails as expected because a gRPC service can't be accessed using the HTTP protocol.
284+
285+
## Set the ingress configuration
286+
287+
Set the backend protocol to use gRPC so that you can use `grpcurl` commands to test the gRPC server. Update your application's ingress settings. For more information, see [Customize the ingress configuration in Azure Spring Apps](how-to-configure-ingress.md).
288+
289+
## Call the sample application from a local environment
290+
291+
You can use `grpcurl` to test the gRPC server. The only port supported for gRPC calls from outside Azure Spring Apps is port `443`. The traffic is automatically routed to port 1025 on the backend.
292+
293+
Use the following `grpcurl` commands to check the gRPC server by listing all the pet owners.
294+
295+
```bash
296+
grpcurl <service-instance-name>-customers-service.azuremicroservices.io:443 list
297+
grpcurl <service-instance-name>-customers-service.azuremicroservices.io:443 org.springframework.samples.petclinic.customers.grpc.CustomersService.findAll
298+
grpcurl -d "{\"ownerId\":7}" <service-instance-name>-customers-service.azuremicroservices.io:443 org.springframework.samples.petclinic.customers.grpc.CustomersService.findOwner
299+
```
300+
301+
## Frequently asked questions
302+
303+
- How do I use the test endpoint?
304+
305+
Use the following `curl` and HTTP commands to use the test endpoint of the gRPC server:
306+
307+
```bash
308+
echo -n '0000000000' | xxd -r -p - frame.bin
309+
curl -v --insecure --raw -X POST -H "Content-Type: application/grpc" -H "TE: trailers" --data-binary @frame.bin <test-endpoint/org. springframework.samples.petclinic.customers.grpc.CustomersService/findAll
310+
```
311+
312+
For more information, see the [View apps and deployments](how-to-staging-environment.md#view-apps-and-deployments) section of [Set up a staging environment in Azure Spring Apps](how-to-staging-environment.md).
313+
314+
## Next steps
315+
316+
- [Customize the ingress configuration in Azure Spring Apps](how-to-configure-ingress.md)

articles/spring-apps/toc.yml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -215,6 +215,8 @@ items:
215215
href: connect-managed-identity-to-azure-sql.md
216216
- name: Azure Load Balance Solutions
217217
href: how-to-integrate-azure-load-balancers.md
218+
- name: Use gRPC
219+
href: how-to-use-grpc.md
218220
- name: Monitor
219221
items:
220222
- name: Alerts and action groups
@@ -431,6 +433,8 @@ items:
431433
href: connect-managed-identity-to-azure-sql.md
432434
- name: Azure Load Balance Solutions
433435
href: how-to-integrate-azure-load-balancers.md
436+
- name: Use gRPC
437+
href: how-to-use-grpc.md
434438
- name: Monitor
435439
items:
436440
- name: Alerts and action groups

0 commit comments

Comments
 (0)