JMS Correlation ID getting truncated - jms

I am setting uuid field as JMSCorrelationID to my outbound message. I also set the reply to Queue and reply to Quemanger for getting COD. After setting correct user Identifier I am able to receive the COD message in the set ReplyTo Q. But the correlationID received in the COD message has truncated the bytes of my UUID field to 32 bytes. Due to this I cannot reconcile the message to which COD was received. Please find below code while sending the message. I have omitted the ReplyToQ and ReplytoQm part but it works as expected.
if(msgUuidId != null){
msg.setJMSCorrelationID(msgUuidId);
}
logger.info("Setting IBM_REPORT_COD");
msg.setIntProperty(JmsConstants.JMS_IBM_REPORT_COD, MQC.MQRO_COD);
logger.info("Setting JMS_IBM_MQMD_USERIDENTIFIER to :: "+ userid );
msg.setStringProperty(JmsConstants.JMS_IBM_MQMD_USERIDENTIFIER, userid);
I am also setting the MQMD Context on destination
((MQDestination) destination).setTargetClient(WMQConstants.WMQ_CLIENT_NONJMS_MQ);
((JmsDestination) destination).setBooleanProperty(WMQConstants.WMQ_MQMD_READ_ENABLED, true);
((JmsDestination) destination).setBooleanProperty(WMQConstants.WMQ_MQMD_WRITE_ENABLED, true);
((MQDestination) destination).setMQMDMessageContext(WMQConstants.WMQ_MDCTX_SET_IDENTITY_CONTEXT);
While receiving the message I am reading as follows:. I am using Mule API
String correlationID = (String)eventContext.getMessage().getInboundProperty("JMSCorrelationID");
So here I am observing that the value is truncated hex portion of uuid which I had set. Can someone please help me with this?

Shashi's comment rang a bell. As can be read here, MQ truncates JMSCorrelationId to 48 hex digits/24 bytes:
Note 1: The MQMD CorrelId field can hold a standard WebSphere MQ Correlation ID of 48 hexadecimal digits (24 bytes). The JMSCorrelationID can be a byte[] value, a string value containing hexadecimal characters and prefixed with "ID:", or an arbitrary string value not beginning "ID:". The first two of these represent a standard WebSphere MQ Correlation ID and map directly to or from the MQMD CorrelId field (truncated or padded with zeros as applicable); they do not use the MQRFH2 jms.Cid field. The third (arbitrary string) uses the MQRFH2 jms.Cid field; the first 24 bytes of the string, in UTF-8 format, are written into the MQMD CorrelID.
Does that correlate (pun intended) to the truncation you're seeing? If so, the pragmatic solution would be to use a 24 byte correlation ID.
Cheers,

Related

<logic:messagesPresent> tag in Struts1 not looping through multiple errors in Action Messages

