Data Flow - From a Job to Petals using Attachments

Preliminary notes

This use case can be reproduced with both Talend Open Studio and Talend Integration Suite.
It is an alternative way to undertake what is done in the use cases "Data Flow - From a job to Petals using a tPetalsOutput" and "Data Flow - From a job to Petals using a tBufferOutput".

Rationale

Generate a data flow in a job, write it into a file and send this file as an attachment inside Petals.

The input message provides nothing.
The job's result and an attachment file are expected in the response.

Creating and exporting the job

The job to be executed performs the following actions:

  1. The job generates a data flow.
  2. This data flow is written into a file, as an XML document (it could also be any kind of file, e.g. CSV, positional...).
  3. This file is loaded and attached to the returned message.

This job has one context variable outputLocation, which indicates the location of the file to load and attach.
Remember, this file will be deleted once it has been loaded.

Creating the job

The job is made up of two components:

  1. The tRowGenerator generates the data flow.
  2. The tFileOutputXML serializes the data flow as an XML file. The file location is defined by a context variable (of type String).

Here is the overall aspect of the job.


Here is the schema and the generation settings for the tRowGenerator component.


Here are the properties of the tFileOutputXML component.
It has the same schema than the tRowGenerator.

Exporting the job

Select the job and right-click it. Select Export to Petals ESB.
Update the target destination.
Let the job be exposed as a singleton.

Click Edit the exported contexts to export the file location context.
In the export mode, select OUT-Attachment or Parameter and OUT-Attachment.

In the scope of this use case, we are going to use OUT-Attachment.
Consequently, the file location is the default one, defined in the job (cannot be null).

You should have the following dialog:

Click Finish.

Deploying and testing in Petals

Looking at the generated WSDL

In the created Petals service assembly, the most interesting thing to look at is the WSDL.
Indeed, the WSDL will determine the way the exported service will be called.


The input message's description expects no parameter.

<xs:element name="executeJob" type="tns:executeJob" />
<xs:complexType name="executeJob">
	<xs:sequence>
		<xs:element minOccurs="0" name="contexts" type="tns:talendContexts" />
		<xs:element minOccurs="0" name="in-attachments" type="tns:inAttachments" />
		<xs:element maxOccurs="unbounded" minOccurs="0" name="in-data-bean" type="tns:inRow" />
		<xs:element maxOccurs="unbounded" minOccurs="0" name="talend-option" type="xs:string" />
	</xs:sequence>
</xs:complexType>

<xs:complexType name="talendContexts">
	<xs:sequence>
	</xs:sequence>
</xs:complexType>

<xs:complexType name="inAttachments">
	<xs:sequence>
	</xs:sequence>
</xs:complexType>

<xs:complexType name="inRow">
	<xs:sequence>
	</xs:sequence>
</xs:complexType>


And the output message includes the job's result and the attached file.

<xs:element name="executeJobResponse" type="tns:executeJobResponse" />
<xs:complexType name="executeJobResponse">
	<xs:sequence>
		<xs:element minOccurs="0" name="talend-job-output" type="tns:talendJobOutput" />
	</xs:sequence>
</xs:complexType>

<xs:complexType name="talendJobOutput">
	<xs:sequence>
		<xs:element maxOccurs="unbounded" minOccurs="0" name="executionResult" nillable="true" type="ns1:stringArray" />
		<xs:element minOccurs="0" name="outAttachment" type="tns:outAttachments" />
		<xs:element maxOccurs="unbounded" minOccurs="0" name="outDataBean" nillable="true" type="tns:outRow" />
	</xs:sequence>
</xs:complexType>

<xs:complexType name="outAttachments">
	<xs:sequence>
		<xs:element name="outputLocation" nillable="true" type="tns:attachment" />
	</xs:sequence>
</xs:complexType>

<xs:complexType name="outRow">
	<xs:sequence>
	</xs:sequence>
</xs:complexType>


As you can see, the WSDL generation has taken into account the exported context.

Deploying and testing this new service

Since we use attachments, we will prefer using a Java client instead of SoapUI.
However, it is possible to use SoapUI to send or receive messages with attachments. Just make sure the MTOM property is activated.


The first thing to do is to create a service-unit for the Petals-BC-SOAP component, that exposes (consumes) our Talend job as a service outside the bus.
This step is not described here. You can take a look at the Petals-BC-SOAP documentation and the Petals Studio documentation.
Just make sure the SOAP configuration uses the InOut MEP and calls the executeJob method.


