Skip to Content

Intro

Integration between SAP PI/PO and message oriented middleware / broker is one of commonly faced requirements – and this is where Java Message Service (JMS) is often used to fulfil this requirement. But JMS is a Java focused standard, so it is relatively complex to utilize JMS message broker in heterogeneous landscape of message producing and consuming systems and applications, which are running on various platforms and implemented using different programming languages. Even though some JMS brokers support variety of protocols which can be used by non-Java clients (a good example is support of Streaming Text Oriented Messaging Protocol (STOMP) for Ruby and Python applications and Microsoft Message Queuing Protocol (MSMQP) for .Net applications) and can be bridged to JMS, this brings complexity to configuration and maintenance of the JMS broker, increases technical debt, and in some cases is not technically feasible at all.

 

In heterogeneous landscape, an alternative to JMS broker and bridging to platform specific protocols is complete replacement of JMS broker with generic platform agnostic message broker – and this is where the one may benefit from using Advanced Message Queuing Protocol (AMQP). One of advantages of usage of AMQP in contrast to JMS, is that it is intended to unify message brokering across various platforms – in such a way that applications written in Java, PHP, JavaScript, Ruby, C#, Python and other languages can all communicate with a single message broker. It is important to have clear differentiation between JMS and AMQP: JMS, being a messaging standard, defines Java messaging API, whereas AMQP, being a messaging protocol, defines wire-level protocol and principles of message structure and transmission over the network, it doesn’t provide industry standard API.

 

Currently SAP PI/PO doesn’t support AMQP out of the box – in contrast to JMS adapter, there is no SAP standard adapter that implements AMQP client functionality and can communicate with message broker using AMQP.

