ASG
IBM
Zystems
Cressida
Icon
Netflexity
 
  MQSeries.net
Search  Search       Tech Exchange      Education      Certifications      Library      Info Center      SupportPacs      LinkedIn  Search  Search                                                                   FAQ  FAQ   Usergroups  Usergroups
 
Register  ::  Log in Log in to check your private messages
 
RSS Feed - WebSphere MQ Support RSS Feed - Message Broker Support

MQSeries.net Forum Index » WebSphere Message Broker (ACE) Support » Converting Message Length to Binary

Post new topic  Reply to topic
 Converting Message Length to Binary « View previous topic :: View next topic » 
Author Message
mjain
PostPosted: Thu Aug 09, 2012 2:48 am    Post subject: Converting Message Length to Binary Reply with quote

Novice

Joined: 01 May 2012
Posts: 15

Hi,
I am trying o communicate to a backend system caled B24 over TCP/IP and getting error "No Valid Connection Acquired". As per b24 team, the message they are expecting is a character stream with first two bytes having length in binary form which our flow is not sending causing this issue probably. Can someone please guide as how can I convert the integer into binary form and store it in forst field of my MRM message. I presume that my message type will have first field of hexBinary data type. Any help is appreciated.

-Thanks
Back to top
View user's profile Send private message
smdavies99
PostPosted: Thu Aug 09, 2012 4:08 am    Post subject: Reply with quote

Jedi Council

Joined: 10 Feb 2003
Posts: 6076
Location: Somewhere over the Rainbow this side of Never-never land.

I posted some sample code a few months ago that does this very thing.
Here it is again. You WILL NEED to sort out the lengths of the header to meet your requirements.
Code:

CREATE COMPUTE MODULE Add_TCP_Header
   CREATE FUNCTION Main() RETURNS BOOLEAN
   BEGIN
      declare cHeader char;
      declare iMsgLen integer;
      declare subBitStream BLOB ASBITSTREAM(InputRoot.XMLNSC CCSID 1208);
      set iMsgLen = length(CAST(subBitStream AS CHAR CCSID 1208));
      set cHeader = '#' || left(cast(iMsgLen as char) || '    ',4);
      set OutputRoot.Properties.MessageFormat = 'BLOB';
      set OutputRoot.BLOB.BLOB = cast(cHeader as BLOB CCSID 1208) || subBitStream;
      RETURN TRUE;
   END;
END MODULE;

_________________
WMQ User since 1999
MQSI/WBI/WMB/'Thingy' User since 2002
Linux user since 1995

Every time you reinvent the wheel the more square it gets (anon). If in doubt think and investigate before you ask silly questions.
Back to top
View user's profile Send private message
mqjeff
PostPosted: Thu Aug 09, 2012 4:31 am    Post subject: Reply with quote

Grand Master

Joined: 25 Jun 2008
Posts: 17447

smdavies99 wrote:
Code:
left(cast(iMsgLen as char) || '    ',4)


I've been doing this kind of thing to zero-pad a number (using RIGHT instead of LEFT, of course) for part of an output file name.

