Designing the GlobalSight Adapters

From Globalsight
Jump to navigation Jump to search
Developers
Go to: Getting Started Guide
Footer-logo.gif
System requirements

Installing GlobalSight
3rd party comps: Windows | Ubuntu
GlobalSight: Windows | Ubuntu
Desktop Icon

Setting up GlobalSight
Running GlobalSight Behind an Apache Reverse Proxy

Developing GlobalSight
GlobalSight Architecture
Getting the Code
Building and Deploying GlobalSight
GlobalSight Developer’s Guide
Setting up the Development Environment
Debugging GlobalSight
Designing the GlobalSight Adapters
GlobalSight Web Services API
Using the GlobalSight Web Services API Test Tool
Using the GlobalSight CVS Connector
Connecting to a CVS with the GlobalSight Desktop Icon

Upgrading GlobalSight
Comparing GlobalSight with WorldServer

GlobalSight adapters are developed to help the system to read and write customer content from various formats to the more common formats XML or HTML. GlobalSight can then extract easily when importing or exporting a job.

GlobalSight itself does not read content directly from binary documents like Word and InDesign. This is because Java does not use the API of the application well to handle the proprietary document format.

Use cases

1: An administrator or PM imports a document

When an admin or PM user imports a document in a format that GlobalSight does not understand, the document is placed in the directory that the converter is watching. The converter then converts the document to XML or HTML using the APIs of the corresponding application.

GlobalSight gets the converted XML or HTML file, creates the job and then processes the job as normal.

2: An administrator or PM exports a document

When an admin or PM user exports a job or workflow that was created by the converter, GlobalSight puts the XML or HTML into the directory that the converter is watching. The converter then converts the XML or HTML to the original format using the APIs of the corresponding application.

GlobalSight gets the converted document and exports the job or workflow as normal.

Design overview

  • The converter watches a directory and converts to or from XML/HTML files according to the APIs of each application
  • GlobalSight sends a JMS message to the adapter mdb according to its event type
  • The adapter mdb invokes the adapter
  • The adapter puts the imported or exported file into the directory that the converter is watching
  • The adapter communicates with the converter to convert from the original format file to XML/HTML or from XML/HTML back to the original format file
  • The converter tells GlobalSight that the conversion is complete once the converted file is generated
  • GlobalSight takes the converted file or returns an error message to the system for subsequent import or export

UI interaction

Add a new source file format to the system.

A list of existing Source File Formats in the system

Object model

This section addresses the converter itself on C# or C++ side, and how it works with the GlobalSight adapter at the implementation level.

Converter side

The converter must do the following:

  1. Watch a directory. The files in the directory or sub-directory are watched at all times when it is running
  2. Communicate with the GlobalSight adapter before the conversion
    • Define the method of communication as needed, as long as the adapter puts the imported/exported file(s) into the watched directory
    • The adapter first tells the converter what process it is. The converter then decides the type of conversion needed - for an import, the conversion is from original file format to XML/HTML but for an export the conversion is from XML/HTML to the original file format
  3. Start the conversion
    • Once the conversion type is decided, the converter searches the for file delivered by the adapter in the watched directory and starts the conversion
    • When converting from the original file format to XML/HTML for import, the converter extracts the content of the original format file to XML or HTML using the APIs for extraction. For example, in a Word file, the Word converter extracts the content from the Word file into a HTML file using the Word APIs. This extraction process can be done easily done using the API in C#
    • When converting from XML/HTML back to the original for export, the converter puts the translated XML or HTML back into the original format using the APIs for this. For the Word file, the Word application also has useful APIs to do the conversion in C#
  4. Communicates with the adapter after the conversion
    • The converter tells the adapter whether the conversion was completed successfully or not
    • The adapter waits for the conversion to finish and then reads whether it was successful or not from the converter
    • The adapter gets the converted file back or returns an error message to the system for the remaining processes

GlobalSight side

The GlobalSight adapter works with the converter for these wo major processes : “Import a job” and “Export a job”.

Import a job

In GlobalSight, for a file that needs a converter to process, after clicking the “Create Job” button, the basic workflow is as follows:

  1. A JMS message comes to an MDB “FileSystemSourceAdapterMDB” which extends a super MDB “BaseAdapterMDB” of the adapters. In this stage, GlobalSight makes an event flow xml which records some information from the imported file.
    • After that, the event flow xml(String) and the event type(CxeMessageType) for the new Adapter will be set to CxeMessage.
    • Then CxeMessage will be wrapped to an AdapterResult array and return it to BaseAdapterMDB for subsequent processing.
  2. BaseAdapterMDB looks for the next MDB topic (the new adapter) according to the event type(CxeMessageType) and sends the JMS message. After the new adapter receives the JMS message, it goes to BaseAdapterMDB first since the new adapter MDB (NewlyDevelopedSourceAdapterMDB) extends BaseAdapterMDB.
    • Then BaseAdapterMDB searches the new adapter (NewlyDevelopedAdapter) and invokes the business method handleMessage() of it to start the work with converter.
  3. After the conversion is finished, the event type (CxeMessageType) should be set to XML_IMPORTED_EVENT (if the converted file is HTML, set the type to HTML_LOCALIZED_EVENT) and set the new type to CxeMessage and then wrap CxeMessage to AdapterResult array (AdapterResult[]) and return the array to BaseAdapterMDB for subsequent processing.

