python using tls : error connecting to a Solace pubsub broker

coz787
coz787 Member Posts: 6
edited October 2023 in General Discussions #1

# Broker Config
broker_props = {
# "solace.messaging.application_id" : "default",
"solace.messaging.transport.host": os.environ.get('SOLACE_HOST') or "tcps://pubsub.preops.nm.eurocontrol.int:5671",

"solace.messaging.service.vpn-name": os.environ.get('SOLACE_VPN') or "",
"solace.messaging.authentication.scheme.basic.username": os.environ.get('SOLACE_USERNAME') or "********",
"solace.messaging.authentication.scheme.basic.password": os.environ.get('SOLACE_PASSWORD') or "********"
}
strustedstore= os.environ['HOME']+"/dev/solace-samples-python/howtos/fixtures"
strustedstore= os.environ['HOME'] + "/nm_store"
strustedstore= "/etc/ssl/certs"

transport_security = TLS.create() \
.with_certificate_validation(True, validate_server_name=True,
trust_store_file_path=strustedstore )
# .without_certificate_validation()
# trust_store_file_path=SamplerUtil.get_trusted_store_dir())


occauth= ClientCertificateAuthentication.of(certificate_file=smycrt,\
key_file=smykey ,\
key_password=None )
# Build A messaging service with a reconnection strategy of 20 retries over an interval of 3 seconds
# Note: The reconnections strategy could also be configured using the broker properties object
messaging_service = MessagingService.builder().from_properties(broker_props)\
.with_reconnection_retry_strategy(RetryStrategy.parametrized_retry(20,3))\
.with_transport_security_strategy(transport_security) \
.with_authentication_strategy(occauth) \
.build()
print("messaging_service",messaging_service)

# Blocking connect thread
messaging_service.connect()

Hello, my code just above ; and the error that i have :

{'solace.messaging.transport.host': 'tcps://pubsub.preops.nm.eurocontrol.int:5671', 
'solace.messaging.service.vpn-name': '', 
'solace.messaging.authentication.scheme.basic.username': '********', 
'solace.messaging.authentication.scheme.basic.password': '********', 
'solace.messaging.transport.reconnection-attempts': 20, 
'solace.messaging.transport.reconnection-attempts-wait-interval': 3, 
'solace.messaging.tls.cert-validated': True, 
'solace.messaging.tls.cert-reject-expired': False, 
'solace.messaging.tls.cert-validate-servername': True, 
'solace.messaging.tls.trust-store-path': '/etc/ssl/certs', 
'solace.messaging.authentication.scheme': 'AUTHENTICATION_SCHEME_CLIENT_CERTIFICATE',
'solace.messaging.authentication.client-cert.private-key-password': None, 
'solace.messaging.authentication.client-cert.private-key-file': '/home/pavet/.nmcert/key.pem', 
'solace.messaging.authentication.client-cert.file': '/home/pavet/.nmcert/crt.pem'}
cs 0
messaging_service application_id : gitana/29418/00000001/Y83XXFfUui connected : False
2023-10-07 16:10:07,124 [WARNING] solace.messaging.core: [_solace_session.py:950] [[SERVICE: 0x7f6e47017f70] - [APP ID: gitana/29418/00000001/Y83XXFfUui]] {'caller_description': 'do_connect', 'return_code': 'Not ready', 'sub_code': 'SOLCLIENT_SUBCODE_PROTOCOL_ERROR', 'error_info_sub_code': 8, 'error_info_contents': "ClientdataParser: Bad SMF version of 1 when last/everReadMoreThanOne=0/0in session state 'CONNECTING': client name 'gitana/29418/00000001/Y83XXFfUui', peer host 'tcps://pubsub.preops.nm.eurocontrol.int:5671' address 'IP 193.58.21.120', connection 'tcps_Tx"}
2023-10-07 16:10:07,126 [WARNING] solace.messaging.connections: [messaging_service.py:1164] [[SERVICE: 0x7f6e47017f70] - [APP ID: gitana/29418/00000001/Y83XXFfUui]] Connection failed. Status code: 3
Traceback (most recent call last):
File "./howto40_solace_reader_r01.py", line 119, in <module>
messaging_service.connect()
File "/home/pavet/py3std/lib/python3.8/site-packages/solace/messaging/messaging_service.py", line 1165, in connect
raise error
solace.messaging.errors.pubsubplus_client_error.PubSubPlusCoreClientError: {'caller_description': 'do_connect', 'return_code': 'Not ready', 'sub_code': 'SOLCLIENT_SUBCODE_PROTOCOL_ERROR', 'error_info_sub_code': 8, 'error_info_contents': "ClientdataParser: Bad SMF version of 1 when last/everReadMoreThanOne=0/0in session state 'CONNECTING': client name 'gitana/29418/00000001/Y83XXFfUui', peer host 'tcps://pubsub.preops.nm.eurocontrol.int:5671' address 'IP 193.58.21.120', connection 'tcps_Tx"}

