1 /* 2 * hunt-amqp: AMQP library for D programming language, based on hunt-net. 3 * 4 * Copyright (C) 2018-2019 HuntLabs 5 * 6 * Website: https://www.huntlabs.net 7 * 8 * Licensed under the Apache-2.0 License. 9 * 10 */ 11 12 module hunt.amqp.ProtonClientOptions; 13 14 import hunt.collection.LinkedHashSet; 15 import hunt.collection.Set; 16 import hunt.net.ProxyOptions; 17 import hunt.net.OpenSSLEngineOptions; 18 //import io.vertx.core.buffer.Buffer; 19 //import io.vertx.core.json.JsonObject; 20 //import io.vertx.core.net.JdkSSLEngineOptions; 21 //import io.vertx.core.net.JksOptions; 22 //import io.vertx.core.net.KeyCertOptions; 23 //import io.vertx.core.net.NetClientOptions; 24 //import io.vertx.core.net.OpenSSLEngineOptions; 25 //import io.vertx.core.net.PemKeyCertOptions; 26 //import io.vertx.core.net.PemTrustOptions; 27 //import io.vertx.core.net.PfxOptions; 28 //import io.vertx.core.net.ProxyOptions; 29 //import io.vertx.core.net.SSLEngineOptions; 30 //import io.vertx.core.net.TrustOptions; 31 import hunt.String; 32 import hunt.net.NetClientOptions; 33 import std.json; 34 import hunt.Exceptions; 35 import hunt.logging; 36 import core.time; 37 import hunt.collection.Map; 38 import hunt.collection.LinkedHashMap; 39 import std.variant; 40 41 import hunt.amqp.generated.ProtonClientOptionsConverter; 42 /** 43 * Options for configuring {@link hunt.amqp.ProtonClient} connect operations. 44 */ 45 //@DataObject(generateConverter = true, publicConverter = false) 46 class ProtonClientOptions : NetClientOptions { 47 48 private Set!string enabledSaslMechanisms;// = new LinkedHashSet<>(); 49 private int heartbeat; 50 private int maxFrameSize; 51 private string virtualHost; 52 private string sniServerName; 53 54 this() { 55 super(); 56 setHostnameVerificationAlgorithm("HTTPS"); 57 enabledSaslMechanisms = new LinkedHashSet!string; 58 } 59 60 /** 61 * Copy constructor 62 * 63 * @param other the options to copy 64 */ 65 this(ProtonClientOptions other) { 66 super(other); 67 this.enabledSaslMechanisms = new LinkedHashSet!string(other.enabledSaslMechanisms); 68 this.heartbeat = other.heartbeat; 69 this.maxFrameSize = other.maxFrameSize; 70 this.virtualHost = other.virtualHost; 71 this.sniServerName = other.sniServerName; 72 } 73 74 /** 75 * Create options from JSON 76 * 77 * @param json the JSON 78 */ 79 this(JSONValue json) { 80 Map!(string, Variant) mp = new LinkedHashMap!(string,Variant)(); 81 foreach (string key, value; json) 82 { 83 Variant tmp = value; 84 mp.put(key,tmp); 85 } 86 ProtonClientOptionsConverter.fromJson(mp, this); 87 super(this); 88 } 89 90 /** 91 * Convert to JSON 92 * 93 * @return the JSON 94 */ 95 public JSONValue toJson() { 96 implementationMissing(false); 97 JSONValue tmp; 98 return tmp; 99 //JSONValue json = super.toJson(); 100 //ProtonClientOptionsConverter.toJson(this, json); 101 //return json; 102 } 103 104 /** 105 * Get the mechanisms the client should be restricted to use. 106 * 107 * @return the mechanisms, or null/empty set if there is no restriction in place 108 */ 109 public Set!string getEnabledSaslMechanisms() { 110 return enabledSaslMechanisms; 111 } 112 113 /** 114 * Adds a mechanism name that the client may use during SASL negotiation. 115 * 116 * @param saslMechanism 117 * the sasl mechanism name . 118 * @return a reference to this, so the API can be used fluently 119 */ 120 public ProtonClientOptions addEnabledSaslMechanism(string saslMechanism) { 121 // Objects.requireNonNull(saslMechanism, "Mechanism must not be null"); 122 if (saslMechanism.length == 0) 123 { 124 logError("Mechanism must not be null"); 125 } 126 enabledSaslMechanisms.add(saslMechanism); 127 return this; 128 } 129 130 override 131 public ProtonClientOptions setSendBufferSize(int sendBufferSize) { 132 super.setSendBufferSize(sendBufferSize); 133 return this; 134 } 135 136 override 137 public ProtonClientOptions setReceiveBufferSize(int receiveBufferSize) { 138 super.setReceiveBufferSize(receiveBufferSize); 139 return this; 140 } 141 142 override 143 public ProtonClientOptions setReuseAddress(bool reuseAddress) { 144 super.setReuseAddress(reuseAddress); 145 return this; 146 } 147 148 override 149 public ProtonClientOptions setTrafficClass(int trafficClass) { 150 super.setTrafficClass(trafficClass); 151 return this; 152 } 153 154 override 155 public ProtonClientOptions setTcpNoDelay(bool tcpNoDelay) { 156 super.setTcpNoDelay(tcpNoDelay); 157 return this; 158 } 159 160 override 161 public ProtonClientOptions setTcpKeepAlive(bool tcpKeepAlive) { 162 super.setTcpKeepAlive(tcpKeepAlive); 163 return this; 164 } 165 166 override 167 public ProtonClientOptions setSoLinger(int soLinger) { 168 super.setSoLinger(soLinger); 169 return this; 170 } 171 172 override 173 public ProtonClientOptions setIdleTimeout(Duration idleTimeout) { 174 super.setIdleTimeout(idleTimeout); 175 return this; 176 } 177 178 //override 179 //public ProtonClientOptions setIdleTimeoutUnit(TimeUnit idleTimeoutUnit) { 180 // super.setIdleTimeoutUnit(idleTimeoutUnit); 181 // return this; 182 //} 183 184 override 185 public ProtonClientOptions setSsl(bool ssl) { 186 super.setSsl(ssl); 187 return this; 188 } 189 190 //override 191 //public ProtonClientOptions setKeyStoreOptions(JksOptions options) { 192 // super.setKeyStoreOptions(options); 193 // return this; 194 //} 195 // 196 //override 197 //public ProtonClientOptions setPfxKeyCertOptions(PfxOptions options) { 198 // super.setPfxKeyCertOptions(options); 199 // return this; 200 //} 201 // 202 //override 203 //public ProtonClientOptions setPemKeyCertOptions(PemKeyCertOptions options) { 204 // super.setPemKeyCertOptions(options); 205 // return this; 206 //} 207 // 208 //override 209 //public ProtonClientOptions setTrustStoreOptions(JksOptions options) { 210 // super.setTrustStoreOptions(options); 211 // return this; 212 //} 213 // 214 //override 215 //public ProtonClientOptions setPemTrustOptions(PemTrustOptions options) { 216 // super.setPemTrustOptions(options); 217 // return this; 218 //} 219 // 220 //override 221 //public ProtonClientOptions setPfxTrustOptions(PfxOptions options) { 222 // super.setPfxTrustOptions(options); 223 // return this; 224 //} 225 226 //override 227 //public ProtonClientOptions addEnabledCipherSuite(string suite) { 228 // super.addEnabledCipherSuite(suite); 229 // return this; 230 //} 231 232 //override 233 //public ProtonClientOptions addCrlPath(String crlPath) { 234 // super.addCrlPath(crlPath); 235 // return this; 236 //} 237 // 238 //override 239 //public ProtonClientOptions addCrlValue(Buffer crlValue) { 240 // super.addCrlValue(crlValue); 241 // return this; 242 //} 243 244 override 245 public ProtonClientOptions setTrustAll(bool trustAll) { 246 super.setTrustAll(trustAll); 247 return this; 248 } 249 250 override 251 public ProtonClientOptions setConnectTimeout(Duration connectTimeout) { 252 super.setConnectTimeout(connectTimeout); 253 return this; 254 } 255 256 override 257 public ProtonClientOptions setReconnectAttempts(int attempts) { 258 super.setReconnectAttempts(attempts); 259 return this; 260 } 261 262 override 263 public ProtonClientOptions setReconnectInterval(Duration interval) { 264 super.setReconnectInterval(interval); 265 return this; 266 } 267 268 override size_t toHash() @safe nothrow 269 { 270 int prime = 31; 271 272 int result = cast(int)super.toHash(); 273 result = prime * result + cast(int)enabledSaslMechanisms.toHash(); 274 result = prime * result + this.heartbeat; 275 result = prime * result + this.maxFrameSize; 276 result = prime * result + (this.virtualHost !is null ? cast(int)this.virtualHost.hashOf : 0); 277 result = prime * result + (this.sniServerName !is null ? cast(int)this.sniServerName.hashOf : 0); 278 279 return cast(size_t)result; 280 } 281 282 override 283 public bool opEquals (Object obj) { 284 if (this == obj) { 285 return true; 286 } 287 288 if (obj is null){ 289 return false; 290 } 291 292 //if (!super.equals(obj)) { 293 // return false; 294 //} 295 296 ProtonClientOptions other = cast(ProtonClientOptions) obj; 297 if ((enabledSaslMechanisms != other.enabledSaslMechanisms)){ 298 return false; 299 } 300 if (this.heartbeat != other.heartbeat) { 301 return false; 302 } 303 if (this.maxFrameSize != other.maxFrameSize) { 304 return false; 305 } 306 if ((this.virtualHost != other.virtualHost)) { 307 return false; 308 } 309 if ((this.sniServerName != other.sniServerName)) { 310 return false; 311 } 312 313 return true; 314 } 315 316 override 317 public ProtonClientOptions setUseAlpn(bool useAlpn) { 318 throw new UnsupportedOperationException(); 319 } 320 321 //override 322 //public ProtonClientOptions addEnabledSecureTransportProtocol(String protocol) { 323 // super.addEnabledSecureTransportProtocol(protocol); 324 // return this; 325 //} 326 327 override 328 public ProtonClientOptions setHostnameVerificationAlgorithm(string hostnameVerificationAlgorithm) { 329 super.setHostnameVerificationAlgorithm(hostnameVerificationAlgorithm); 330 return this; 331 } 332 333 //override 334 //public ProtonClientOptions setKeyCertOptions(KeyCertOptions options) { 335 // super.setKeyCertOptions(options); 336 // return this; 337 //} 338 339 override 340 public ProtonClientOptions setLogActivity(bool logEnabled) { 341 super.setLogActivity(logEnabled); 342 return this; 343 } 344 345 override 346 public ProtonClientOptions setMetricsName(string metricsName) { 347 super.setMetricsName(metricsName); 348 return this; 349 } 350 351 override 352 public ProtonClientOptions setProxyOptions(ProxyOptions proxyOptions) { 353 super.setProxyOptions(proxyOptions); 354 return this; 355 } 356 357 //override 358 //public ProtonClientOptions setTrustOptions(TrustOptions options) { 359 // super.setTrustOptions(options); 360 // return this; 361 //} 362 363 //override 364 //public ProtonClientOptions setJdkSslEngineOptions(JdkSSLEngineOptions sslEngineOptions) { 365 // super.setJdkSslEngineOptions(sslEngineOptions); 366 // return this; 367 //} 368 369 override 370 public ProtonClientOptions setOpenSslEngineOptions(OpenSSLEngineOptions sslEngineOptions) { 371 super.setOpenSslEngineOptions(sslEngineOptions); 372 return this; 373 } 374 375 //override 376 //public ProtonClientOptions setSslEngineOptions(SSLEngineOptions sslEngineOptions) { 377 // super.setSslEngineOptions(sslEngineOptions); 378 // return this; 379 //} 380 381 override 382 public ProtonClientOptions setSslHandshakeTimeout(Duration sslHandshakeTimeout) { 383 super.setSslHandshakeTimeout(sslHandshakeTimeout); 384 return this; 385 } 386 387 //override 388 //public ProtonClientOptions setSslHandshakeTimeoutUnit(TimeUnit sslHandshakeTimeoutUnit) { 389 // super.setSslHandshakeTimeoutUnit(sslHandshakeTimeoutUnit); 390 // return this; 391 //} 392 393 override 394 public ProtonClientOptions setLocalAddress(string localAddress) { 395 super.setLocalAddress(localAddress); 396 return this; 397 } 398 399 override 400 public ProtonClientOptions setReusePort(bool reusePort) { 401 super.setReusePort(reusePort); 402 return this; 403 } 404 405 override 406 public ProtonClientOptions setTcpCork(bool tcpCork) { 407 super.setTcpCork(tcpCork); 408 return this; 409 } 410 411 override 412 public ProtonClientOptions setTcpFastOpen(bool tcpFastOpen) { 413 super.setTcpFastOpen(tcpFastOpen); 414 return this; 415 } 416 417 override 418 public ProtonClientOptions setTcpQuickAck(bool tcpQuickAck) { 419 super.setTcpQuickAck(tcpQuickAck); 420 return this; 421 } 422 423 //override 424 //public ProtonClientOptions removeEnabledSecureTransportProtocol(String protocol) { 425 // super.removeEnabledSecureTransportProtocol(protocol); 426 // return this; 427 //} 428 429 //override 430 //public ProtonClientOptions setEnabledSecureTransportProtocols(Set<String> enabledSecureTransportProtocols) { 431 // super.setEnabledSecureTransportProtocols(enabledSecureTransportProtocols); 432 // return this; 433 //} 434 435 /** 436 * Override the hostname value used in the connection AMQP Open frame and TLS SNI server name (if TLS is in use). 437 * By default, the hostname specified in {@link ProtonClient#connect} will be used for both, with SNI performed 438 * implicit where a FQDN was specified. 439 * 440 * The SNI server name can also be overridden explicitly using {@link #setSniServerName(String)}. 441 * 442 * @param virtualHost hostname to set 443 * @return current ProtonClientOptions instance 444 */ 445 public ProtonClientOptions setVirtualHost(string virtualHost) { 446 this.virtualHost = virtualHost; 447 return this; 448 } 449 450 /** 451 * Get the virtual host name override for the connection AMQP Open frame and TLS SNI server name (if TLS is in use) 452 * set by {@link #setVirtualHost(String)}. 453 * 454 * @return the hostname 455 */ 456 public string getVirtualHost() { 457 return this.virtualHost; 458 } 459 460 /** 461 * Explicitly override the hostname to use for the TLS SNI server name. 462 * 463 * If neither the {@link ProtonClientOptions#setVirtualHost(String) virtualhost} or SNI server name is explicitly 464 * overridden, the hostname specified in {@link ProtonClient#connect} will be used, with SNI performed implicitly 465 * where a FQDN was specified. 466 * 467 * This method should typically only be needed to set different values for the [virtual] hostname and SNI server name. 468 * 469 * @param sniServerName hostname to set as SNI server name 470 * @return current ProtonClientOptions instance 471 */ 472 public ProtonClientOptions setSniServerName(string sniServerName) { 473 this.sniServerName = sniServerName; 474 return this; 475 } 476 477 /** 478 * Get the hostname override for TLS SNI Server Name set by {@link #setSniServerName(String)}. 479 * 480 * @return the hostname 481 */ 482 public string getSniServerName() { 483 return this.sniServerName; 484 } 485 486 /** 487 * Set the heartbeat (in milliseconds) as maximum delay between sending frames for the remote peers. 488 * If no frames are received within 2*heartbeat, the connection is closed 489 * 490 * @param heartbeat hearthbeat maximum delay 491 * @return current ProtonClientOptions instance 492 */ 493 public ProtonClientOptions setHeartbeat(int heartbeat) { 494 this.heartbeat = heartbeat; 495 return this; 496 } 497 498 /** 499 * Return the heartbeat (in milliseconds) as maximum delay between sending frames for the remote peers. 500 * 501 * @return hearthbeat maximum delay 502 */ 503 public int getHeartbeat() { 504 return this.heartbeat; 505 } 506 507 /** 508 * Sets the maximum frame size for the connection. 509 * <p> 510 * If this property is not set explicitly, a reasonable default value is used. 511 * <p> 512 * Setting this property to a negative value will result in no maximum frame size being announced at all. 513 * 514 * @param maxFrameSize The frame size in bytes. 515 * @return This instance for setter chaining. 516 */ 517 public ProtonClientOptions setMaxFrameSize(int maxFrameSize) { 518 if (maxFrameSize < 0) { 519 this.maxFrameSize = -1; 520 } else { 521 this.maxFrameSize = maxFrameSize; 522 } 523 return this; 524 } 525 526 /** 527 * Gets the maximum frame size for the connection. 528 * <p> 529 * If this property is not set explicitly, a reasonable default value is used. 530 * 531 * @return The frame size in bytes or -1 if no limit is set. 532 */ 533 public int getMaxFrameSize() { 534 return maxFrameSize; 535 } 536 }