Following sequence diagram shows the process of importing a job before JMS leaves the new adapter.

Importing a job before JMS leaves the new adapter

Export a job

In GlobalSight, for a file that needs a converter to process, after clicking the “Export” button, the basic workflow is as follows:

  1. A JMS message comes to a MDB “CapSourceAdapterMDB” which extends a super MDB “BaseAdapterMDB” of the adapters. In this stage, GlobalSight parses the event flow xml which was created in the import stage.
    • After that, the event flow xml(String) and the event type(CxeMessageType) for the new Adapter will be set to CxeMessage.
    • Then CxeMessage will be wrapped to an AdapterResult array and return it to BaseAdapterMDB for left processes.
  2. BaseAdapterMDB looks for the next MDB topic (the new adapter) according to the event type(CxeMessageType) and sends the JMS message. After the new adapter receives the JMS message, it goes to BaseAdapterMDB first since the new adapter MDB (NewlyDevelopedTargetAdapterMDB) extends BaseAdapterMDB.
    • Then BaseAdapterMDB searches the new adapter (NewlyDevelopedAdapter) and invokes the business method handleMessage() of it to start the work with converter.
  3. After the conversion is finished, the event type(CxeMessageType) should be set to XML_IMPORTED_EVENT (if the converted file is HTML, set the type to HTML_LOCALIZED_EVENT) and set the new type to CxeMessage and then wrap CxeMessage to AdapterResult array(AdapterResult[]) and return the array to BaseAdapterMDB for left processes.

Following sequence diagram shows the process of exporting a job before JMS leaves the new adapter.

Exporting a job before JMS leaves the new adapter.

Deployment considerations

Database script updates

To insert a new source file format to database, the following statements should be added to insert_known_formats_mysql.sql.

--adds a new source file format for a new adapter
INSERT INTO KNOWN_FORMAT_TYPE VALUES (
ID, 'NAME',' DESCRIPTION’,' FORMAT_TYPE',
   'PRE_EXTRACT_EVENT',
   'PRE_MERGE_EVENT'
);
  • ID: max(id) + 1
  • NAME: name of the new source file format, displaying in file profile – Source File Format
  • DESCRIPTION: description of the new source file format
  • FORMAT_TYPE: format type of the new source file format
  • PRE_EXTRACT_EVENT: the event type for the format document when importing. For example, the event type for the new adapter is * * NEW_IMPORTED_EVENT (used in above code)
  • PRE_MERGE_EVENT: the event type for format document when exporting. For example, if the converter is developed to convert the document to XML, the type should be XML_LOCALIZED_EVENT; if to HTML, the type should be HTML_LOCALIZED_EVENT.
  • Execute the newly added statements to update the database.

JMS configuration

Because the import and export operations are processed by JMS, the elated configuration files need to be modified.

Jboss.xml

#Location in code: main6\diplomat\dev\src\java\com\globalsight\cxe\adaptermdb\jboss.xml

#Location in server: GlobalSight\jboss\jboss_server\server\default\deploy\globalsight.ear\cxe-ejb.jar\META-INF\jboss.xml

<message-driven>
      <ejb-name>NewlyDevelopedSourceAdapterMDB</ejb-name>
           <destination-jndi-
name>topic/com.globalsight.cxe.jms.ForNewlyDevelopedSourceAdapter</destination-jndi-name>  
           <jndi-name>com.globalsight.cxe.adaptermdb.new.NewlyDevelopedSourceAdapterMDB</jndi-name>
      <mdb-subscription-id>NewlyDevelopedSourceAdapterMDB</mdb-subscription-id>
</message-driven>
<message-driven>
      <ejb-name>NewlyDevelopedTargetAdapterMDB</ejb-name>
           <destination-jndi-
name>topic/com.globalsight.cxe.jms.ForNewlyDevelopedTargetAdapter</destination-jndi-name>
      <jndi-name>com.globalsight.cxe.adaptermdb.new.NewlyDevelopedSourceAdapterMDB</jndi-name>
      <mdb-subscription-id>NewlyDevelopedTargetAdapterMDB</mdb-subscription-id>