Then, to generate a client from the WSDL, you can use Apache CXF or Axis2.
As an example, the following code was generated with Apache CXF 2.2.6.
Check the CXF documentation to see how to develop a service consumer in Java.


Only the main client class is shown here.
The client's code is the following:

package org.ow2.petals.talend;

/**
 * Please modify this class to meet your needs This class is not complete
 */

import java.io.File;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.net.MalformedURLException;
import java.net.URL;

import javax.xml.namespace.QName;
import javax.xml.ws.BindingProvider;
import javax.xml.ws.soap.SOAPBinding;

/**
 * This class was generated by Apache CXF 2.2.6 Wed Mar 31 21:57:39 CEST 2010
 * Generated source version: 2.2.6
 */
public final class Client {

	private static final QName SERVICE_NAME = new QName(
			"http://petals.ow2.org/talend/", "GeneratedXmlService" );


	/**
	 * Constructor.
	 */
	private Client() {
		// nothing
	}


	/**
	 * Main method.
	 * @param args
	 * @throws Exception
	 */
	public static void main( String args[] ) throws Exception {

		URL wsdlURL = GeneratedXmlService.WSDL_LOCATION;
		if( args.length > 0 ) {
			File wsdlFile = new File( args[ 0 ]);
			try {
				if( wsdlFile.exists() ) {
					wsdlURL = wsdlFile.toURI().toURL();
				}
				else {
					wsdlURL = new URL( args[ 0 ]);
				}
			} catch( MalformedURLException e ) {
				e.printStackTrace();
			}
		}

		GeneratedXmlService ss = new GeneratedXmlService( wsdlURL, SERVICE_NAME );
		GeneratedXmlServicePortType port = ss.getGeneratedXmlEndpoint();

		// Activate the MTOM mode
		((SOAPBinding) ((BindingProvider) port).getBinding()).setMTOMEnabled( true );
		//

		System.out.println( "Invoking executeJob..." );
		org.ow2.petals.talend.TalendContexts contexts = null;
		org.ow2.petals.talend.InAttachments inAttachments = null;
		java.util.List<org.ow2.petals.talend.InRow> inDataBean = null;
		java.util.List<java.lang.String> talendOption = null;
		try {
			org.ow2.petals.talend.TalendJobOutput result = port.executeJob(
					contexts,
					inAttachments,
					inDataBean,
					talendOption );

			// Get the output attachment
			if( result == null )
				System.out.println( "Something went wrong. The result is null." );
			else {
				boolean errorOccured = true;
				if( result.getOutAttachment() != null ) {

					// Notice that "outputLocation" is the name of the context variable we exported.
					// The Talend export propagated its name in the WSDL.
					Attachment att = result.getOutAttachment().getOutputLocation();
					if( att != null ) {
						InputStream is = null;
						FileOutputStream fos = null;

						try {
							is = att.getFileContent().getInputStream();;
							fos = new FileOutputStream( new File(
									"C:/Documents and Settings/vzurczak/Bureau/outputXml.xml" ));

							byte[] buf = new byte[ 1024 ];
							int len;
							while((len = is.read( buf )) > 0) {
								fos.write( buf, 0, len );
							}

							errorOccured = false;

						} finally {
							if( is != null )
								is.close();
							if( fos != null )
								fos.close();
						}
					}
				}

				// Check what happened
				if( errorOccured )
					System.out.println( "Something went wrong. Good luck for debugging!" );
				else
					System.out.println( "OK." );
			}

		} catch( TalendTechnicalException_Exception e ) {
			System.out.println( "Expected exception: TalendTechnicalException has occurred." );
			System.out.println( e.toString() );

		} catch( TalendBusinessException_Exception e ) {
			System.out.println( "Expected exception: TalendBusinessException has occurred." );
			System.out.println( e.toString() );
		}

		System.exit( 0 );
	}
}


Notice that the MTOM-mode was activated. Not enabling it will result in errors.


The execution output (displayed in the console) is:

Invoking executeJob...
OK.

Labels

petals petals Delete
tutorial tutorial Delete
se se Delete
talend talend Delete
Enter labels to add to this page:
Please wait 
Looking for a label? Just start typing.