Get only MQ9 messages that belong to a group "2" in C++ - c++

I am trying to use IBM MQ client 9 with C++. I would like to read only messages that has group id '2'. I have tried everything but it just does not work. Can someone assist please?
I tried to set groupId and flag to match on group.
MQGET
gmoptions.setMatchOptions(MQMO_MATCH_GROUP_ID);
MQBYTE24 bGroupId("2");
ImqBinary _groupId;
_groupId.set(bGroupId, sizeof(bGroupId));
message.setGroupId(_groupId);
q->get(message, gmoptions);
MQPUT
MQBYTE24 bGroupId("2");
ImqBinary _groupId;
_groupId.set(bGroupId, sizeof(bGroupId));
message.setGroupId(_groupId);
ImqPutMessageOptions pmo;
pmo.setOptions(MQPMO_LOGICAL_ORDER);
pmo.setRecordFields(MQPMRF_GROUP_ID);
q->put(message, pmo);
mqget should be able to get all the msgs with groupId "2" but it does not. Though it can read the msg as soon as I remove setMatchOptions.
Basically, I want to use Group Id as filter where server instance 1 will read msgs only in group1 and server instance 2 will read msgs only in group 2 and so on, instead of creating separate queues for each server instance.
May be following can help me if group id is only for batching instead of filtering though not sure how to do 'Selection using the MQSUB and MQOPEN function calls' in C++
https://www.ibm.com/support/knowledgecenter/SSFKSJ_9.0.0/com.ibm.mq.dev.doc/q022990_.htm
Is there any C++ equivalent of MQSETMP ? I am unable to find any interface in ImqQueue or ImqObject that will let me set message property or selectionString.

I don't think you are going about this the right way.
IBM published a Java/MQ sample program to get messages in a group called GetGroup.java. You can find it here. You can use it as a model for your C++ program.
Basically, the code retrieves a message from the queue and then checks the messageFlags field if the message is part of a group.
if ((myMessage.messageFlags & CMQC.MQMF_MSG_IN_GROUP) == CMQC.MQMF_MSG_IN_GROUP)
If the message is part of the group then the code sets the matchOptions for matching on a group and retrieves all of the messages in the group.
Note: You will probably want to add logical order to the GMO options.
gmo.options |= CMQC.MQGMO_LOGICAL_ORDER;
Finally, what is this?
pmo.setRecordFields(MQPMRF_GROUP_ID);
That doesn't make any sense. You should be setting messageFlags field to MQMF_MSG_IN_GROUP.

You can use the concept of SELECTORS in IBM MQ. A message selector is a variable-length string used by an application to register its interest in only those messages that have properties that satisfy the Structured Query Language (SQL) query that the selection string represents.
A message selector is a concept that has been in the JMS specification for a long time. It
is a way of limiting the messages that are passed to an application to those that meet
certain criteria. Those criteria are based on the values of the message properties and only
the value of the message properties. It is important to understand that selection cannot be
based on any values of the message payload, only on the message property values.
In your case, the PUT application will have to put messages with populating the a certain topic string in MQMD or MQRFH2 header and using MQ Interface function calls, you should be able to pick the messages only with a certain value which in your case is GroupId value.
Below are few reference links to the concept:
https://www.ibm.com/support/knowledgecenter/SSFKSJ_7.5.0/com.ibm.mq.dev.doc/q022990_.htm
http://publib.boulder.ibm.com/infocenter/ieduasst/v1r1m0/topic/com.ibm.iea.wmq_v7/wmq/7.0/MQI/iea_330_wmqv7_API_3_Selectors.pdf ==> Pdf gets downloaded
To understand Message Properties => https://www.ibm.com/support/knowledgecenter/en/SSFKSJ_8.0.0/com.ibm.mq.dev.doc/q022920_.htm

Related

DynamoDB Single Table Design guidance