</message-driven>

GlobalSight-JMS-service.xml

#Location in code: main6\tools\j2eeVendor\jboss\util\GlobalSight-JMS-service.xml

#Location in server: GlobalSight\jboss\GlobalSight-JMS-service.xml; GlobalSight\jboss\jboss_server\server\default\deploy\GlobalSight-JMS-service.xml

<mbean code="org.jboss.mq.server.jmx.Topic"
name="jboss.mq.destination:service=Topic,name=com.globalsight.cxe.jms.ForNewlyDevelopedSourceAdapter">
>
      <depends optional-attribute-name="DestinationManager">jboss.mq:service=DestinationManager</depends>
</mbean>	
<mbean code="org.jboss.mq.server.jmx.Topic"
name="jboss.mq.destination:service=Topic,name=com.globalsight.cxe.jms.ForNewlyDevelopedTargetAdapter">
>
      <depends optional-attribute-name="DestinationManager">jboss.mq:service=DestinationManager</depends>
</mbean>

Ejb-jar.xml

#Location in code: main6\diplomat\dev\src\java\com\globalsight\cxe\adaptermdb\ejb-jar.xml

#Location in server: GlobalSight\jboss\jboss_server\server\default\deploy\globalsight.ear\cxe-ejb.jar\META-INF\ejb-jar.xml

<message-driven>
      <ejb-name>NewlyDevelopedSourceAdapterMDB</ejb-name>
      <ejb-class>com.globalsight.cxe.adaptermdb.new.NewlyDevelopedSourceAdapterMDB</ejb-class>
      <transaction-type>Container</transaction-type>
      <message-driven-destination>
        <destination-type>javax.jms.Topic</destination-type>
              <subscription-durability>Durable</subscription-durability>
      </message-driven-destination>
</message-driven>    
<message-driven>
      <ejb-name>NewlyDevelopedTargetAdapterMDB</ejb-name>
      <ejb-class>com.globalsight.cxe.adaptermdb.new.NewlyDevelopedTargetAdapterMDB</ejb-class>
      <transaction-type>Container</transaction-type>
      <message-driven-destination>
        <destination-type>javax.jms.Topic</destination-type>
              <subscription-durability>Durable</subscription-durability>
      </message-driven-destination>
</message-driven>

Class locations

Above configuration is assuming NewlyDevelopedSourceAdapterMDB and NewlyDevelopedTargetAdapterMDB are put at following path:

  1. On the server: GlobalSight\jboss\jboss_server\server\default\deploy\globalsight.ear\lib\classes\com\globalsight\cxe\adaptermdb\new
  2. In the code: main6\diplomat\dev\src\java\com\globalsight\cxe\adaptermdb\new

The NewlyDevelopedAdapter is supposed to be put at:

  1. In server: GlobalSight\jboss\jboss_server\server\default\deploy\globalsight.ear\lib\classes\com\globalsight\cxe\adapter\new
  2. In code: main6\diplomat\dev\src\java\com\globalsight\cxe\adapter\new

Dependency API

Existing classes that you do not need to modify

BaseAdapterMDB

BaseAdapterMDB is a base class for all adapter message-driven beans to extend. The related adapter class is loaded when BaseAdapterMDB is created. In the ejbCreate() method, this.setAdapter(this.loadAdapter()) is called to specify the adapter used for the business logic.

In onMessage(Message msg), it invokes the handleMessage(msg) method of the adapter to make the business logic process.

After a process is done by an adapter, it gets the returned result AdapterResult[] to continue the next process of sending JMS message and receiving again. In the publishToJMS(msg) method, it first gets the jms topic for the next MDB by

CxeMessageType eventName = msg.getMessageType(); //was set and returned in the first adapter.

String jmsTopicName = EventTopicMap.getJmsTopicName(eventName); //Need to add the new jms topic for the new adapter in EventTopicMap.java.

Then a new JMS message will be sent out to this JMS topic for the next process in the new adapter.

BaseAdapter

The BaseAdapter is a class that all adapters extend. It provides common methods for the adapters.

AdapterResult[] is returned when an adapter has successfully finished its process with following method.

AdapterResult[] makeSingleAdapterResult(CxeMessage p_cxeMessage)

You can also wrap exceptions for import in method

AdapterResult[] makeImportError(CxeMessage p_cxeMessage,GeneralException p_exception)

And wrap exceptions for export in method

AdapterResult[] makeExportStatus(CxeMessage p_cxeMessage,GeneralException p_exception)

Existing classes that you do need to modify

EventTopicMap

This class location in source code is:

main6\diplomat\dev\src\java\com\globalsight\cxe\adaptermdb\EventTopicMap.java

New constants need to be added for the new adapter as following in construct method EventTopicMap()

