Using value transformers to convert data between a source system and Rational Team Concert

Summary

Whenever data is migrated from one system to another, it needs to be converted to the format which the target system accepts. The Rational Team Concert (RTC) item connector framework provides a set of transformers which can be used to convert data from source system to RTC defined format and vice versa. In some cases the available set of transformers might not be able to meet the specific need of the source system formats. This article provides an insight into how to create custom transformers while importing any data to the RTC system, and vice versa.

Overview

Rational Team Concert (RTC) is a tool used for collaborative project planning and change management. Project planning and change management pieces are controlled using various attributes. Each attribute in RTC accepts values in a specific format. While accessing these attributes through RTC UI, user is prompted to enter values as expected by RTC.

Similarly other project planning and change management systems have their own set of attributes which may have different attribute formats. The challenge arises when data from this system needs to be imported in RTC or vice versa.

RTC provides an Item connector framework that supports this synchronization between objects. For item connector development the major components to be developed are item connector client, external repository manager and value transformers. The most important part of designing item connector is to create mapping between attributes i.e. which attribute of connected RTC object would be synchronized to which attribute of external objects. To define this and other such mapping item connector framework provides synchronization rule. Find out more about how to create a synchronization rule.

These synchronization rules act as synchronization guideline while exchanging data between the two systems. Synchronization rule files are created for similar work items and it contains their detailed attribute mappings. For example sync rule file would be created for RTC ‘defect’ and object of type ‘defect’ in the other system. After the creation of the sync rule we need to define attribute mappings in it. An example of the attribute mapping contained within the sync rule file is, defect ‘summary’ of RTC would map to the other system’s defect ‘abstract’. The intent of sync rule is to map the attributes having similar meaning but with same/different names and formats in the different systems. These mappings help the system understand which value to set in the target system for a particular value in the source system. This helps a lot but becomes a challenge when attribute formats are different in both systems.

For situations where formats are different in RTC and the other source system, RTC provides the capability to add transformers to sync rules. These transformers take data input in source defined format and convert it in RTC format and vice versa.

Lets take an example of value transformer to understand better. ‘Comment’ attribute of RTC work item type ‘Defect’ maps to ‘remarks’ field of an external object type ‘defect’. Comment’ in RTC is added in a special format by adding user name and timestamp to it whereas ‘Remarks’ in the external system just has plain text. Now if ‘remarks’ is fetched from external source and sent to RTC, it would throw an error of invalid format. This mapping requires some transformation before this data is passed on to RTC and similarly the reverse transformation to be applied when the data from RTC is been passed on to external system.

For each attribute that requires specific handling value transformers are written. User can select “No Transformation” option for attributes which do not require any special handling.

Value transformers are jazz server extensions which are deployed on server side just like external repository manager and are used in synchronization rules. Item connector framework supplies many predefined value transformers like category field mapping, timestamp field mapping, reference fields mapping, enumerated values mapping, etc. Apart from the value transformers provided we at point in times need customized transformers to meet our need. In this tutorial we will see how to write transformer for our customized need.

Writing Value Transformers

As a pre-requisite for item connector development user should go through the instructions provided on our wiki page and create an external repository manager.

Creating a value transformer is similar to creating an external repository manager, since it is also a Jazz extension service.

Value transformer should implement IValueTransformer interface. Extension point for declaring the value transformer is com.ibm.team.interop.service.valueTransformer .Note that one should not add another extension of the com.ibm.team.repository.common.components extension point. User need to ensure that the component id created for external repository manager is used for all value transformers. External repository manager and any value transformers would be considered all part of one component.

The two methods to be implemented from IValueTransformer interface are transformJazzToExternal and transformExternalToJazz. As the name suggests these are called when there is data flow from jazz to external repository and vice versa.

Illustrated below is an example of date transformer where ‘creationDate’ of RTC is mapped to ‘addDate’ field of another external repository. “addDate” in the external repository is in format yyyy/MM/dd HH:mm:ss and RTC expects it to be yyyy-mm-dd hh:mm:ss.

The method transformExternalToJazz starts with a check on property name which is one of the parameter. This method should be called only for attribute, it is intended for. If user selects this transformer for any other attribute in synchronization rule, this check will prevent it from being called. Next is to get the value of attribute form the map external state. This map contains all the properties of external object which are to be synchronized to RTC. After attributes are fetched from both systems, perform transformations as required. In the code snippet the external object ‘addDate’ is parsed using simpleDateFormat and which is then is converted to long and parsed to create new object of timestamp class.

