I am trying to send message and receive response using following code
MessageProperties props =MessagePropertiesBuilder.newInstance().setContentType(MessageProperties.CONTENT_TYPE_TEXT_PLAIN)
.setMessageId("MSG12345").setHeader("type", "type1").setCorrelationId(UUID.randomUUID().toString().getBytes()).build();
Message message = MessageBuilder.withBody(input.getBytes()).andProperties(props).build();
Message response = (Message) template.convertSendAndReceive("key", message);
But, its is throwing ava.lang.ClassCastException: java.lang.String cannot be cast to org.springframework.amqp.core.Message
May be because, I am sending request using java (spring-amqp) program and the receiver is a python (pika) program.
Recevier is sending me a JSON object dumped in string format but I am not able to handle it.
Your problem that you use RabbitTemplate.convertSendAndReceive():
/**
* Basic RPC pattern with conversion. Send a Java object converted to a message to a default exchange with a
* specific routing key and attempt to receive a response, converting that to a Java object. Implementations will
* normally set the reply-to header to an exclusive queue and wait up for some time limited by a timeout.
*
* #param routingKey the routing key
* #param message a message to send
* #return the response if there is one
* #throws AmqpException if there is a problem
*/
Object convertSendAndReceive(String routingKey, Object message) throws AmqpException;
Even if your payload is Message and we we have:
protected Message convertMessageIfNecessary(final Object object) {
if (object instanceof Message) {
return (Message) object;
}
return getRequiredMessageConverter().toMessage(object, new MessageProperties());
}
It converts a reply into a target object from body:
return this.getRequiredMessageConverter().fromMessage(replyMessage);
and don't return Message as you expected.
So, you really have to cast to String and deal with your JSON already on your own.
Related
I'm using Spring AMQP to send message from one microservice to other one and get response.
I can send message and receive content with this code part:
public void sendAmqpCoreMessage(Message message) throws JsonProcessingException {
List<MyCustomType> response = rabbitTemplate.convertSendAndReceiveAsType("jms.durable.queues", this.queue.getName(), message, new ParameterizedTypeReference<List<MyCustomType>>() {
});
logger.info("Response: {}", new ObjectMapper().writeValueAsString(response));
}
But instead of getting only message content, I need the whole Message object because I'm using some headers which stay in messageProperties of response which's type is Message.
How can I get Message object as response?
Don't use the convert... methods with a Message, just use sendAndReceive().
Business Impact: Not being able to use the Pub/Sub job update notifications feature. Issue Summary: We (Recall) are trying to use the Pub/Sub notifications for job updates (https://cloud.google.com/transcoder/docs/how-to/create-pub-sub).
However, since the PubsubMessage data is serialized into bytes [1], without knowing the proto type, we cannot deserialize it [2]. (Unless the intention is to treat the data as a string and parse from there?)
Based off the message we see published in the Pub/Sub topic:
data: "{\"job\":{\"name\":\"projects/PROJECT_NUMBER/locations/us-central1/jobs/JOB_ID\",\"state\":\"SUCCEEDED\",\"failureReason\":null}}"
message_id: "2356400951506061"
publish_time {
seconds: 1620063162
nanos: 430000000
}
We were guessing that the type is google.cloud.video.transcoder.v1beta1.Job [3], but parsing the message into that type throws InvalidProtocolBufferException.
Is this the type we should be using to deserialize the message? Any tips to help parse the published message would be helpful.
Thanks!
Pubsub message in v1beta1 doesn't refer to any protos. The data is in json form so I think you could "treat the data as a string and parse from there".
The message in transcoder v1 will be in proto format. The doc has not been updated yet. Please check later
https://cloud.google.com/pubsub/docs/pull
Here is documentation, they have mentioned we need to convert the buffer to string and then we can parse the data.
// Create an event handler to handle messages
let messageCount = 0;
const messageHandler = message => {
console.log(`Received message ${message.id}:`);
console.log(`\tData: ${message.data}`);
console.log(`\tAttributes: ${message.attributes}`);
messageCount += 1;
// "Ack" (acknowledge receipt of) the message
message.ack();
};
// Listen for new messages until timeout is hit
subscription.on('message', messageHandler);
I have tried the same
converting buffer to a string
parsing the string
let stringData = message.data.toString();
console.log(stringData);
let jsonData = JSON.parse(stringData);
console.log(jsonData);
This worked for me in javascript
I'm starting out with Mirth and HL7 and I'm trying to send a message to a remote server. My MSH looks as follows:
MSH|^~\&|EPIC|EPIC|IMG_SCHEDULE_APPT|REMOTE|20170328193318|PERSONNAME|ORM^O01|12345678|T|2.4||||||||||
The response looks as follows:
MSH|^~\&|IMG_SCHEDULE_APPT|REMOTE|EPIC|EPIC|20170328193318||ACK|12345678|T|2.4|
MSA|AA|||
and I get an error saying ERROR: Message control Ids do not match.
As far as I understand this error means that the Message Control Id which is returned in the ACK message is not the same.
From what I can see, the number 12345678 is the Message Control Id, and I see that number both in the message I send as well as the in the ACK which is returned. So what is wrong here? And who is at fault? Me or the remote party?
Does anybody know how I can solve or debug this?
If you don't want to validate the message control ID, you can open the Response Validation properties and uncheck "Validate Message Control Id":
If the remote system cannot change their logic and you still want to validate the control ID, you can do that in a response transformer:
if (responseStatus == ERROR) {
// msg here is the ACK, origMsg is the encoded data that was sent outbound
var origMsg = new XML(SerializerFactory.getSerializer('HL7V2').toXML(connectorMessage.getEncodedData()));
if (origMsg.MSH['MSH.10']['MSH.10.1'].toString() == msg.MSH['MSH.10']['MSH.10.1'].toString()) {
responseStatus = SENT;
}
}
MSA.2 (Message Control ID) is required and should be the same as the ControlId in the former message that the ACK message acknowleges..
How do I update a sent QBChatMessage in the server? For e.g. After the message is sent/delivered, how does one update it's text or custom parameters. Also are there parameters that cannot be changed or updated once sent and delivered?
Here's a link to the snippet on Quickblox Android that seems to be doing the same. How is this achieved in IOS?
There is a method in QBRequest:
/**
Update existing chat message - mark it as read.
#param message Сhat message to update.
#param successBlock Block with response instance if request succeded.
#param errorBlock Block with response instance if request failed.
#return An instance of QBRequest for cancel operation mainly.
*/
+ (QBRequest *)updateMessage:(QBChatMessage *)message
successBlock:(nullable void(^)(QBResponse *response))successBlock
errorBlock:(nullable QBRequestErrorBlock)errorBlock;
The usage is the same as in android pretty much. Here you can read which fields you can update: http://quickblox.com/developers/Chat#Fields_to_update_2
I have implemented a chat sample app using Quickblox,And I followed SampleChat app provided by Quckblox(Urls provided below). But I want to update Read and Delivery status of each message. How to achieve this?
http://quickblox.com/developers/SimpleSample-chat_users-ios
https://github.com/QuickBlox/quickblox-ios-sdk/tree/master/sample-chat
In link 1 they have explained some code but I'm unable to implement.
There are docs for read and delivered status in the link you provided.
To make this answer more explicit, there are several ways to mark messages as read and delivered. For delivered marking there is only XMPP way available, use this method from QBChat to do it:
/**
* Send "delivered" status for message.
*
* #param message QBChatMessage message to mark as delivered.
* #param completion Completion block with failure error.
*/
- (void)markAsDelivered:(QB_NONNULL QBChatMessage *)message completion:(QB_NULLABLE QBChatCompletionBlock)completion;
For read marker you can use either REST request using QBRequest method:
/**
Mark messages as read.
#note Updates message "read" status only on server.
#param dialogID dialog ID.
#param messagesIDs Set of chat message IDs to mark as read. If messageIDs is nil then all messages in dialog will be marked as read.
#param successBlock Block with response instance if request succeded.
#param errorBlock Block with response instance if request failed.
#return An instance, which conforms Cancelable protocol. Use this instance to cancel the operation.
*/
+ (QB_NONNULL QBRequest *)markMessagesAsRead:(QB_NONNULL NSSet QB_GENERIC(NSString *) *)messagesIDs
dialogID:(QB_NONNULL NSString *)dialogID
successBlock:(QB_NULLABLE void(^)(QBResponse * QB_NONNULL_S response))successBlock
errorBlock:(QB_NULLABLE QBRequestErrorBlock)errorBlock;
or XMPP method of QBChat:
/**
* Send "read" status for message and update "read" status on a server
*
* #param message QBChatMessage message to mark as read.
* #param completion Completion block with failure error.
*/
- (void)readMessage:(QB_NONNULL QBChatMessage *)message completion:(QB_NULLABLE QBChatCompletionBlock)completion;
Anyway look closer to samples and documentation if you need a "live" example.