1 // pubsubplus-go-client 2 // 3 // Copyright 2021-2025 Solace Corporation. All rights reserved. 4 // 5 // Licensed under the Apache License, Version 2.0 (the "License"); 6 // you may not use this file except in compliance with the License. 7 // You may obtain a copy of the License at 8 // 9 // http://www.apache.org/licenses/LICENSE-2.0 10 // 11 // Unless required by applicable law or agreed to in writing, software 12 // distributed under the License is distributed on an "AS IS" BASIS, 13 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 // See the License for the specific language governing permissions and 15 // limitations under the License. 16 17 package config 18 19 import "fmt" 20 21 // ServicePropertiesConfigurationProvider represents a generic configuration provider that can be used 22 // to provide configurations to MessagingServiceBuilders. 23 type ServicePropertiesConfigurationProvider interface { 24 // GetConfiguration retrieves the configuration provided by the provider 25 // in the form of a ServicePropertyMap. 26 GetConfiguration() ServicePropertyMap 27 } 28 29 // ServiceProperty is a key for a property. 30 type ServiceProperty string 31 32 // ServicePropertyMap is a map of SolaceServicePropery keys to values. 33 type ServicePropertyMap map[ServiceProperty]interface{} 34 35 // GetConfiguration returns a copy of the servicePropertyMap. 36 func (servicePropertyMap ServicePropertyMap) GetConfiguration() ServicePropertyMap { 37 ret := make(ServicePropertyMap) 38 for key, value := range servicePropertyMap { 39 ret[key] = value 40 } 41 return ret 42 } 43 44 // MarshalJSON implements the json.Marshaler interface. 45 func (servicePropertyMap ServicePropertyMap) MarshalJSON() ([]byte, error) { 46 m := make(map[string]interface{}) 47 for k, v := range servicePropertyMap { 48 m[string(k)] = v 49 } 50 return nestJSON(m) 51 } 52 53 // UnmarshalJSON implements the json.Unmarshaler interface. 54 func (servicePropertyMap ServicePropertyMap) UnmarshalJSON(b []byte) error { 55 m, err := flattenJSON(b) 56 if err != nil { 57 return err 58 } 59 for key, val := range m { 60 servicePropertyMap[ServiceProperty(key)] = val 61 } 62 return nil 63 } 64 65 const obfuscation = "******" 66 67 var obfuscatedProperties = []ServiceProperty{ 68 AuthenticationPropertySchemeBasicPassword, 69 AuthenticationPropertySchemeClientCertPrivateKeyFilePassword, 70 AuthenticationPropertySchemeOAuth2AccessToken, 71 AuthenticationPropertySchemeOAuth2OIDCIDToken, 72 } 73 74 // String implements the fmt.Stringer interface. 75 func (servicePropertyMap ServicePropertyMap) String() string { 76 toPrint := make(map[string]interface{}) 77 for key, value := range servicePropertyMap { 78 for _, property := range obfuscatedProperties { 79 if key == property { 80 value = obfuscation 81 break 82 } 83 } 84 toPrint[string(key)] = value 85 } 86 return fmt.Sprint(toPrint) 87 } 88 89 const ( 90 /* AuthenticationProperties */ 91 92 // AuthenticationPropertyScheme defines the keys for the authentication scheme type. 93 // Possible values for configuration of authentication scheme are defined in 94 // the AuthenticationScheme type, which has the following possible strings, 95 // accessible by constants 96 // config.AuthenticationSchemeBasic | "AUTHENTICATION_SCHEME_BASIC" 97 // config.AuthenticationSchemeClientCertificate | "AUTHENTICATION_SCHEME_CLIENT_CERTIFICATE" 98 // config.AuthenticationSchemeKerberos | "AUTHENTICATION_SCHEME_GSS_KRB" 99 // config.AuthenticationSchemeOAuth2 | "AUTHENTICATION_SCHEME_OAUTH2" 100 AuthenticationPropertyScheme ServiceProperty = "solace.messaging.authentication.scheme" 101 102 // AuthenticationPropertySchemeBasicUserName specifies the username for basic authentication. 103 AuthenticationPropertySchemeBasicUserName ServiceProperty = "solace.messaging.authentication.basic.username" 104 105 // AuthenticationPropertySchemeBasicPassword specifies password for basic authentication. 106 AuthenticationPropertySchemeBasicPassword ServiceProperty = "solace.messaging.authentication.basic.password" 107 108 // AuthenticationPropertySchemeSSLClientCertFile specifies the client certificate file used for Secure Socket Layer (SSL). 109 AuthenticationPropertySchemeSSLClientCertFile ServiceProperty = "solace.messaging.authentication.client-cert.file" 110 111 // AuthenticationPropertySchemeSSLClientPrivateKeyFile specifies the client private key file. 112 AuthenticationPropertySchemeSSLClientPrivateKeyFile ServiceProperty = "solace.messaging.authentication.client-cert.private-key-file" 113 114 // AuthenticationPropertySchemeClientCertPrivateKeyFilePassword specifies the private key password for client certificate authentication. 115 AuthenticationPropertySchemeClientCertPrivateKeyFilePassword ServiceProperty = "solace.messaging.authentication.client-cert.private-key-password" 116 117 // AuthenticationPropertySchemeClientCertUserName specifies the username to use when connecting with client certificate authentication. 118 AuthenticationPropertySchemeClientCertUserName ServiceProperty = "solace.messaging.authentication.client-cert.username" 119 120 // AuthenticationPropertySchemeKerberosInstanceName specifies the first part of Kerberos Service Principal Name (SPN) of the 121 // form ServiceName/Hostname\@REALM (for Windows) or Host Based Service of the form 122 // ServiceName\@Hostname (for Linux and SunOS). 123 AuthenticationPropertySchemeKerberosInstanceName ServiceProperty = "solace.messaging.authentication.kerberos.instance-name" 124 125 // AuthenticationPropertySchemeKerberosUserName allows configuration of the client username to use when connecting to the broker. 126 // It is only used if Kerberos is the chosen authentication strategy. 127 // This property is ignored by default and only needed if the 'allow-api-provided-username' is enabled in the 128 // configuration of the message-vpn in the broker. This property is not recommended for use. 129 AuthenticationPropertySchemeKerberosUserName ServiceProperty = "solace.messaging.authentication.kerberos.username" 130 131 // AuthenticationPropertySchemeOAuth2AccessToken specifies an access token for OAuth 2.0 token-based authentication. 132 AuthenticationPropertySchemeOAuth2AccessToken ServiceProperty = "solace.messaging.authentication.oauth2.access-token" 133 134 // AuthenticationPropertySchemeOAuth2IssuerIdentifier defines an optional issuer identifier for OAuth 2.0 token-based authentication. 135 AuthenticationPropertySchemeOAuth2IssuerIdentifier ServiceProperty = "solace.messaging.authentication.oauth2.issuer-identifier" 136 137 // AuthenticationPropertySchemeOAuth2OIDCIDToken specifies the ID token for Open ID Connect token-based authentication. 138 AuthenticationPropertySchemeOAuth2OIDCIDToken ServiceProperty = "solace.messaging.authentication.oauth2.oidc-id-token" 139 140 /* ClientProperties */ 141 142 // ClientPropertyName sets the client name used when connecting to the broker. This field is set on: 143 // MessagingServiceBuilder::BuildWithApplicationID 144 ClientPropertyName ServiceProperty = "solace.messaging.client.name" 145 146 // ClientPropertyApplicationDescription can be set to set the application description viewable on a broker. 147 ClientPropertyApplicationDescription ServiceProperty = "solace.messaging.client.application-description" 148 149 /* Service Properties */ 150 151 // ServicePropertyVPNName name of the Message VPN to attempt to join when connecting to a broker. Default 152 // value is "" when this property is not specified. When using default values, the client attempts to join 153 // the default Message VPN for the client. This parameter is only valid for sessions operating 154 // in client mode. If specified, it must be a maximum of 32 bytes in length when encoded as 155 // UTF-8. 156 ServicePropertyVPNName ServiceProperty = "solace.messaging.service.vpn-name" 157 158 // ServicePropertyGenerateSenderID specifies whether the client name should be included in the SenderID 159 // message-header parameter. Setting this property is optional. 160 ServicePropertyGenerateSenderID ServiceProperty = "solace.messaging.service.generate-sender-id" 161 162 // ServicePropertyGenerateSendTimestamps specifies whether timestamps should be generated for outbound messages. 163 ServicePropertyGenerateSendTimestamps ServiceProperty = "solace.messaging.service.generate-send-timestamps" 164 165 // ServicePropertyGenerateReceiveTimestamps specifies whether timestamps should be generated on inbound messages. 166 ServicePropertyGenerateReceiveTimestamps ServiceProperty = "solace.messaging.service.generate-receive-timestamps" 167 168 // ServicePropertyReceiverDirectSubscriptionReapply enables reapplying a subscription when a session reconnection occurs 169 // for a direct message receiver the value type is boolean. 170 ServicePropertyReceiverDirectSubscriptionReapply ServiceProperty = "solace.messaging.service.receivers.direct.subscription.reapply" 171 172 // ServicePropertyProvisionTimeoutMs specifies the timeout for provision and deprovision operations, in milliseconds. 173 ServicePropertyProvisionTimeoutMs ServiceProperty = "solace.messaging.management.endpoint.provision-timeout" 174 175 // ServicePropertyPayloadCompressionLevel Enables (1-9) or disables (0, the default) outgoing payload compression. 176 // Incoming messages with payloads compressed this way are automatically and unconditionally decompressed before delivery to user code independently from this setting. 177 // 178 // Value meanings: 179 // 0 - disable outgoing payload compression (the default) 180 // 1 - least amount of compression and the fastest data throughput 181 // 9 - most compression and slowest data throughput 182 // 183 // The payload compression value should be adjusted according to particular network requirements and the performance required. 184 // 185 // Note: Please ensure that both publishers and consumers are updated to support payload compression before enabling this property. 186 // In the case where a publisher compresses the payload and a consumer does not support payload decompression, the untouched compressed message 187 // will be received which can lead to potential issues within the consuming application. Therefore, the consumer would either need to update 188 // to a newer version of the API or the user would need to handle the decompression on the receiving side in their own application. 189 // If a publishing application is able to send a compressed message, the broker's treatment of message-type will vary depending on the protocol. 190 // Lastly, do not enable payload compression when sending cache-requests. Applications that are sending cache-requests and receiving cache-responses 191 // may end up getting compressed messages that they are not able to handle. 192 // 193 // Default: 0 (disabled) 194 // 195 ServicePropertyPayloadCompressionLevel ServiceProperty = "solace.messaging.service.payload-compression-level" 196 197 /* TransportLayerProperties */ 198 199 // TransportLayerPropertyHost is IPv4 or IPv6 address or host name of the broker to which to connect. 200 // Multiple entries are permitted when each address is separated by a comma. 201 // The entry for the HOST property should provide a protocol, host and port. 202 TransportLayerPropertyHost ServiceProperty = "solace.messaging.transport.host" 203 204 // TransportLayerPropertyConnectionAttemptsTimeout is the timeout period for a connect operation to a given host. 205 TransportLayerPropertyConnectionAttemptsTimeout ServiceProperty = "solace.messaging.transport.connection-attempts-timeout" 206 207 // TransportLayerPropertyConnectionRetries is how many times to try connecting to a broker during connection setup. 208 TransportLayerPropertyConnectionRetries ServiceProperty = "solace.messaging.transport.connection-retries" 209 210 // TransportLayerPropertyConnectionRetriesPerHost defines how many connection or reconnection attempts are made to a 211 // single host before moving to the next host in the list, when using a host list. 212 TransportLayerPropertyConnectionRetriesPerHost ServiceProperty = "solace.messaging.transport.connection.retries-per-host" 213 214 // TransportLayerPropertyReconnectionAttempts is the number reconnection attempts to the broker (or list of brokers) after 215 // a connected MessagingService goes down. 216 // Zero means no automatic reconnection attempts, while a -1 means attempt to reconnect forever. The default valid range is greather than or equal to -1. 217 // When using a host list, each time the API works through the host list without establishing a connection is considered a 218 // reconnection retry. Each reconnection retry begins with the first host listed. After each unsuccessful attempt to reconnect 219 // to a host, the API waits for the amount of time set for TransportLayerPropertyReconnectionAttemptsWaitInterval before attempting another 220 // connection to a broker. The number of times attempted to connect to one broker before moving on to the 221 // next listed host is determined by the value set for TransportLayerPropertyConnectionRetriesPerHost. 222 TransportLayerPropertyReconnectionAttempts ServiceProperty = "solace.messaging.transport.reconnection-attempts" 223 224 // TransportLayerPropertyReconnectionAttemptsWaitInterval sets how much time (in milliseconds) to wait between each connection or reconnection attempt to the configured host. 225 // If a connection or reconnection attempt to the configured host (which may be a list) is not successful, the API waits for 226 // the amount of time set for ReconnectionAttemptsWaitInterval, and then makes another connection or reconnection attempt. 227 // The valid range is greater than or equal to zero. 228 TransportLayerPropertyReconnectionAttemptsWaitInterval ServiceProperty = "solace.messaging.transport.reconnection-attempts-wait-interval" 229 230 // TransportLayerPropertyKeepAliveInterval is the amount of time (in milliseconds) to wait between sending out Keep-Alive messages. 231 TransportLayerPropertyKeepAliveInterval ServiceProperty = "solace.messaging.transport.keep-alive-interval" 232 233 // TransportLayerPropertyKeepAliveWithoutResponseLimit is the maximum number of consecutive keep-alive messages that can be sent 234 // without receiving a response before the connection is closed by the API. 235 TransportLayerPropertyKeepAliveWithoutResponseLimit ServiceProperty = "solace.messaging.transport.keep-alive-without-response-limit" 236 237 // TransportLayerPropertySocketOutputBufferSize is the value for the socket send buffer size (in bytes). 238 // Zero indicates to not set the value and leave the buffer size set at operating system default. The valid range is zero or 239 // a value greater than or equal to 1024. 240 TransportLayerPropertySocketOutputBufferSize ServiceProperty = "solace.messaging.transport.socket.output-buffer-size" 241 242 // TransportLayerPropertySocketInputBufferSize is the value for socket receive buffer size (in bytes). 243 // Zero indicates to not set the value and leave the buffer size set at operating system default. The valid range is zero or 244 // a value greater than or equal to 1024. 245 TransportLayerPropertySocketInputBufferSize ServiceProperty = "solace.messaging.transport.socket.input-buffer-size" 246 247 // TransportLayerPropertySocketTCPOptionNoDelay is a boolean value to enable TCP no delay. 248 TransportLayerPropertySocketTCPOptionNoDelay ServiceProperty = "solace.messaging.transport.socket.tcp-option-no-delay" 249 250 // TransportLayerPropertyCompressionLevel enables messages to be compressed with ZLIB before transmission and decompressed on receive. 251 // This property should preferably be set by MessagingServiceClientBuilder.WithCompressionLevel function. 252 // The valid range is zero (off) or a value from 1 to 9, where 1 is less compression (fastest) and 9 is most compression (slowest). 253 // Note: If no port is specified in TransportLayerPropertyHost, the API automatically connects to either the default 254 // non-compressed listen port (55555) or default compressed listen port (55003) based on the specified 255 // CompressionLevel. If a port is specified in TransportLayerPropertyHost, you must specify the non-compressed listen port if you are not 256 // using compression (compression level 0), or the compressed listen port if using compression (compression levels 1 to 9). 257 TransportLayerPropertyCompressionLevel ServiceProperty = "solace.messaging.transport.compression-level" 258 259 /* TransportLayerSecurityProperty */ 260 261 // TransportLayerSecurityPropertyCertValidated is a boolean property that will specify if server certificates should be validated. 262 // Setting this property to false exposes a client and data being sent to a higher security risk. 263 TransportLayerSecurityPropertyCertValidated ServiceProperty = "solace.messaging.tls.cert-validated" 264 265 // TransportLayerSecurityPropertyCertRejectExpired is a boolean property that specifies if server certificate's expiration date should be validated. 266 // Setting this property to false exposes a client and data being sent to a higher security risk. 267 TransportLayerSecurityPropertyCertRejectExpired ServiceProperty = "solace.messaging.tls.cert-reject-expired" 268 269 // TransportLayerSecurityPropertyCertValidateServername is a boolean property that enables or disables server certificate hostname or 270 // IP address validation. When enabled, the certificate received from the broker must match 271 // the host used to connect. 272 TransportLayerSecurityPropertyCertValidateServername ServiceProperty = "solace.messaging.tls.cert-validate-servername" 273 274 // TransportLayerSecurityPropertyExcludedProtocols is deprecated, use TransportLayerSecurityPropertyMinimumProtocol and 275 // TransportLayerSecurityPropertyMaximumProtocol instead. 276 TransportLayerSecurityPropertyExcludedProtocols ServiceProperty = "solace.messaging.tls.excluded-protocols" 277 278 // TransportLayerSecurityPropertyMinimumProtocol is the oldest TLS protocol version accepted. 279 // Valid protocols are 'SSLv3', 'TLSv1', 'TLSv1.1', 'TLSv1.2', and 'TLSv1.3' 280 // Defaults to 'TLSv1.2'. 281 TransportLayerSecurityPropertyMinimumProtocol ServiceProperty = "solace.messaging.tls.minimum-protocol" 282 283 // TransportLayerSecurityPropertyMaximumProtocol is the newest TLS protocol version accepted. 284 // Valid protocols are 'SSLv3', 'TLSv1', 'TLSv1.1', 'TLSv1.2', and 'TLSv1.3' 285 // Defaults to empty, meaning highest supported version. 286 TransportLayerSecurityPropertyMaximumProtocol ServiceProperty = "solace.messaging.tls.maximum-protocol" 287 288 // TransportLayerSecurityPropertyProtocolDowngradeTo specifies a transport protocol that the SSL connection is downgraded to after 289 // client authentication. Allowed transport protocol is 'PLAIN_TEXT'. 290 // May be combined with non-zero compression level to achieve compression without encryption. 291 TransportLayerSecurityPropertyProtocolDowngradeTo ServiceProperty = "solace.messaging.tls.protocol-downgrade-to" 292 293 // TransportLayerSecurityPropertyCipherSuites specifies a comma-separated list of cipher suites to use. 294 // Allowed cipher suites are as follows: 295 // +-----------------+-------------------------------+--------------------+ 296 // | 'AES256-SHA' | 'ECDHE-RSA-AES256-SHA' | 'AES256-GCM-SHA384'| 297 // +-----------------+-------------------------------+--------------------+ 298 // | 'AES256-SHA256' | 'ECDHE-RSA-AES256-GCM-SHA384' | 'AES128-SHA256' | 299 // +-----------------+-------------------------------+--------------------+ 300 // | 'DES-CBC3-SHA' | 'ECDHE-RSA-DES-CBC3-SHA' | | 301 // +-----------------+-------------------------------+--------------------+ 302 // | 'RC4-SHA' | 'ECDHE-RSA-AES256-SHA384' | 'AES128 | 303 // +-----------------+-------------------------------+--------------------+ 304 // | 'ECDHE-RSA-AES128-SHA256' | 'AES128-GCM-SHA256'| 305 // +-----------------+-------------------------------+--------------------+ 306 // | 'RC4-MD5' | 'ECDHE-RSA-AES128-GCM-SHA256' | | 307 // +----------------------------------------+-----------------------------+ 308 // | 'TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384'| 'ECDHE-RSA-AES128-SHA' | 309 // +----------------------------------------+-----------------------------+ 310 // | 'TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384'| | 311 // +----------------------------------------+-----------------------------+ 312 // | 'TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA' | | 313 // +----------------------------------------+-----------------------------+ 314 // | 'TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA' | | 315 // +----------------------------------------+-----------------------------+ 316 // | 'TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256'| | 317 // +----------------------------------------+-----------------------------+ 318 // | 'TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA' | | 319 // +----------------------------------------+-----------------------------+ 320 // | 'TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256'| | 321 // +-----------------------------------+----------------------------------+ 322 // | 'TLS_RSA_WITH_AES_128_GCM_SHA256' | | 323 // +-----------------------------------+----------------------------------+ 324 // | 'TLS_RSA_WITH_AES_128_CBC_SHA256' |'TLS_RSA_WITH_AES_256_GCM_SHA384' | 325 // +-----------------------------------+----------------------------------+ 326 // | 'TLS_RSA_WITH_AES_256_CBC_SHA256' | 'TLS_RSA_WITH_AES_256_CBC_SHA' | 327 // +-----------------------------------+----------------------------------+ 328 // | 'SSL_RSA_WITH_3DES_EDE_CBC_SHA | 'TLS_RSA_WITH_AES_128_CBC_SHA' | 329 // +-----------------------------------+----------------------------------+ 330 // | 'SSL_RSA_WITH_RC4_128_SHA' | 'SSL_RSA_WITH_RC4_128_MD5' | 331 // +-----------------------------------+----------------------------------+ 332 TransportLayerSecurityPropertyCipherSuites ServiceProperty = "solace.messaging.tls.cipher-suites" 333 334 // TransportLayerSecurityPropertyTrustStorePath specifies the path of the directory where trusted certificates are found 335 // The maximum depth for the certificate chain verification is 3. 336 TransportLayerSecurityPropertyTrustStorePath ServiceProperty = "solace.messaging.tls.trust-store-path" 337 338 // TransportLayerSecurityPropertyTrustedCommonNameList is provided for legacy installations and is not recommended as part of our best practices. 339 // The API performs Subject Alternative Name (SAN) verification when the SAN is found in the server certificate, 340 // which is generally the best practice for a secure connection. 341 // This property specifies a comma-separated list of acceptable common names in certificate validation. 342 // The number of common names specified by an application is limited to 16. Leading and trailing whitespaces are considered 343 // to be part of the common names and are not ignored. 344 // If the application does not provide any common names, there is no common-name verification. 345 // An empty string specifies that no common-name verification is required. 346 TransportLayerSecurityPropertyTrustedCommonNameList ServiceProperty = "solace.messaging.tls.trusted-common-name-list" 347 ) 348