or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

core-api.mddiscovery-extension.mdindex.mdresolution-types.md

resolution-types.mddocs/

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

```