Passing a file attachment from OIC to a Process Application

In Oracle Integration Cloud you have the ability to create human tasks, with the user given the opportunity to upload files from their desktops to add to the BPM flow. However, what about starting a Process flow with an attachment already there for the user? Maybe trigger the Process Application from an OIC Integration?

Figure 1 – Example flow, triggering a Process Application instance from OIC

Whether the file is sourced externally [1], or produced as a result of an OIC Integration process [2], the purpose of this example is to create a task for a user, group of users, or application role to pick up in their task list and process.

Custom WSDL

For this example I created a custom WSDL endpoint. The cut-down schema is loosely based on an old 11g version of an Oracle BPM task process.. (Interesting to note that the Oracle BPM/task schemas haven’t changed for many years!!)

<?xml version="1.0" encoding="UTF-8"?>
<definitions targetNamespace="http://example.com/bpmn/bpmnCloudProcess/YanPoc2a/ReceiveFileProcess" xmlns="http://schemas.xmlsoap.org/wsdl/" xmlns:tns="http://example.com/bpmn/bpmnCloudProcess/YanPoc2a/ReceiveFileProcess" xmlns:soap12="http://schemas.xmlsoap.org/wsdl/soap12/" xmlns:mime="http://schemas.xmlsoap.org/wsdl/mime/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" name="ReceiveFileProcess">
	<types>
		<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns="http://example.com/bpmn/bpmnCloudProcess/YanPoc2a/ReceiveFileProcess" targetNamespace="http://example.com/bpmn/bpmnCloudProcess/YanPoc2a/ReceiveFileProcess">
			<xsd:complexType name="attachmentType">
				<xsd:sequence>
					<xsd:element name="content" type="xsd:string" minOccurs="0"/>
					<xsd:element name="mimeType" type="xsd:string" minOccurs="0"/>
					<xsd:element name="name" type="xsd:string" minOccurs="0"/>
					<xsd:element name="updatedBy" type="xsd:string" minOccurs="0"/>
					<xsd:element name="URI" type="xsd:string" minOccurs="0"/>
					<xsd:element name="systemVersionFlag" type="xsd:string" minOccurs="0"/>
					<xsd:element name="taskId" type="xsd:string" minOccurs="0"/>
					<xsd:element name="version" type="xsd:integer" minOccurs="0"/>
					<xsd:element name="acl" type="xsd:string" minOccurs="0"/>
					<xsd:element name="doesBelongToParent" type="xsd:boolean" minOccurs="0"/>
					<xsd:element name="updatedDate" type="xsd:dateTime" minOccurs="0"/>
				</xsd:sequence>
			</xsd:complexType>
			<xsd:complexType name="taskType">
				<xsd:sequence>
					<xsd:element name="title" type="xsd:string" minOccurs="0"/>
					<xsd:element name="ownerUser" type="xsd:string" minOccurs="0"/>
					<xsd:element name="ownerGroup" type="xsd:string" minOccurs="0"/>
					<xsd:element name="ownerRole" minOccurs="0" type="xsd:string"/>
					<xsd:element name="attachment" type="attachmentType"/>
				</xsd:sequence>
			</xsd:complexType>
			<xsd:element name="start">
				<xsd:complexType>
					<xsd:sequence>
						<xsd:element name="userName" type="xsd:string"/>
						<xsd:element name="fileName" type="xsd:string"/>
						<xsd:element name="fileContent" type="xsd:base64Binary"/>
						<xsd:element name="task" type="taskType"/>
					</xsd:sequence>
				</xsd:complexType>
			</xsd:element>
			<xsd:element name="endResponse">
				<xsd:complexType>
					<xsd:sequence>
						<xsd:element name="FlowID" type="xsd:string"/>
						<xsd:element name="Status" type="xsd:string"/>
						<xsd:element name="Feedback" type="xsd:string"/>
					</xsd:sequence>
				</xsd:complexType>
			</xsd:element>
		</xsd:schema>
	</types>
	<message name="MessageIn">
		<part name="parameters" element="tns:start"/>
	</message>
	<portType name="ReceiveFileProcessPortType">
		<operation name="start">
			<input message="tns:MessageIn"/>
		</operation>
	</portType>
	<binding name="ReceiveFileProcessBinding" type="tns:ReceiveFileProcessPortType">
		<soap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http"/>
		<operation name="start">
			<soap:operation soapAction="http://example.com/services/ReceiveFile"/>
			<input>
				<soap:body use="literal" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>
			</input>
		</operation>
	</binding>
	<service name="ReceiveFileProcess">
		<documentation>This is a test service for use in a BPM or Process Application process. It is a simple SOAP PoC to upload files up to 10mb in size.</documentation>
		<port name="ReceiveFilePort" binding="tns:ReceiveFileProcessBinding">
			<soap:address location="http://example.com/services/ReceiveFile"/>
		</port>
	</service>
