0
# Resolution Data Types
1
2
Data structures representing service discovery results including resolved endpoints with host, port, and IP address information. These types encapsulate the results of service discovery operations and provide both Scala and Java APIs for accessing the resolved service endpoints.
3
4
## Capabilities
5
6
### Resolved Result Class
7
8
Container for service discovery results, holding the service name and a collection of resolved service endpoints.
9
10
```scala { .api }
11
/**
12
* Result of a successful service discovery lookup
13
* @param serviceName The service name that was looked up
14
* @param addresses Sequence of resolved service endpoints
15
*/
16
final class Resolved(val serviceName: String, val addresses: immutable.Seq[ResolvedTarget]) {
17
/**
18
* Java API: Get the resolved addresses as a Java List
19
* @return List of ResolvedTarget instances
20
*/
21
def getAddresses: java.util.List[ResolvedTarget]
22
23
/**
24
* String representation for debugging
25
* @return String in format "Resolved(serviceName,addresses)"
26
*/
27
override def toString: String
28
29
/**
30
* Equality comparison based on service name and addresses
31
* @param obj Object to compare with
32
* @return true if equal, false otherwise
33
*/
34
override def equals(obj: Any): Boolean
35
36
/**
37
* Hash code based on service name and addresses
38
* @return Hash code value
39
*/
40
override def hashCode(): Int
41
}
42
```
43
44
**Usage Examples:**
45
46
```scala
47
import akka.discovery.ServiceDiscovery.{Resolved, ResolvedTarget}
48
import scala.collection.immutable
49
50
// Creating Resolved instances (typically done by discovery implementations)
51
val targets = immutable.Seq(
52
ResolvedTarget("service1.local", Some(8080), None),
53
ResolvedTarget("service2.local", Some(8080), None)
54
)
55
val resolved = Resolved("my-service", targets)
56
57
// Accessing results
58
println(s"Service: ${resolved.serviceName}")
59
println(s"Found ${resolved.addresses.length} endpoints")
60
61
resolved.addresses.foreach { target =>
62
println(s"Host: ${target.host}, Port: ${target.port}")
63
}
64
```
65
66
```java
67
import akka.discovery.ServiceDiscovery;
68
import java.util.List;
69
70
// Processing results from service discovery (Java API)
71
CompletionStage<ServiceDiscovery.Resolved> futureResolved =
72
serviceDiscovery.lookup("my-service", Duration.ofSeconds(3));
73
74
futureResolved.thenAccept(resolved -> {
75
System.out.println("Service: " + resolved.serviceName());
76
77
List<ServiceDiscovery.ResolvedTarget> addresses = resolved.getAddresses();
78
System.out.println("Found " + addresses.size() + " endpoints");
79
80
addresses.forEach(target -> {
81
System.out.println("Host: " + target.host() +
82
", Port: " + target.getPort().orElse(-1));
83
});
84
});
85
```
86
87
### ResolvedTarget Endpoint Class
88
89
Represents an individual service endpoint with host, optional port, and optional IP address information.
90
91
```scala { .api }
92
/**
93
* Individual resolved service endpoint
94
* @param host Hostname or IP address string
95
* @param port Optional port number
96
* @param address Optional resolved IP address (used for cluster bootstrap)
97
*/
98
final class ResolvedTarget(val host: String, val port: Option[Int], val address: Option[InetAddress]) {
99
/**
100
* Java API: Get the port number
101
* @return Optional containing port if available
102
*/
103
def getPort: Optional[Int]
104
105
/**
106
* Java API: Get the IP address
107
* @return Optional containing InetAddress if available
108
*/
109
def getAddress: Optional[InetAddress]
110
111
/**
112
* String representation for debugging
113
* @return String in format "ResolvedTarget(host,port,address)"
114
*/
115
override def toString: String
116
117
/**
118
* Equality comparison based on host, port, and address
119
* @param obj Object to compare with
120
* @return true if equal, false otherwise
121
*/
122
override def equals(obj: Any): Boolean
123
124
/**
125
* Hash code based on host, port, and address
126
* @return Hash code value
127
*/
128
override def hashCode(): Int
129
}
130
```
131
132
**Usage Examples:**
133
134
```scala
135
import akka.discovery.ServiceDiscovery.ResolvedTarget
136
import java.net.InetAddress
137
138
// Different ways to create ResolvedTarget instances
139
val basicTarget = ResolvedTarget("api.example.com", None, None)
140
val withPort = ResolvedTarget("api.example.com", Some(8080), None)
141
val withIPAddress = ResolvedTarget("api.example.com", Some(8080), Some(InetAddress.getByName("192.168.1.100")))
142
143
// Accessing target information
144
println(s"Host: ${withIPAddress.host}")
145
println(s"Port: ${withIPAddress.port.getOrElse("not specified")}")
146
println(s"IP: ${withIPAddress.address.map(_.getHostAddress).getOrElse("not resolved")}")
147
148
// Pattern matching on targets
149
withIPAddress.port match {
150
case Some(port) => println(s"Service available on port $port")
151
case None => println("No specific port information")
152
}
153
```
154
155
```java
156
import akka.discovery.ServiceDiscovery;
157
import java.net.InetAddress;
158
import java.util.Optional;
159
160
// Processing individual targets (Java API)
161
ServiceDiscovery.ResolvedTarget target = /* obtained from Resolved.getAddresses() */;
162
163
System.out.println("Host: " + target.host());
164
165
Optional<Integer> port = target.getPort();
166
if (port.isPresent()) {
167
System.out.println("Port: " + port.get());
168
} else {
169
System.out.println("No port specified");
170
}
171
172
Optional<InetAddress> address = target.getAddress();
173
if (address.isPresent()) {
174
System.out.println("IP: " + address.get().getHostAddress());
175
} else {
176
System.out.println("IP not resolved");
177
}
178
```
179
180
### Factory Objects
181
182
Companion objects providing factory methods and utilities for creating result instances.
183
184
```scala { .api }
185
/**
186
* Factory methods for creating Resolved instances
187
*/
188
object Resolved {
189
/**
190
* Create a Resolved instance
191
* @param serviceName Service name that was looked up
192
* @param addresses Sequence of resolved endpoints
193
* @return Resolved instance
194
*/
195
def apply(serviceName: String, addresses: immutable.Seq[ResolvedTarget]): Resolved
196
197
/**
198
* Pattern matching extractor
199
* @param resolved Resolved instance to extract from
200
* @return Option containing service name and addresses tuple
201
*/
202
def unapply(resolved: Resolved): Option[(String, immutable.Seq[ResolvedTarget])]
203
}
204
205
/**
206
* Factory methods and utilities for ResolvedTarget
207
*/
208
object ResolvedTarget {
209
/**
210
* Create a ResolvedTarget instance
211
* @param host Hostname or IP address
212
* @param port Optional port number
213
* @param address Optional IP address
214
* @return ResolvedTarget instance
215
*/
216
def apply(host: String, port: Option[Int], address: Option[InetAddress]): ResolvedTarget
217
218
/**
219
* Implicit ordering for ResolvedTarget instances
220
* Orders by IP address first, then hostname, then port number for consistent sorting.
221
* This ensures deterministic ordering when multiple endpoints are returned.
222
*/
223
implicit val addressOrdering: Ordering[ResolvedTarget]
224
}
225
```
226
227
**Usage Examples:**
228
229
```scala
230
import akka.discovery.ServiceDiscovery.{Resolved, ResolvedTarget}
231
import scala.collection.immutable
232
233
// Using factory methods
234
val target1 = ResolvedTarget("host1.local", Some(8080), None)
235
val target2 = ResolvedTarget("host2.local", Some(8080), None)
236
val resolved = Resolved("my-service", immutable.Seq(target1, target2))
237
238
// Pattern matching with unapply
239
resolved match {
240
case Resolved(serviceName, addresses) =>
241
println(s"Found service '$serviceName' with ${addresses.length} addresses")
242
case _ =>
243
println("Unexpected result type")
244
}
245
246
// Sorting targets using implicit ordering
247
val sortedTargets = resolved.addresses.sorted
248
println("Targets in sorted order:")
249
sortedTargets.foreach(println)
250
```
251
252
### Integration with Service Discovery
253
254
These types are returned by all service discovery implementations and provide consistent access patterns:
255
256
```scala
257
import akka.discovery.{Discovery, Lookup}
258
import scala.concurrent.Future
259
260
// All discovery methods return these same types
261
val serviceDiscovery = Discovery(system).discovery
262
263
// Basic lookup returns Resolved
264
val basicResult: Future[Resolved] = serviceDiscovery.lookup("web-service", 3.seconds)
265
266
// Advanced lookup also returns Resolved
267
val advancedLookup = Lookup("web-service").withPortName("http").withProtocol("tcp")
268
val advancedResult: Future[Resolved] = serviceDiscovery.lookup(advancedLookup, 3.seconds)
269
270
// Processing results is consistent regardless of discovery method
271
basicResult.foreach { resolved =>
272
println(s"Service '${resolved.serviceName}' resolved to:")
273
resolved.addresses.foreach { target =>
274
val portInfo = target.port.map(p => s":$p").getOrElse("")
275
val ipInfo = target.address.map(ip => s" (${ip.getHostAddress})").getOrElse("")
276
println(s" ${target.host}$portInfo$ipInfo")
277
}
278
}
279
```
280
281
### Empty Results
282
283
Service discovery may return empty results when no endpoints are found:
284
285
```scala
286
import akka.discovery.ServiceDiscovery.{Resolved, ResolvedTarget}
287
import scala.collection.immutable
288
289
// Empty result (no endpoints found)
290
val emptyResult = Resolved("non-existent-service", immutable.Seq.empty[ResolvedTarget])
291
292
// Checking for empty results
293
serviceDiscovery.lookup("some-service", 3.seconds).foreach { resolved =>
294
if (resolved.addresses.isEmpty) {
295
println(s"No endpoints found for service '${resolved.serviceName}'")
296
} else {
297
println(s"Found ${resolved.addresses.length} endpoints")
298
}
299
}
300
```