Difference between revisions of "Asynchronous Web Services"

From Agility
Jump to: navigation, search
(Asynchronous Respond Delivery)
(Known Issues)
 
(26 intermediate revisions by the same user not shown)
Line 7: Line 7:
 
Web service host process (import) received data in separate thread. Advantage of asynchronous processing is that client do not have to wait for time consuming processing (big data volume). Network connection can be easily broken and it is important to keep it as short as possible.
 
Web service host process (import) received data in separate thread. Advantage of asynchronous processing is that client do not have to wait for time consuming processing (big data volume). Network connection can be easily broken and it is important to keep it as short as possible.
 
Action after processing of message depend on agreement. Possible scenarios:
 
Action after processing of message depend on agreement. Possible scenarios:
# Client don’t expect processing results (send ad forget)
+
# Client don’t expect processing results (send and forget)
 
# Client will periodically call sever and asks for results (until processed)
 
# Client will periodically call sever and asks for results (until processed)
 
# Client expects that server will always send back result.
 
# Client expects that server will always send back result.
 
# Client expects that server will send back result only when processing fail.
 
# Client expects that server will send back result only when processing fail.
  
Currently supported are only first two patterns.
 
  
 
[[File:async process.png|650px]]
 
[[File:async process.png|650px]]
 +
 +
 +
It is very important to understand how messages are processed internally. Basically new Thread is created and time consuming message processing is executed in background. Each request to agility create new thread. Asynchronous processing uses same as Agility thread pool. Thread pool is handled by IIS and by default there is no need to configure anything. This approach allows to pass security context (user authentication) from request to asynchronous processing thread. This approach brings brings some limitations however.
 +
 +
Current implementation cons:
 +
*Not possible to reprocess messages automatically after agility crash.
 +
*Not possible to synchronize same interface calls. It means that each request to agility will be immediately processed. It is not possible to delay (queue) asynchronous processing.
  
 
== Asynchronous Web Service Definition ==
 
== Asynchronous Web Service Definition ==
Line 57: Line 63:
 