public Object transformExternalToJazz(final String externalPropertyName,    final Map<String, ?> externalState, final String jazzPropertyName,    final Map<String, ?> currentJazzState,    final Map<String, ?> newJazzState,    final IExternalProxy workingProxy, final ISyncRule syncRule,    final IProcessArea processArea) throws TeamRepositoryException {    if (!externalPropertyName.contains("date")    && !externalPropertyName.contains("Date")) {    return null;    }    final String externalPropValue = (String) externalState    .get(externalPropertyName);    if (externalPropValue == null || externalPropValue.length() == 0) {    return null;    }    final SimpleDateFormat cmvcDateFormat = new SimpleDateFormat(    CmvcDateFormat);    Date currentDate = null;    try {    currentDate = cmvcDateFormat.parse(externalPropValue);    } catch (final java.text.ParseException e) {    e.printStackTrace();    }    final long time = currentDate.getTime();    return new Timestamp(time);    }

Similarly when data flows from RTC to external object the method tranformJazToExternal is called. The procedure is almost same as described in the above example. Check for attribute name and get its value from jazz object and then convert the timestamp received from RTC into object of simple date format.

public Object transformJazzToExternal(final String jazzPropertyName,    final Map<String, ?> jazzState, final String externalPropertyname,    final Map<String, ?> currentExternalState,    final Map<String, ?> newExternalState,    final IExternalProxy workingProxy, final ISyncRule syncRule,    final IProcessArea processArea) throws TeamRepositoryException {    if (!jazzPropertyName.contains("date")    && !jazzPropertyName.contains("Date")) {    return null;    }    final String jazzPropValue = (String) jazzState.get(jazzPropertyName);    if (jazzPropValue == null || jazzPropValue.length() == 0) {    return null;    }    final SimpleDateFormat format = new SimpleDateFormat(CmvcDateFormat);    final String date = format.format(Timestamp.valueOf(jazzPropValue));    return date;    }

Deploying Transformers

Transformer is a jazz extension service and can be the part of same component id as external repository manager. Typically class created for value transformer is part of the same package of external repository manager. In this case just add the new extension to plugin.xml of external repository manager .The attached snippet gives an overview of plugin.xml after creating external repository manager and value transformer.

<?xml version="1.0" encoding="UTF-8"?>    <?eclipse version="3.2"?>    <plugin>    <extension    point="com.ibm.team.interop.service.externalManager">    <externalManager    id="External Repository Manager"    name="External Repository Manager">    <extensionService    componentId="com.ibm.sdwb.connector.cmvc.workitem"    implementationClass="com.ibm.sdwb.connector.cmvc.workitem.ExternalRepositoryManager">    <prerequisites>    <requiredService    interface="com.ibm.team.interop.common.service.IInteropService">    </requiredService>    <requiredService    interface="com.ibm.team.repository.service.IRepositoryItemService">    </requiredService>    <requiredService    interface="com.ibm.team.workitem.service.IWorkItemServer">    </requiredService>    </prerequisites>    </extensionService>    </externalManager>    </extension>    <extension    point="com.ibm.team.interop.service.valueTransformer">    <valueTransformer    id="WorkItemDateTimestampTransformer"    name="WorkItemDateTimestampTransformer">    <extensionService    componentId="com.ibm.sdwb.connector.cmvc.workitem"    implementationClass="com.ibm.sdwb.connector.cmvc.workitem.WorkItemDateTimestampTransformer">    </extensionService>    </valueTransformer>    </extension>    <extension    point="com.ibm.team.repository.common.components">    <component    id="com.ibm.sdwb.connector.cmvc.workitem"    name="My Repository Item connector">    </component>    </extension>    </plugin>

After creating plugin.xml build site.xml for the new created external repository manager. Once all the settings for deploying external repository manager is complete, do a request reset of the server and then restart the server.

Using the URI, https://localhost:9443/ccm/admin/cmd/requestReset, you can do a server request reset. Localhost and port number would need to be replaced with the server URI.

After server restart value transformers should be visible in the synchronization rule.

For More Information


About the authors

Megha Mittal is also part of Rational Corp Tools team at IBM Software Labs, in India and working on RTC integrations with IBM legacy systems. Megha holds a master’s degree in computer applications and has seven years of experience in application development, primarily in Java technology. She can be contacted at mmittal1@in.ibm.com

Siddharth Kumar Saraya is working as Technical Lead for Rational at IBM Software Labs. He has completed Dual Masters degree, one in Computer Application and second in Business Administration with majors as Risk and Insurance Management. A summary of the experiences gained over the number of years are manual, automation testing, involved in delivery of projects and managing project teams from project initiation till deployment. He can be contacted at Siddharth.Kumar.Saraya@in.ibm.com

Dashboards and work items are no longer publicly available, so some links may be invalid. We now provide similar information through other means. Learn more here.
Feedback
Was this information helpful? Yes No 0 people rated this as helpful.