For something like this, I might be tempted to use a really quick message model (particularly if at v8 when I can use DFDL instead of MRM - although in either case it's *quick* to build) that has two fields, one for the length string and one for the message blob. But that's really only because it's building the actual message data - rather than a piece of metadata (the file name, whilst a very *important* piece of metadata, is still just metadata).

But it's easy to see that a couple of lines of esql is an attractive choice.
Back to top
View user's profile Send private message
mjain
PostPosted: Thu Aug 09, 2012 5:24 am    Post subject: Reply with quote

Novice

Joined: 01 May 2012
Posts: 15

Thanks smdavies99,
Actually the requirement from backend is to receive the length as binary in first two bytes and the remaining message body as character stream.....I know it might sound strange.....but in such a scenario should I be setting the MessageFormat as BOLB or CWF?? Below is the code I have written......

Code:
SET OutputRoot.MRM.MessageLength= CAST(333 AS BLOB CCSID 1208);
SET OutputRoot.MRM.StartOfHeader= 'ISO';
SET OutputRoot.MRM.ProductIdentifier= '02';
SET OutputRoot.MRM.RelNum = '60';
...
...
....


I have created a CWF message definition with first element as MessageLength and type as xsd:unsignedShort. Could you please commen id there is anything wrong with this approach.
Back to top
View user's profile Send private message
mqjeff
PostPosted: Thu Aug 09, 2012 5:30 am    Post subject: Reply with quote

Grand Master

Joined: 25 Jun 2008
Posts: 17447

Okay, so
Code:
SET OutputRoot.MRM.MessageLength= CAST(333 AS BLOB CCSID 1208);

is wrong.

You should just
Code:
Set OutputRoot.MRM.MessageLength=333
and leave it to the CWF format to convert it to the correct physical representation.

And, yes, if you are outputting a message described by an MRM format, then you need to ensure that the MessageFormat property field matches the name of the MRM format - so "text1" or "CWF1" or whatever your format is named in the message set.
Back to top
View user's profile Send private message
mjain
PostPosted: Thu Aug 09, 2012 5:35 am    Post subject: Reply with quote

Novice

Joined: 01 May 2012
Posts: 15

Thanks for reply mqjeff....
Even I had the same impression....but was not sure about the type of the element(representing length) in my message definition so that it is sent as binary field of 2 bytes.....any suggestion on that part....should it be packed decimal??
Back to top
View user's profile Send private message
mqjeff
PostPosted: Thu Aug 09, 2012 5:52 am    Post subject: Reply with quote

Grand Master

Joined: 25 Jun 2008
Posts: 17447

mjain wrote:
Thanks for reply mqjeff....
Even I had the same impression....but was not sure about the type of the element(representing length) in my message definition so that it is sent as binary field of 2 bytes.....any suggestion on that part....should it be packed decimal??


You need to get a sample message that is known to work, with a known length.

I can't tell you off the cuff if the remote system is expecting to receive a big-endian or little-endian number, whether it's expecting a packed decimal or not, whether it's expecting an unsigned integer or a signed decimal or what.
Back to top
View user's profile Send private message
mjain
PostPosted: Sat Aug 11, 2012 1:54 am    Post subject: Reply with quote

Novice

Joined: 01 May 2012
Posts: 15

Hi mqjeff.......
I believe they are expecting Bin Endian integer.....as I have a C program running on he same server (where message broker runs) and it passes the length as unsignedshort (which is 2 bytes long and Big Endian as its a AIX system). When I communicate with the remote host using this C program, I get valid response.....while when I try same request through MB, I get 'No Valid Connection Aquired' error and Remote host complain that they are not receving the data.
The first field in my cwf message definition is an int (physical type: Integer), with length as 2 and Byte Alignment as 1 Byte. Any suggestions what I might be doing wrong here. Thanks for your help again.
Back to top
View user's profile Send private message
mjain
PostPosted: Sat Aug 11, 2012 2:13 am    Post subject: Reply with quote

Novice

Joined: 01 May 2012
Posts: 15

Here is the C code snippet if it helps.....

Code:
int msgLength;   
                struct timeval TimeOutB24;   
                fd_set ReadfdsB24;   

                union msgHeader   
                {   
                                char length[2];   
                                short shortlength;   
                }header;   
   
                header.shortlength = strlen(B24ReqPacket);   
                msgLength=header.shortlength;   

                memset(B24Request,' ',sizeof(B24Request));   
                memcpy(B24Request,header.length,2);   
                memcpy(B24Request+2,B24ReqPacket,strlen(B24ReqPacket));   


B24Request contains the final request message.
Back to top
View user's profile Send private message
McueMart
PostPosted: Sat Aug 11, 2012 2:18 am    Post subject: Reply with quote

Chevalier

Joined: 29 Nov 2011
Posts: 490
Location: UK...somewhere

Sorry not a solution to your problem but just some advice...

When I dealt with ISO8583, one of the first things I did was write a network proxy (im sure you could use something like WireShark for this). This way you can look at the exact bytes which are being sent/received over the wire.

You can then compare the message which is being generated by the C program with the one being generated by Broker.

When i was using ISO8583 I did not use a message set to represent the header part of the message. I simply did the following: (badly written sudocode follows)

Code:

DECLARE msgLen INTEGER LENGTH(iso8583msgblob);
DECLARE 2byteMsgLen BLOB SUBSTRING(CAST(msgLen AS BLOB) FROM 7 FOR 2); #broker uses 8 bytes for 'INTEGERS' - get the last 2 bytes
SET completeOutputMsg = 2byteMsgLen || restOfHeader || iso8583msgblob;
Back to top
View user's profile Send private message
mjain
PostPosted: Sat Aug 11, 2012 4:44 am    Post subject: Reply with quote

Novice

Joined: 01 May 2012
Posts: 15

Hi McueMart....thanks....
Sounds better approach to me as well.....I modified my code as below to test it....

Code:
      DECLARE byteMsgLen BLOB SUBSTRING(CAST(333 AS BLOB) FROM 7 FOR 2);
      
      SET Environment.Variables.InputMsg = ASBITSTREAM(OutputRoot.MRM, InputProperties.Encoding, InputProperties.CodedCharSetId);
      SET OutputRoot.MRM = NULL;
      SET Environment.Variables.InputMsg = CAST(Environment.Variables.InputMsg AS CHARACTER CCSID InputProperties.CodedCharSetId, ENCODING InputProperties.Encoding);
      DECLARE outputMsg BLOB CAST(Environment.Variables.InputMsg AS BLOB CCSID InputProperties.CodedCharSetId, ENCODING InputProperties.Encoding);
      SET OutputRoot.BLOB.BLOB = byteMsgLen||outputMsg;
                                SET OutputRoot.Properties.MessageDomain = 'BLOB';

but I sll get the same error.....am I missing any property required to be set to send BLOB data over tcpip...I have tried all options....appreciate your suggestion.
Back to top
View user's profile Send private message
McueMart
PostPosted: Sun Aug 12, 2012 3:13 am    Post subject: Reply with quote

Chevalier

Joined: 29 Nov 2011
Posts: 490
Location: UK...somewhere

The first thing I would do is stick a Trace node (or view in the debugger... but better with a trace node), right before your TCPIP Output node to view the Binary data which you are about to send over TCP. You could alternatively capture this with a proxy/wireshark.

You will then need to go through it, byte by byte, and ensure that the data being sent matches with the specification. It sounds a bit tedious but its the only good way of ensuring that Message Broker is sending what you are expecting.
Back to top
View user's profile Send private message
mjain
PostPosted: Sun Aug 26, 2012 4:30 am    Post subject: Reply with quote

Novice

Joined: 01 May 2012
Posts: 15

Hi McueMart.....Thanks so much....Sory for delayed response though.
I used wire shark and it helped locating the issue. I changed the whole message body to blob and appending the length (as integer of 2 bytes) as prefix. I can now see that the out is same as my C program.
Another issue found was due to TCPIPClientReceive node property Record Detection being set as "Closed Connection". Requests were timing out when set to this value while I got valid response when I changed it to Fixed Length and specified the expected length....probably because the remote host is not terminating the connection after sending the response.
Back to top
View user's profile Send private message
Display posts from previous:   
Post new topic  Reply to topic Page 1 of 1

MQSeries.net Forum Index » WebSphere Message Broker (ACE) Support » Converting Message Length to Binary
Jump to:  



You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum
Protected by Anti-Spam ACP
 
 


Theme by Dustin Baccetti
Powered by phpBB © 2001, 2002 phpBB Group

Copyright © MQSeries.net. All rights reserved.