I would be greatful if an expert could help me … k.regards

Comments

  • emilzegers
    emilzegers Member, Employee Posts: 3 Solace Employee

    Hi Didier,

    Thanks for posting to the Solace Community forum. I'm not sure I'm the right expert here but will try to help anyway :-)

    Looks like the (tls) connection is not established properly? Does the messaging_service.connect() run successfully, can you test that?

    In the code I see solace.messaging.transport.host can either pick an environment variable and if not set fall back to a default hardcoded host name. In this case it is 'tcps://pubsub.preops.nm.eurocontrol.int:5671' address 'IP 193.58.21.120'. Is that the expected value for the host? Would be useful to check if the service is up and reachable on the IP address mentioned. Also the VPN value seems to be empty, is that expected?

    The description for 'sub_code': 'SOLCLIENT_SUBCODE_PROTOCOL_ERROR' is:
    'An API call failed due to a protocol error with the broker (not an application fault).'

    By default port 5671 is AMQP TLS / SSL. Is this AMQP TLS port enabled on the broker, assuming you want to connect using TLS? Are you working against a software broker or appliance?

    More questions than answers maybe, but hopefully it helps you to check some settings and find the right direction.

    Regards,

    Emil

  • coz787
    coz787 Member Posts: 6

    Hello & thank you Emil,

    The amqps software broker ( and it is a Solace pubsub+ instance) is functional. I have another python tool - using qpid::proton capable to consume its messages and it works.

    You are right : messaging_service.connect() raises an exception . What's strikes me is this part .

    'return_code': 'Not ready', 'sub_code': 'SOLCLIENT_SUBCODE_PROTOCOL_ERROR', 'error_info_sub_code': 8, 'error_info_contents': "ClientdataParser: Bad SMF version of 1 when last/everReadMoreThanOne=0/0in session state 'CONNECTING': client name 'gitana/29418/00000001/Y83XXFfUui',
    

    Best regards . Didier

  • emilzegers
    emilzegers Member, Employee Posts: 3 Solace Employee

    Bit of a guess but could this be due to a version mismatch between the Python solace-pubsubplus module and the broker? What versions do you use on either side?

  • Ragnar
    Ragnar Member, Employee Posts: 64 Solace Employee

    The PubSub+ Messaging API for Python that you are using is an SMF (Solace Message Format) API. SMF is a Solace proprietary messaging protocol the comes with advantages when connecting to Solace brokers.

    Solace brokers also support AMQP and MQTT if you want to use a open standard messaging protocol. In those cases you should use an AMQP API such as qpid::proton. There is no need to use a Solace API for open standard messaging protocols as there are many implementations to choose from.

    There error you are seeing is simply the API expects SMF and is getting back AMQP.

    The default port for SMF is '55555' but this often is changed by the network administration and you should consult with your solace administrator for the appropriate port to use for SMF.

  • coz787
    coz787 Member Posts: 6

    Hello Ragnar, thank you . I confirm your analysis and my misunderstanding about the nature of the protocol. In fact, i use yet qpid::proton in Python but … find it quite cumbersome to deploy …

    and so i am searching a python library capable of amqp 1.0 mostly as a listener / reader . That's why i gave a glance to solace pub/sub+ … I you have some ideas. Best regards

  • emilzegers
    emilzegers Member, Employee Posts: 3 Solace Employee

    Hi Didier, there are some repositories with examples at https://github.com/orgs/SolaceSamples/repositories?q=amqp&type=all&language=&sort=

    Did you already look at these? Also https://www.solace.dev/ might have some useful information.