fillMap(CxeMessageType.NEW_IMPORTED_EVENT, FOR_NEW_SOURCE_ADAPTER); //for import process

fillMap(CxeMessageType.NEW_LOCALIZED_EVENT, FOR_NEW_TARGET_ADAPTER); //for export process

The constants added in EventTopicMap are related with the destination-jndi-name configured in jboss.xml and GlobalSight-JMS-service.xml.

public static final String FOR_NEW_SOURCE_ADAPTER = " ForNewlyDevelopedSourceAdapter ";

public static final String FOR_NEW_TARGET_ADAPTER = " ForNewlyDevelopedTargetAdapter ";

CxeMessageType

This class location in source code is:

main6\diplomat\dev\src\java\com\globalsight\cxe\message\CxeMessageType.java

Based on the change in EventTopicMap, new constants need to be added in CxeMessageType

public static final int NEW_IMPORTED_EVENT = newid;

public static final int NEW_LOCALIZED_EVENT = newid+1;

Newly added classes

NewlyDevelopedSourceAdapterMDB

The source adapter mdb should extends the BaseAdapterMDB class and implement the two methods declared as abstract in BaseAdapterMDB.

abstract protected String getAdapterName();

abstract protected BaseAdapter loadAdapter() throws Exception;

The NewlyDevelopedAdapter should be returned in the implementation of method loadAdapter().

NewlyDevelopedTargetAdapterMDB

Because target adapter mdb invokes the same adapter as the source adapter mdb, the implementation could be the same as NewlyDevelopedSourceAdapterMDB.

NewlyDevelopedAdapter

The NewlyDevelopedAdapter handles conversions of new format file to xml/html using the new converter. For the implementation of this class, please get reference to the sequence diagram for import and export processes shown above.

Sample code

NewlyDevelopedSourceAdapterMDB

public class NewlyDevelopedSourceAdapterMDB extends BaseAdapterMDB
{
       private static String ADAPTER_NAME = "NewlyDevelopedSourceAdapter";
       protected String getAdapterName()
       {
           return ADAPTER_NAME;
       }
       protected BaseAdapter loadAdapter() throws Exception
       {
           return new NewlyDevelopedAdapter(ADAPTER_NAME);                
       }
}

NewlyDevelopedTargetAdapterMDB

public class NewlyDevelopedTargetAdapterMDB extends BaseAdapterMDB
{
       private static String ADAPTER_NAME = "NewlyDevelopedTargetAdapter";
       protected String getAdapterName()
       {
           return ADAPTER_NAME;
       }
       protected BaseAdapter loadAdapter() throws Exception
       {
           return new NewlyDevelopedAdapter(ADAPTER_NAME);                
       }
}

NewlyDevelopedAdapter

public class NewlyDevelopedAdapter extends BaseAdapter
{
}

AdapterResult[] handleMessage(CxeMessage p_cxeMessage)

Called in BaseAdapterMDB to handle the import and export process with the converter.

public AdapterResult[] handleMessage(CxeMessage p_cxeMessage)
           throws GeneralException
{
       switch (p_cxeMessage.getMessageType().getValue())
       {
           case CxeMessageType.NEW_IMPORTED_EVENT:
               return convertFromNew(p_cxeMessage);
           case CxeMessageType.NEW_LOCALIZED_EVENT:
               return convertToNew(p_cxeMessage);
           default:             
       }
}


convertFromNew(CxeMessage p_cxeMessage)

is for import process with the converter converting the new format document to XML or HTML.

private AdapterResult[] convertFromNew(CxeMessage p_cxeMessage)
           throws GeneralException
{
       try
       {
           writeNewToWatchingDir(); //method1()
           communicateWithConverterForImportConversion(); //method2()
           MessageData[] messageData = readXml/HtmlOutput(); //method3()
           copyToTargetLocaleFolders(); //method4()
           modifyCxeMessage(); //method5()
           return wrapCxeMessages(); //method6()
       }
       catch (Exception e)
       {
           getLogger().error("Problem handling New Conversion. ", e);
           return this.makeImportError(p_cxeMessage, e);
       }
}

convertToNew(CxeMessage p_cxeMessage)

is for export process with the converter converting XML or HTML back to the new format document

private AdapterResult[] convertToNew(CxeMessage p_cxeMessage)
           throws GeneralException
{
       try
       {
           writeXml/HtmlToWatchingDir(); //method1()
           communicateWithConverterForExportConversion(); //method2()
           MessageData[] messageData = readNewOutput(); //method3()
           modifyCxeMessage(); //method4()
           return wrapCxeMessages(); //method5()
       }
       catch (Exception e)
       {
           getLogger().error("Problem handling New Conversion. ", e);
           return this.makeExportStatus(p_cxeMessage, e);
       }
}