setting a message attribute of a message in an SQS queue w/boto? - boto

Is there a way to set a message attribute of a message in an SQS queue? I am trying to examine a message sent to an SQS queue and change its value. The last line of the code below gets and prints the value.
for message in queue.receive_messages(MaxNumberOfMessages=10, AttributeNames=['All'], MessageAttributeNames=['All']):
print(message.body)
print(message.attributes)
print(message.message_attributes)
print(message.message_attributes.get('attr').get('StringValue'))
I would like a way of setting the StringValue of attr in this message. Is there any way of doing that? I would prefer a way of doing this using boto (rather than boto3).

The message attributes of an SQS message are immutable once the message has been sent to the queue. The SQS Query API (used by all client libraries) has no support for modifying a message in the queue, other than to change its visibility timeout.

Related

BizTalk - Why does a suspended message appear in the console for a handled exception?

Here is an image of a common structure we have in a few of our BizTalk orchestrations:
So when we GET information from an API and the account doesn't exist, we terminate the orchestration. This works fine and I can see the orchestration doing this and terminating when it should, but what I don't understand is why do I see the suspended message from the GET in the console? Since the exception handling works, shouldn't this stop an error showing in the console?
As a way around this, I've considered using a pipeline component to check the response message, and if it contains what would be ignored, just return null in place of the message. Would this have the desired effect? I'm more interested as to why I see the suspended messages in the console.
Yes, this is a known issue with the WCF-WebHttp adapter, that has to do with the fact that it throws it back as a SOAP formatted error, but without setting the MessageType context property (see my blog post and look for Bug: BizTalk WCF-WebHttp adapter does not set the message type on error). So although the exception is thrown back at the Orchestration and can be handled there, the message is not as BizTalk does not know what type it is and it suspends.
A workaround we use is
To set Enable Routing for failed messages on the send port
To have a send port that subscribes to all the response messages from that send port using the BTS.SPName = xxxx filter, and send port sends it to a custom NULL adapter (throw the message away), and yes, your Orchestration will still get the good response as well as the exceptions.
Update the send port that handles routing errors from other send ports that we do want to go to our exception handing to exclude those send ports which we are handling via an Orchestration.

Message does not contain valid HTTP context information, Need return context info

I am using IBM integration toolkit
I have an application with two flows; the request flow has a json request message using http request node then the message is thrown to another flow (in another application representing a stub)through a MQ Input, compute node then MQ reply.
It then throws the message to the response flow in my application through MQ Input
I need to output the message in a json form through http reply node but in the flow it runs an exception "Message does not contain valid HTTP context information, Need return context info"
if anyone have a clue for this error and how to solve it
Thanks in advance
The problem is that your HTTP response flow does not know which request it has to respond.
In case you really need your request and response to be implemented as different flows, you have to store identifier of incoming HTTP or SOAP request somewhere, for example as a message in some dedicated queue.
In your request flow you can find identifier of request in
InputLocalEnvironment.Destination.HTTP.RequestIdentifier
or
InputLocalEnvironment.Destination.SOAP.RequestIdentifier
depending on the type of your input node.
Then, your response flow should read a message written by request flow to find a value of RequestIdentifier.
This value should be set into the LocalEnvironment of response message assembly:
OutputLocalEnvironment.Destination.HTTP.Reply.ReplyIdentifier
or
OutputLocalEnvironment.Destination.SOAP.Reply.ReplyIdentifier
Here is IBM doc: https://www.ibm.com/support/knowledgecenter/SSMKHH_9.0.0/com.ibm.etools.mft.doc/ac20450_.htm#ac20450___le
When the HTTPInput node receives an input request message, it sets the local environment field Destination.HTTP.RequestIdentifier to a unique value that identifies the Web service client that sent the request. You can refer to this value, and you can save it to another location if appropriate.
For example, if you design a pair of message flows that interact with
an existing WebSphere MQ application (as described in Broker calls
existing Web service), you can save the identifier value in the
request flow, and restore it in the reply flow, to ensure that the
correct client receives the reply. If you use this technique, you must
not change the data, and you must retain the data as a BLOB.
The HTTPReply node extracts the identifier value from the local
environment tree and sets up the reply so that it is sent to the
specific client. However, if you are using an HTTPReply node in a flow
that does not have an HTTPInput node, and this field has been deleted
or set incorrectly, message BIP3143S is issued.

Passing messages in message Queue

How can I, in my application, sent a message as input to my application using message queue?
It is showing as number of messages in message queue is zero.
Providing that you use Linux and C language, a simple example how POSIX message queue can be used to pass data between separate threads or processes can be found here.

Trying to get message via message id and Boto

I am trying to get a message via a message id by using Boto.
This question:
Trying to Get SQS Message ID with Boto
Makes me think that Boto might have a way to get a message by a message id, but I can't find anything in the Boto documentation.
Is there anyway to get a message via message id?
No, there isn't. The SQS API does not provide a way to retrieve a message body given a message id. All you can do is read messages from the queue.
The question you link to is about how to get the message ID from a message that you have already read. That is possible and the details can be found in that message.
I dont know what exactly your problem is, however, in my case:
I am getting about 20 messages at once from Sqs and processing them asyncronously. When a message done, I want to delete it from sqs. So, I put the progressing message to a HashMap with Id value.
When I am done with message I get it from Map easily.
If you have Id of message, you should also have Message object before. And If the range of Message count is not so much you can also use Maps.
Message msg = onProcess.get(processId);
sqs.deleteMessage(new DeleteMessageRequest().withQueueUrl(queueUrl).withReceiptHandle(msg.getReceiptHandle()));
onProcess.remove(processId);

is it possible to send a data when a websocket connection is opened

I am implementing a Jetty Websocket servlet.
When the server receives a new connection, I want to send a message that will be read by websocket's onopen function. I want this message to be sent only during the open and not using the regular connection.SendMessage() function. Is it possible to do that? and how?
Don't forget the query string. It's valid in WebSocket url.
new Websocket('ws://yoursite.com/path?a=1&b=2&c=3')
Then you can easily parse this url on server side to retrieve the data.
There is no support for this in the protocol but you could fudge something yourself.
When your server completes a handshake, store the initial message you want to deliver to a client.
In your client's onopen function, send a "read initial message" request.
In your server, check that this client hasn't read its initial message; respond with the message; set a flag saying that the initial message has been sent.
Your client and server are both now free to send other messages.