Skip to main content

Notice: this Wiki will be going read only early in 2024 and edits will no longer be possible. Please see: https://gitlab.eclipse.org/eclipsefdn/helpdesk/-/wikis/Wiki-shutdown-plan for the plan.

Jump to: navigation, search

Difference between revisions of "SMILA/Development Guidelines/Tutorial - Integration of the HelloWorld webservice as a Pipelet"

(Undo revision 120944 by Daniel.stucky.empolis.com (Talk))
 
Line 1: Line 1:
This page illustrates all steps that need to be performed in order to integrate a sample HelloWorld web service as a pipelet in SMILA.
+
#REDIRECT [[SMILA/Development Guidelines/HowTo integrate the HelloWorld webservice as a Pipelet]]
 
+
== Introduction ==
+
 
+
As you can learn from [[SMILA/Howto_integrate_a_component_in_SMILA|How to integrate a component in SMILA]] there are several integration strategies available for adding further functionality to SMILA. One technique, which we assume as the default method, involves the integration of a web service as either a [[SMILA/Glossary#P|pipelet]] or - for more advanced applications - as a [[SMILA/Glossary#P|processing service]]. On this page, however, we restrict ourselves to the implementation of a pipelet, which is the easier one of the two. To do this we show the necessary steps that are required to implement a pipelet that provides the functionality of a simple HelloWorld web service to SMILA.
+
 
+
For your convenience and an easy start-up you may also download the sample as a compressed ZIP file from [[Media:HelloWorldPipelet.zip|HelloWorldPipelet.zip]].
+
 
+
== Preparations ==
+
 
+
It may be helpful to first take a look at the SMILA [[SMILA/Development_Guidelines|Development_Guidelines]] as many topics that are beyond the scope of this tutorial are illustrated there in detail.
+
 
+
=== Create a new Bundle ===
+
 
+
* First you have to create a new bundle that will contain the Pipelet. Please follow the instructions on [[SMILA/Development_Guidelines/Create_a_bundle_%28plug-in%29|How to create a bundle]] and use the following settings:
+
<pre>
+
Project name: org.eclipse.smila.sample.pipelet
+
Plug-in ID: org.eclipse.smila.sample.pipelet
+
Plug-in Version: 1.0.0
+
Plug-in Name: Sample Pipelet Bundle
+
Plug-in Provider: your name or company
+
</pre>
+
 
+
* Then you have to integrate your new bundle into the SMILA build process. Therefore please follow the instructions on [[SMILA/Development_Guidelines/How_to_integrate_new_bundle_into_build_process|How to integrate a new bundle into build process]].
+
* Edit file <tt>META-INF/MANIFEST.MF</tt> and add the following import-package dependencies as those are required to implement the basic functionalities of your Pipelet:
+
<pre>
+
Import-Package: org.apache.commons.logging;version="1.1.1",
+
org.eclipse.smila.blackboard.BlackboardService;version="0.5.0",
+
org.eclipse.smila.datamodel.id.Id;version="0.5.0",
+
org.eclipse.smila.processing.ProcessingException;version="0.5.0",
+
org.eclipse.smila.processing.SimplePipelet;version="0.5.0",
+
org.eclipse.smila.processing.configuration.PipeletConfiguration;version="0.5.0"
+
</pre>
+
* In order for the PipeletTrackerService to detect your new Pipelet you have to add the following line to file <tt>META-INF/MANIFEST.MF</tt> to register the class that will implement your SMILA Pipelet:
+
<pre>
+
SMILA-Pipelets: org.eclipse.smila.sample.pipelet.HelloWorldPipelet
+
</pre>
+
 
+
=== Create Java classes from WSDL ===
+
comming soon ...
+
 
+
 
+
== Implementation ==
+
 
+
* create a package <tt>org.eclipse.smila.sample.pipelet</tt> and a Java class <tt>HelloWorldPipelet</tt>
+
* use the following code as a template for your new class. It contains empty method bodies and a reference to the logger. The comments are successively replaced with code snippets in the following sections. For your convenience you may also download the complete zipped source file [[Media:HelloWorldPipelet.zip|HelloWorldPipelet.zip]].
+
<source lang="Java">
+
package org.eclipse.smila.sample.pipelet
+
+
import org.apache.commons.logging.Log;
+
import org.apache.commons.logging.LogFactory;
+
import org.eclipse.smila.blackboard.BlackboardService;
+
import org.eclipse.smila.blackboard.path.Path;
+
import org.eclipse.smila.datamodel.id.Id;
+
import org.eclipse.smila.datamodel.record.Literal;
+
import org.eclipse.smila.datamodel.record.RecordFactory;
+
import org.eclipse.smila.processing.ProcessingException;
+
import org.eclipse.smila.processing.SimplePipelet;
+
import org.eclipse.smila.processing.configuration.PipeletConfiguration;
+
+
public class HelloWorldPipelet implements SimplePipelet {
+
+
  // additional member variables
+
  private final Log _log = LogFactory.getLog(HelloWorldPipelet.class);
+
 
+
  public HelloWorldPipelet(){
+
  }
+
+
  public void configure(PipeletConfiguration configuration) throws ProcessingException {
+
    // read the configuration properties
+
  }
+
+
  public Id[] process(BlackboardService blackboard, Id[] recordIds) throws ProcessingException {
+
    // process the recordIds and create a result
+
  }
+
}
+
</source>
+
 
+
 
+
=== Read PipeletConfiguration ===
+
* first let's create two member variables that store the names of the in- and output Attributes as well as String constants for the property names used in the configuration. Replace the comment "<tt>// additional member variables </tt>" with the following code snippet.
+
<source lang="Java">
+
private final String PROP_IN_ATT_NAME= "IN_ATT_NAME";
+
private final String PROP_OUT_ATT_NAME= "OUT_ATT_NAME";
+
 
+
private String _inAttName;
+
private String _outAttName;
+
</source>
+
 
+
* then we will fill those members with the Attribute names provided by the PipeletConfiguration in method <tt>configure(PipeletConfiguration configuration)</tt>. The method <tt>getPropertyFirstValueNotNull(String)</tt> will check that the value of the property is not null. If it is null a <tt>ProcessingException</tt> will be thrown. In addition we should ensure, that the provided String is not empty or consists only of whitespaces. Replace the comment "<tt>// read the configuration properties</tt>" with the following code snippet.
+
<source lang="Java">
+
_inAttName = (String) configuration.getPropertyFirstValueNotNull(PROP_IN_ATT_NAME);
+
if (_inAttName.trim().length() == 0) {
+
    throw new ProcessingException("Property " + PROP_IN_ATT_NAME + " must not be an empty String");
+
}
+
 
+
_outAttName = (String) configuration.getPropertyFirstValueNotNull(PROP_OUT_ATT_NAME);
+
if (_outAttName.trim().length() == 0) {
+
    throw new ProcessingException("Property " + PROP_OUT_ATT_NAME + " must not be an empty String");
+
}
+
</source>
+
'''Note''': Of course it is also possible to store the PipeletConfiguration in a member variable and access the properties as needed in the <tt>process(BlackboardService blackboard, Id[] recordIds)</tt> method.
+
 
+
=== Processing of IDs and exception handling ===
+
The method <tt> process(BlackboardService blackboard, Id[] recordIds)</tt> has two parameters:
+
* a reference to the BlackboardService that allows access on Records
+
* a list of Record IDs to process
+
The HelloWorldPipelet should therefor iterate over the IDs in parameter <tt>recordIds</tt>, get the required data from the Record identified by the ID, process this data and store the Result in the  Record. Let's place a <tt>try ... catch()</tt> block in the for loop to ensure that errors do only interrupt the processing of the current ID. The comments in the code serve as placeholders for the functionality described in the following sections. At the end we return the unmodified input parameter <tt>recordIds</tt> as the result of the Pipelet. Replace the comment "<tt>// process the recordIds and create a result</tt>" with the following code snippet.
+
<source lang="Java">
+
for (Id id : recordIds) {
+
    try {
+
        // Read Input Data
+
 
+
        // Process Input Data
+
 
+
        // Write Output Data
+
 
+
    } catch (final Exception ex) {
+
        if (_log.isErrorEnabled()) {
+
            _log.error("error during execution of HelloWorldPipelet with record " + id, ex);
+
        }
+
    }
+
} // for
+
 
+
return recordIds;
+
</source>
+
 
+
'''Note''': Most of the time the return value of a Pipelet is the unmodified input parameter <tt>recordIds</tt>. However, in some cases a Pipelet may filter Record IDs or even create new Records. Then the return value has to be adopted appropriately.
+
 
+
 
+
=== Read Input Data ===
+
Now we want to read the data of the Attribute with the name stored in <tt>_inAttName</tt>. Therefore we first have to create a <tt>Path</tt> object with the Attribute's name. Before accessing the literal value we check if the Record contains a Attribute with the given Path. In this Tutorial we know that the value of the Attribute is a String value, so we directly access the value by calling the method<tt>getStringValue()</tt>.
+
Replace the comment "<tt>// Read Input Data</tt>" with the following code snippet.
+
<source lang="Java">
+
String inputValue = "";
+
final Path path = new Path(_inAttName);
+
if (blackboard.hasAttribute(id, path)) {
+
  inputValue = blackboard.getLiteral(id, path).getStringValue();
+
}
+
</source>
+
'''Note''': The accessing of Attribute values can be done more generic. Therefore you have to check what DataType a certain Literal contains using method <tt>getDataType()</tt>. Then you can use the appropriate getter method to access thee raw data.
+
 
+
=== Process Input Data ===
+
At this point the HelloWorld webservice should be called with parameter <tt>inputValue</tt> and storing the result in variable <tt>outputValue</tt>, using the classes generated from WSDL.<br/>
+
Until this tutorial description is complete simply assign the content of variable <tt>inputValue</tt> to variable <tt>outputValue</tt> and append a constant string value. Replace the comment "<tt>// Process Input Data</tt>" with the following code snippet.
+
<source lang="Java">
+
    String outputValue = inputValue + " modified by HelloWorldPipelet";
+
</source>
+
 
+
=== Write Output Data ===
+
Finally we want to store the content of variable <tt>outputValue</tt> in the Record Attribute with the name contained in variable <tt>_outAttName</tt>. Therefore we have to create a new Literal object and set it's value. Then we only need to set this Literal for the current ID on the Blackboard.
+
Replace the comment "<tt>// Write Output Data</tt>" with the following code snippet.
+
<source lang="Java">
+
final Literal literal = RecordFactory.DEFAULT_INSTANCE.createLiteral();
+
literal.setStringValue(outputValue);
+
blackboard.setLiteral(id, new Path(_outAttName), literal);
+
</source>
+
'''Note''': The method <tt>commit(Id)</tt> of the BlackboardService does not need to be called in every Pipelet. It is automatically called at the end of the Pipeline.
+
 
+
 
+
== Configuration and Invocation in BPEL ==
+
In this tutorial we will integrate the HelloWorldPipelet in the SMILA indexing process just before the Record is stored in the Lucene index. With this configuration the input for the HelloWorldPipelet will be read from Attribute ''Title'' and the modified output will be stored in the same Attribute, overwriting the previous value.
+
* edit file configuration\org.eclipse.smila.processing.bpel\pipelines\addpipeline.bpel and add the following right between <tt><extensionActivity name="convertDocument"></tt> and <tt><extensionActivity name="invokeLuceneService"></tt>
+
<source lang="XML">
+
<extensionActivity name="invokeHelloWorldPipelet">
+
    <proc:invokePipelet>
+
        <proc:pipelet class="org.eclipse.smila.sample.pipelet.HelloWorldPipelet" />
+
        <proc:variables input="request" output="result" />
+
        <proc:PipeletConfiguration>
+
            <proc:Property name="IN_ATT_NAME">
+
                <proc:Value>Title</proc:Value>
+
            </proc:Property>
+
            <proc:Property name="OUT_ATT_NAME">
+
                <proc:Value>Title</proc:Value>
+
            </proc:Property>
+
        </proc:PipeletConfiguration>     
+
    </proc:invokePipelet>
+
</extensionActivity>
+
</source>
+
 
+
 
+
== Test your Pipelet ==
+
comming soon ...
+
 
+
[[Category:SMILA]]
+

Latest revision as of 04:37, 22 April 2009

Back to the top