Over a million developers have joined DZone.

How to Connect Anypoint Mule ESB With FileNet Content Engine (CE)

This articles goes in-depth showing how to connect Mule ESB and IBM's FileNet Content Engine to perform CRUD operations.

Build APIs from SQL and NoSQL or Salesforce data sources in seconds. Read the Creating REST APIs white paper, brought to you in partnership with CA Technologies.

FileNet is a software developed by IBM to help enterprises in managing their contents (Content Management) and business processes. Using FileNet we can store the contents in the form of documents. Using Mule ESB we can perform CRUD operations on the FileNet. To establish a connection between our application and FileNet we need some details about FileNet like Credentials, Stanza, ObjectStore details. 

Prerequisites

  1. Anypoint Studio

  2. FileNet Connection Information:

    1. ObjectStore

    2. Stanza

    3. URI

    4. Credentials

    5. Document Folder Path

  3. FileNet jars

    • jace.jar

    • javaapi.jar

    • xlxpScanner.jar

    • xlxpScannerUtils.jar

    • p8cjares

    • stax-api.jar

    • listner.jar

    • log4j.jar

Steps

Step 1

Create a sample mule application and add the FileNet related jars to the application. Under src/main/resources create a property file and configure the FileNet related info over there.

#FileNet Configuration
filenet.uri=xxxxxxxxxxxxxx
filenet.userName=xxxxxxxxx
filenet.password=xxxxxxxxxxx
filenet.stanza=xxxxxxxxxxxx
filenet.objectStore=xxxxxxxxx
filenet.path=xxxxxx

Step 2

Create an abstract Java class for connection establishment and for accessing the property file values.

public abstract class AbstractFileNet{

    //can be directly accessed in java components
    protected String objectStore;
    protected String filenetDocPath;
    private String userName;
    private String password;
    private String stanza;
    private String uri;

    protected MCEConnection getMCEConnection(){
        MCEConnection ceConnection = new MCEConnection(); // TODO This can be a prototype spring bean, singleton doesnt work
        ceConnection.setPassword(password);
        ceConnection.setStanza(stanza);
        ceConnection.setUri(uri);
        ceConnection.setUserName(userName);
        ceConnection.initConnection();
        return ceConnection;
    }

    /**
    * @return the objectStore
    */
    public String getObjectStore() {
        return objectStore;
    }

    /**
    * @param objectStore the objectStore to set
    */
    public void setObjectStore(String objectStore) {
        this.objectStore = objectStore;
    }

    /**
    * @return the filenetDocPath
    */
    public String getFilenetDocPath() {
        return filenetDocPath;
    }

    /**
    * @param filenetDocPath the filenetDocPath to set
    */
    public void setFilenetDocPath(String filenetDocPath) {
        this.filenetDocPath = filenetDocPath;
    }

    /**
    * @return the userName
    */
    public String getUserName() {
        return userName;
    }

    /**
    * @param userName the userName to set
    */
    public void setUserName(String userName) {
        this.userName = userName;
    }

    /**
    * @return the password
    */
    public String getPassword() {
        return password;
    }

    /**
    * @param password the password to set
    */
    public void setPassword(String password) {
        this.password = password;
    }
    /**
    * @return the stanza
    */
    public String getStanza() {
        return stanza;
    }

    /**
    * @param stanza the stanza to set
    */
    public void setStanza(String stanza) {
        this.stanza = stanza;
    }

    /**
    * @return the uri
    */
    public String getUri() {
        return uri;
    }

    /**
    * @param uri the uri to set
    */
    public void setUri(String uri) {
        this.uri = uri;
    }
}

Step 3

Configure one spring bean for accessing property file referring the created Abstract class.

<spring:beans>
    <spring:bean id="abstractFilenet" name="abstractFilenet"
        class="com.test.poc.AbstractFileNet" abstract="true">
        <spring:property name="objectStore" value="${filenet.objectStore}" />
        <spring:property name="userName" value="${filenet.userName}" />
        <spring:property name="password" value="${filenet.password}" />
        <spring:property name="stanza" value="${filenet.stanza}" />
        <spring:property name="uri" value="${filenet.uri}" />
        <spring:property name="filenetDocPath" value="${filenet.path}" />
    </spring:bean>
</spring:beans>

Step 4

Create a sample flow to get the content from a file using Mule File component. FileNet will maintain the content in the form of a document. For every document we need to set some mandatory properties (properties specifies the metadata of the document). These mandatory fields will vary based on the user requirements. For example, in our case, for each and every document we need to set mimeType of the content, ScanDateTime, DocumentType, Source etc.,

