Author |
Message
|
blane99 |
Posted: Tue Jun 01, 2004 8:11 am Post subject: No responses to MQ from workflow server |
|
|
 Apprentice
Joined: 12 Jun 2002 Posts: 41
|
We are using workflow 3.4 SP5 on solaris 8.
We were seeing a full system outage that appeared to be MQSeries
related: our java programs (local to workflow server ) that connected to MQ (for the purpose of submitting MQWF XML messages) hung.
THIS TIME we diagnosed a bit further:
1) We ran an IBM supplied diagnostic java program which worked
properly, showing us that MQ was working.
2) We ran our java programs submitting messages to a TEST queue (not
FMC.FMCGRP.FMCSYS.EXE.XML):
a) those messages were successfully PUT to the queue.
b) Our java program then hung up waiting for a response from the
responses queue designated in the message header:
c) we would expect this hangup as our test code is waiting for MQWF
to respond even though the message wasn t sent to MQWF.
3) THEN we took down workflow, but left MQSeries running
4) We put our test messages BACK against the proper MQWF input queue
(FMC.FMCGRP.FMCSYS.EXE.XML) and submitted messages. We saw that ALL the messages were cleanly submitted and sitting in the queue.
From this we conclude:
1) Our hangup problem is MQSeries workflow related.
2) More specifically, its related to those parts of workflow involved
between:
a) The time an XML message is submitted and
b) The time a RESPONSE message is sent.
NOTE: All the messages we tried were trying to create were valid XML
trying to create and start a process instance
Any ideas on what might be going on with workflow? |
|
Back to top |
|
 |
jmac |
Posted: Tue Jun 01, 2004 8:45 am Post subject: |
|
|
 Jedi Knight
Joined: 27 Jun 2001 Posts: 3081 Location: EmeriCon, LLC
|
Bob:
Is the basic problem that you are sending valid XML Process start messages to MQWF, and then not getting responses back?
I am not sure from reading your post whether this is the case or not. If it is I may know what the issue is, but it will take a little bit of reserach on my part. Let me know if this is your issue and if so, I will look into what I did to solve this problem. _________________ John McDonald
RETIRED |
|
Back to top |
|
 |
blane99 |
Posted: Tue Jun 01, 2004 8:53 am Post subject: |
|
|
 Apprentice
Joined: 12 Jun 2002 Posts: 41
|
correct. Replies are not coming back from workflow. It works and then stops. The only way out of this is to reboot. Bringing down workflow components does not fix the problem.
-Bob |
|
Back to top |
|
 |
jmac |
Posted: Tue Jun 01, 2004 8:55 am Post subject: |
|
|
 Jedi Knight
Joined: 27 Jun 2001 Posts: 3081 Location: EmeriCon, LLC
|
Did you write the code that you are using to do the put to EXEXMLINPUTQ? If so can you send it to me? _________________ John McDonald
RETIRED |
|
Back to top |
|
 |
blane99 |
Posted: Tue Jun 01, 2004 9:16 am Post subject: |
|
|
 Apprentice
Joined: 12 Jun 2002 Posts: 41
|
I did not write but here 's what was sent to me. I can get more if needed.
#####START OF XML SENT
<WfMessage>
<WfMessageHeader>
<ResponseRequired>Yes</ResponseRequired>
<UserContext>This is a placeholder</UserContext>
</WfMessageHeader>
<ProcessTemplateCreateAndStartInstance>
<ProcTemplName>DVW_TOBEDEFINED</ProcTemplName>
<ProcInstName>TOBEDEFINED</ProcInstName>
<ProcInstInputData>
<TradeReference>
</TradeReference>
</ProcInstInputData>
</ProcessTemplateCreateAndStartInstance>
</WfMessage>
#####END OF XML SENT
Note: The template DVW_TOBEDEFINED is intentionally an undefined
name that show trigger an error from workflow. |
|
Back to top |
|
 |
jmac |
Posted: Tue Jun 01, 2004 9:26 am Post subject: |
|
|
 Jedi Knight
Joined: 27 Jun 2001 Posts: 3081 Location: EmeriCon, LLC
|
Bob:
Not the XML message, the actual program you are using to PUT the XML message to the EXEXMLINPUTQ.
There was a change made sometime in one of the early FixPacks of 3.4 I don't recall which that made my process start code begin to misbehave. I don't recall the specifics, but if you are experiencing this problem after a jump to 3.4.0.5 from 3.4.0.2 or less I think you may have the same problem. It would really help me IF I could see the actual code you are using to do you process starts. _________________ John McDonald
RETIRED |
|
Back to top |
|
 |