I have a field in a bean that is failing 2 validations, as such 2 messages are being inserted in ActionMessages with the following command:
validationErrors.add("field1", new ActionMessage("Phone number is greater than 10 digits", false));
validationErrors.add("field1", new ActionMessage("Phone number has invalid characters", false));
Although I see the errors in the ActionMessages object (by setting a breakpoint in the debugger), only the first one gets displayed in my JSP, where I have:
<logic:messagesPresent message="true">
<html:messages id="message" property="field1" message="true">
<logic:present name="message">
<c:out value="${message}"/>
</logic:present>
</html:messages>
</logic:messagesPresent>
Why is only the first message displayed, when <html:messages> should loop through all the messages where the property is "field1"?
I ended up figuring out my issue and it had to do with how I am creating the new ActionMessage.
When you use:
public ActionMessage(<error message>, false)
While it allows you to display a literal value by using the <html:messages> tag in conjunction with either a <bean:write> or <c:out>, it won't iterate over multiple messages for a given property, why I don't know.
I tested and found that if I use a resource bundle and create the ActionMessage with a standard:
public ActionMessage(<key in resource bundle>)
I am able to display multiple messages for a single property.
Unfortunately, because I am using hibernate validator I don't want to use a resource bundle and struts to replace the values (would rather have the hibernate validator annotation replace values) and will likely just display a single message at a time for now.
Struts <logic:messagesPresent> tag checks that the messages exist on the current request.
Messages are found in the request under the key Globals.MESSAGE_KEY. If you use attribute message only messages are checked.
By default the tag will retrieve the request scope bean it will
iterate over from the Globals.ERROR_KEY constant string, but if this
attribute is set to true the request scope bean will be retrieved
from the Globals.MESSAGE_KEY constant string. Also if this is set to
true, any value assigned to the name attribute will be ignored.
The <html:messages> tag is used to display the messages if specified attribute message is true.
Now you have used a property attribute that filters messages for the given property.
Name of the property for which messages should be displayed. If not
specified, all messages (regardless of property) are displayed.
If you have only one message with the field1 property, then only one message will be displayed.
Look here how can you use action messages object
ActionMessages messages = new ActionMessages();
messages.add(ActionMessages.GLOBAL_MESSAGE, new ActionMessage("error.common.field1.required");
saveMessages(request, messages); // storing messages as request attributes
Properties file:
error.common.field1.required = Field1 is required.
And display messages
<logic:messagesPresent message="true">
<html:messages id="message" message="true">
<bean:write name="message"/><br/>
</html:messages>
</logic:messagesPresent>
It will loop all massages under the global message key. If you want to use custom key you can use it with the parameter of ActionMessage
messages.add("field1", new ActionMessage("error.common.field1.required");
to retrieve the message
<logic:messagesPresent message="true">
<html:messages id="message" property="field1" message="true">
<bean:write name="message"/><br/>
</html:messages>
</logic:messagesPresent>

How to return localized content from WebAPI? Strings work but not numbers

Given this ApiController:
public string TestString() {
return "The value is: " + 1.23;
}
public double TestDouble() {
return 1.23;
}
With the browser's language set to "fr-FR", the following happens:
/apiController/TestString yields
<string xmlns="http://schemas.microsoft.com/2003/10/Serialization/">The value is: 1,23</string>
/apiController/TestDouble yields
<double xmlns="http://schemas.microsoft.com/2003/10/Serialization/">1.23</double>
I would expect TestDouble() to yield 1,23 in the XML. Can anyone explain why this isn't the case and, more importantly, how to make it so that it does?
It is because the conversion from double to string happens at different stage for each API. For the TestString API, double.ToString() is used to convert the number to a string using CurrentCulture of the current thread and it happens when the TestString method is called. Meanwhile, the double number which is returned by TestDouble is serialized to string during the serialization step which uses GlobalConfiguration.Configuration.Formatters.JsonFormatter.SerializerSettings.Culture.
In my opinion, both should use InvariantCulture. On the consumer side, the values will be parsed and be formatted with the correct culture.
Update: this is only used for JsonFormatter. XmlFormatter doesn't have such a setting.
Update 2:
It seems (decimal) numbers need special converter to make it culture-aware:
Handling decimal values in Newtonsoft.Json
Btw, if you want o change data format per action/request, you can try the last piece of code of the following link: http://tostring.it/2012/07/18/customize-json-result-in-web-api/

how to send arguments on messages.properties when JSR 303 validation

I have a class something like
class Sample{
#Min(1) #Max(20) private int num_seats;
...
}
and messages.properties like
Min.sample.num_seats = the number must be bigger than 1
Question is
how can I set the message dynamically by sending arguments as like "the number must bigger than {MIN_VALUE}"?
how can I share the message? such like "Min.* = the number .... " is possible?
Thank you Ralph it has helped me a lot to find a solution.
I would just add this:
I would use #Range in this case (except if you want two different message for min and max).
In Sample class
#Range(min = 1, max = 20)
private int num_seats;
And in messages.properties file
Range.sample.num_seats=The number must be between {2} and {1}.
Note that the min is argument numbered {2} and max is numbered {1} !
According to SPR-6730 (Juergen Hoellers comment) it should work in this way:
#Min(value="1", message="the number must be higher than {1}")
I have not tested it, but this is the way, I have understand the issue comment.
second question: You can share the text, be putting them in a message properties file.
If you use the same key as the default does, then you override the default message. If you want not to override the default message, then you need an other key, and need to write the key in currly brackets in the message attribute.
message properties file
javax.validation.constraints.Min.message=My mew default message
someOtherKey=Some Other Message
Using the other key:
#Min(value="1", message="{someOtherKey}")

How to assign a NULL value to an OID?

I have to make the code portable to work on 2 different devices where the length of the OID is just different by 1 byte. Therefore I am reusing the same struct to send the OIDs.
For device #1 I have
MIB[0]=0x2b
MIB[1]=0x06
MIB[2]=0x01
MIB[3]=0x02
MIB[4]=0x01
MIB[5]=0x02
MIB[6]=0x02
MIB[7]=0x01
MIB[8]=0x08
MIB[9]=0xA0
MIB[10]=0x00
For device #2 I have
MIB[0]=0x2b
MIB[1]=0x06
MIB[2]=0x01
MIB[3]=0x02
MIB[4]=0x01
MIB[5]=0x02
MIB[6]=0x02
MIB[7]=0x01
MIB[8]=0x08
MIB[9]=0x01
MIB[10]=???
How do I assign MIB[10] to be NULL, so that the OID that is sent will be 1.3.6.1.2.1.8.1 instead of 1.3.6.1.2.1.8.1.0 by sending MIB[10] = 0x00?
There is no representation for end-of-OID in the data; the length is encoded in the ASN.1 field used to transfer the OID, and this field needs to be replicated along with the OID (especially as you are using the serialized form anyway).

Google Protocol Buffer error: "Encountered string containing invalid UTF-8 data while serializing protocol buffer"

I am using the following code
int lenSend = odl->ByteSize();
char* buf = (char *)malloc(lenSend);
odl->SerializeToArray(buf, lenSend);
I get this error and I can't understand why I get it (yes I get it three times):
libprotobuf ERROR google/protobuf/wire_format.cc:1059] Encountered string containing invalid UTF-8 data while serializing protocol buffer. Strings must contain only UTF-8; use the 'bytes' type for raw bytes.
libprotobuf ERROR google/protobuf/wire_format.cc:1059] Encountered string containing invalid UTF-8 data while serializing protocol buffer. Strings must contain only UTF-8; use the 'bytes' type for raw bytes.
libprotobuf ERROR google/protobuf/wire_format.cc:1059] Encountered string containing invalid UTF-8 data while serializing protocol buffer. Strings must contain only UTF-8; use the 'bytes' type for raw bytes.
Thanks.
You can get rid of the warning by following the advice in the message!
You must have a field or fields in the definition of odl (in your .proto file) which are defined as string but into which you are putting non-UTF-8 characters. The docs state that you shouldn't do this. If you change these to bytes, the warnings should disappear.
string A string must always contain UTF-8 encoded or 7-bit ASCII text. string String str/unicode[4]
bytes May contain any arbitrary sequence of bytes. string ByteString str
somtimes you should user bytes instead of string!
Use byte[] to replace string, which encoding is not UTF-8 or ASCII.
Convert []byte for translate
Example:
message Data {
Object obj = 1;
}
If <grpc: failed to unmarshal the received message string field contains invalid UTF-8>:
# marshal object
message Data {
bytes encodeObject = 1;
}
# unmarshal object
In golang, you can use strings.ToValidUTF8 to avoid temporary

Resources