Correlation Id and Message Id in IBM MQ - c++

For a c++ and c program, I am trying to set a value for msgId or CorrelId for a particular message in IBM MQ, that will be later put to a topic. But there's an error of "Expression must be a modifiable L-value" for both the ids.
I defined the ids as
MQBYTE24 MsgId;
MQBYTE24 CorrelId;
and the MQMD is defined as default:
MQMD md = {MQMD_DEFAULT};
I cannot use the #define directive as I am trying to single out a message to be put to a topic from the publisher's end. Receive all the messages for subscriber and check for the particular message.
Is my approach of using correlIds or MsgIds correct or is there a better way for doing this?

I would expect you to have some code that looks like the following:-
memcpy(md.CorrelId, CorrelId, MQ_MSG_ID_LENGTH);
Please also remember that the message ID that you MQPUT to a topic does not end up at the subscribers. A new message ID is created for each copy of the published message that is given to each subscriber. You should use the Correlation ID instead to have it flow through to the subscriber, and ensure the subscribers are made correctly to receive the publishers correlation ID.
Read IBM MQ Little Gem #31: Publisher's CorrelId for more information about this.

Related

Can't access SQS message attributes using boto3

I'm trying to pass and then retrieve a message with attributes into AWS SQS.
Even though I can see attributes of a message through Management Console, I can't get them using boto3, always get None. Changing "AttributeNames" doesn't make a difference. Message body can be retrieved OK.
import boto3
sqs = boto3.resource('sqs', region_name = "us-west-2")
queue = sqs.get_queue_by_name(QueueName='test')
queue.send_message(MessageBody = "LastEvaluatedKey",
MessageAttributes ={
'class_number':{
"StringValue":"Value value ",
"DataType":"String"
}
}
)
messages = queue.receive_messages(
MaxNumberOfMessages=1,
AttributeNames=['All']
)
for msg in messages:
print(msg.message_attributes) # returns None
print(msg.body) # returns correct value
Attributes (system generated) and Message Attributes (user defined) are two different kinds of things provided by the back-end API.
You're looking for message attributes, but you're asking the code to fetch attributes, instead.
AttributeNames=['All']`
It seems like you need to be fetching message attributes...
MessageAttributeNames=['All']
...when calling queue.receive_messages(). Or, the specific message attribute names that you want, if known, could be used instead of 'All' (which -- had I designed this API -- would have been called '*', but I digress).
Admittedly, this is only an intuitive guess on my part based on familiarity with the underlying API, but it seems to be consistent with http://boto3.readthedocs.io/en/latest/guide/sqs.html.

c++ quickfix failure to send

I'm having an unexpected issue with a c++ quickfix client application using FIX 4.4. I form marketdatarequest and populate it and then call send which returns true. The message is not found in the message or event log files.
No error seems to be reported - what could be happening?
FIX44::MarketDataRequest request(FIX::MDReqID(tmp)
, FIX::SubscriptionRequestType('1')
, FIX::MarketDepth(depth)); // 0 is full depth
FIX::SubscriptionRequestType subType(FIX::SubscriptionRequestType_SNAPSHOT);
FIX44::MarketDataRequest::NoRelatedSym symbolGroup;
symbolGroup.set(FIX::Symbol(I.subID));
request.addGroup(symbolGroup);
FIX::Header &header = request.getHeader();
header.setField(FIX::SenderCompID(sessionSenderID));
header.setField(FIX::TargetCompID(sessionTargetID));
if (FIX::Session::sendToTarget(request) == false)
return false;
My FixConfig looks like:
[DEFAULT]
HeartBtInt=30
ResetOnLogout=Y
ResetOnLogon=Y
ResetOnDisconnect=Y
ConnectionType=initiator
UseDataDictionary=Y
FileLogPath=logs
[SESSION]
FileLogPath=logs
BeginString=FIX.4.4
DataDictionary=XXXXX
ConnectionType=initiator
ReconnectInterval=60
TargetCompID=tCompID
SenderCompID=sCompID
SocketConnectPort=123456
SocketConnectHost=XX.XX.XXX.XX
SocketConnectProtocol=TCP
StartTime=01:05:00
EndTime=23:05:30
FileLogPath=logs
FileStorePath=logs
SocketUseSSL=N
thanks for any help,
Mark
Mark, just couple of notes not really related to your question but which you may found useful:
you dont have to explicitly set TargetCompId/SenderCompId for each message, engine will do it for you.
Do not place logic into callbacks(like you did with market data subscription in onLogon). Better create additional thread which will consume events from you listener, make decisions and take an action.

Need information regarding publishing a double variable on to a ROS topic

I am using ROS to publish double variables on to a ROS topic. This topic will be advertising the topic so that any subscribers can access the data.
The following is the code which I have used to publish the data:
ros::NodeHandle n;
ros::Publisher Auc_pub = n.advertise<std_msgs::Float64>("/auc", 1000);
std_msgs::Float64 areaValue;
areaValue.data.push_back(Area)
Auc_pub.publish(areaValue);
Here Area is the double variable which I need to publish it over the topic /auc. I am not able to build this file as don't know how to enter the Area variable into the areaValue.
If you look at the documentation for std_msgs::Float64, it shows that it contains a single data field, which is called data and will be of type double in C++.
So, in your code, you just do:
areaValue.data = Area
assuming that Area is a double.
I suggest that you take a look at the basic Writing a simple Publisher and Subscriber tutorial on the ROS wiki.
EDIT
If what is in the original post is the entirety of your code, then it's probably not going to do exactly what you think it does. If you use the default constructor for a publisher, messages published on them are emitted once immediately. Any nodes subscribed to that topic at the moment of publishing will get the message, and then the topic will be clear. If you want any node that subscribes to the topic to receive the last message published on it, do the following:
ros::Publisher Auc_pub = n.advertise<std_msgs::Float64>("/auc", 1000, true);
That last bool true tells the publisher that it should latch messages that are published.
But you have yet another problem, presuming this is all your code: You never spin, so your node starts up, advertises its topic, publishes one message on it, and then shuts down, taking the topic with it (assuming nothing was subscribed to the topic). You need to add the following before the end of your main:
ros::spin();
This will keep the node active (and thus the topic alive) until ros::ok() returns false, I.E. until the node is killed.
Of course, your message is still only going to be published once, but the topic will at least stay alive. If you want the message to be broadcast periodically, use a ros::Timer and put the pulish call inside the timer's callback.
But seriously, please read the tutorials, they'll walk you through all of this stuff.
I finally found the solution for the problem. I had multiple ros:spinOnce() in the code. And also in the snippet
ros::NodeHandle n;
ros::Publisher Auc_pub = n.advertise<std_msgs::Float64>("/auc", 1000);
std_msgs::Float64 areaValue;
areaValue.data;
Auc_pub.publish(areaValue);
The publisher Auc_pub was created and destroyed ( As I had included the publisher in a function... my bad). Instead, i included the publisher in the main function where the publisher is created only once and stays alive until the execution completes. And, thanks to #aruisdante your suggestion helped.

Webport Issus with webmessage and multippart messages

I'm having an issue while creating orchestration by consuming webservice
Web message response variable name - msgReponse.webserviceResponse
multipart message response variable name - msgResponse.multipartresponse
I'm receiving the webmessage type(msgwebserviceResponse.Respone) from the webport.
Then after receive shape, I'm trying to map that response with another message.
So, here when I try map them by using the transfer shape, When I want to select msgResponse.multipartresponse as input schema for the map, I'm seeing msgResponse.multipartresponse(I can't see this, as I'm recieving msgReponse.webserviceResponse at receive shape)
could you please help me on this?
Thank You,
I had similar problems with yours. Asked a question and got an answer. Check this.

OpenDDS and notification of publisher presence

Problem: How can I get liveliness notifications of booth publisher connect and disconnect?
Background:
I'm working with a OpenDDS implementation where I have a publisher and a subscriber of a data type (dt), using the same topic, located on separate computers.
The reader on the subscriber side has overridden implementations of on_data_available(...)and on_liveliness_changed(...). My subscriber is started first, resulting in a callback to on_liveliness_changed(...) which says that there are no writers available. When the publisher is started I get a new callback to telling me there is a writer available, and when the publisher publishes, on_data_available(...) is called. So far everything is working as expected.
The writer on the publisher has a overridden implementation of on_publication_matched(...). When starting the publisher, on_publication_matched(...) gets called since we already have a subscriber started.
The problem is that when the publisher disconnects, I get no callback to on_liveliness_changed(...) on the reader side, nor do I get a new callback when the publisher is started again.
I have tried to change the readerQos by setting the readerQos.liveliness.lease_duration.
But the result is that the on_data_available(...) never gets called, and the only callback to on_liveliness_changed(...) is at startup, telling me that there are no publishers.
DDS::DataReaderQos readerQos;
DDS::StatusKind mask = DDS::DATA_AVAILABLE_STATUS | DDS::LIVELINESS_CHANGED_STATUS | DDS::LIVELINESS_LOST_STATUS ;
m_subscriber->get_default_datareader_qos( readerQos );
DDS::Duration_t t = { 3, 0 };
readerQos.liveliness.lease_duration = t;
m_binary_Reader = static_cast<binary::binary_tdatareader( m_subscriber->create_datareader(m_Sender_Topic,readerQos,this, mask, 0, false) );
/Kristofer
Ok, guess there aren't many DDS users here.
After some research I found that a reader/writer match occurs only if this compatibility criterion is satisfied: offered lease_duration <= requested lease_duration
The solution was to set the writer QoS to offer the same liveliness. There is probably a way of checking if the requested reader QoS could be supplied by the corresponding writer, and if not, use a "lower" QoS, all thou I haven't tried it yet.
In the on_liveliness_changed callback method I simply evaluated the alive_count in the from the LivelinessChangedStatus.
/Kristofer