Thursday, March 15, 2012

Filtering a subscription trigger

So you want to filter out your subscription trigger so it only triggers on certain events.   There's a filter field in the subscription trigger, but it's just a free-form field.  The documentation isn't clear.

Update - found an easier way.
(%myField%=="myvalue")

Complex filters can look like this:

(%textMessageMonitorEvent/textMessageEnvelope/processType%=="VehicleReady" && %textMessageMonitorEvent/textMessageTrackingInfo/monitorStatus%=="DONE" && %textMessageMonitorEvent/textMessageTrackingInfo/deliveryStatus%<>"SUCCESS")

The below also works, but is harder to read and you have to include the document in the clause.  The above just needs the field path.

%myDoc/myField% L_EQUALS myvalue

Note that there are no quotes on the right operand even though it is a string value!

Also, you need to use the "name" operators like L_EQUALS to have the filter operate on the broker, rather than passing it to the Integration Server and then filtering it (which causes more network traffic and IS CPU usage).

Here are the possible comparators I found in the Developer's handbook.

L_EQUALS
L_NOT_EQUALS
L_LESS_THAN
L_LESS_OR_EQUAL
L_GREATER_THAN
L_GREATER_THAN
L_GREATER_OR_EQUAL
L_GREATER_OR_EQUAL

Monday, February 27, 2012

Branch and regular expressions

I don't know why but it just never clicked.  You can use regular expressions as the labels on your branch step even when evaluate labels is false.  A simple example is checking the http status values from a RESTful call:

  • Branch header->status
    • /^2[0-9][0-9]$/ (OK)
    • /^4[0-9][0-9]$/ (Non retry enabled error)
    • /^5[0-9][0-9]$/ (Retry enabled error)
Much easier than trying to list all combinations.

Wednesday, October 26, 2011

External ID is missing the system ID

com.wm.lang.wsdl.WSDException: com.wm.lang.flow.WattEvaluationException: com.wm.lang.xml.WMDocumentException: [ISC.0042.9322] External ID is missing the system ID

I got this error when trying to import a WSDL from an outside company.  Searched the net, wmusers, no help.

Then I tried saving the WSDL to a file from the URL, then importing the file directly.  That worked!  Whew!

Wednesday, October 12, 2011

Restful Service in webMethods

This is another of those things that should be easy right?  Well, it is once you know what to do.

++++ Added note ++++
After I figured out how to do this indirectly, I found the actual Webmethods REST users guide.  It is a more complete way to implement RESTful services. This only works in version 8.2 however.

See http://documentation.softwareag.com/webmethods/wmsuites/wmsuite8-2_ga/Integration_Server/8-2-SP1_REST_Developers_Guide.pdf
++++++++++++

I had a rest service call coming into the Integration Server with an HTTP Post request to http://<server>:5555/invoke/TestForKev.esla.pub/event with a type of application/xml in UTF-8.

  1. So I wrote a flow service in TestForKev/esla/pub called event.  
  2. I created an input parameter of contentStream with an object type.
  3. I called pub.io:streamToString to convert the contentStream to a string
  4. I called pub.xml:xmlStringToXMLNode to create the XML node.
  5. Then I called pub.xml:xmlNodeToDocument to finally convert to a webmethods document.

It should look something like this.



Now you have a webmethods document from your rest service interface.


URL Parameters

If you need to take a rest service input that uses URL parameters, you can still get to them.  Say you have a url like http://<server>:5555/invoke/TestForKev.esla.pub/event_change/98765 where 98765 is the event_id.  


Just write the service as above, but add in a call to pub.flow:getTransportInfo.  The requestURL returned will contain the service name and the parameters at the end of the url, so you can parse them out.   


<value name="requestUrl">/invoke/TestForKev.esla.pub/event_change/98765</value>

Response Values

Found out how to send the http status and message back to the caller.  Use pub.flow:setResponseCode to explicitly set the response values.  Otherwise defaults are chosen for you.

Tuesday, August 23, 2011

File Polling Setup and Usage.

Checking for a file that is placed on your IS or on a shared directory?  The documentation is lacking and incomplete.  Here's how to set it up.

File Polling Port Setup

In IS Admin, look under security->ports.  Click "Add Port" and select webMethods/FilePolling.  Now you are at the File Polling listener configuration screen.

Leave the package name as WmRoot.
The monitoring directory is the location you want to look for files.
The working, completion and error directories are all optional (sort of).  If you do not specify them, then they will default to the <monitoring directory>/../<type>.  I prefer to specify them explicitly.

Processing Service is the name of the service that will be called when a new file is placed in the monitoring directory (and the polling schedule hits).

File Polling Interval is how often the poller checks for a file.  Times of 1 second are not recommended.

I cannot comment too much on the other settings as I'm not using them.

Once that is done, you need to save changes, then enable the port.  If you don't have write permissions to the directories in the config (or the implicit directories if you didn't specify the optional directories) then you will get an error.

Service Setup

Create a flow service with one input:
originalFileName

This is put on the pipeline when the service is called, though not necessary as it also comes in the next step.

You then want to call pub.flow.getTransportInfo from WmPublic.  This will provide the filename information in:
transport->filePolling
    filename
    originalFilename

At this point the filename will in the format of:
<workingdir>/FilePolling.<ID Num>.<original file name>

Now you can do any file operations you'd normally do on a file and process it however you want.

If your flow service exits and signals failure, the file will be moved to the error directory.

If your flow service exits correctly, the file will be moved to the completion directory.