First time building a single table design and was just wondering if anyone had any advice/feedback/better ways on the following plan?
Going to be building a basic 'meetup' clone. so e.g. Users can create events, and then users can attend those events essentially.
How the entities in the app relate to eachother:
Entities: (Also added an 'ItemType' to each entity) so e.g. ItemType=Event
Key Structure:
Access Patterns:
Get All Attendees for an event
Get All events for a specific user
Get all events
Get a single event
Global Secondary Indexes:
Inverted Index: SK-PK-index
ItemType-SK-Index
Queries:
1. Get all attendees for an event:
PK=EVENT#E1
SK=ATTENDEE# (begins with)
2. Get All Events for a specific User
Index: SK-PK-index
SK=ATTENDEE#User1
PK=EVENT# (Begins With)
3. Get All Events (I feel like there's a much better way to do this, if there is please let me know)
Index: ItemType-SK-Index
ItemType=Event
SK=EVENT# (Begins With)
4. Get a single event
PK=EVENT#E1
SK=EVENT#E1
A couple of questions I had:
When returning a list of attendees, I'd want to be able to get extra data for that attendee, e.g. First/Lastname etc.
Based on this example: https://aws.amazon.com/getting-started/hands-on/design-a-database-for-a-mobile-app-with-dynamodb/module-5/
To avoid having to duplicate data and handle when data changes, (e.g. user changes name) use Partial Normalization and the BatchGetItem API to retrieve details?
For fuzzy searches etc, is the best approach to stream this data into e.g. elastic/opensearch?
If so, when building API's - would you still use dynamoDB for some queries, or just use elasticsearch for everything?
e.g. for Get All Events - would using an ItemType of 'Events' end up creating a hot partition if there's a huge number of events?
Sorry for the long post, Would appreciate any feedback/advice/better ways to do things, thank you!!

Message to create different types of DNS records

For work i am going to use use DNS records between two servers using a software made by the company. Mostly SRV, NAPTR and A records.
To propagate the information i have to create a new type of message which is going to be sent by a function in our software managing all messages.
Instead of creating 3 types of messages "SRv" "NAPTR "A" i thought about creating only one kind - general for all DNS records - with a part of the message dedicated to the type; NAPTR, A, SRV, MX etc...
I would like to have advice for the fields needed in this message, for example which fields are common for each DNS record type to include them in all messages, and which fields are specials for each records ? (Maybe creating a Data field in the message for additionnal informations specific for each type (prefix and protocol for NAPTR for example))
Actually for NAPTR (only one i did) i have various variables like TTL, zone, that i receive.
And i put every one in a stream and update it with :
system("nsupdate update.txt")
the file filled with the oss looks like this:
update add test.zone 60 NAPTR 10 100 "S" "SIP+D2T" "" _sip._tcp.zone.
send
But i would like to have a more general message which adapts for various DNS records if someday i need new ones.
Any help appreciated.
To solve the problem i created one message subdivised in two part, header and body. The header has all the common infos of the RR, like TTL, domain, Class, Type, and in function of the type i create a "length of data" and "data" field for each RR. For example NAPTR got data field with others fields in it, like Weight, Priority etc...
I did not found any better idea to factorise the informations.

How to create an intent with multiple slot values in its utterances in AWS Lex?

How do I create an intent which expects multiple consecutive slot values in its utterances which are set to expandable values? In the screenshot, the manufacturer model variant trio appears together in the utterances. Problem is the manufacturer and model slot types has possible two-three word values and variants could go up to five words. Lex is not able to understand the manufacturer utterances and straightaway detecting model slot type. How do I deal with this issue? Thanks.
intent utterance test chat screenshot slot data screenshot
You should greatly increase the values listed in your manufacture slotType so that it can better detect all the possibilities, especially since you need it to differentiate from the next slot.
Then also increase the variations of the intent utterances.
The error looks like the slotType is set to "Restrict to Slot values and Synonyms" so make sure you have it saved, built, and published with the setting "Expand Values" applied.
You should try to "teach" Lex as much as possible with all the expected variations of slotType values and utterances, but there will still be things that Lex will fail to catch. So I highly suggest using Lambda to parse the slot values, and sometimes the input itself so that you make sure the values are placed in the correct slots.

biztalk xpath query in orchestration

I am using decide shape in orchestration and I receive 2 xml file.
and i have filter that file using xpatch because depend first node i have to process in different map. I use xpach statement to get find if the first node equal specific value if yes it will process if not it wil be send to second map.
how i should do that? I do not do it usually and try to find out how my statement should look
xpath(ACKSchema(name(/*))== CstmrPmtStsRpt;
How to check if xml file equal specific condition?
thanks
You can use the xpath query function to probe the value in the message, or set the value. The syntax for receiving a string value is
variable = xpath(BiztalkMessage,"string(xpath-query)");
To set a value in the message
xpath(BiztalkMessage,"xpath-query") = value
An easy way to locate the xpath you want to use is to open the schema in the Visual Studio BizTalk project, and select the node that will hold your value. Then look at the properties window and use the 'Instance Xpath' value (see this post for more details)
The xpath query can be a bit verbose, and depending on your situation you could shorten it (with a small loss of fidelity). If you are comparing a string value, you'll want to use the string function;
xpath(msgTestMessage,"string(//MyNode)") == "TestValue"
Without the xpath string function, you'll be receiving the equivalent of a nodeset, rather than the value.
You may not need to use the xpath and decide shape at all if your two xml files have different root nodes.
Using direct bound ports BizTalk can route your messages to the correct "subscriber" for you automatically. You drop the two input messages into the message box database. If you create one subscriber for each message type BizTalk will send the messages to the correct subscriber for you.
BizTalk uses the target namespace and the root node name to decide which subscriber gets which message.

Repeating groups in quickfix/c++

I am writing a program that uses the quickfix library. The documentation is very poor, so I am requesting the help of SO fellows.
I have seen in the Group class that there are iterators. So I suppose that there is some STL-ish way of parsing repeating groups. Am I wrong?
Can anybody provide a simple example for doing that?
Thank you very much in advance.
Use Quickfix library alongwith the documentation of how FIX messages are constructed. Else it would be very difficult to decipher how the messages are organized.
This is an example from Quickfix website
Your message is the MarketDataSnapshotFullRefresh class object.
FIX::NoMDEntries noMDEntries;
message.get(noMDEntries); ->
You get the count of repeating groups, how many times you need to iterate over the object message to get all the entries. Remember FIX::NoMDEntries is a field.
FIX42::MarketDataSnapshotFullRefresh::NoMDEntries group; ->
This is a little tricky. You go inside a message to get the groups. Here NoMDEntries is an enclosed class inside MarketDataSnapshotFullRefresh class. Remeber this is the class which will give you the data. Now either you run through a loop or write the same code multiple times to extract all the fields inside each group. getGroup gives you the group from which you extract fields. getField will give you the field data. Most of the nomenclature of Quickfix is FIX messages. So refer a FIX message website like Fiximate and your life will be much easier.
FIX::MDEntryType MDEntryType;
FIX::MDEntryPx MDEntryPx;
FIX::MDEntrySize MDEntrySize;
FIX::OrderID orderID;
message.getGroup(1, group);
group.get(MDEntryType);
group.get(MDEntryPx);
group.get(MDEntrySize);
group.get(orderID);
message.getGroup(2, group);
group.get(MDEntryType);
group.get(MDEntryPx);
group.get(MDEntrySize);
group.get(orderID);
There are iterators in FieldMap class which is a super class of Message and Group class.
I'm not sure what do you mean by parsing repeating groups.
Fix engine parses raw fix messages for you when they arrive and your callback gets parsed FIX message - which has internal maps of tags (key/value) for tags in message header, body and tail.
Looking at 1.13.2 version of code, when the engine gets new string message from network it will eventually create a Message passing it the string. Message constructor then calls setString() on itself which effectively parses the received string and creates a map of tags.
If you look at Message::setString you can see that first the new field is added and then in setGroup it checks if the field is part of the group. If it is then this method, setGroup, takes over parsing of the following tags while those tags are part of the group. Once it comes across of tag that is not part of the group it stops parsing the group, it returns and continues parsing fields from message.
Now this all happens internally before the callback to your app where you handle received message.
There is a way to iterate over fields in a message. You can iterate over fields of header, body or over groups (and over each group).
const FIX40::ExecutionReport& msg; // new incoming message
// iterate over header
FIX::FieldMap::iterator it;
FIX::FieldMap::iterator b = msg.getHeader().begin();
FIX::FieldMap::iterator e = msg.getHeader().end();
for(it = b; it != e; ++it)
{
switch(it->first)
{
case FIX::FIELD::MsgSeqnum:
/* it->second.getString() - do something with tag data*/ ;
break;
...
}
}
And similarly for body:
FIX::FieldMap::iterator it;
FIX::FieldMap::iterator b = msg.begin();
FIX::FieldMap::iterator e = msg.end();
And there is groups iterator (FieldMap::g_begin/g_end) as well so you could iterate over groups in msg or header and you can similarly iterate, or search, tags within each group.
Group as well as Message extends FieldMap so all the getField/setField functionality is shared across.
Internals ... skip if too much detail.
In the above example this code:
message.getGroup(1, group);
group.get(MDEntryType);
Effectively passes the call from message.getGroup(1, group) -> FieldMap::getGroup(1, group.field(), group) -> getGroupRef(num,field) -> m_groups.find(field) which gives you a vector of groups (vector<FieldMap*>) and returns the num element, aka the num group from the message (a FieldMap).
group.get(field) is created using macros for each tag which is effectively translated as (map).getField(field).
During initialization the (map) for group is a reference to the object of which the tag is member of so it returns the tag from the specific group (see example src/C++/fix44/NewOrderSingle.h it has couple of internal classes which extend Group)
Hope that it makes some sense.