Setting timeout for SOAP client

This one required help from our support. I don’t know what the default timeout value for the JSM SOAP client is, but by experiment I would guess about 3 minutes. Which is a long time to wait for a user.

So I wanted to change this and it turns out to be quite easy, though not supported by the Lansa Integrator UI.

In the solution folder, like

drive:\lansarootfolder\partitionfolder\Integrator\Studio\workspace\projectgroup\project\solutions\solutionname

you add a file called

AGENT_INCLUDE.TXT

in this file you write

stub.setTimeout ( 20000 );

if you want the timeout to be 20 secconds (20,000 milliseconds, obviously).

Then you generate, compile, publish and reboot the JSM service and your new timeout is set. And, again obviously, this applies to the entire solution. I wonder if it is an Apache Axis client Stub we are using here, and this page holds the documentation?
https://axis.apache.org/axis/java/apiDocs/org/apache/axis/client/Stub.html

JSM bindings and field length

Normally, in RDML, setting a char field to a string value that is too long truncates the string, silently.

Imagine my surprise when, using Lansa Integrator’s JSM, this was different. I am pretty sure that is because JSM, being Java, does not truncate a string value silently. In fact, looking at the trace files, in SERVICE.TXT I find

stack trace: java.lang.IllegalArgumentException: DataTypeText: byte data exceeds size of data type definition (34,30) (field: WERROR)
at com.lansa.jsm.d.setValue(Unknown Source)
at com.lansa.jsm.service.SOAPAgentService.a(Unknown Source)
at com.lansa.jsm.service.SOAPAgentService.do(Unknown Source)
at com.lansa.jsm.service.SOAPAgentService.a(Unknown Source)
at com.lansa.jsm.service.SOAPAgentService.for(Unknown Source)
at com.lansa.jsm.service.SOAPAgentService.command(Unknown Source)
at com.lansa.jsm.f.for(Unknown Source)
at com.lansa.jsm.f.do(Unknown Source)
at com.lansa.jsm.f.run(Unknown Source)

Command : ERROR : "DataTypeText: byte data exceeds size of data type definition (34,30) (field: WERROR)"

Unfortunately, using RDML and JSM, this is difficult to prevent in all cases. In this specific case, I can be fairly sure what the maximum length of the string value will be so I changed #WERROR to be a char(255).

A Farewell To Internet Explorer

For the first time since Internet Explorer 4, I no longer have to support the IE browser. The nail in the coffin is update 11.0.34 to Internet Explorer, as this messes up the Visual Lansa Framework frameview. I verified that it worked in 11.0.32 and 11.0.33, but from 11.0.34 the filter and instance list is hidden.

Given that Internet Explorer is all but discontinued, I no longer have to support it.

Implicit Visible(True)

Another small lesson: When setting the display position of a column, the column is implicitly set to visible. Understandable, but if one does not know it…

So