Sample definition: [[#Asynchronous_Web_Service_With_Message_Identification_Handling|Asynchronous Web Service With Message Identification Handling]].
 
Sample definition: [[#Asynchronous_Web_Service_With_Message_Identification_Handling|Asynchronous Web Service With Message Identification Handling]].
  
All data from both remote connections (ResponseTo & ErrorTo) are passed as variables to Result Export (responsible for generating async. response)
+
====Result Destination Paramters====
 +
 
 +
All data from both remote connections (ResponseTo & ErrorTo) are passed as variables to Result Export (responsible for generating async. response):
  
 
<pre>
 
<pre>
Line 85: Line 93:
 
#ErrorToRemoteConnection.Domain
 
#ErrorToRemoteConnection.Domain
 
#ErrorToRemoteConnection.PreAuthenticate
 
#ErrorToRemoteConnection.PreAuthenticate
 +
</pre>
 +
 +
====Appending Result Destination Url====
 +
 +
It is possible to append destination url (ResponseTo or ErrorTo) directly inside result resultexport. Value of global variable '''RequestParameters''' is appended to url.
 +
 +
In below example url from remote connection will be appended with OK or ERROR:
 +
<pre>
 +
...
 +
<foreach table="JobList" datacontext="mappings" classname="DataBO.ProcessMngt.JobBO">
 +
    <variable name="RequestParameters">{:if #Result.IsImported}OK{:else}ERROR{:endif}(</variable>
 +
    <data>
 +
...
 +
</pre>
 +
 +
Possible results:
 +
<pre>
 +
http://remoteconnectionurl.com/OK
 +
http://remoteconnectionurl.com/ERROR
 
</pre>
 
</pre>
  
Line 126: Line 153:
  
 
Sample definition: [[#Asynchronous_Web_Service_With_Message_Identification_Handling|Asynchronous Web Service With Message Identification Handling]]
 
Sample definition: [[#Asynchronous_Web_Service_With_Message_Identification_Handling|Asynchronous Web Service With Message Identification Handling]]
 +
 +
 +
==Known Issues==
 +
 +
*Validation in acknowledgement import should be avoided. Acknowledgement is intended to confirm that message is received. Validation should be placed in asynchronous import section. If for some reason it is required to validate message early in acknowledgement then it is important to know that validation section in acknowledgement import do not break following asynchronous import automatically. To workaround this issue same validation rules should be placed in both imports.
 +
 +
 +
*When identification in import fail (for example record in database is not matched and add is not allowed) then it is not treated as exception. Message will not be passed into '''ErrorTo''' automatically. Internally system will assume that identification problems are not error and send response message to '''ResponseTo''' url. To workaround this potential issue, validation section can be used. It is possible to define validation expression equivalent to identification. When validation fails system will send response to '''ErrorTo''' url. Another option is to redirect default url directly in ''resultexport'' responsible for generating ''Async Respond Message''. In ''resultexport'' it is possible to determine if particular record is imported or not and append default url with any string. This mean that it is possible to deliver message to ErrorTo endpoint even if internally system do not detect exception. For details check [[#Appending_Result_Destination_Url|Appending Result Destination Url]].
  
 
==Examples==
 
==Examples==
Line 285: Line 320:
 
</table>
 
</table>
 
       <validation>
 
       <validation>
       <error message="WO not allowed to update">#Import.JobCode!='13605'</error>
+
       <error message="WO 13605 not allowed to update (this is sample error message defined in import validation).">#Import.JobCode='13605'</error>
 
       </validation>
 
       </validation>
 
</mappings>
 
</mappings>

Latest revision as of 08:05, 16 December 2016


Introduction

Base principal of asynchronous processing is to store request data (from web service client) in queue and immediately respond with simple acknowledgement. From client point of view acknowledge means that his message is delivered and pending processing. Web service host process (import) received data in separate thread. Advantage of asynchronous processing is that client do not have to wait for time consuming processing (big data volume). Network connection can be easily broken and it is important to keep it as short as possible. Action after processing of message depend on agreement. Possible scenarios:

  1. Client don’t expect processing results (send and forget)
  2. Client will periodically call sever and asks for results (until processed)
  3. Client expects that server will always send back result.
  4. Client expects that server will send back result only when processing fail.


Async process.png


It is very important to understand how messages are processed internally. Basically new Thread is created and time consuming message processing is executed in background. Each request to agility create new thread. Asynchronous processing uses same as Agility thread pool. Thread pool is handled by IIS and by default there is no need to configure anything. This approach allows to pass security context (user authentication) from request to asynchronous processing thread. This approach brings brings some limitations however.

Current implementation cons:

  • Not possible to reprocess messages automatically after agility crash.
  • Not possible to synchronize same interface calls. It means that each request to agility will be immediately processed. It is not possible to delay (queue) asynchronous processing.

Asynchronous Web Service Definition

Basic Definition (without asynchronous respond)

To enable Asynchronous Import setup Storage Type as "AsyncWebService".


Import def form.png


Asynchronous import definition consists of regular import and additional section <ack>…<ack>. Inside ack element defined is additional separate import definition (full featured) which is responsible for generating acknowledgement. Import form ack section is processed first and import result is responded to client immediately. After respond main import is processed asynchronously (in separate thread). Result is stored in syImpExpQueue.AsyncResult.


Queue det formAsync result.png


With above basic pattern, message is processed asynchronously, result is generated (and stored in AsyncResult field). But result is not delivered anywhere. It is up to remote client to ask agility web service (with separate request) and retrieve result. Unfortunately there is no helper to support this pattern. Separate web service must be defined which will work on ImportExportQueueBO and query agility database for particular message status.

Sample definition: Simple Asynchronous Web Service Example.

Asynchronous Respond Delivery

When StorageType is set to AsyncWebService additional options appear on form: ResponseTo & ErrorTo. Both fields reference remote connections. If message is processed without exception generated response (AsyncResult) is delivered to ResponseTo. If message processing fail then response is delivered to ErrorTo. Both fields can use same remote connection, but in most cases used is only ErrorTo (with ResponseTo set to null). In most cases first assumption is that message is processed OK and no respond after processing is expected from server. But when something wrong happen server should respond with exception.


Import def form with async response.png


To handle response additional outgoing message is created in queue. This message is processed as any other message generated by export.


Impexp asyncresp scan.png


Both messages Incoming and Outgoing are referenced by OriginQueueID.


Impexpqueue async resp.png


Sample definition: Asynchronous Web Service With Message Identification Handling.

Result Destination Paramters

All data from both remote connections (ResponseTo & ErrorTo) are passed as variables to Result Export (responsible for generating async. response):

#ResponseToRemoteConnection.NetworkLogin
#ResponseToRemoteConnection.NetworkPassword
#ResponseToRemoteConnection.Login
#ResponseToRemoteConnection.Password
#ResponseToRemoteConnection.Code
#ResponseToRemoteConnection.Description
#ResponseToRemoteConnection.Type
#ResponseToRemoteConnection.Protocol
#ResponseToRemoteConnection.Url
#ResponseToRemoteConnection.AuthType
#ResponseToRemoteConnection.Domain
#ResponseToRemoteConnection.PreAuthenticate

#ErrorToRemoteConnection.NetworkLogin
#ErrorToRemoteConnection.NetworkPassword
#ErrorToRemoteConnection.Login
#ErrorToRemoteConnection.Password
#ErrorToRemoteConnection.Code
#ErrorToRemoteConnection.Description
#ErrorToRemoteConnection.Type
#ErrorToRemoteConnection.Protocol
#ErrorToRemoteConnection.Url
#ErrorToRemoteConnection.AuthType
#ErrorToRemoteConnection.Domain
#ErrorToRemoteConnection.PreAuthenticate

Appending Result Destination Url

It is possible to append destination url (ResponseTo or ErrorTo) directly inside result resultexport. Value of global variable RequestParameters is appended to url.

In below example url from remote connection will be appended with OK or ERROR:

...
<foreach table="JobList" datacontext="mappings" classname="DataBO.ProcessMngt.JobBO">
    <variable name="RequestParameters">{:if #Result.IsImported}OK{:else}ERROR{:endif}(</variable>
    <data>	
...

Possible results:

http://remoteconnectionurl.com/OK
http://remoteconnectionurl.com/ERROR

Import option element

Option element allows to exchange data between code and all stages of particular queue item (Import Export Queue Item). In code Options are stored in flat list of variables:

Import Options.png

Option element can be defined in mappings section. Option definition is similar like field element. Option element is implemented only for xml file import, and it must be defined inside table element.


<mappings>
    <table name="ImportedAssets" xpath="ImportFile/assets/asset">
          <option name="WSRemoteMessageID" xpath="//header/MessageID"></option>
          <field name="Description">#Import.Field3 + #Option.WSRemoteMessageID</field>
          ...
    </table>
</mappings>


In string expression reference to option is made with #Option prefix: #Option.WSRemoteMessageID. Options can be accessed in result export without declaring any context.

Messages Identification

In asynchronous processing it is important to allow identification of particular message conversation. Our interfaces are defined in generic way, and there is no automatic mechanism to handle messages identification. Each interface must take carte of identification itself. Import Options functionality is developed to help handle this problem.

Queue is extended with two additional string fields: WSMessageID & WSRemoteMessageID. Message Identification fields has corresponding import options: WSMessageID & WSRemoteMessageID. Be aware that both fields represent particular message conversation (not just single queue element or packet send over the network!).

MessageID can be set by client but also by server. For example client can assign message id in request and will expect that any respond will carry same messageid (so client can match which respond belongs to which request). But client can leave this task for server for example client create message without id but expect that server will assign id and acknowledgement contains message id. Client will reuse provided id to periodically ask for processing result. Both patterns are supported.

WSMessageID
Assigned automatically in code for each import which is handled by queue (Web Service Import). It is unique GUID generated during creating of item in syImpExpQueue.
WSRemoteMessageID
Represent ID assigned by remote client. It is optional and depend on import definition (in most cases declared in ack-import, but it can be defined in regular import too). When in web service import definition, one of options is named WSRemoteMessageID then result of option evaluation is automatically saved to appropriate queue item (syImpExpQueue.WSRemoteMessageID).

Sample definition: Asynchronous Web Service With Message Identification Handling


Known Issues

  • Validation in acknowledgement import should be avoided. Acknowledgement is intended to confirm that message is received. Validation should be placed in asynchronous import section. If for some reason it is required to validate message early in acknowledgement then it is important to know that validation section in acknowledgement import do not break following asynchronous import automatically. To workaround this issue same validation rules should be placed in both imports.


  • When identification in import fail (for example record in database is not matched and add is not allowed) then it is not treated as exception. Message will not be passed into ErrorTo automatically. Internally system will assume that identification problems are not error and send response message to ResponseTo url. To workaround this potential issue, validation section can be used. It is possible to define validation expression equivalent to identification. When validation fails system will send response to ErrorTo url. Another option is to redirect default url directly in resultexport responsible for generating Async Respond Message. In resultexport it is possible to determine if particular record is imported or not and append default url with any string. This mean that it is possible to deliver message to ErrorTo endpoint even if internally system do not detect exception. For details check Appending Result Destination Url.

Examples

With examples in this chapter it is possible to setup full asynchronous communication between two Agility systems. Purpose of Asynchronous functionality is to enhance Server Side Import functionality, but for testing purpose and reference created are samples to set up RemoteClient too.

Web Service (Server Side)

Simple Asynchronous Web Service

In this example client asynchronously request update of particular job. In simplest scenario ack import consists with result generator (result export):

<?xml version="1.0" encoding="utf-8"?>
<import>
	<!-- =======================================================
	ACKnowledgement hander 
	============================================================ -->
	<ack>
		<resultexport>
			<contents>
				<data type="template-xml">
					<ack>OK</ack>
				</data>
			</contents> 
		</resultexport>	
	</ack>

	<!-- =======================================================
	Standard import processed asynchronously in separate thread 
	============================================================ -->
	<namespaces>
		<namespace name="wo" uri="http://www.fastnetasp.com/GeneralImport/WO"/>
		<namespace name="soap" uri="http://www.w3.org/2003/05/soap-envelope"/>
	</namespaces>
	<mappings classname="Control.GeneralInterface.XMLFileImport">	
		<table name="JobList" xpath="soap:Envelope/soap:Body/wo:UpdateJob/wo:JobList/wo:woJob">
			<field name="JobCode" xpath="wo:JobCode"/>
			<field name="Description" xpath="wo:Description"/>
			<field name="JobStatus" xpath="wo:JobStatus"/>
			<field name="JobType" xpath="wo:JobType"/>			
			<table name="JobTask" xpath="wo:woJobTask">
				<field name="TaskCode" xpath="wo:TaskCode"/>
				<field name="TaskDescription" xpath="wo:Description"/>
				<field name="TaskType" xpath="wo:TaskType"/>
				<field name="TaskStatus" xpath="wo:TaskStatus"/>
			</table>
		</table>
	</mappings>



	<assign classname="Control.GeneralInterface.StandardImportProcessor">
		<businessobject classname="DataBO.ProcessMngt.JobBO">
			<table name="woJob" sourceTable="JobList">
				<identification>
					woJob.JobCode = #Import.JobCode
				</identification>
				<mode>
					<update/>
				</mode>			
				<set>
					<field name="JobStatusID">Lookup("DataBO.SystemData.JobStatusBO","syJobStatus","Code",#Import.JobStatus,"JobStatusID")</field>
					<field name="FullDescription">#Import.Description</field>
				</set>
			</table>
		</businessobject>
	</assign>

	<resultexport>
		<contents defaulttype="template-xml">
			<data>
				<soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope">
					<soap:Body>
						<UpdateJobResponse xmlns="http://www.fastnetasp.com/GeneralImport/WO">
							<UpdateJobResult>
							{:include "jobresults"}
							</UpdateJobResult>
						</UpdateJobResponse>
					</soap:Body>
				</soap:Envelope>
			</data>

			<partial name="jobresults">
				<foreach table="JobList" datacontext="mappings" classname="DataBO.ProcessMngt.JobBO">	
					<data>	
						<woJobResult>
							<JobCode>{woJob.JobCode}</JobCode>
							<StatusCode>
								{:if #Result.IsImported}OK{:else}ERROR{:endif}
							</StatusCode>
							<StatusDescription>{#Result.Message}</StatusDescription>
						</woJobResult>
					</data>
				</foreach>
			</partial>		
		</contents>
	</resultexport>
</import>



Asynchronous Web Service With Message Identification Handling

This example show how to use options to handle WSMessageID & WSRemoteMessageID. Please note that inside import defined is field:

    <field name="justwait">System.Threading.Thread.Sleep(20000)</field>		

This field purpose is to fake long processing of message, so asynchronous processing can be observed. It should be used only for debug purpose!


<?xml version="1.0" encoding="utf-8"?>
<import>
  <ack>
	<namespaces>
		<namespace name="wo" uri="http://www.fastnetasp.com/GeneralImport/WO"></namespace>
		<namespace name="soap" uri="http://www.w3.org/2003/05/soap-envelope"></namespace>
	</namespaces>
  	<mappings classname="Control.GeneralInterface.XMLFileImport">	
			<table name="JobList" xpath="soap:Envelope/soap:Body/wo:UpdateJob/wo:JobList/wo:woJob">
				<option name="WSRemoteMessageID" xpath="wo:JobCode"></option>
				<table name="JobTask" xpath="wo:woJobTask">
					<field name="TaskCode" xpath="wo:TaskCode"></field>
					<option name="WSRemoteMessageID">#Option.WSRemoteMessageID + "-" + #Import.TaskCode</option>
					<option name="ScopeTest">"I'm in scope"</option>
				</table>
			</table>
	</mappings>
  
	<resultexport>
		<contents>
			<data type="template-xml"><ack WSMessageID="{#Option.WSMessageID}" WSRemoteMessageID="{#Option.WSRemoteMessageID}">OK</ack></data>
		</contents>
	</resultexport>	
  </ack>
  
  <namespaces>
    <namespace name="wo" uri="http://www.fastnetasp.com/GeneralImport/WO"></namespace>
	<namespace name="soap" uri="http://www.w3.org/2003/05/soap-envelope"></namespace>
  </namespaces>
  	<mappings classname="Control.GeneralInterface.XMLFileImport">	
			<table name="JobList" xpath="soap:Envelope/soap:Body/wo:UpdateJob/wo:JobList/wo:woJob">
				<field name="JobCode" xpath="wo:JobCode"></field>
				<field name="Description">#Option.ScopeTest</field>
				<field name="JobStatus" xpath="wo:JobStatus"></field>
				<field name="JobType" xpath="wo:JobType"></field>
				<field name="justwait">System.Threading.Thread.Sleep(20000)</field>				
				<table name="JobTask" xpath="wo:woJobTask">
					<field name="TaskCode" xpath="wo:TaskCode"></field>
					<field name="TaskDescription" xpath="wo:Description"></field>
					<field name="TaskType" xpath="wo:TaskType"></field>
					<field name="TaskStatus" xpath="wo:TaskStatus"></field>
				</table>
			</table>
      <validation>
      <error message="WO 13605 not allowed to update (this is sample error message defined in import validation).">#Import.JobCode='13605'</error>
      </validation>
	</mappings>
	

	
	<assign classname="Control.GeneralInterface.StandardImportProcessor">
		<businessobject classname="DataBO.ProcessMngt.JobBO">
			<table name="woJob" sourceTable="JobList">
				<identification>
					woJob.JobCode = #Import.JobCode
				</identification>
				<mode>
					<update/>
				</mode>			
				<set>
					<field name="JobStatusID">Lookup("DataBO.SystemData.JobStatusBO","syJobStatus","Code",#Import.JobStatus,"JobStatusID")</field>
					<field name="FullDescription">#Import.Description + "\r\n" + #Option.WSMessageID +"\r\n" + #Option.WSRemoteMessageID</field>
				</set>
			</table>
		</businessobject>
	</assign>
	
	<resultexport>
		<contents defaulttype="template-xml">
          <variable name="globalVarTest" type="stringexpression">"Hello I'm Global Var"</variable>
			<data>
				<soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope">
				<soap:Body>
					<UpdateJobResponse xmlns="http://www.fastnetasp.com/GeneralImport/WO">
						<UpdateJobResult>
							{:include "jobresults"}
						</UpdateJobResult>
					</UpdateJobResponse>
				</soap:Body>
				</soap:Envelope>
			</data>
			
			<partial name="jobresults">
				<foreach table="JobList" datacontext="mappings" classname="DataBO.ProcessMngt.JobBO">	
					<data>	
						<woJobResult WSMessageID="{#Option.WSMessageID}" WSRemoteMessageID="{#Option.WSRemoteMessageID}">
							<JobCode>{woJob.JobCode}</JobCode>
							<StatusCode>
								{:if #Result.IsImported}
                              		OK
								{:else}
									ERROR
								{:endif}
							</StatusCode>
							<ScopeTest>
								{#Option.ScopeTest}
							</ScopeTest>
							<StatusDescription>{#Result.Message}</StatusDescription>
						</woJobResult>
					</data>
				</foreach>
			</partial>		
		</contents>
	</resultexport>

</import>

Remote Client

Request Job Update on Asynchronous WebService (Export)

This basic export definition should be configured on RemoteClient. Remote Connection should point to Asynchronous Web Service on ServerSide. In this example exported are basic informations form job (job with code: '13605'). Particular code is embedded directly in definition so it can be triggered directly from ImpExpConfiguration details.

<export>
	<contents defaulttype="template-xml">
		<data>
			<soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope">
			<soap:Body>
				<UpdateJob xmlns="http://www.fastnetasp.com/GeneralImport/WO">
					{:include "joblist"}
				</UpdateJob>
			</soap:Body>
			</soap:Envelope>
		</data>
		
		<partial name="joblist">
			<foreach table="woJob" datacontext="dataset" classname="DataBO.ProcessMngt.JobBO">
				<dbfilter>
					woJob.JobCode = "13605"
				</dbfilter>
				<container>
					<JobList>{:foreach_data}</JobList>
				</container>
				<data>
					<woJob>
					   <JobCode>{woJob.JobCode}</JobCode>
					   <Description>{woJob.FullDescription}</Description>
					   <JobStatus>{syJobStatus.Code}</JobStatus>
					   <JobType>{syJobType.Code}</JobType>
					   {:include "jobtask"}
					</woJob>
				</data>
			</foreach>
		</partial>
		
		<partial name="jobtask">
			<foreach table="woJobTask">
				<data>
					<woJobTask>
						<TaskCode>{woJobTask.Code}</TaskCode>
						<Description>{woJobTask.Description}</Description>
						<TaskType>{syTaskType.Code}</TaskType>
						<TaskStatus>{syJobStatus.Code}</TaskStatus>
					</woJobTask>
				</data>
			</foreach>
		</partial>
		
	</contents>
</export>

Receive Job Update Respond (WebService Import for ResponseTo)

Below definition represent web service which will be called by Remote Web Service with Asynchronous result.

<import>
  <namespaces>
    <namespace name="wo" uri="http://www.fastnetasp.com/GeneralImport/WO"></namespace>
	<namespace name="soap" uri="http://www.w3.org/2003/05/soap-envelope"></namespace>
  </namespaces>
  	<mappings classname="Control.GeneralInterface.XMLFileImport">	
			<table name="JobList" xpath="soap:Envelope/soap:Body/wo:UpdateJobResponse/wo:UpdateJobResult/wo:woJobResult">
				<field name="JobCode" xpath="wo:JobCode"></field>
				<field name="StatusCode" xpath="wo:StatusCode"></field>
				<option name="WSRemoteMessageID" xpath="@WSRemoteMessageID"></option>
			</table>
	</mappings>
	
	<assign classname="Control.GeneralInterface.StandardImportProcessor">
		<businessobject classname="DataBO.ProcessMngt.JobBO">
			<table name="woJob" sourceTable="JobList">
				<identification>
					woJob.JobCode = #Import.JobCode
				</identification>
				<mode>
					<update/>
				</mode>			
				<set>
					<field name="FullDescription">woJob.FullDescription + "\r\n Async Result Received. WSRemoteMessageID: " + #Option.WSRemoteMessageID</field>
				</set>
			</table>
		</businessobject>
	</assign>
	
	<resultexport>
		<contents defaulttype="template-xml">
			<data>
				<AsynResultReceived>OK</AsynResultReceived>
			</data>
		</contents>
	</resultexport>
	
</import>

Receive Job Update Error (WebService Import for ErrorTo)

Below definition represent web service which will be called by Remote Web Service with Asynchronous ERROR result.

<import>
  <namespaces>
    <namespace name="wo" uri="http://www.fastnetasp.com/GeneralImport/WO"></namespace>
	<namespace name="soap" uri="http://www.w3.org/2003/05/soap-envelope"></namespace>
  </namespaces>
  	<mappings classname="Control.GeneralInterface.XMLFileImport">	
			<table name="JobList" xpath="soap:Envelope/soap:Body/wo:UpdateJobResponse/wo:UpdateJobResult/wo:woJobResult">
				<field name="JobCode" xpath="wo:JobCode"></field>
				<field name="StatusCode" xpath="wo:StatusCode"></field>
				<option name="WSRemoteMessageID" xpath="@WSRemoteMessageID"></option>
			</table>
	</mappings>
	
	<assign classname="Control.GeneralInterface.StandardImportProcessor">
		<businessobject classname="DataBO.ProcessMngt.JobBO">
			<table name="woJob" sourceTable="JobList">
				<identification>
					woJob.JobCode = #Import.JobCode
				</identification>
				<mode>
					<update/>
				</mode>			
				<set>
					<field name="FullDescription">woJob.FullDescription + "\r\n Async ERROR result Receiced. WSRemoteMessageID: " + #Option.WSRemoteMessageID</field>
				</set>
			</table>
		</businessobject>
	</assign>
	
	<resultexport>
		<contents defaulttype="template-xml">
			<data>
				<AsyncErrorReceived>OK</AsyncErrorReceived>
			</data>
		</contents>
	</resultexport>
	
</import>