(private) sorry...!! contact@ecmnotes.com

Creating DFS Service Using Documentum Composer

Introduction To DFS Project

When you create a Documentum Project in Composer, it has DFS Service enabled build path which makes it DFS project as well. If you right click one of your Documentum projects and bring up its properties, then select the Java Build Path, and under the Libraries you will see DFS Service Library.

And if you select Properties>Builders, you should see DFS builder.

When an Documentum Project is created it also adds all the necessary DFS resources to allow you to develop Documentum services. It will deploy a copy of the DFS SDK to your core project (incidentally this is why creating the first project in a workspace takes a little longer than you might expect) and add the DFS Services Library to your project’s java build path and add a DFS Builder for building your services.

Building a Service

As you can see your project is all set up for service development. Now you need to develop a service. As you would probably all be aware there are a couple of flavors of DFS service; one based on a POJO and another based on a BOF SBO (service-based object). They are, in fact, very similar and are just annotated java classes. You can get more information about DFS and its annotations from the DFS developer’s guide. In this DFS project, we’ll use the POJO variant. And for convenience we’re going to use one of the samples provided in the DFS SDK.

Steps to create Custom DFS Service.

Create a Documentum Project

  • Create a java class “HelloWorldService.java” into /DFSProj/Web Services/src folder of the project.
  • Define @DfsPojoService(targetNamespace = “http://example.service.com”, requiresAuthentication = true)
  • Create required methods into HelloWorldService.java
  • Example:
package com.service.example;
import com.emc.documentum.fs.datamodel.core.DataObject;
import com.emc.documentum.fs.datamodel.core.DataPackage;
import com.emc.documentum.fs.datamodel.core.ObjectIdentity;
import com.emc.documentum.fs.datamodel.core.ObjectPath;
import com.emc.documentum.fs.datamodel.core.OperationOptions;
import com.emc.documentum.fs.datamodel.core.ReferenceRelationship;
import com.emc.documentum.fs.datamodel.core.Relationship;
import com.emc.documentum.fs.datamodel.core.content.ContentTransferMode;
import com.emc.documentum.fs.datamodel.core.content.FileContent;
import com.emc.documentum.fs.datamodel.core.context.RepositoryIdentity;
import com.emc.documentum.fs.datamodel.core.profiles.ContentTransferProfile;
import com.emc.documentum.fs.rt.ServiceException;
import com.emc.documentum.fs.rt.ServiceInvocationException;
import com.emc.documentum.fs.rt.annotations.DfsPojoService;
import com.emc.documentum.fs.rt.context.ContextFactory;
import com.emc.documentum.fs.rt.context.IServiceContext;
import com.emc.documentum.fs.rt.context.ServiceFactory;
import com.emc.documentum.fs.services.core.CoreServiceException;
import com.emc.documentum.fs.services.core.client.IObjectService;
import com.emc.documentum.fs.datamodel.core.properties.PropertySet;
@DfsPojoService(targetNamespace = "http://example.service.com", requiresAuthentication = true)
public class HelloWorldService {
    protected IServiceContext serviceContext;
    public String sayHello(String name) {
        return "Hello " + name;
    }
    public boolean importFile(String source, String fileName, String target) {
        boolean imported = false;
        String fileFormat = fileName.split(".")[fileName.split(".").length - 1];
        try {
            updateServiceContext();
            ServiceFactory serviceFactory = ServiceFactory.getInstance();
            IObjectService objectService = serviceFactory.getLocalService(IObjectService.class, serviceContext);
            ObjectIdentity objIdentity = new ObjectIdentity(Constants.REPOSITORY_NAME);
            DataObject dataObject = new DataObject(objIdentity, Constants.DOCCLASS_NAME);
            DataPackage dataPackage = new DataPackage(dataObject);
            OperationOptions operationOptions = new OperationOptions();
            PropertySet properties = dataObject.getProperties();
            DataPackage importDataObject = new DataPackage();
            properties.set("object_name", fileName);
            properties.set("a_content_type", fileFormat);
            dataObject.getContents().add(new FileContent(source, fileFormat));
            ObjectPath objectPath = new ObjectPath(target);
            ObjectIdentity sampleFolderIdentity = new ObjectIdentity(objectPath, Constants.REPOSITORY_NAME);
            /** relationship object defines a relationship between the repository object represented by
            the DataObject and another repository object
            the Relationship is used to specify object location **/
            ReferenceRelationship FolderRelationship = new ReferenceRelationship();
            FolderRelationship.setName(Relationship.RELATIONSHIP_FOLDER);
            FolderRelationship.setTarget(sampleFolderIdentity);
            FolderRelationship.setTargetRole(Relationship.ROLE_PARENT);
            dataObject.getRelationships().add(FolderRelationship);
            importDataObject = objectService.create(dataPackage, operationOptions);
            imported = true;
        } catch (ServiceInvocationException ex) {
            ex.printStackTrace();
            return false;
        } catch (CoreServiceException ex) {
            ex.printStackTrace();
            return false;
        } catch (ServiceException ex) {
            ex.printStackTrace();
            return false;
        }
        return imported;
    }
    public void updateServiceContext() {
        //DFS client uses ContextFactory to create an instance of IServiceContext.
        ContextFactory contextFactory = ContextFactory.getInstance();
        serviceContext = contextFactory.newContext();
        // Repository Identity Object is created
        RepositoryIdentity repoId = new RepositoryIdentity();
        //Reporsitory Identity Object contain login credentials
        repoId.setRepositoryName(Constants.DOCBASE_NAME);
        repoId.setUserName(Constants.DOCBASE_USER);
        repoId.setPassword(Constants.DOCBASE_PASSWORD);
        //RepositoryIdentity Object is assigned to Service context
        serviceContext.addIdentity(repoId);
        /** Note:DFS clients uses one of three content transfer mode - Base64,MTOM,UCF
        UCF:- Used for content transfer between client and server **/
        ContentTransferProfile contentTransferProfile = new ContentTransferProfile();
        contentTransferProfile.setTransferMode(ContentTransferMode.UCF);
        serviceContext.setProfile(contentTransferProfile);
    }
}

package com.service.example;
public class Constants {
    public static final String DOCBASE_NAME = "";
    public static final String DOCBASE_USER = "";
    public static final String DOCBASE_PASSWORD = "";
    public static final String REPOSITORY_NAME = "";
    public static final String DOCCLASS_NAME = "";
}

Once you create java files into the Web Services folder, and assuming that you have “automatic build” turned on from project menu in composer, you should see the DFS Builder leap into life and attempt to build the service. In your Console view you’ll get a build report

And if you open the standard Navigator view (WindowàOpen ViewàNavigator) and navigate to the Web Services/bin/gen-src folder you should also see a set of generated source. This is actually a jax-ws web service that has been generated from your POJO service. And under the classes folder you should see a set of classes and wsdl.

These classes are an aggregate compilation of your POJO (and associated classes) and the generated jax-ws web service. The wsdl is obviously just standard wsdl also generated from your POJO.

Testing the service

So now we’ve reached the point where we have a service that needs testing. There are two approaches to this. The first is to create a parallel test project with Junit tests that exercise your service. To facilitate this, your test project would be configured with the local client library, as described before, so that it can make local invocations to your service. This project should of course be placed under the same version control as your services project.

The second approach is to export your services as an ear, deploy it to an application server and exercise your service again via another project capable of making remote service invocations. Before you do this though you must remember to set the archive’s context root and module name as both of these affect the eventual URL of your service. This is a one time deal though so just right-click on the project and select PropertiesàDocumentum ProjectàDFS Module and set Context Root and DFS Module Name.

Just so you are aware. Typically all EMC DFS services share a context root of “services” and a module name that describes their general function. Core for core services, bpm for business process, etc. These will then be available via URLs such as http://localhost:9080/services/core/ObjectService and http://localhost:9080/services/bpm/WorkflowService.

Once these settings are made you can export the service. Right-click on the project and select Export>>Documentum>>Export Service Archive to generate ear and client reference library.

The archive name and context root should be defaulted for you from your DFS Module settings page. Choose an output folder. Uncheck the Generate Publish Manifest. This is only required is you want to publish your services to a UDDI registry using the DFS tools. And click finish.

This will produce your ear file. Once you are in possession of the ear you can deploy it onto your app server or Documentum java method server using the appropriate app manager console or by dropping it into the hot deploy folder. Whichever is feasible for you.

Once you have it deployed you can perform a quick sanity check by requesting the service’s WSDL document by requesting something like

http://localhost:9080/services/helloworld/HelloWorldService?wsdl

Assuming you get back the WSDL document (that matches the one that was generated by the builder earlier) then you are good to go.

Next you will need to create yourself another test project or client project. But this time configure it with one of the two available Remote Client library options, depending on your content transfer requirements. Again, creating Junit test cases I find is the quickest and easiest. These can be rolled up into test suites and all can be invoked easily enough through the Composer (eclipse) UI. And once again, if you can standardize this process across your development team then you can check this test project into source control right along side your services project.

One thought on “Creating DFS Service Using Documentum Composer”

  1. Parag says:

    If you face any issue regarding blank page or error in page while accessing url,

    http://localhost:9080/services/helloworld/HelloWorldService?wsdl

    You can check server log and there will be some entries for HelloWorldService

Leave a Reply