Set Com(#GDCL_161) Displayposition(#I2)

is the same as

Set Com(#GDCL_161) Displayposition(#I2) Visible(True)

If this is not what you want you have to set visible to false, explicitly:

Set Com(#GDCL_161) Displayposition(#I2) Visible(False)

Added later: Also, setting visible separately to false resets the display position to zero.

So, precision is not just for the result

Today’s small lesson

Change Field(#PCTFLT) To(#ANTSAL * 100 / #KTOTKOB) Precision(4 1) Round_Up(*YES)

only really works if #ANTAL is sufficiently small, that is, one digit. As I would probably have numbers up to a maximum of three digits, I changed the precision to 7 2 and (5 digits with 2 digits after the decimal point, as * 100 adds another 2 digits). Also, I know that #KTOTKOB can only be an integer and will always be larger than #ANTSAL.

SOAP client example in RDML

There is a nice sample in the LANSA Integrator Guide but as with many of the examples the information about how to understand how something else could be done is more difficult to find.

So I spent some time trying to create a simple SOAP client. But, unlike the example in the guide, this one would be without fragments – a single root element with a number of elements directly within. Specifically, the GetCityWeatherByZIP public sample, as I was just trying the SOAP services out.

I followed the instructions in the guide to create an Integrator solution, map the parameters, build and deploy, but coming up to the actual program I had trouble getting the data from the SOAP response. The field were not being bound to the response.

It turned out to quite simple

My experiment is written in RDML as I thought it would be best to get in running on the least-capable platform first. In RDMLX you can have more than one connection at the same time, using different JSMX handles, but I did not need that here.

Function Options(*DIRECT)
* The following fields should be defined in the dictionary
Define Field(#JSMSTS) Type(*CHAR) Length(20)
Define Field(#JSMMSG) Type(*CHAR) Length(256)
Define Field(#JSMCMD) Type(*CHAR) Length(256)
* The following fields are used by the soap binding map
Define Field(#RESULT) Type(*CHAR) Length(256) Label('Reply:')
Define Field(#DEBUG) Reffld(#RESULT) Label('Debug:')
* The following fields are used by the soap binding map
Define Field(#ZIP) Type(*CHAR) Length(5) Label('Zip..:')
Define Field(#CITY) Type(*CHAR) Length(20)
Define Field(#DESC) Type(*CHAR) Length(20)
Define Field(#PRES) Type(*CHAR) Length(20)
Define Field(#RELHUM) Type(*CHAR) Length(20)
Define Field(#REMARKS) Type(*CHAR) Length(20)
Define Field(#RESPONSE) Type(*CHAR) Length(20)
Define Field(#STATE) Type(*CHAR) Length(20)
Define Field(#SUCCESS) Type(*CHAR) Length(20)
Define Field(#TEMP) Type(*CHAR) Length(20)
Define Field(#VISI) Type(*CHAR) Length(20)
Define Field(#WIND) Type(*CHAR) Length(20)
Define Field(#WINDCHILL) Type(*CHAR) Length(20)
Def_List Name(#SOAPLIST) Fields(#CITY #DESC #PRES #RELHUM #REMARKS #RESPONSE #STATE #SUCCESS #TEMP #VISI #WIND #WINDCHILL) Type(*WORKING)
Change Field(#ZIP) To('''80210''') /* Denver */
Dowhile Cond('A *EQ A')
Request Fields((#FUNCTION *L1 *P2 *OUT) (#DATE *L1 *P73 *OUT) (#ZIP *L4 *P2 *LAB) (#DEBUG *L7 *P2 *LAB *OUT)) Design(*ACROSS) Identify(*NOID) Down_Sep(1) Across_Sep(1) Exit_Key(*YES *NEXT) Menu_Key(*NO) Text((*TMAP002 1 1)) Std_Head(*NO)
* F-keys
Case Of_Field(#IO$KEY)
When Value_Is('*EQ ''03''')
Return
Endcase
Change Field(#DEBUG) To(*BLANKS)
* Open service
Use Builtin(JSM_OPEN) To_Get(#JSMSTS #JSMMSG)
Execute Subroutine(CHECK) With_Parms(#JSMSTS #JSMMSG)
* Load service
Change Field(#JSMCMD) To('SERVICE_LOAD SERVICE(SOAPAgentService) TRACE(*YES)')
Use Builtin(JSM_COMMAND) With_Args(#JSMCMD) To_Get(#JSMSTS #JSMMSG)
Execute Subroutine(CHECK) With_Parms(#JSMSTS #JSMMSG)
* Open SOAP service
Change Field(#JSMCMD) To('OPEN SERVICE(WEATHER2)')
Use Builtin(JSM_COMMAND) With_Args(#JSMCMD) To_Get(#JSMSTS #JSMMSG)
Execute Subroutine(CHECK) With_Parms(#JSMSTS #JSMMSG)
* Set operation - GETCITYWEATHERBYZIP
Change Field(#JSMCMD) To('SET OPERATION(GETCITYWEATHERBYZIP)')
Use Builtin(JSM_COMMAND) With_Args(#JSMCMD) To_Get(#JSMSTS #JSMMSG)
Execute Subroutine(CHECK) With_Parms(#JSMSTS #JSMMSG)
* Set parameter - ZIP
Change Field(#JSMCMD) To('SET PARAMETER(ZIP) SERVICE_EXCHANGE(*FIELD)')
Use Builtin(JSM_COMMAND) With_Args(#JSMCMD) To_Get(#JSMSTS #JSMMSG)
Execute Subroutine(CHECK) With_Parms(#JSMSTS #JSMMSG)
* Call remote service
Change Field(#JSMCMD) To('CALL SERVICE_LIST(CITY,DESC,PRES,RELHUM,REMARKS,RESPONSE,STATE,SUCCESS,TEMP,VISI,WIND,WINDCHILL)')
Use Builtin(JSM_COMMAND) With_Args(#JSMCMD) To_Get(#JSMSTS #JSMMSG #SOAPLIST)
Execute Subroutine(CHECK) With_Parms(#JSMSTS #JSMMSG)
Change Field(#JSMCMD) To('IS NOT_NULL(*RETURN)')
Use Builtin(JSM_COMMAND) With_Args(#JSMCMD) To_Get(#JSMSTS #JSMMSG)
Execute Subroutine(CHECK) With_Parms(#JSMSTS #JSMMSG)
* Close SOAP service
Use Builtin(JSM_COMMAND) With_Args('CLOSE') To_Get(#JSMSTS #JSMMSG)
Execute Subroutine(CHECK) With_Parms(#JSMSTS #JSMMSG)
* Unload service
Use Builtin(JSM_COMMAND) With_Args('SERVICE_UNLOAD') To_Get(#JSMSTS #JSMMSG)
Execute Subroutine(CHECK) With_Parms(#JSMSTS #JSMMSG)
* Close service
Use Builtin(JSM_CLOSE) To_Get(#JSMSTS #JSMMSG)
Execute Subroutine(CHECK) With_Parms(#JSMSTS #JSMMSG)
Display Fields(#CITY #DESC #PRES #RELHUM #REMARKS #RESPONSE #STATE #SUCCESS #TEMP #VISI #WIND #WINDCHILL)
Endwhile
* Check routine
Subroutine Name(CHECK) Parms((#JSMSTS *RECEIVED) (#JSMMSG *RECEIVED))
If Cond('#JSMSTS *NE OK')
Use Builtin(JSM_CLOSE) To_Get(#JSMSTS #JSMMSG)
Use Builtin(BCONCAT) With_Args(#DEBUG 'error') To_Get(#DEBUG)
Endif
Endroutine

The tiny change that made this work was changing

Change Field(#JSMCMD) To('CALL')

to

Change Field(#JSMCMD) To('CALL SERVICE_LIST(CITY,DESC,PRES,RELHUM,REMARKS,RESPONSE,STATE,SUCCESS,TEMP,VISI,WIND,WINDCHILL)')

which is the list of all the fields I had defined in the Integrator setup. It did not work when I was testing it with just a couple of the fields.

If the response is best split in fragments, I expect the code in the guide to be usable.

Other resources:

http://www.lansa.com/resources/implementing-soap-web-services-with-lansa-integrator.htm

http://www.lansa.com/support/tips/soaptutorials.htm

http://www.lansa.com/support/tips/t0382.htm

Lansa Editor rewriting my code

This happened in v.12.5 and continues to happen in v.14: When I write XSLT I may write something that is perfectly valid and correct (at least, most of the time) and which produces no errors.

But then, when I reload the command handler the next day, I am not getting the same code. The Lansa Editor has rewritten my code to something else that is perfectly valid and correct (and indented differently) but which the Lansa Editor now reports an error in.

Without a doubt this is an error that comes from the rewriting and now, everytime I save, compile or check-in, I see this:

xsltparsing.png

It happens when I have used <![CDATA[ … ]]> and <xsl:text disable-output-escaping=”yes”> … </xsl:text>. The Lansa Editor removes the <![CDATA[ … ]]> and replaces the characters with the proper entities, but chokes on it itself.

A bug in the editor

It turns out that the error I got trying to access the XSLT source (not the missing shortcut, the crash) was due to a bug in the editor. I had a

<table>
<xsl:choose>
...

with no <tbody>. Yes, I know.

But the editor checked the XSLT and appears to think it is fine. Then the renderer took over and crashed, due to the missing <tbody>.

Fortunately I found the XSLT in the temp cache so with the supplier’s help I could regenerate the XSLT (deleting all my work) and reinsert my code, now with the <tbody> tag.

Done.