forked from nats-io/java-nats-examples
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathIntroToServiceFramework.java
More file actions
142 lines (122 loc) · 6.31 KB
/
IntroToServiceFramework.java
File metadata and controls
142 lines (122 loc) · 6.31 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
// Copyright 2023 The NATS Authors
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at:
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package io.nats;
import io.nats.client.Connection;
import io.nats.client.Message;
import io.nats.client.Nats;
import io.nats.service.*;
import java.io.IOException;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
/**
* This example will demonstrate a basic micro service
*/
public class IntroToServiceFramework {
public static void main(String[] args) {
String natsURL = System.getenv("NATS_URL");
if (natsURL == null) {
natsURL = "nats://127.0.0.1:4222";
}
try (Connection conn = Nats.connect(natsURL)) {
// ### What is a Service?
//
// A "service" consists of one or more endpoints.
// An endpoint can be part of a group of endpoints or by itself.
// ### Defining a Group
//
// In this example, the services will be part of a group.
// The group name will be the prefix for the subject of the request.
// Alternatively you could manually specify the group's subject
// Here we create the group.
Group serviceGroup = new Group("minmax");
// ### Defining Endpoints
// For each endpoint we give it a name. Like group,
// you could manually specify the endpoint's subject.
// In this example we are adding the endpoint to the group we defined
// and are providing a ServiceMessageHandler implementation
ServiceEndpoint min = ServiceEndpoint.builder()
.endpointName("min")
.group(serviceGroup)
.handler(msg -> minRequestHandler(conn, msg))
.build();
ServiceEndpoint max = ServiceEndpoint.builder()
.endpointName("max")
.group(serviceGroup)
.handler(msg -> maxRequestHandler(conn, msg))
.build();
// ### Defining the Service
//
// The Service definition requires a name and version, description is optional.
// The name must be a simple name consisting of the characters A-Z, a-z, 0-9, dash (-) or underscore (_).
// Add the endpoints that were created. Give the service a connection to run on.
// A unique id is created for the service to identify it from different instances of the service.
Service service = Service.builder()
.name("minmax")
.version("0.0.1")
.description("Returns the min/max number in a request")
.addServiceEndpoint(min)
.addServiceEndpoint(max)
.connection(conn)
.build();
System.out.println("Created Service: " + service.getName() + " with the id: " + service.getId());
// ### Running the Service
//
// To run the service we call service.startService().
// Uou can have a future that returns when service.stop() is called.
CompletableFuture<Boolean> serviceStopFuture = service.startService();
// For the example we use a simple string for the input and output
// but in the real world it will be some sort of formatted data such as json.
// The input and output is sent as the data payload of the NATS message.
byte[] input = "-1,2,100,-2000".getBytes();
// To "call" a service, we simply make a request to the proper endpoint with
// data that it expects. Notice how the group name is prepended to the endpoint name.
CompletableFuture<Message> minResponse = conn.request("minmax.min", input);
CompletableFuture<Message> maxResponse = conn.request("minmax.max", input);
Message minMessage = minResponse.get(1, TimeUnit.SECONDS);
System.out.println("Min value is: " + new String(minMessage.getData()));
Message maxMessage = maxResponse.get(1, TimeUnit.SECONDS);
System.out.println("Max value is: " + new String(maxMessage.getData()));
// The statistics being managed by micro should now reflect the call made
// to each endpoint, and we didn't have to write any code to manage that.
EndpointStats esMin = service.getEndpointStats(min.getName());
System.out.println("The min service received " + esMin.getNumRequests() + " request(s).");
EndpointStats esMax = service.getEndpointStats(max.getName());
System.out.println("The max service received " + esMax.getNumRequests() + " request(s).");
}
catch (IOException | InterruptedException | ExecutionException | TimeoutException e) {
// * IOException: problem making the connection
// * InterruptedException: thread interruption in the body of the example
// * ExecutionException: something went wrong in the request
// * TimeoutException: the request took longer than the timeout specified
System.err.println(e);
}
}
private static void minRequestHandler(Connection conn, ServiceMessage msg) {
int min = Integer.MAX_VALUE;
String[] input = new String(msg.getData()).split(",");
for (String n : input) {
min = Math.min(min, Integer.parseInt(n));
}
msg.respond(conn, ("" + min).getBytes());
}
private static void maxRequestHandler(Connection conn, ServiceMessage msg) {
int max = Integer.MIN_VALUE;
String[] input = new String(msg.getData()).split(",");
for (String n : input) {
max = Math.max(max, Integer.parseInt(n));
}
msg.respond(conn, ("" + max).getBytes());
}
}