</definitions>

The only thing of note regarding the above WSDL is that I intend for it to be a one-way (fire and forget) operation from the OIC Integration to call the Process Application. Obviously OIC will raise an error if the endpoint cannot be reached, or if there is an issue executing the Process Application, but otherwise I want OIC to create the task containing the file in the Process Application, and that’s it.

Process Application – customize the start event

Create a new Process Application.

Choose the Create an Application option and give it a name.

Depending on your requirements, pick the Structured or Dynamic Process style. We’ll pick a Structure Process for this example. Choose the ‘Start when a message is received‘ option.

On the Start event, edit the Properties (Open Properties) to add and edit the endpoint signature.

You can give the process a more meaningful name, but when you’re done press the Create button.

Change the implementation from ‘Define Interface’ to ‘Use Interface‘ and press the pencil button to edit.

Press the + button to add a new reference.

Choose ‘Upload from file‘ and select your wsdl file. Press Next.

Press Next again to import the wsdl.

Update the reference name and press Create. Note that the import reference contains both a Port Type and Callback Port Type. The callback port will have been created automatically, but in this example I will change the End event later to stop to process, rather than create and make any callback.

Go back into the Start ‘Open Properties‘ page, and again choose ‘Use Interface‘. Press the Configure button.

In the Configure screen, press the magnifier glass and select the ‘ReceiveFile‘ reference. Press OK, then OK again.

Your properties should look like this.

Create a custom Business Object using the WSDL schema

Open the Data Objects window.

Give the Business Object a name, receiveFileBO. Change the Data Type to ‘Business‘, and choose the Start type. Press Create.

Map data to receiveFileBO

Open the Data Association screen on the Start event.

As they are of the same types, simply map the Start.start to the receiveFileBO. Press Apply.

Create your Human Task and map the values

Add a Human Task to the flow as normal. Create the form as you desire, but when it comes to mapping, the important data associations are shown below. Although the Human Form can take more than one attachment, this example only wants to create one human task with one attachment. Therefore we will use the [1] notation to build the attachment into the first [1] attachment array slot.

The ‘name’ will be the file name, and the content will be the base64 encoded value of the file attachment.

Once you have fully configured the Human Task and the rest of the Process Application flow has been configured, published and activated, grab the URL of the exposed Process Application service from the ‘Web Services’ screen.

Map the file name and content in OIC

Back in OIC Integration, create a SOAP Connection based on the Process Application web service you’ve just Activated, and place it within your Integration flow.

In this basic OIC Integration flow we have a scheduled File Adapter that is polling for files on a server. The process will create a List of files that exist on the server, and for-each of them the process will loop over each one to download it, encode it, and send it to the ‘Receive File Process’ Process Application.

The mapping for the SOAP call to the Receive File Process links the downloaded file to the content of the attachment.

The important mapping of note is the FileReference of the downloaded file. The encodeReferenceToBase64 mapping uses the FileReference, and encodes the payload to a Base64 encoded string. In our example we will map it to the attachment.content element.

I’ve added elements for userName, ownerUser and ownerGroup to the wsdl schema definition. You can use any of them if you want to set the target user or group in the OIC Integration for later use/mapping to the Human Task target actors of the task in the Process Application.

When you run the OIC process it will convert the files to a base64 encoded string, and execute the Process Application. The Process Application will run and the Human Task will be accessible by the ownerUser/ownerGroup.

If run successfully a Task is created. The assigned user (or group) will be able to claim/open the task. Within the assigned task the document attachment will be accessible. The diagram below shows that the file ‘text1.txt’ can be downloaded from the task under the ‘Documents’ link (on the far right hand side).

That’s it! There are many use cases I can think of that starting a Process Application flow from an integration, including a file attachment, would be very useful. I hope that reading this blog post this gives you a little confidence to try it yourself.

Notes:

The 10mb limit. Each document you process cannot be more than 10mb in size. This is an OIC payload size limit.

Expire Tasks: You may not want large amount of tasks on the OIC platform running indefinitely so remember to set an expiration.

One thought on “Passing a file attachment from OIC to a Process Application

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s