Image title

Step 5

Create another java class with MCEConnection for establishing the connection with the Filenet.

import java.util.Iterator;
import java.util.Vector;
import javax.security.auth.Subject;
import com.filenet.api.collection.ObjectStoreSet;
import com.filenet.api.core.Connection;
import com.filenet.api.core.Domain;
import com.filenet.api.core.Factory;
import com.filenet.api.core.ObjectStore;
import com.filenet.api.util.UserContext;

/**
 * This object represents the connection with
 * the Content Engine. Once connection is established
 * it intializes Domain and ObjectStoreSet with
 * available Domain and ObjectStoreSet.
 * 
 */
public class MCEConnection 
{
    private Connection con;
    private Domain dom;
    private String domainName;
    private ObjectStoreSet ost;
    private Vector osnames;
    private boolean isConnected;
    private UserContext uc;

    private String userName;
    private String password;
    private String stanza;
    private String uri;

    /*
    * constructor
    */
    public MCEConnection()
    {
        con = null;
        uc = UserContext.get();
        dom = null;
        domainName = null;
        ost = null;
        osnames = new Vector();
        isConnected = false;
    }


    /*
    * Establishes connection with Content Engine using
    * supplied username, password, JAAS stanza and CE Uri.
    */

    public void initConnection()
    {
        con = Factory.Connection.getConnection(uri);
        Subject sub = UserContext.createSubject(con,userName,password,stanza);
        uc.pushSubject(sub);
        dom = fetchDomain();
        domainName = dom.get_Name();
        ost = getOSSet();
        isConnected = true;
    }

    /*
    * Establishes connection with Content Engine using
    * supplied username, password, JAAS stanza and CE Uri.
    */
    public void establishConnection(String userName, String password, String stanza, String uri)
    {
        con = Factory.Connection.getConnection(uri);
        Subject sub = UserContext.createSubject(con,userName,password,stanza);
        uc.pushSubject(sub);
        dom = fetchDomain();
        domainName = dom.get_Name();
        ost = getOSSet();
        isConnected = true;
    }

    /*
    * Returns Domain object.
    */
    public Domain fetchDomain()
    {
        dom = Factory.Domain.fetchInstance(con, null, null);
        return dom;
    }

     /*
     * Returns ObjectStoreSet from Domain
     */
    public ObjectStoreSet getOSSet()
    {
        ost = dom.get_ObjectStores();
        return ost;
    }

     /*
     * Returns vector containing ObjectStore
     * names from object stores available in
     * ObjectStoreSet.
     */
    public Vector getOSNames()
    {
        if(osnames.isEmpty())
        {
            Iterator it = ost.iterator();
            while(it.hasNext())
            {
                ObjectStore os = (ObjectStore) it.next();
                osnames.add(os.get_DisplayName());
            }
        }
        return osnames;
    }

    /*
    * Checks whether connection has established
    * with the Content Engine or not.
    */
    public boolean isConnected() 
    {
        return isConnected;
    }

    /*
    * Returns ObjectStore object for supplied
    * object store name.
    */
    public ObjectStore fetchOS(String name)
    {
        ObjectStore os = Factory.ObjectStore.fetchInstance(dom, name, null);
        return os;
    }

    /*
    * Returns the domain name.
    */
    public String getDomainName()
    {
        return domainName;
    }

