1 // pubsubplus-go-client 2 // 3 // Copyright 2021-2024 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 /* TransportLayerProperties */ 173 174 // TransportLayerPropertyHost is IPv4 or IPv6 address or host name of the broker to which to connect. 175 // Multiple entries are permitted when each address is separated by a comma. 176 // The entry for the HOST property should provide a protocol, host and port. 177 TransportLayerPropertyHost ServiceProperty = "solace.messaging.transport.host" 178 179 // TransportLayerPropertyConnectionAttemptsTimeout is the timeout period for a connect operation to a given host. 180 TransportLayerPropertyConnectionAttemptsTimeout ServiceProperty = "solace.messaging.transport.connection-attempts-timeout" 181 182 // TransportLayerPropertyConnectionRetries is how many times to try connecting to a broker during connection setup. 183 TransportLayerPropertyConnectionRetries ServiceProperty = "solace.messaging.transport.connection-retries" 184 185 // TransportLayerPropertyConnectionRetriesPerHost defines how many connection or reconnection attempts are made to a 186 // single host before moving to the next host in the list, when using a host list. 187 TransportLayerPropertyConnectionRetriesPerHost ServiceProperty = "solace.messaging.transport.connection.retries-per-host" 188 189 // TransportLayerPropertyReconnectionAttempts is the number reconnection attempts to the broker (or list of brokers) after 190 // a connected MessagingService goes down. 191 // 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. 192 // When using a host list, each time the API works through the host list without establishing a connection is considered a 193 // reconnection retry. Each reconnection retry begins with the first host listed. After each unsuccessful attempt to reconnect 194 // to a host, the API waits for the amount of time set for TransportLayerPropertyReconnectionAttemptsWaitInterval before attempting another 195 // connection to a broker. The number of times attempted to connect to one broker before moving on to the 196 // next listed host is determined by the value set for TransportLayerPropertyConnectionRetriesPerHost. 197 TransportLayerPropertyReconnectionAttempts ServiceProperty = "solace.messaging.transport.reconnection-attempts" 198 199 // TransportLayerPropertyReconnectionAttemptsWaitInterval sets how much time (in milliseconds) to wait between each connection or reconnection attempt to the configured host. 200 // If a connection or reconnection attempt to the configured host (which may be a list) is not successful, the API waits for 201 // the amount of time set for ReconnectionAttemptsWaitInterval, and then makes another connection or reconnection attempt. 202 // The valid range is greater than or equal to zero. 203 TransportLayerPropertyReconnectionAttemptsWaitInterval ServiceProperty = "solace.messaging.transport.reconnection-attempts-wait-interval" 204 205 // TransportLayerPropertyKeepAliveInterval is the amount of time (in milliseconds) to wait between sending out Keep-Alive messages. 206 TransportLayerPropertyKeepAliveInterval ServiceProperty = "solace.messaging.transport.keep-alive-interval" 207 208 // TransportLayerPropertyKeepAliveWithoutResponseLimit is the maximum number of consecutive keep-alive messages that can be sent 209 // without receiving a response before the connection is closed by the API. 210 TransportLayerPropertyKeepAliveWithoutResponseLimit ServiceProperty = "solace.messaging.transport.keep-alive-without-response-limit" 211 212 // TransportLayerPropertySocketOutputBufferSize is the value for the socket send buffer size (in bytes). 213 // Zero indicates to not set the value and leave the buffer size set at operating system default. The valid range is zero or 214 // a value greater than or equal to 1024. 215 TransportLayerPropertySocketOutputBufferSize ServiceProperty = "solace.messaging.transport.socket.output-buffer-size" 216 217 // TransportLayerPropertySocketInputBufferSize is the value for socket receive buffer size (in bytes). 218 // Zero indicates to not set the value and leave the buffer size set at operating system default. The valid range is zero or 219 // a value greater than or equal to 1024. 220 TransportLayerPropertySocketInputBufferSize ServiceProperty = "solace.messaging.transport.socket.input-buffer-size" 221 222 // TransportLayerPropertySocketTCPOptionNoDelay is a boolean value to enable TCP no delay. 223 TransportLayerPropertySocketTCPOptionNoDelay ServiceProperty = "solace.messaging.transport.socket.tcp-option-no-delay" 224 225 // TransportLayerPropertyCompressionLevel enables messages to be compressed with ZLIB before transmission and decompressed on receive. 226 // This property should preferably be set by MessagingServiceClientBuilder.WithCompressionLevel function. 227 // 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). 228 // Note: If no port is specified in TransportLayerPropertyHost, the API automatically connects to either the default 229 // non-compressed listen port (55555) or default compressed listen port (55003) based on the specified 230 // CompressionLevel. If a port is specified in TransportLayerPropertyHost, you must specify the non-compressed listen port if you are not 231 // using compression (compression level 0), or the compressed listen port if using compression (compression levels 1 to 9). 232 TransportLayerPropertyCompressionLevel ServiceProperty = "solace.messaging.transport.compression-level" 233 234 /* TransportLayerSecurityProperty */ 235 236 // TransportLayerSecurityPropertyCertValidated is a boolean property that will specify if server certificates should be validated. 237 // Setting this property to false exposes a client and data being sent to a higher security risk. 238 TransportLayerSecurityPropertyCertValidated ServiceProperty = "solace.messaging.tls.cert-validated" 239 240 // TransportLayerSecurityPropertyCertRejectExpired is a boolean property that specifies if server certificate's expiration date should be validated. 241 // Setting this property to false exposes a client and data being sent to a higher security risk. 242 TransportLayerSecurityPropertyCertRejectExpired ServiceProperty = "solace.messaging.tls.cert-reject-expired" 243 244 // TransportLayerSecurityPropertyCertValidateServername is a boolean property that enables or disables server certificate hostname or 245 // IP address validation. When enabled, the certificate received from the broker must match 246 // the host used to connect. 247 TransportLayerSecurityPropertyCertValidateServername ServiceProperty = "solace.messaging.tls.cert-validate-servername" 248 249 // TransportLayerSecurityPropertyExcludedProtocols is a comma-separated list specifying SSL protocols to exclude. 250 // Valid protocols are 'SSLv3', 'TLSv1', 'TLSv1.1' and 'TLSv1.2' 251 TransportLayerSecurityPropertyExcludedProtocols ServiceProperty = "solace.messaging.tls.excluded-protocols" 252 253 // TransportLayerSecurityPropertyProtocolDowngradeTo specifies a transport protocol that the SSL connection is downgraded to after 254 // client authentication. Allowed transport protocol is 'PLAIN_TEXT'. 255 // May be combined with non-zero compression level to achieve compression without encryption. 256 TransportLayerSecurityPropertyProtocolDowngradeTo ServiceProperty = "solace.messaging.tls.protocol-downgrade-to" 257 258 // TransportLayerSecurityPropertyCipherSuites specifies a comma-separated list of cipher suites to use. 259 // Allowed cipher suites are as follows: 260 // +-----------------+-------------------------------+--------------------+ 261 // | 'AES256-SHA' | 'ECDHE-RSA-AES256-SHA' | 'AES256-GCM-SHA384'| 262 // +-----------------+-------------------------------+--------------------+ 263 // | 'AES256-SHA256' | 'ECDHE-RSA-AES256-GCM-SHA384' | 'AES128-SHA256' | 264 // +-----------------+-------------------------------+--------------------+ 265 // | 'DES-CBC3-SHA' | 'ECDHE-RSA-DES-CBC3-SHA' | | 266 // +-----------------+-------------------------------+--------------------+ 267 // | 'RC4-SHA' | 'ECDHE-RSA-AES256-SHA384' | 'AES128 | 268 // +-----------------+-------------------------------+--------------------+ 269 // | 'ECDHE-RSA-AES128-SHA256' | 'AES128-GCM-SHA256'| 270 // +-----------------+-------------------------------+--------------------+ 271 // | 'RC4-MD5' | 'ECDHE-RSA-AES128-GCM-SHA256' | | 272 // +----------------------------------------+-----------------------------+ 273 // | 'TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384'| 'ECDHE-RSA-AES128-SHA' | 274 // +----------------------------------------+-----------------------------+ 275 // | 'TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384'| | 276 // +----------------------------------------+-----------------------------+ 277 // | 'TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA' | | 278 // +----------------------------------------+-----------------------------+ 279 // | 'TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA' | | 280 // +----------------------------------------+-----------------------------+ 281 // | 'TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256'| | 282 // +----------------------------------------+-----------------------------+ 283 // | 'TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA' | | 284 // +----------------------------------------+-----------------------------+ 285 // | 'TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256'| | 286 // +-----------------------------------+----------------------------------+ 287 // | 'TLS_RSA_WITH_AES_128_GCM_SHA256' | | 288 // +-----------------------------------+----------------------------------+ 289 // | 'TLS_RSA_WITH_AES_128_CBC_SHA256' |'TLS_RSA_WITH_AES_256_GCM_SHA384' | 290 // +-----------------------------------+----------------------------------+ 291 // | 'TLS_RSA_WITH_AES_256_CBC_SHA256' | 'TLS_RSA_WITH_AES_256_CBC_SHA' | 292 // +-----------------------------------+----------------------------------+ 293 // | 'SSL_RSA_WITH_3DES_EDE_CBC_SHA | 'TLS_RSA_WITH_AES_128_CBC_SHA' | 294 // +-----------------------------------+----------------------------------+ 295 // | 'SSL_RSA_WITH_RC4_128_SHA' | 'SSL_RSA_WITH_RC4_128_MD5' | 296 // +-----------------------------------+----------------------------------+ 297 TransportLayerSecurityPropertyCipherSuites ServiceProperty = "solace.messaging.tls.cipher-suites" 298 299 // TransportLayerSecurityPropertyTrustStorePath specifies the path of the directory where trusted certificates are found 300 // The maximum depth for the certificate chain verification is 3. 301 TransportLayerSecurityPropertyTrustStorePath ServiceProperty = "solace.messaging.tls.trust-store-path" 302 303 // TransportLayerSecurityPropertyTrustedCommonNameList is provided for legacy installations and is not recommended as part of our best practices. 304 // The API performs Subject Alternative Name (SAN) verification when the SAN is found in the server certificate, 305 // which is generally the best practice for a secure connection. 306 // This property specifies a comma-separated list of acceptable common names in certificate validation. 307 // The number of common names specified by an application is limited to 16. Leading and trailing whitespaces are considered 308 // to be part of the common names and are not ignored. 309 // If the application does not provide any common names, there is no common-name verification. 310 // An empty string specifies that no common-name verification is required. 311 TransportLayerSecurityPropertyTrustedCommonNameList ServiceProperty = "solace.messaging.tls.trusted-common-name-list" 312 ) 313