blane99 |
Posted: Wed Jun 02, 2004 7:22 am Post subject: |
|
|
 Apprentice
Joined: 12 Jun 2002 Posts: 41
|
Here you go:
package com.bear.MQ.MQu_utils;
//GENERAL
import java.io.ByteArrayInputStream;
import java.io.InputStream;
//MQ related classes
import com.bear.util.mq.MQConnectionPool;
import com.ibm.mq.MQGetMessageOptions;
import com.ibm.mq.MQPutMessageOptions;
import com.ibm.mq.MQC;
import com.ibm.mq.MQQueue;
import com.ibm.mq.MQMessage;
import com.bear.MQ.MQu_utils.MQerrorparserHandler;
import com.bear.MQ.MQu_utils.RestartPoolHandler;
//SAX related classes
import org.xml.sax.helpers.XMLReaderFactory;
import org.xml.sax.XMLReader;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
public class MQAccessUtil {
public synchronized static boolean putWithResponse(MQPutMessageOptions pmo, MQErrorMessage errors, MQConnectionPool pname, MQMessage message, String correlId, String rname, String MQVersion) throws java.lang.Exception
{
String queueVersion = MQVersion;
MQQueue x = null;
MQQueue y = null;
MQConnectionPool yx = null;
MQErrorMessage d_em = errors;
try {
System.out.println("MQAccessUtil: putting message on queue");
putMessage(pname, message, pmo);
System.out.println("MQAccessUtil: message placed on queue");
} catch (Exception e) {
System.out.println("ERROR putting message: " +
e.getMessage());
System.out.println("MQAccessUtil: replacing connection on pool");
pname.disconnect(x);
System.out.println("MQAccessUtil: connection replaced on pool");
return false;
}
try {
yx = MQConnectionPool.getPool(rname);
MQMessage response = new MQMessage();
if (!MQVersion.equals("5.3")) {
response.correlationId =
MQC.MQMI_NONE;
response.messageId = message.messageId;
} else {
response.correlationId = message.messageId;
}
MQGetMessageOptions opt = new MQGetMessageOptions();
opt.options = MQC.MQGMO_WAIT;
opt.matchOptions = MQC.MQMO_MATCH_MSG_ID;
opt.waitInterval=20000;
try {
System.out.println("MQAccessUtil: getting message from queue");
getMQMessage(yx, y, response, opt);
System.out.println("MQAccessUtil: message retrieved from queue");
} catch (Exception ye) {
System.out.println("MQAccessUtil: exception caught on reading response queue, creating message text");
d_em.setMessageText("Unable to retrieve response message for message: " + ye.getMessage());
d_em.setOrigin("FMCQM/FMCQM.CL.TCP/DVW.MAINWF.RESPONSES");
System.out.println("MQAccessUtil: replacing read connection on pool");
pname.disconnect(y);
System.out.println("MQAccessUtil: replaced read connection on pool");
return false;
}
} catch (Exception e) {
System.out.println("ERROR reading message from queue " +
e.getMessage());
d_em.setMessageText("Unable to retrieve response message from workflow: " + e.getMessage());
d_em.setOrigin("DVW.MAINWF.RESPONSES");
if (y!=null) {
System.out.println("MQAccessUtil: returning read connection to pool");
yx.disconnect(y);
System.out.println("MQAccessUtil: returned read connection to pool");
}
return false;
}
return true;
}
public static String byteToHex(byte data)
{
StringBuffer buf = new StringBuffer();
buf.append(toHexChar((data>>>4)&0x0F));
buf.append(toHexChar(data&0x0F));
return buf.toString();
}
public static String bytesToHex(byte[] data)
{
StringBuffer buf = new StringBuffer();
for (int i = 0; i < data.length; i++)
{
buf.append(byteToHex(data[i]));
}
return(buf.toString());
}
public static char toHexChar(int i)
{
if ((0 <= i) && (i <= 9 ))
return (char)('0' + i);
else
return (char)('a' + (i-10));
}
public static void getErrors(MQMessage response, MQErrorMessage d_em) {
try {
XMLReader reader = XMLReaderFactory.createXMLReader();
MQerrorparserHandler ph = new MQerrorparserHandler(d_em, reader);
reader.setContentHandler(ph);
byte readbytes[] = new byte[response.getMessageLength()];
response.readFully(readbytes);
ByteArrayInputStream bas = new ByteArrayInputStream(readbytes);
InputSource is = new InputSource(bas);
reader.parse(is);
} catch (Exception e) {
System.out.println("error parsing message " + e.getMessage());
e.printStackTrace();
}
}
public static void putMessage(MQConnectionPool pname,
MQMessage message,
MQPutMessageOptions pmo)
throws Exception
{
MQQueue mq = null;
try {
mq = pname.connect();
} catch (Exception e) {
System.out.println("putMessage connection error: " + e.getMessage());
}
if (mq!=null) {
mq.put(message, pmo);
pname.disconnect(mq);
} else {
System.out.println("MQConnection is null, attempting to " +
"get new connection");
pname.refresh(mq);
mq.put(message, pmo);
pname.disconnect(mq);
}
}
public static void getMQMessage(MQConnectionPool pname,
MQQueue x, MQMessage message,
MQGetMessageOptions mgmo)
throws Exception
{
MQQueue mq = pname.connect();
if (mq!=null) {
System.out.println("MQAccessUtil: attempting to get message from reponse queue");
mq.get(message, mgmo);
System.out.println("MQAccessUtil: message retrieved, closing connection");
pname.disconnect(mq);
System.out.println("MQAccessUtil: response connection closed");
} else {
pname.refresh(mq);
mq.get(message, mgmo);
pname.disconnect(mq);
}
}
} |
|
Back to top |
|
 |