One of options that can be used to overcome this standard limitation, is installation and usage of 3rd party adapter – for example, Advantco AMQP Adapter (https://www.advantco.com/product/adapter/amqp). Usage of this adapter was described by Peter Ha in his blogs Advantco AMQP Adapter for SAP PI. and SAP PI – RabbitMQ  AMQP 0-9-1 integration.

In this blog, I would like to describe another alternative which doesn’t require additional adapters and is based on usage of SAP PI/PO standard JMS adapter – to be more precise, usage of JMS based communication between SAP PI/PO and AMQP broker. In a demo, I use RabbitMQ AMQP broker – probably one of the most commonly used AMQP brokers at the moment. The idea behind this approach is to establish messaging interoperability between SAP PO and AMQP broker using JMS API which is well supported by JMS adapter of SAP PO.

RabbitMQ provides RabbitMQ JMS Connector which implements JMS 1.1 and enables JMS communication between JMS client (here, SAP PO) and RabbitMQ server. The connector consists of two parts:

  • JMS client library – to be deployed and used by JMS client;
  • JMS server plugin – to be installed on RabbitMQ server

Demo

Scope of the demo is to illustrate connectivity and interoperability of SAP PO system with RabbitMQ server where RabbitMQ is a receiver system. The same approach can be potentially used to configure scenarios where RabbitMQ is a sender system for SAP PO.

In RabbitMQ, following AMQP entities have been configured:

  • Durable exchange topic test.po.topic – used as a destination for messages produced by SAP PO;
  • Durable queue test.po.queue – used as a destination for arbitrary AMQP consumer.

For the exchange topic, binding to a queue has been created with routing key test_po.

The flow is depicted on the illustration below:

Flow.png

Configurations of exchange and queue in RabbitMQ are illustrated below:

RabbitMQ exchange.png

RabbitMQ queue.png

(if necessary, you may find overview of main concepts and terms used in RabbitMQ and AMQP in general at RabbitMQ – AMQP 0-9-1 Model Explained).

In the demo, I use RabbitMQ server which was downloaded from https://www.rabbitmq.com/ (release: RabbitMQ 3.5.6). JMS connector for RabbitMQ was downloaded from http://pivotal.io/ (release: JMS Client 1.4.4).

Installation and configuration of JMS connector is described in details in documentation provided by vendor (for example in “Installing and Configuring JMS Client for Pivotal RabbitMQ” located at Pivotal RabbitMQ Documentation | Pivotal Docs).

 

The first step is to install JMS server plugin on RabbitMQ server using command rabbitmq-plugins.

 

The next step is to deploy JMS driver (which is contained in downloaded RabbitMQ JMS client library) to SAP PO system. This is done using the standard approach which is applicable for deployment of any other JMS driver – for detailed steps, refer to the SAP Note 1138877. I used SAP SDA Maker Tool to simplify the process of the required SDA file assembly – regarding SDA Maker Tool, refer to the SAP Note 1987079. When assembling the SDA file, please note that not only RabbitMQ JMS client library shall be included in the archive, but also its dependencies, which all can be found in distribution of JMS connector for RabbitMQ and are listed in the documentation referred above.

 

After JMS driver for RabbitMQ is deployed to SAP PO system, we are ready to configure the receiver communication channel. The configured JMS receiver communication channel shall be configured to use generic JMS broker access mode – which is, transport protocol shall be Access JMS Provider Generically. There are already a couple of useful blogs which describe how to use generic JMS broker access mode in JMS adapter (that time, when integrating SAP PI/PO with Apache ActiveMQ JMS broker), so it may make sense to look through them to get more diversified outlook at this functionality:

Generally speaking, besides JMS common parameterization (tab “Parameters” > “Processing”), when configuring generic access to JMS broker, it is very important to provide advanced parameterization (tab “Parameters” > “Advanced”). Here we specify classes which are to be used by the communication channel when establishing connection to the broker (JMS connection factory implementing class) and to the destination registered on the broker (JMS destination implementing class), as well as arguments required to instantiate respective objects (connection and destination).

JMS receiver channel configuration.png

JMS connection factory implementing full class name is specified in parameter JMS.QueueConnectionFactoryImpl.classname, JMS destination implementing class – in parameter JMS.QueueImpl.classname. For each of specified classes, it is necessary to provide arguments which contain specification of connectivity details to the broker and destination details. There are two ways to achieve this:

  • Providing parameters as arguments for a constructor method of the respective class. Following this approach, parameters JMS.QueueConnectionFactoryImpl.constructor and JMS.QueueImpl.constructor (one constructor entry for each of classes specified earlier) should be added in communication channel advanced configuration. Argument values for each constructor entry are provided comma-delimited and preceded with argument type specification;
  • If the respective class has setter methods for effective parameters, they can be used instead of a constructor entry. Corresponding parameters in communication channel advanced configuration have follow naming convention JMS.QueueConnectionFactoryImpl.method.<method name> and JMS.QueueImpl.method.<method name>. Argument value for each setter method entry should also be preceded with argument type specification.

Please consult with documentation regarding connection factory and destination classes: not all classes may have setter methods, and it is critical to specify exactly same the amount of arguments of expected types as constructor method implementations expect (otherwise you will most likely observe NoSuchMethodException in SAP PO logs when this class constructor will be called by JMS adapter at runtime).

 

The complete list of parameters maintained in communication channel advanced configuration together with their values for this demo is as following:

 

Parameter Value
JMS.QueueConnectionFactoryImpl.classname com.rabbitmq.jms.admin.RMQConnectionFactory
JMS.QueueConnectionFactoryImpl.method.setHost java.lang.String e107184
JMS.QueueConnectionFactoryImpl.method.setPort java.lang.Integer 5672
JMS.QueueConnectionFactoryImpl.method.setUsername java.lang.String middleware_user
JMS.QueueConnectionFactoryImpl.method.setPassword java.lang.String TestPassword_2015!
JMS.QueueImpl.classname com.rabbitmq.jms.admin.RMQDestination
JMS.QueueImpl.method.setDestinationName java.lang.String Test_RabbitMQ_Topic
JMS.QueueImpl.method.setAmqpExchangeName java.lang.String test.po.topic
JMS.QueueImpl.method.setAmqpRoutingKey java.lang.String test_po
JMS.QueueImpl.method.setAmqpQueueName java.lang.String null
JMS.QueueImpl.method.setAmqp java.lang.Boolean true


If you prefer using arguments for a constructor method instead of setter methods, parameterization above can be re-written into following for JMS destination implementing class:

 

Parameter Value
JMS.QueueConnectionFactoryImpl.classname com.rabbitmq.jms.admin.RMQConnectionFactory
JMS.QueueConnectionFactoryImpl.method.setHost java.lang.String e107184
JMS.QueueConnectionFactoryImpl.method.setPort java.lang.Integer 5672
JMS.QueueConnectionFactoryImpl.method.setUsername java.lang.String middleware_user
JMS.QueueConnectionFactoryImpl.method.setPassword java.lang.String TestPassword_2015!
JMS.QueueImpl.classname com.rabbitmq.jms.admin.RMQDestination
JMS.QueueImpl.constructor java.lang.String Test_RabbitMQ_Topic, java.lang.String test.po.topic, java.lang.String test_po, java.lang.String null
JMS.QueueImpl.method.setAmqp java.lang.Boolean true

 

If you would like to establish connection to a non-default RabbitMQ virtual host, please also ensure that proper virtual host is specified in parameterization for invoked connection factory – this can be done by adding extra parameter JMS.QueueConnectionFactoryImpl.method.setVirtualHost with a value java.lang.String <virtual host name>.

 

The communication channel has been started successfully and got connected to RabbitMQ server:

JMS channel - startup.png


In sake of test, I send several messages for the developed scenario – few SOAP messages like the one below:

Message 1.png

PO messages.png

These messages can be immediately observed in the queue at RabbitMQ (which means, messages have been sent out by SAP PO, delivered to the topic in RabbitMQ and forwarded to the queue, from where it can now be retrieved and processed by some AMQP consumer application):

RabbitMQ - messages overview in topic.png

RabbitMQ - messages overview in queue.png

RabbitMQ - messages.png

Outro

As it can be seen, the nature of interoperability between SAP PO and RabbitMQ remains JMS based – even though message consumers are likely to be AMQP clients for RabbitMQ, message producer (SAP PO) is still a JMS client and doesn’t really utilize AMQP capabilities within this approach.

 

It should also be noted that the described implementation is vendor specific – in other words, the implementation and demo are based on functionality and libraries that are provided by RabbitMQ specifically for their AMQP broker. In case of using AMQP brokering application delivered by another vendor, the one should check documentation in order to verify if the used AMQP broker supports similar capabilities. Absence of generic solution and risk of it being inappropriate for some implementations of AMQP brokers is a major disadvantage of the described approach (in contrast to AMQP adapter which is designed to support literally any AMQP compatible broker) that should be taken into consideration when designing integration of SAP PO with the specific AMQP broker.

To report this post you need to login first.

55 Comments

You must be Logged on to comment or reply to a post.

  1. Former Member

    Hi Vadim,

    I´m doing exactly the same, but i´m getting this error for class com.rabbitmq.jms.admin.RMQConnectionFactory:

    “A channel error occurred. Detailed error (if any): com.sap.aii.adapter.jms.api.connector.ConnectorException: Cannot construct connection factory using constructor: ConstructorInvocationException: Error executing constructor invocation: <br>{ConstructorInvocation<br>{className=com.rabbitmq.jms.admin.RMQConnectionFactory,<br>invokeParams=[]<br>}; java.lang.reflect.InvocationTargetException”

    Any suggestion???

    Warm regards

    Juan

    (0) 
    1. Vadim Klimov Post author

      Hi Juan,

      Can you please provide a list of parameters JMS.QueueConnectionFactoryImpl.* that you maintained in a communication channel, and their values (you may mask actual host/port/user/password, etc. – I’m interested in checking how the value is composed and which types are used)? You may also want to create a forum thread for this issue so that we don’t overload blog comments with a specific problem discussion.

      Regards,

      Vadim

      (1) 
      1. Piotr Radzki

        Hello Vladim,

        First of all – thanks for this blog!

        In my case parameters looks like that (I masked some of them) and I’m getting the following error.

        JMS.QueueConnectionFactoryImpl.classname com.rabbitmq.jms.admin.RMQConnectionFactory
        JMS.QueueConnectionFactoryImpl.method.setHost java.lang.String test.xxxx.xxx.xx
        JMS.QueueConnectionFactoryImpl.method.setPort java.lang.Integer xxxx
        JMS.QueueConnectionFactoryImpl.method.setUsername java.lang.String test
        JMS.QueueConnectionFactoryImpl.method.setPassword java.lang.String test
        JMS.QueueImpl.classname com.rabbitmq.jms.admin.RMQDestination
        JMS.QueueImpl.method.setDestinationName java.lang.String Test_RabbitMQ_Topic
        JMS.QueueImpl.method.setAmqpExchangeName java.lang.String e.test
        JMS.QueueImpl.method.setAmqpRoutingKey java.lang.String test
        JMS.QueueImpl.method.setAmqpQueueName java.lang.String q.test
        JMS.QueueImpl.method.setAmqp java.lang.Boolean true

        What about “Processing” tab of JMS receiver adapter, is there a need for any specific configuration or configuration using parameters is enough in “Advanced” tab ?

        On “Processing” tab of JMS receiver adapter I specified:

        Transactional JMS Session (Recommended) – is checked

        JMS ReplyTo Queue Name = RabbitMQReply

        JMS Queue/Topic User = test

        JMS Queue/Topic Password = test

         

        The rest I left as it was in default.

         

        Still getting this error:

        A channel error occurred. Detailed error (if any) : com.sap.aii.adapter.jms.api.connector.ConnectorException: Cannot construct connection factory using constructor: ConstructorInvocationException: Error executing constructor invocation:
        {ConstructorInvocation
        {className=com.rabbitmq.jms.admin.RMQConnectionFactory,
        invokeParams=[]
        }: java.lang.reflect.InvocationTargetException

        (0) 
        1. Vadim Klimov Post author

          Hello Piotr,

           

          Verbose trace of the failing communication channel at its startup shall provide mode details regarding what the issue is (InvocationTargetException is a higher level exception, which intention is to wrap the concrete nested exception thrown by an invoked method – here, constructor of the connection). If possible, it would be great to see XPI Inspector trace for this channel so that you can track all nested exceptions down to cause.

           

          Can you also give a try to setting:

          • Value of JMS.QueueImpl.method.setDestinationName same as value of JMS.QueueImpl.method.setAmqpExchangeName, which is an exchange name registered on RabbitMQ,
          • Value of JMS.QueueImpl.method.setAmqpQueueName equal to java.lang.String null.

          Together with this, please check if virtual hosts are used in RabbitMQ configuration – if so (and if not default virtual host is to be used), set additional parameter JMS.QueueConnectionFactoryImpl.method.setVirtualHost with a value java.lang.String <virtual host name>.

           

          I didn’t have to customize processing parameterization (tab ‘Processing’) – in my case, I left parameters on that tab with their default values.

           

          Regards,

          Vadim

          (1) 
          1. Piotr Radzki

            Hello Vadim,

            it was a while, in the meantime we found out that some of the libraries were missing in the initial deployment to SAP PO of RabbitMQ lib.

            After we deployed missing libraries and we started Communication Channel again we get “connection time out”. In general it was the issue related to Network setup and open connectivity between our SAP PO system and RabbitMQ system.

            After the connection is open now we are having the communication channel status as succesfully started and connected to destination.

            Unfortunatelly when we are testing and trying to send some dummy messages to RabbitMQ we are getting errors:

            reply-code=403, reply-text=ACCESS_REFUSED – access to exchange ‘jms.durable.topic’ in vhost ‘/’ refused for user ‘xxxxxx’, class-id=40, method-id=10

            instead of xxxx there is of course proper username.

            I think its related to the setup on RabbitMQ side and its addressed to my colelagues responsible for MQ. Looking forward to solve it finaly 🙂

            BR,

            Piotr

            (0) 
            1. Vadim Klimov Post author

              Hi Piotr,

              You are absolutely right: the error ACCESS_REFUSED that you mentioned, is not related to PO side, but is caused by missing write permissions for the given user to the given exchange on RabbitMQ side. RabbitMQ has good documentation about how permissions are managed and configured there: https://www.rabbitmq.com/access-control.html .

              Regards,

              Vadim

              (1) 
              1. Piotr Radzki

                RabbitMQ side was adjusted and I also removed one not necessary parameter from communication channel that I’ve set inititaly: JMS ReplyTo Queue Name.

                We have tested it and are able to send messages from SAP PO to RabbitMQ succesfully!

                Thanks for your blog it help a lot!

                Now I will setup scenario with Sender JMS adapter to allows RabbitMQ send messages to SAP PO. But I feel it will be much easier now.

                All the best for you Vadim!

                (1) 
                  1. Andrej Dukovski

                    Hi Piotr, hi everybody.

                    Ij

                    I have already successfully configured the receiver channel, thanks to Vadim.

                    But I have no luck with the sender channel.

                    Have you managed to successfully configure RabbitMQ sender?

                     

                    My ‘non-working’ configuration is as follows:

                     

                    JMS.QueueConnectionFactoryImpl.classname com.rabbitmq.jms.admin.RMQConnectionFactory
                    JMS.QueueConnectionFactoryImpl.method.setHost java.lang.String x.x.x.x
                    JMS.QueueConnectionFactoryImpl.method.setPort java.lang.Integer 5672
                    JMS.QueueConnectionFactoryImpl.method.setVirtualHost java.lang.String xxxxxxx
                    JMS.QueueConnectionFactoryImpl.method.setUsername java.lang.String middleware_user
                    JMS.QueueConnectionFactoryImpl.method.setPassword java.lang.String TestPassword
                    JMS.QueueImpl.classname com.rabbitmq.jms.admin.RMQDestination
                    JMS.QueueImpl.method.setDestinationName java.lang.String Test_RabbitMQ_Topic
                    JMS.QueueImpl.method.setAmqpExchangeName java.lang.String null
                    JMS.QueueImpl.method.setAmqpRoutingKey java.lang.String null
                    JMS.QueueImpl.method.setAmqpQueueName java.lang.String xxx.test.queue
                    JMS.QueueImpl.method.setAmqp java.lang.Boolean true

                     

                     

                    The channel is running (green) showing:

                     

                    connected to destination: RMQDestination{destinationName=’Test_RabbitMQ_Topic’, queue(permanent, amqp)’, amqpExchangeName=’null’, amqpRoutingKey=’null’, amqpQueueName=’xxx.test.queue’}

                     

                    but nothing is happening and no messages are pulled from the queue.

                    If I uncheck the “Use Message Listener Based Connector”, I get the following error:

                    Error receiving JMS message : while trying to invoke the method java.lang.Object.toString() of a null object returned from java.util.Map.get(java.lang.Object)

                     

                    I also wonder where to define the pooling interval (in processing tab or as an additional parameter)? Is the processing tab relevant at all? If so, should the listener based connector be checked or unchecked?

                     

                    Best regards,

                    Andrej

                     

                     

                    (0) 
                    1. Vadim Klimov Post author

                      Hi Andrej,

                      I recall we had the discussion on configuration of JMS adapter for polling messages from RabbitMQ with Sandra some time ago, where there were issues with particular parameterization required in JMS sender channel – hence, please have a look in a forum thread PI Sender JMS RabbitMQ Integration, it might be helpful in your case, too. Few points to pay attention to: a) in polling scenarios, JMS adapter shall poll from RabbitMQ’s queue (hence, topic specification in channel configuration is redundant), b) there are few JMS specific message properties that are advisable to be set in the message to make it successfully polled by JMS adapter (this originates from JMS specification).

                      As for polling interval, please use configuration parameters provided on the tab ‘Parameters’ > ‘Processing’.

                      Regards,

                      Vadim

                      (1) 
                      1. Andrej Dukovski

                        Dear Vadim,

                        Thank you very much for your quick reply. I solved the issue by following the thread you suggested.
                        Indeed, there was a problem with message properties.

                        Kind regards, Andrej

                        (0) 
                  2. Piotr Radzki

                    Hello Vadim,

                    I received requirement from my RabbitMQ colleague to provide 2 additional parameters ,they look like message header parameters but non JMS related:

                    type = ‘new’

                    content_type = ‘<object_name>’

                    Did you faced simillar requirement? As far as I can see its hard to push such parameters.

                    Do you know if its feasible using described here approach with JMS adapter and AMQP modules for Receiver adapter ?

                    BR,

                    Piotr

                    (0) 
                    1. Vadim Klimov Post author

                      Hi Piotr,

                      I’m not sure this kind of requirements can be fulfilled with the approached described here. Reason for this is, when we make use of RabbitMQ’s JMS client library, PI/PO system interacts with the message in the way as if it would be a generic JMS message (and has access to message’s JMS properties), but it will not have awareness of any additional properties that are not a part of JMS specification. Moreover, some properties are defaulted by RabbitMQ’s JMS client library – ‘content_type’ being one of them. It might be worth checking discussion we had in regards to a similar requirement – https://archive.sap.com/discussions/thread/3909380. Although it is now possible to set content type using native AMQP library of RabbitMQ, as to my knowledge and outlook into implementation of JMS library for RabbitMQ, this is not something that has been exposed within the JMS library.

                      Regards,

                      Vadim

                      (1) 
                      1. Piotr Radzki

                        Thanks Vadim, I have same understanding of the topic. Nevertheless thanks for looking back into this.

                        RabbitMQ colleagues made a workaround using RoutingKey and route the message properly based on that.

                         

                        BR,

                        Piotr

                        (0) 
                  3. Piotr Radzki

                    To elaborate more on the topic, what I was able to do so far is to influence message header parameters but not message properties:

                    I used described already appraoch specifying Additional JMS Message Properties:

                    I used adapter modules to populate value for these parameters:

                    It resulted with below messsage on RabbitMQ side, we have populated header parameters.

                    But actual requirement is to populate message properties as below:

                    Is it possible?

                     

                    (0) 
                    1. Vadim Klimov Post author

                      Not something I would be aware of. When we discussed possibility of manipulating header values for constructed messages earlier, this ended up with the similar approach you used – handling JMS headers of the message, not headers of the AMQP message.

                      (1) 
    2. Piotr Radzki

      Hello Juan,

       

      Did you solved this issue? Or maybe did you started a discussion in SCN?

      I’m facing exactly same error and looking actively for solution.

       

      Best Regards,

      Piotr

      (0) 
  2. Former Member

    Hi Vadim,

    We have tried SAP PI/PO with RabbitMQ AMQP Broker via JMS adapter as per your documentation and able to connect the server and publish the message from SAP PO JMS to RabbitMQ queue. However the message format is not readable i.e we tried to publish the soap message but the message contains the entire XML instead of actual message.Please find attached image for the sample message format in RabbitMQ queue.

    XML Message which we sent from SAP PO to RabbitMQ JMS Queue:

    <soapenv:Envelope xmlns:soapenv=”http://schemas.xmlsoap.org/soap/envelope/” xmlns:urn=”urn::XXXXXXXXX:JMSPOC”>
    <soapenv:Header/>
    <soapenv:Body>
    <urn:MT_SOAP_Sen>
    <!–Zero or more repetitions:–>
    <Header>
    <ID>100</ID>
    <Text>Testing JMS</Text>
    </Header>
    </urn:MT_SOAP_Sen>
    </soapenv:Body>
    </soapenv:Envelope>

    Can you help us to resolve the issue.

    Regards,

    Ravi

    (0) 
    1. Vadim Klimov Post author

      Hello Ravi,

      It is likely to be related not to specifics of communication with RabbitMQ, but configuration of the used receiver communication channel in part of which sections of the message are passed to the JMS provider and how they are converted before the message is published to the JMS topic. Hence, in the JMS receiver communication channel, please check:

      • Tab ‘Parameters’ > ‘Processing’, configuration for ‘Mapping of message’. Here you can configure which part of the processed message will be dispatched to the JMS adapter;
      • Tab ‘Module’, which modules and with which configuration for them are configured before the module ‘SendBinarytoXIJMSService’ (the last in the sequence) is invoked. Here you can specify conversion logic for the processed message before it reaches the JMS adapter and gets published to the topic.

      Regards,

      Vadim

      (0) 
      1. Former Member

        Hi Vadim,

        Thanks for the reply.We have not used any conversion module,still we are facing same issue.I am attaching JMS adapter configuration screens. Please help me if anything is missed from my end.

         

        Thanks

        Ravi

        (0) 
    1. Vadim Klimov Post author

      Hi Flor,

      Thank you, this is a valid point in certain circumstances – originally in Java centric environments, ActiveMQ fits very nicely as a JMS message broker, and together with AMQP (and some other alternative protocols) support that was introduced in it in later releases (AMQP support was introduced in release 5.8), its usage can be extended to other types of clients. I shall note, choice of the particular message broker commonly depends on already existing infrastructure – for example, a case that further led me to writing this blog, was based on the infrastructure where RabbitMQ cluster had already been setup and used productively in the company, and when we designed decoupled interfaces and looked into required dependencies / options for re-use of existing components (precisely, message brokers), already running highly available and robust RabbitMQ cluster was our preferred choice. In an organization that doesn’t have any message broker in place, as you fairly pointed out, there are other alternatives and options to choose from.

      Regards,

      Vadim

      (0) 
  3. Former Member

    Hi Vadim,

     

    We have tried SAP PI/PO integration with RabbitMQ AMQP Broker via JMS adapter as SAP PO as Consumer(Sender JMS Channel)

    1) If we set up all parameters suggested by you while publishing  message to RMQ our sender JMS channel is working fine but if few parameters missing our channel went to error (no message id generated as it’s unable to pull the message) logs

    Error occurred while processing message: null. The detailed error (if any) is :  java.lang.IllegalArgumentException: The JMS message ID cannot be set as null.
    at com.sap.aii.adapter.jms.core.connector.JmsHeadersProfileImpl.setJMSMessageID(JmsHeadersProfileImpl.java:80)
    ….

    In RMQ We can see Unacked count 1 as this message not reached to SAP PI(or not acknowledged by SAP PI)

     

    After Restarting JMS sender Communication channel the un acked count  becomes 0 and PI didn’t get any message and channel started polling freshly(Here we lost the message with improper headers) Even if we publish new message with all header params  to RMQ after this invalid message with out restarting JMS channel then new message reaches to SAP PI and  unacked count becomes (again losing message)

     

    In both the cases  no message reached to  SAP PI(No message id generated except error log with illegal argument exception  ) for message with missing header param and  message is not available in RMQ.

    So here we lost one message.

    So how can we achieve integration with out message lost.

    I have read (RMQ docs)  generally  followed mechanism for publish consume model in RMQ

    1. Set explicit  acknowledgement  in Consumer side so RMQ will  keep the message until it gets acknowledgement by consumer as received.
    2. By any case message got error ed out in consumer we have to put it in Error_Queue of RMQ (need to configure this in Consumer)

     

    Can we achieve above two configurations in our JMS Sender channel(As it is the consumer in our scenario).

    I have gone through RMQ Client   libraries and found that explicit acknowledgement method in RMQMessageConsumer class

     

    void dealWithAcknowledgements(boolean ack, long dtag) {
    if (ack) {
    this.session.explicitAck(dtag);
    } else {
    this.session.unackedMessageReceived(dtag);
    }
    }

     

    Didn’t get any method to set it true in QueueImpl class.

    Can we configure error_queue in our sender JMS Channel.

    Please let me know your views.

    Thanks

     

     

     

     

     

    (0) 
    1. Vadim Klimov Post author

      Hi Ramesh,

       

      Let’s firstly figure what causes the observed an error. The error “The JMS message ID cannot be set as null” commonly indicates that the JMS message’s header field ‘JMSMessageID’ is missing. One option to check this is to trace sender channel when it polls a message, and check if that header exists in the polled JMS message. It will also be helpful if you describe which configuration parameters you remove to cause failure.

       

      Regarding acknowledgement mode, this is something that would normally be set up on session level (in contrast to connection and destination that are configured in the channel when using generic JMS provider access), but I don’t think we can easily manipulate session properties from generic JMS provider access configuration.

       

      Regards,

      Vadim

      (0) 
      1. Former Member

        Thanks Vadim.

                     It will also be helpful if you describe which configuration parameters you remove to cause failure.

                 I didn’t give message id while publishing the message to RMQ Queue(Manual) to analyses the error. I hope in real time  application wouldn’t  miss header parameters  only  for few messages while publishing to RMQ Excahgne.

        I didn’t see any other error as of now (just done POC) and just  want to ensure no message lost and to know whether is there any possibility for Explicit ack and error_queue mechanism.

        Regards,

        Ramesh M.

         

         

        (0) 
  4. Jordi Sales

    Hi Vadim,

    I’m new integrating SAP PI with RabbitMQ and I have a problem with JMS Sender.

    I’ve read Sandra’s thread (https://archive.sap.com/discussions/thread/3920564) and you said that is necessary to inform expiration property in messages published on RabbitMQ side.

    Is there any way of consume messages from RabbitMQ queue without setting expiration property?

    Thanks.

    Regards,

    Jordi.

    (0) 
    1. Vadim Klimov Post author

      Hi Jordi,

      Not the way I would be aware of – if the message was placed without property ‘expiration’, then JMS adapter wasn’t able to poll it.

      Regards,

      Vadim

      (0) 
          1. Jordi Sales

            Hi Vadim,

            Now we are trying to  create a JMS receiver, and everything seems OK, we send a message and the channel put it to delivered.
            In RabbitMQ appear an attempt to connect but the message is not published into the exchange (this exchange is a direct exchange).
            In PI there is no error, but we are not sure about the value informed in the parameter “setDestinationName”, which value we should inform here?

             

            Thanks.

             

            Jordi.

             

            (0) 
            1. Vadim Klimov Post author

              Hi Jordi,

              From the graphic you provided, it looks like RabbitMQ received something, as there was a spike in exchange activity. Hence, can you please check in JMS receiver channel configuration, in its processing properties, if delivery mode is set to persist JMS messages (that is the default mode – so unless you changed it explicitly manually, it shall be set).

              Good test on RabbitMQ side can be as following: stop consumer that polls messages from the queue, for which there is routing / binding from the exchange that you use, and then send a new message from PO. If RabbitMQ received message and persisted it, you shall be able to see activity spike in the exchange to which PO published a message, and then observe the message in the queue to which RabbitMQ routed the message from the exchange.

              As for the destination name, this is an alias for the destination – you can use the name that would make sense to you, or alternatively just re-use the same value as you use for AMQP exchange name, as the destination in this sense is the exchange.

              Regards,

              Vadim

              (0) 
              1. Jordi Sales

                Hi Vadim,

                Yes, we have delivery mode is set to persist JMS messages.

                We have already done the test you described, but the result was the same. Is it possible that Expiration should be informed in this case too? How could we Inform Expiration in JMS Receiver adapter?

                Thanks.

                Jordi.

                (0) 
                1. Vadim Klimov Post author

                  Jordi,

                  By default, JMS receiver adapter sets message expiry period to unlimited, so if you want to change this, it is possible (check JMS message expiry period property in channel configuration), but if you don’t set it manually, the channel will work as it will implicitly set unlimited expiry period.

                  Can you send test message to the exposed exchange from the other publisher and see if it works? And, can you also collect a trace of a receiver communication channel in PO – it shall provide evidences of message transmission and publication to an exchange (or, given it is reflected in JMS terms, topic).

                  Regards,

                  Vadim

                  (0) 
                  1. Jordi Sales

                    Hi Vadim,

                    We just have successful tests with JMS sender, the problem was the Routing Key in RabbitMQ, this property was informed with an empty string and it was not possible to put this value in JMS parameter, even informing ‘null’ didn’t work. We had to inform a fix value in Rabbit, because if not, the adapter only tried to connect, not publishing any message.

                    Now we have JMS Sender and Receiver working correctly, thanks so much for your help.

                    Regards.

                    Jordi.

                    (0) 
                    1. Vadim Klimov Post author

                      Hi Jordi,

                      Thank you for the update, nice to hear you fixed the issue.

                      Although, your comment regarding routing key makes me concerned. Routing key needs to be specified in the receiver channel (for example, via parameter ‘JMS.QueueImpl.method.setAmqpRoutingKey’) for scenarios when RabbitMQ receives a message published to its exchange, and needs to identify binding that it shall use to route the message to a corresponding queue. In receiver channel, when this parameter was set, and its value was set to non-null String value containing the routing key (which was reflection of routing key configured in RabbitMQ for the corresponding binding in the exchange configuration), it worked well for me. What kind of fix did you need to apply on RabbitMQ side and did you evidence that JMS adapter couldn’t send routing key for some reason?

                      Regards,

                      Vadim

                      (0) 
                      1. Jordi Sales

                        Sorry Vadim,

                        I was wrong, the problem was with Receiver JMS Adapter. We only had to set a value to Routing Key in RabbitMQ, previusly, that property was informed with a empty string  and JMS adapter was not able to use JMS.QueueImpl.method.setAmqpRoutingKey with a empty string as parameter.

                        Thanks so much for the help.

                        Regards,

                        Jordi.

                        (0) 
  5. Christof Johner

    Hello Vadim

    First of all: thanks for the interesting and nicely written blog.
    We’ve tried to implement your demo scenario and went through all the configuration steps.

    We’ve deployed the JMS driver: we’ve included the following client libraries:

    As a matter of fact the java class laoder shows this libraries after deployment:

    We’re using the following connection parameters (XXXX=masked):

    Now the problem where we don’t see the reason why. The communication channel show the following:

    …..Com.sap.aii.adapter.jms.api.connector.ConnectorException: cannot construct connection factory using constructor: ConstructorInvocationException: error executing constructor invocation:…<br> ConstructorInvocation className=com.rabbitmq.jms.admin.RMQConnectionFactory … Java.lang.reflect.InvocationTargetException…..
    at com.sap.aii.adapter.jms.core.connector.DirectConnectorImpl.createConnectionFactory(DirectConnectorImpl.java:105) ……..

    Do you have a suggestion where to dig further in order to resolve this problem? We’ve checked different blogs but didn’t find similar errors.

    Thanks for your feedback.

    Kind regards
    Christof

    (0) 
    1. Vadim Klimov Post author

      Hi Christof,

      All values in parameters that correspond to connection factory and queue constructors’ properties, shall be preceeded with their type reference. In configuration you provided, parameter ‘JMS.QueueConnectionFactoryImpl.method.setVirtualHost’ has value of the virtual host ‘XXXX-test’, but the complete parameter value in this case shall become ‘java.lang.String XXXX-test’.

      After this is adjusted, give another try to establish connection by the channel to RabbitMQ, if it will not be successful, something else that might be worth testing:

      • JMS.QueueImpl.method.setDestinationName = JMS.QueueImpl.method.setAmqpExchangeName = ‘java.lang.String XXXX.xproduct’,
      • JMS.QueueImpl.method.setAmqpQueueName = ‘java.lang.String null’

      Regards,

      Vadim

      (0) 
  6. Christof Johner

    Hello Vadim

    thanks for your reply and suggestions.
    We’ve followed your advices and tried first with the following parameters:

    Afterwards with the following:

    But still exactly the same error as above:
    …..Com.sap.aii.adapter.jms.api.connector.ConnectorException: cannot construct connection factory using constructor: ConstructorInvocationException: error executing constructor invocation:…<br> ConstructorInvocation className=com.rabbitmq.jms.admin.RMQConnectionFactory … Java.lang.reflect.InvocationTargetException…..
    at com.sap.aii.adapter.jms.core.connector.DirectConnectorImpl.createConnectionFactory(DirectConnectorImpl.java:105) ……..

    Even with other combinations always the same error.

    Is there another way to further tackle down the source of the problem?

    Kind regards
    Christof

     

    (0) 
    1. Vadim Klimov Post author

      Hi Christof,

      Will it be possible for you to trace startup of the channel (stop the channel, enable trace – such as XPI Inspector trace for this channel, and then start channel while trace is running)? This is to get more details on the context of the exception. I’ve checked configuration that I used, and in part of parameters that were passed to the connection factory constructor, I used the same combinations as you – so it will be helpful to see what nested exception (and potentially additional information on it) connection factory invocation throws in your setup.

      Regards,

      Vadim

      (0) 
  7. Christof Johner

    Hello Vadim

    We’ve tried to get more details with the XPI inspector and also log entries, but the information gathered did not really help to find the source of the problem:

    EXCEPTION]

    com.sap.aii.adapter.jms.api.connector.ConnectorException: Cannot construct connection factory using constructor: ConstructorInvocationException: Error executing constructor invocation:

    {ConstructorInvocation

    {className=com.rabbitmq.jms.admin.RMQConnectionFactory,

    invokeParams=[]

    }: java.lang.reflect.InvocationTargetException

    at com.sap.aii.adapter.jms.core.connector.DirectConnectorImpl.createConnectionFactory(DirectConnectorImpl.java:105)

    at com.sap.aii.adapter.jms.core.connector.ConnectorImpl.doConnect(ConnectorImpl.java:414)

    at com.sap.aii.adapter.jms.core.connector.ConnectorImpl.connectIfDisconnected(ConnectorImpl.java:237)

    at com.sap.aii.adapter.jms.core.connector.ConnectorImpl.connect(ConnectorImpl.java:220)

    at com.sap.aii.adapter.jms.core.channel.ChannelImpl.doStart(ChannelImpl.java:422)

    at com.sap.aii.adapter.jms.core.channel.ChannelImpl.start(ChannelImpl.java:179)

    at com.sap.aii.adapter.jms.core.channel.AdapterImpl$1.run(AdapterImpl.java:857)

    at com.sap.engine.core.thread.impl3.ActionObject.run(ActionObject.java:37)

    at java.security.AccessController.doPrivileged(Native Method)

    at com.sap.engine.core.thread.impl3.SingleThread.execute(SingleThread.java:185)

    at com.sap.engine.core.thread.impl3.SingleThread.run(SingleThread.java:302)

    Caused by: com.sap.aii.adapter.jms.api.base.ConstructorInvocationException: Error executing constructor invocation:

    {ConstructorInvocation

    {className=com.rabbitmq.jms.admin.RMQConnectionFactory,

    invokeParams=[]

    }: java.lang.reflect.InvocationTargetException

    at com.sap.aii.adapter.jms.core.common.InvokeUtils.invoke(InvokeUtils.java:548)

    at com.sap.aii.adapter.jms.core.common.InvokeUtils.invoke(InvokeUtils.java:514)

    at com.sap.aii.adapter.jms.core.connector.DirectConnectorImpl.createConnectionFactory(DirectConnectorImpl.java:101)

    … 10 more

    Caused by: java.lang.reflect.InvocationTargetException

    at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)

    at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:39)

    at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:27)

    at java.lang.reflect.Constructor.newInstance(Constructor.java:513)

    at com.sap.aii.adapter.jms.core.common.InvokeUtils.invoke(InvokeUtils.java:543)

    … 12 more

    Caused by: java.lang.NoClassDefFoundError: org/slf4j/LoggerFactory

    at com.rabbitmq.jms.admin.RMQConnectionFactory.<init>(RMQConnectionFactory.java:32)

    … 17 more

    Caused by:

    com.sap.aii.adapter.jms.api.base.ConstructorInvocationException: Error executing constructor invocation:

    {ConstructorInvocation

    {className=com.rabbitmq.jms.admin.RMQConnectionFactory,

    invokeParams=[]

    }: java.lang.reflect.InvocationTargetException

    at com.sap.aii.adapter.jms.core.common.InvokeUtils.invoke(InvokeUtils.java:548)

    at com.sap.aii.adapter.jms.core.common.InvokeUtils.invoke(InvokeUtils.java:514)

    at com.sap.aii.adapter.jms.core.connector.DirectConnectorImpl.createConnectionFactory(DirectConnectorImpl.java:101)

    at com.sap.aii.adapter.jms.core.connector.ConnectorImpl.doConnect(ConnectorImpl.java:414)

    at com.sap.aii.adapter.jms.core.connector.ConnectorImpl.connectIfDisconnected(ConnectorImpl.java:237)

    at com.sap.aii.adapter.jms.core.connector.ConnectorImpl.connect(ConnectorImpl.java:220)

    at com.sap.aii.adapter.jms.core.channel.ChannelImpl.doStart(ChannelImpl.java:422)

    at com.sap.aii.adapter.jms.core.channel.ChannelImpl.start(ChannelImpl.java:179)

    at com.sap.aii.adapter.jms.core.channel.AdapterImpl$1.run(AdapterImpl.java:857)

    at com.sap.engine.core.thread.impl3.ActionObject.run(ActionObject.java:37)

    at java.security.AccessController.doPrivileged(Native Method)

    at com.sap.engine.core.thread.impl3.SingleThread.execute(SingleThread.java:185)

    at com.sap.engine.core.thread.impl3.SingleThread.run(SingleThread.java:302)

    Caused by: java.lang.reflect.InvocationTargetException

    at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)

    at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:39)

    at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:27)

    at java.lang.reflect.Constructor.newInstance(Constructor.java:513)

    at com.sap.aii.adapter.jms.core.common.InvokeUtils.invoke(InvokeUtils.java:543)

    … 12 more

    Caused by: java.lang.NoClassDefFoundError: org/slf4j/LoggerFactory

    at com.rabbitmq.jms.admin.RMQConnectionFactory.<init>(RMQConnectionFactory.java:32)

    … 17 more

    Caused by:

    java.lang.reflect.InvocationTargetException

    at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)

    at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:39)

    at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:27)

    at java.lang.reflect.Constructor.newInstance(Constructor.java:513)

    at com.sap.aii.adapter.jms.core.common.InvokeUtils.invoke(InvokeUtils.java:543)

    at com.sap.aii.adapter.jms.core.common.InvokeUtils.invoke(InvokeUtils.java:514)

    at com.sap.aii.adapter.jms.core.connector.DirectConnectorImpl.createConnectionFactory(DirectConnectorImpl.java:101)

    at com.sap.aii.adapter.jms.core.connector.ConnectorImpl.doConnect(ConnectorImpl.java:414)

    at com.sap.aii.adapter.jms.core.connector.ConnectorImpl.connectIfDisconnected(ConnectorImpl.java:237)

    at com.sap.aii.adapter.jms.core.connector.ConnectorImpl.connect(ConnectorImpl.java:220)

    at com.sap.aii.adapter.jms.core.channel.ChannelImpl.doStart(ChannelImpl.java:422)

    at com.sap.aii.adapter.jms.core.channel.ChannelImpl.start(ChannelImpl.java:179)

    at com.sap.aii.adapter.jms.core.channel.AdapterImpl$1.run(AdapterImpl.java:857)

    at com.sap.engine.core.thread.impl3.ActionObject.run(ActionObject.java:37)

    at java.security.AccessController.doPrivileged(Native Method)

    at com.sap.engine.core.thread.impl3.SingleThread.execute(SingleThread.java:185)

    at com.sap.engine.core.thread.impl3.SingleThread.run(SingleThread.java:302)

    Caused by: java.lang.NoClassDefFoundError: org/slf4j/LoggerFactory

    at com.rabbitmq.jms.admin.RMQConnectionFactory.<init>(RMQConnectionFactory.java:32)

    … 17 more

    Error starting channel: com.sap.aii.af.service.cpa.impl.object.ChannelImpl@b8059564 with ID=7b4b0b1df4ad30d5ada9ea9de6f8cd56 due to com.sap.aii.adapter.jms.api.connector.ConnectorException: Cannot construct connection factory using constructor: ConstructorInvocationException: Error executing constructor invocation:

    {ConstructorInvocation

    {className=com.rabbitmq.jms.admin.RMQConnectionFactory,

    invokeParams=[]

    }: java.lang.reflect.InvocationTargetException

    Do you have yet another approach how we can make this Scenario working?

    Kind regards

    Christof

    PS: with Java Producer and consumer Programm it is possible to write to and read from the queue above.

     

    (0) 
  8. Christof Johner

    PS2: the parameters used for the Java producer /consumer programm is as follows:

    If this 12 Parameters are used in the PI CC channel the same error like above occurs.

    (0) 
    1. Vadim Klimov Post author

      Hi Christof,

      Actually, XPI Inspector trace you provided, contains valuable input – note nested exception saying “java.lang.NoClassDefFoundError: org/slf4j/LoggerFactory”. This one would appear, if not all dependencies required by RabbitMQ JMS client library were added to com.sap.aii.adapter.lib.sda – here in particular, slf4j library seems missing. Please check that following libraries are added to com.sap.aii.adapter.lib.sda:

      • rabbitmq-jms
      • amqp-client
      • geronimo-jms_1.1_spec
      • slf4j-api

      For example, for the latest RabbitMQ JMS client version that is available currently in public repository (version 1.9.0), they will be:

      • rabbitmq-jms-1.9.0.jar
      • amqp-client-4.6.0.jar
      • geronimo-jms_1.1_spec-1.1.1.jar
      • slf4j-api-1.7.25.jar

      Regards,

      Vadim

      (0) 
  9. Christof Johner

    Hello Vadim

    Thanks, you’re right, so xpi inspector provided the necessary input to get one step further: I’ve added this library slf4j-api:

    Now this new error “Catching java.lang.UnsupportedClassVersionError: com/rabbitmq/client/ConnectionFactory” appears:

    Could this be due to our java version in the PI:

    I didn’t find and prerequisites on the java version to be used. Or is this yet another problem?

    Kind regards
    Christof

    (0) 
    1. Vadim Klimov Post author

      Hi Christof,

      Yes, you are right: exception UnsupportedClassVersionError is thrown if JVM’s runtime version is not compatible with the version, for which corresponding library was compiled. Your system uses SAP JVM 1.6, so libraries shall be compliant to this version. Hence, you can give a try downgrading version of used libraries to the version that is relevant for Java 1.6. Here, it is also important to note that is sake of consistency, it will be worth re-downloading all dependencies for RabbitMQ JMS client so that their versions correspond to what RabbitMQ JMS client library expects.

      At a time of a blog writing, I configured this scenario on PO 7.4 system, which was also based on JVM 1.6. Following set of library versions worked well for me that time:

      • rabbitmq-jms-1.4.4.jar
      • amqp-client-3.5.4.jar
      • geronimo-jms_1.1_spec-1.1.1.jar
      • slf4j-api-1.7.5.jar

      You can check if there is a version newer than RabbitMQ JMS client version 1.4.4, which is still compliant to Java 1.6 – that shall still work.

      Regards,

      Vadim

      (0) 
  10. Christof Johner

    Hello Vadim

    Thanks for the confirmation. I’ve downgraded the versions as follows:

    • rabbitmq-jms-1.4.7.jar (rabbitmq-jms-1.4.4.jar was not available anymore)
    • amqp-client-3.5.4.jar
    • geronimo-jms_1.1_spec-1.1.1.jar
    • slf4j-api-1.7.5.jar

    As a matter of fact this time it went a bit further but still refusing the connection:

    com.sap.aii.adapter.jms.api.connector.ConnectionException: Error creating Connection from JMS Connection Factory.: com.rabbitmq.jms.util.RMQJMSException: RabbitMQ connection was refused. RabbitMQ broker may not be available.

    However the port 5672 is open of the host when I telnet it from the PI-Server.

    If I run the java test-programm the RabbitMQ broker is available.

    Could the problem be now that the client version is to low in order to successfully connect to the broker?

     

    Kind regards

    Christof

     

     

    (0) 
    1. Vadim Klimov Post author

      HI Christof,

      Although it is generally nice to have client and server side aligned in versions, it is not always possible – such as the case you faced with the JMS client. Versions should normally be backward compatible – from the personal experience, we didn’t have issues so far with the client side (in PO), when the server side (RabbitMQ message broker) got updated. To ensure this, it might be helpful to get RabbitMQ logs and see if there is anything in there, but connection refused type of error would commonly originate from lower level, network. When looking into details of the exception, I see it says: “Connection refused: connect (local port 63487 to address 0.0.0.0, remote port 5672 to address 127.0.0.1 (localhost))”. I’m a bit confused why the request was sent to the localhost (unless RabbitMQ server runs on the same host as PO application server – but even in that case, it would be worth double checking if local or network adapter interface will be used by PO). Can you please check with the network team how routing is done and what they see about traffic leaving PO application server’s host when you perform telnet test to RabbitMQ server from the terminal, and when you attempt to start communication channel targeting that RabbitMQ server?

      Regards,

      Vadim

      (0) 
  11. Christof Johner

     

    Hello Vadim

    finally it’s working although with one little restriction: only IP hostname works,
    hostname does not yet.

    Let me first explain the issues we had to get out of the way:
    although the port 5672 was reachable by the “telnet” command it still got blocked
    by a firewall rule which impeded the construction of the connection.
    The has now been remedied by our network team and the connection works.

    The only problem is that we have to use the IP adresse instead of the hostname. Because our
    hostname contains special character like “-“.
    It seems that the special character “-” gets interpreted as “?” in the RabbitMQ classes:

    The definition looks like this:

    The same applies for the user name: we had to omit “-” in the user Name.

    Do you know of any restrictions on the usage of special  characters like “-” in the RabbitMQ context?

     

    Kind regards

    Christof

     

     

    (0) 
    1. Vadim Klimov Post author

      Hi Christof,

      Good to know you progressed a lot with the issue!

      I’m not aware of restrictions for dash (hyphen) symbol usage in either host name, or user name in RabbitMQ.

      Moreover, in one of our non-production systems, RabbitMQ broker’s name contains hyphen in the name of the server, and a communication channel establishes connection successfully. I traced that receiver channel, and opposite to the issue you got with replacement of hyphen with the question mark, in the trace I’ve collected, hyphen was recognized correctly. In the trace, before RabbitMQ connection factory is invoked, can you check if host name with hyphen symbol is recognized correctly? At the beginning of a channel trace, there shall be series of calls that read additional parameters and make use of them further – can you see if host name gets corrupted right from the beginning, or this happens on later stages, when the value is passed to RabbitMQ’s connection factory?

      As for a user name, checking client library, I see that user name is handled as String, so also shall not bring any restrictions for hyphen usage.

      Regards,

      Vadim

      (0) 
  12. Christof Johner

     

    Hello Vadim

     

    we could finally also sort ou the last problem with the hyphen:

    The string was copy pasted from the mail given from the provider.

    For some reason the hyphen was “dirty”, after entering it manually the problem disappeared.

    We’d like to thanks you for prompt and expert advice and wish you well.

     

    Kind regards

    Christof

    (0) 
    1. Vadim Klimov Post author

      Hi Christof,

      I’m very glad to hear that you finally made it work, congratulations! Good it all got sorted finally.

      Regards,

      Vadim

      (0) 

Leave a Reply