Getting message in ibmmq Node.js - node.js

I'm using ibmmq module https://github.com/ibm-messaging/mq-mqi-nodejs
I need to get an xml message from a queue and than make an xsl-transformation.
I put messages to the queue with JMeter and if I browse messages in rfhutil I can see them as is on the Data tab.
But when I get it in the code
function getCB(err, hObj, gmo,md,buf, hConn ) {
// If there is an error, prepare to exit by setting the ok flag to false.
if (err) {...
} else {
if (md.Format=="MQSTR") {
console.log("message <%s>", decoder.write(buf));
} else {
console.log("binary message: " + buf);
}
}
I get my message with some service information:
buf=RFH �"�MQSTR � <mcd><Msd>jms_text</Msd></mcd> X<jms><Dst>queue://MY_QM/MY_QUEUE</Dst><Tms>1657791724648</Tms><Dlv>2</Dlv></jms> ...My_message...
How can I get only My message like I do in rfhutil?
I can get it with string methods, but it looks like crutches.

That message has the headers created by a JMS application. There are various ways of dealing with it. You can
Have the sending app disable sending that structure (setting the targClient property)
Use GMO options to ignore the properties (MQGMO_NO_PROPERTIES)
Have your application deal with the RFH2 stucture. See for example the amqsget.js sample in the Node.js repo which includes this fragment:
switch (format) {
case MQC.MQFMT_RF_HEADER_2:
hdr = mq.MQRFH2.getHeader(buf);

Related

Azure Topic Subscription Rule created with Service Bus Explorer not triggering

I am using Service Bus Explorer as a quick way of testing a rule that does not work when deployed via ARM.
In JavaScript in the Azure Function I am setting the Topic message to:
context.bindings.outputSbMsg = { Indicator: 'Itinerary'};
In Service Bus Explorer I am setting a Rule on a Subscription with this string:
Indicator = 'Itinerary'
But messages sent to the Topic do not go to this Subscription ( they go to another with the rule 1 = 1)
Question: What am I missing here?
Supplementary info:
I do not seem to have access to the Indicator property. As a test I created an action on the 1=1 rule that appended to the Indicator property and the result was empty.
I am able to access the Indicator property in JavaScript if I have a Function that is triggered by the 1 = 1 rule, so the property is there.
The rule doesn't work because
The rule works against system or user-defined properties rather than message body.
What js function outputs is merely message body, i.e. context.bindings.outputSbMsg = { Indicator: 'Itinerary'}; sends a message { Indicator: 'Itinerary'} and no property is set by us.
And the default rule with 1=1 true filter enables all messages to be selected into the subscription, so you see messages went there all the time. Check doc of topic filters for more details.
For now, it's by design that js function output can't populate message properties. To make the filter work, we have to send messages with property using SDK instead. Install azure-sb package then try sample code below.
const azuresb = require("azure-sb");
const connStr = "ServiceBusConnectionString";
const mytopic = "mytopic";
var serviceBus = azuresb.createServiceBusService(connStr);
const msg =
{
body: "Testing",
customProperties: {
Indicator: 'Itinerary'
}
};
serviceBus.sendTopicMessage(mytopic, msg, function(error) {
if (error) {
context.log(error);
}
else{
context.log("Message Sent");
}
});

cometd bayeux client can't get subscribed acknowledgement?

Actually i am running cometd-demo server in my local using maven jetty run shown in the doc https://docs.cometd.org/current/reference/ and trying to subscribe and publish something in a broadcast channel. Using Groovy script shown below,
ClientSessionChannel.MessageListener mylistener = new Mylistener();
def myurl = "http://localhost:8080/cometd/"
MyHttpClient httpClient = new MyHttpClient();
httpClient.start()
Map<String, Object> options = new HashMap<String, Object>();
ClientTransport transport = new LongPollingTransport(options, httpClient);
BayeuxClient client = new BayeuxClient(myurl, transport)
println 'client started on URL : '+ client.getURL()
client.handshake ( new ClientSessionChannel.MessageListener() {
public void onMessage(ClientSessionChannel channel, Message message) {
if (message.isSuccessful()) {
println 'Handshake Message : ' + message
}
}
})
boolean handshakecheck = client.waitFor(1000, BayeuxClient.State.CONNECTED);
println 'Handshake check : '+ handshakecheck
client.batch( new Runnable() {
public void run() {
client.getChannel("/foo/hello").subscribe(
new ClientSessionChannel.MessageListener() {
public void onMessage(ClientSessionChannel channel,
Message message) {
println "subscribed : "+ message
}
})
}
});
The program Output :
client started on URL : http://localhost:8080/cometd/
Handshake Message : [minimumVersion:1.0, clientId:fv0ozxw8cb5e11vtlwpacm7afp, supportedConnectionTypes:[websocket, long-polling, callback-polling], advice:[reconnect:retry, interval:0, maxInterval:10000, timeout:20000], channel:/meta/handshake, id:1, version:1.0, successful:true]
Handshake check : true
Here I can't get the subscribed message as in the code. But in server log It prints like shown below,
2018-02-12 20:30:32,687 qtp2069584894-17 [ INFO][examples.CometDDemoServlet] Monitored Subscribe from fv0ozxw8cb5e11vtlwpacm7afp,last=0,expire=0 for /foo/hello
Update 1:
Also i can't subscribe with callback method, i get the message as [channel:/meta/subscribe, id:4, subscription:/foo/hello, error:403:denied_by_not_granting:create_denied, successful:false]. I don't know what i am doing wrong ? I am just following the documentation steps. Thanks in advance.
The ClientSessionChannel.MessageListener that you pass to the subscribe(...) method will be invoked whenever a message will be published on channel /foo/hello.
Your program never publishes a message on that channel, so the listener is never invoked, therefore in your code subscribed is never printed.
You want to double check what version of the subscribe() method you want to use, as there are 2 versions.
The single parameter version takes a listener, while the two parameter version takes a listener and a callback.
Guessing from your code, you want the subscribed log line be in the callback not in the listener, so you just need to change your code to use the two parameter version of the subscribe() method.
Also, pay attention to the fact that if the JVM exits at the end of your groovy script, then that client will be gone and will never receive any message.

SNS Push Notifications with image using Node.js?

I am using Amazon SNS Mobile Push Notifications both for android and ios. I am quite successful with sending push notification with text and icon only. Now i am trying to send the notification with an image bottom. I searched every where but couldn't find a perfect docs to work on. Any suggestions please.
i installed this package using npm , i used this to send push notification. please refer this link.
https://www.npmjs.com/package/sns-mobile
AWS_SNS_App.getUsers(function (err, allDevices) {
if (err) {
console.log(err, err.stack); // an error occurred
} else {
if (allDevices.length != 0) {
var totalDevices = 0;
for (var i = 0; i < allDevices.length; i++) {
totalDevices = totalDevices + 1;
AWS_SNS_App.sendMessage(allDevices[i].EndpointArn, message, function (err, messageId) {
if (err) {
console.log('An error occured sending message to device %s');
res.send(err);
} else {
//res.send('Successfully sent a message to device , MessageID was : ' + messageId);
}
});
}
if (totalDevices === allDevices.length) {
res.send('Successfully sent a message to all devices');
}
}
}
});
sendMessage(endpointArn, message, callback) Send a message to a user.
The message parameter can be a String, or an Object with the formats
below. The callback format is callback(err, messageId).
from docs it indicates to send a endpointArn,message and we will get a callback of any response. what i suppose to send an image along with the image, is that possible or any another way to do that.
thanks.
Every image-containing push notification sent could contain a mediaReference that the app can later use to obtain content from a web service or from the apps bundled resources.
In any media case, the final resource link / bundle-resource-ref. can be composed within the app, (example) depending on other parameters within the push.
Remember that if the resource is not bundled you will have to download the image before displaying the notification (using it)
So the solution is in the client-side...
Implement specific methods for each of your platforms (android & ios), perform the required operations (i repeat, different and specific to the platform) in order to display the push notification with the image.
NOTE :
Tell me if you need references for building platform specific notifications with images. (and if so, what min sdk version you are using for each)

How to be notified of a response message when using RabbitMQ RPC and ServiceStack

Under normal circumstances messages with a response will be published to the response.inq, I understand that and it's a nifty way to notify other parties that "something" has happened. But, when using the RPC pattern, the response goes back to the temp queue and disappears. Is this correct? Is there a convenient way, short of publishing another message, to achieve this behavior, of auto-notification?
The Message Workflow docs in describes the normal message workflow for calling a Service via ServiceStack.RabbitMQ:
Request / Reply
The Request/Reply alters the default message flow by specifying its own ReplyTo address to change the queue where the response gets published, e.g:
const string replyToMq = mqClient.GetTempQueueName();
mqClient.Publish(new Message<Hello>(new Hello { Name = "World" }) {
ReplyTo = replyToMq
});
IMessage<HelloResponse> responseMsg = mqClient.Get<HelloResponse>(replyToMq);
mqClient.Ack(responseMsg);
responseMsg.GetBody().Result //= Hello, World!
When using the Request/Reply pattern no other message is published in any other RabbitMQ topic/queue, to alert other subscribers the client would need to republish the message.
RabbitMqServer callbacks
Another way to find out when a message has been published or received is to use the PublishMessageFilter and GetMessageFilter callbacks on the RabbitMqServer and Client which lets you inspect each message that they sent or received, e.g:
var mqServer = new RabbitMqServer("localhost")
{
PublishMessageFilter = (queueName, properties, msg) => {
//...
},
GetMessageFilter = (queueName, basicMsg) => {
//...
}
};

Cannot deserialize some tweets using NewtonSoft.Json

Hi All,
I am running a C# console app that is using the Twitter Stream API. My code is below
JToken json = JObject.Parse(ResponseStream.ReadLine());
For every +- 20 tweets, I get the following error "Error reading JObject from JsonReader".
I copied the json into JSONLint and it is valid, so I am perplexed to why this keeps happening. Has anyone else had this error?
Yes, and it just started happening recently. I believe it is either a bug with NewtonSoft.Json or a change in the twitter api causing it to send bad jsons. I did a packet capture and found the offending character by counting them, but I didn't see anything wrong. I think we will just have to wait for this bug to be fixed.
update
I downgraded Newtonsoft.Json.dll to 4.3.* and it works fine.
I found the issue. Sometimes the stream returns an empty string. Therefore parsing an empty string will throw an error. An example below on how I protected against it:
public static void ProccessTweet(object objMessage)
{
if(objMessage.ToString() != "")
{
var json = JObject.Parse(objMessage.ToString());
if (json["retweeted_status"] == null)
{
var message = ProcessNewTweet(json);
Db.Votes.Add(new FNBVote
{
Message = message,
Entry = Db.Entries.Find(message.Entry.EntryId)
});
return;
}
ProcessRetweet(json);
}
}

Resources