Access Mode Setup


Once you have your port setup and configured  and your service created, you need to enable access from the file poller.  Go back to the IS Admin screen in Security->Ports and edit the Access Mode of your file poller.


Click to "Add Folders and Services to Allow List" and paste in the fully qualified flow service into the left column and click "Save Additions".


Without this step you will get access denied errors when your file poller tries to run.



It's not hard, but it sure wasn't straightforward the first time I looked at it.

Friday, July 1, 2011

Developer 8 in Linux

So I copied my 8.0 install from my Windows box to my Linux box.  I have it installed in /opt/webmethods8.

I created a developer.sh that looks like this:
#
# developer.bat : launch Developer
#
#
DEVELOPER_DIR=/opt/webmethods8/Developer
LIB_DIR=$DEVELOPER_DIR/lib
SSL_DIR=$DEVELOPER_DIR/lib/entrust
COMMON_LIB_DIR=$DEVELOPER_DIR/../common/lib
JAVA_DIR=/usr/java/latest
#
#
#
#NOTE: Classpath modifications in this file are EXCEPTIONS to the rule.
#
#See ${DEVELOPER_DIR}/config/ini.cnf or create an official <update>.jar to
#change the classpath the 'standard' way.
#
ALLOW_ARRAY_CLASSLOADING="-Dsun.lang.ClassLoader.allowArraySyntax=true"
#
SSL_PATH="${SSL_DIR}/enttoolkit.jar"
CLASSPATH=${JAVA_DIR}/lib/rt.jar:${COMMON_LIB_DIR}/ext/mail.jar:${DEVELOPER_DIR}/lib/wm-isproxy.jar:${SSL_PATH}:${LIB_DIR}/wsi-test-tools.jar:${LIB_DIR}/uddi4j.jar:${LIB_DIR}/wsdl4j-14.jar:${LIB_DIR}/xercesImpl.jar:${COMMON_LIB_DIR}/ext/xml-apis.jar:${LIB_DIR}/xmlParserAPIs.jar:${LIB_DIR}/resolver.jar
#
JAVA_HOME=$JAVA_DIR
#
echo $CLASSPATH
#
cd ${DEVELOPER_DIR}
#
/usr/java/latest/bin/java -Xms128M -Xmx256M ${ALLOW_ARRAY_CLASSLOADING} -classpath ${CLASSPATH} com.wm.app.dev.Main ${DEVELOPER_DIR}/config/ini.cnf &
#
#
#.... restore original classpath and path
#CLASSPATH=${SAVED_CP}
#PATH=${SAVED_PATH}

Changed the paths in /opt/webmethods8/Developer/config/ini.cnf so it looks like this:

#######################################################################
#     STARTUP PROPERTIES FOR WEBMETHODS DEVELOPER
######################################################################
#Thu Jan 21 10:25:27 MST 2010
application.mainMethodParams=-debug 4
application.name=webMethods Developer
application.productDirectory=/opt/webmethods8/Developer
application.version=8.0
application.updateVoidList=
application.classpath=/opt/webmethods8/Developer/lib/developer.jar:/opt/webmethods8/Developer/lib/caffeineLAF.jar:/opt/webmethods8/common/lib/wm-isclient.jar:/opt/webmethods8/Developer/lib/ite3.jar:/opt/webmethods8/Developer/lib/biicons.jar:/opt/webmethods8/Developer/lib/:/opt/webmethods8/common/lib/ext/icu4j.jar:/opt/webmethods8/common/lib/ext/log4j.jar:/opt/webmethods8/common/lib/wm-g11nutils.jar:/opt/webmethods8/common/lib/ext/axis.jar:/opt/webmethods8/common/lib/ext/commons-discovery.jar:/opt/webmethods8/common/lib/ext/enttoolkit.jar:/opt/webmethods8/common/lib/ext/saaj-api.jar:/opt/webmethods8/Developer/lib/wsdl4j.jar:/opt/webmethods8/Developer/lib/jakarta-oro-2.0.5.jar:/opt/webmethods8/common/lib/ext/commons-logging.jar:/opt/webmethods8/common/lib/ext/jaxrpc-api.jar:/opt/webmethods8/common/lib/ext/commons-lang.jar:/opt/webmethods8/Developer/lib/ext/jug-asl-2.0.0.jar:/opt/webmethods8/Developer/lib/uddiv3ClientJars/infravio-commons.jar:/opt/webmethods8/Developer/lib/uddiv3ClientJars/registry-commons.jar:/opt/webmethods8/Developer/lib/uddiv3ClientJars/registry-uddiv3-agent.jar:/opt/webmethods8/Developer/lib/uddiv3ClientJars/registry-uddiv3-client.jar:/opt/webmethods8/Developer/lib/uddiv3ClientJars/registry-uddiv3-commons.jar:/opt/webmethods8/Developer/lib/uddiv3ClientJars/registry-uddiv3-framework.jar:/opt/webmethods8/Developer/lib/uddiv3ClientJars/registry-properties.jar:/opt/webmethods8/common/lib/sin-common.jar:

And then it worked!

Will work on Designer next!

Thursday, June 23, 2011

Writing to the server log from a java service.

If you are trying to debug a java service, you can write directly to server.log on the Integration Server.

Use this call in your java service like you would use System.err.println()

com.wm.util.JournalLogger.log(3,90,3,"LOG " + message );


It looks like the numbers make the log error code look like this:
[ISP.0090.0003I]

Very handy, just don't forget to take them out!