    public void setUserName(String userName) {
        this.userName = userName;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    public void setStanza(String stanza) {
        this.stanza = stanza;
    }

    public void setUri(String uri) {
        this.uri = uri;
    }
}

Step 6 

Now create a java class to access the content of the file which is taken using Mule File Component and to upload to FileNet.

import java.io.InputStream;
import java.util.Date;

import javax.xml.datatype.XMLGregorianCalendar;

import org.mule.api.MuleEventContext;
import org.mule.api.lifecycle.Callable;
import org.mule.util.DateUtils;
import org.mule.util.IOUtils;

import com.filenet.api.collection.ContentElementList;
import com.filenet.api.constants.AutoClassify;
import com.filenet.api.constants.AutoUniqueName;
import com.filenet.api.constants.CheckinType;
import com.filenet.api.constants.DefineSecurityParentage;
import com.filenet.api.constants.RefreshMode;
import com.filenet.api.core.Containable;
import com.filenet.api.core.ContentTransfer;
import com.filenet.api.core.CustomObject;
import com.filenet.api.core.Document;
import com.filenet.api.core.Factory;
import com.filenet.api.core.Folder;
import com.filenet.api.core.ObjectStore;
import com.filenet.api.core.ReferentialContainmentRelationship;
import com.test.poc.MCEConnection;

public class UploadDoc extends AbstractFilenet implements
Callable {

    private static final String DOC_CLASS = "Document";

    @Override
    public Object onCall(MuleEventContext eventContext) throws Exception {

        String content = (String) eventContext.getMessage().getPayload();

        /*---------------------------------------------------------*/


        MCEConnection ceConnection = getMCEConnection();
        ObjectStore os = ceConnection.fetchOS(objectStore);
        Document doc = Factory.Document.createInstance(os, DOC_CLASS);
        doc.set_MimeType("text/plain");
        doc = createDocument(content, doc);


        /*-- Setting Properties to the Document --*/
        doc.getProperties().putValue("DocType", "Adress Chg");
        doc.getProperties().putValue("Source", "Source");
        doc.getProperties().putValue("ScanDate","2015-05-05 12:20:12");

        /*---------------------------------------*/

        doc.save(RefreshMode.REFRESH);

        ReferentialContainmentRelationship rcr = fileObject(os, doc,
        filenetDocPath);

        rcr.save(RefreshMode.REFRESH);

        checkinDocMajor(doc);

        return "";
    }

    public static Document createDocument(String content, Document doc) {

        ContentTransfer ctNew = Factory.ContentTransfer.createInstance();
        InputStream is = IOUtils.toInputStream(htmlContent);
        ctNew.setCaptureSource(is);
        // ctNew.set_RetrievalName(f.getName());

        ContentElementList cel = Factory.ContentElement.createList();
        cel.add(ctNew);

        if (cel != null) {
            doc.set_ContentElements(cel);
        }

        return doc;
    }

    public static ReferentialContainmentRelationship fileObject(ObjectStore os,
        Containable o, String folderPath) {

        Folder fo = Factory.Folder.fetchInstance(os, folderPath, null);
        ReferentialContainmentRelationship rcr;
        if (o instanceof Document)
            rcr = fo.file((Document) o, AutoUniqueName.AUTO_UNIQUE,
            ((Document) o).get_Name(),
            DefineSecurityParentage.DO_NOT_DEFINE_SECURITY_PARENTAGE);
        else
            rcr = fo.file((CustomObject) o, AutoUniqueName.AUTO_UNIQUE,
            ((CustomObject) o).get_Name(),
            DefineSecurityParentage.DO_NOT_DEFINE_SECURITY_PARENTAGE);
        return rcr;
    }

    public static void checkinDocMajor(Document doc) {
        doc.checkin(AutoClassify.AUTO_CLASSIFY, CheckinType.MAJOR_VERSION);
        doc.save(RefreshMode.REFRESH);
        doc.refresh();
    }

    public static void checkinDocMinor(Document doc)
    {
        doc.checkin(AutoClassify.AUTO_CLASSIFY, CheckinType.MINOR_VERSION);
        doc.save(RefreshMode.REFRESH);
        doc.refresh();
    }
}

Step 7

Now drag and drop and one java component to call the UploadDocument Java class using spring bean.

<spring:bean id="uploadDoc" name="uploadDoc"
class="com.test.poc.UploadDoc" parent="abstractFilenet">
</spring:bean>

The flow looks like:

Image title

XML Snippet:

<flow name="filenetFlow">
        <file:inbound-endpoint path="src/main/resources" responseTimeout="10000" doc:name="Source"/>
        <object-to-string-transformer doc:name="Object to String"/>
        <component doc:name="Upload Doc">
           <spring-object bean="uploadDoc"/>
        </component>
 </flow>

 If the application is using mavenised, then you can directly add the dependency into the pom.xml instead of adding it later.

I hope this will be helpful!

Related Refcard:

The Integration Zone is brought to you in partnership with CA Technologies.  Use CA Live API Creator to quickly create complete application backends, with secure APIs and robust application logic, in an easy to use interface.

Topics:
mule 3.7 ,filenet ,anypoint studio ,java

Opinions expressed by DZone contributors are their own.

The best of DZone straight to your inbox.

SEE AN EXAMPLE
Please provide a valid email address.

Thanks for subscribing!

Awesome! Check your inbox to verify your email so you can start receiving the latest in tech news and resources.
Subscribe

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}