jmac |
Posted: Wed Jun 02, 2004 7:41 am Post subject: |
|
|
 Jedi Knight
Joined: 27 Jun 2001 Posts: 3081 Location: EmeriCon, LLC
|
Bob:
Giving a quick look I don't see what pmo options is set to (could be I'm not looking close enough)... Anyway, that's where I had my issue, and I can tell you now that it started with 3.4.0.2 (I went back thru my notes). At that time something was changed internally in MQWF that cause my process starter grief. I had code like this:
Code: |
pmo.options |= MQC.MQPMO_NEW_MSG_ID; |
After I added the following the problem was resolved. This may or may not be your issue.
Code: |
msg.report = MQC.MQRO_COPY_MSG_ID_TO_CORREL_ID; |
GOOD LUCK _________________ John McDonald
RETIRED |
|
Back to top |
|
 |
blane99 |
Posted: Wed Jun 02, 2004 7:55 am Post subject: |
|
|
 Apprentice
Joined: 12 Jun 2002 Posts: 41
|
John
Thanks so much. I passed it on to the developers. I'll let you know how it worked out.
Bob |
|
Back to top |
|
 |
blane99 |
Posted: Wed Jun 02, 2004 9:45 am Post subject: |
|
|
 Apprentice
Joined: 12 Jun 2002 Posts: 41
|
John
Can you be more specific as to what problems you were experiencing?Did you have the same kind of problem where no replies came back from workflow? Things stopped working ?
Bob |
|
Back to top |
|
 |
jmac |
Posted: Wed Jun 02, 2004 10:20 am Post subject: |
|
|
 Jedi Knight
Joined: 27 Jun 2001 Posts: 3081 Location: EmeriCon, LLC
|
Bob:
The issue was that the responses to my process starts never came back. MQWF was otherwise functioning OK. _________________ John McDonald
RETIRED |
|
Back to top |
|
 |
hos |
Posted: Fri Jun 04, 2004 5:09 am Post subject: |
|
|
Chevalier
Joined: 03 Feb 2002 Posts: 470
|
Starting with MQWF 3.4 SP2 (and fixed in 3.4 SP4) the XML responses from the MQWF server contain messageIDs and CorrelationIDs that are compliant to the report options set in the related request message. This may require a code change in existing XML clients or UPES servers.
- Message-identifier options: You can specify one of the options listed below to control how the MsgId of the the reply message is to be set.
MQRO_NEW_MSG_ID
New message identifier.
This is the default action, and indicates that if a reply is generated as a result of this message, a new MsgId is to be generated for the reply message.
MQRO_PASS_MSG_ID
Pass message identifier.
If a reply is generated as a result of this message, the MsgId of this message is to be copied to the MsgId of the reply message.
If this option is not specified, MQRO_NEW_MSG_ID is assumed.
- Correlation-identifier options: You can specify one of the options listed below to control how the CorrelId of the reply message is to be set.
- MQRO_COPY_MSG_ID_TO_CORREL_ID
Copy message identifier to correlation identifier.
This is the default action, and indicates that if a reply is generated as a result of this message, the MsgId of this message is to be copied to the CorrelId of the reply message.
- MQRO_PASS_CORREL_ID
Pass correlation identifier.
If a reply is generated as a result of this message, the CorrelId of this message is to be copied to the CorrelId of the reply message.
If this option is not specified, MQRO_COPY_MSG_ID_TO_CORREL_ID is assumed. |
|
Back to top |
|
 |
|