Using an Expression to Synchronize Attributes for Work Items of a Specific Type


When I created my first custom attribute in RTC long ago, I quickly realized that work items that I created before the attribute was defined did not have the attribute. This is one of the favorite questions on Jazz.net forums and I believe every project administrator ran into it sooner or later. The RTC Eclipse client allows to Synchronize the attributes, which basically creates the new and missing attributes at all work items that need it. This is described in one of my favorite article series Cool ‘Hidden’ Features in Rational Team Concert in Part 2 in the section ‘Applying Work Item Attribute Changes to Existing Work Items’. If you did not come across the series, Part 3 contains the links to the other parts.

This seems to solve the problem, so why blog about it? The reason is, that there is a result set size limit on queries as described in the post Using Work Item Queries for Automation. This makes it problematic to use the UI if the number of work items grows. This post describes how to create a small standalone tool that uses the Plain Java Client Libraries to query the work items and a WorkItemOperation to do the synchronization.

License and how to get started with the RTC API’S

As always, our lawyers reminded me to state that the code in this post is derived from examples from Jazz.net as well as the RTC SDK. The usage of code from that example source code is governed by this license. Therefore this code is governed by this license, which basically means you can use it for internal usage, but not sell. Please also remember, as stated in the disclaimer, that this code comes with the usual lack of promise or guarantee. Enjoy!

If you just get started with extending Rational Team Concert, or create API based automation, start with the post Learning To Fly: Getting Started with the RTC Java API’s and follow the linked resources.

You should be able to use the following code in this environment and get your own automation or extension working.

To keep it simple this example is, as many others in this blog, based on the Jazz Team Wiki entry on Programmatic Work Item Creation and the Plain Java Client Library Snippets. The example in this blog shows RTC Client API.

Download

The code can be downloaded from here. You can import it as an eclipse project from the archive. Please be aware that the project is set up as a plug-in project that requires the RTC SDK (setup described in this article) as well as refers to a user library for the Plain Java Client Libraries. This setup helps with spying the API. If you don’t have the RTC SDK set up, delete the plug in development related artifacts.

*  Update * there seems to be an issue with the cache refresh in 6.0.x. See https://jazz.net/forum/questions/231559/after-work-item-type-updateattribute-sync-the-new-attributes-are-not-visible-on-work-item-object for a work around.

* Update * found a last minute change caused issues. Need to use the FULL_PROFILE as load profile. Did realize that I loaded the work item twice and fixed that.

* Update * See this forum answer with specific information about how the API works with respect to attributes for type changes.

This post only describes the core part of the code. Essentially the code

  1. Gets the required information from the arguments passed. Required arguments are the repositoryURI a user Id, the password for this user, the projectArea and a workitem Type ID.  An example input would look like https://clm.example.com:9443/ccm” “ralph” “ralph” “JKE Banking (Change Management)” “com.ibm.team.apt.workItemType.story”
  2. Constructs an Expression to get all work items of the type as described in Using Expressions for Automation
  3. Retrieves the unresolved result set for the Expression
  4. Overrides the result set limit as described in Using Work Item Queries for Automation
  5. Creates a WorkItemOperation to synchronize the attributes
  6. Iterates all results and runs the WorkItemOperation passed

The core of the algorithm looks like this code:

IQueryResult expression_results = resultsUnresolvedByExpression(
	teamRepository, projectArea, typeinProjectArea);
expression_results.setLimit(Integer.MAX_VALUE);
SynchronizeWorkItemOperation synchronize = new SynchronizeWorkItemOperation(workItemClient);
processUnresolvedResults(projectArea, expression_results, synchronize, monitor);

The SynchronizeWorkItemOperation operation is an inner class that looks like the code below.

private static class SynchronizeWorkItemOperation extends WorkItemOperation {

	private IWorkItemClient fWorkItemClient = null;

	public SynchronizeWorkItemOperation(IWorkItemClient workItemClient) {
		super("Synchronize Work Items", IWorkItem.FULL_PROFILE);
		fWorkItemClient = workItemClient;
	}

	@Override
	protected void execute(WorkItemWorkingCopy workingCopy, IProgressMonitor monitor) throws TeamRepositoryException {
		IWorkItem workItem = workingCopy.getWorkItem();

		IWorkItemType type = fWorkItemClient.findWorkItemType(
		workItem.getProjectArea(), workItem.getWorkItemType(), monitor);
		if (type != null) {
			fWorkItemClient.updateWorkItemType(workItem, type, type, monitor);
		}
		System.out.println("Synchronized: " + workItem.getId());
	}
}

The operation does not assume a specific work item type and, therefore, would work for any work item query. You could further optimize the performance by passing the work item type to the constructor and find it there once, assuming the work items are all of this type.

The other interesting method is the one that uses the unresolved result set, iterates it and runs the operation on it. this method looks like below.

public static void processUnresolvedResults(IProjectArea projectArea,
		IQueryResult results, 
		WorkItemOperation operation, IProgressMonitor monitor)
		throws TeamRepositoryException {

	long processed = 0;
	while (results.hasNext(monitor)) {
		IResult result = (IResult) results.next(monitor);
		operation.run((IWorkItemHandle) result.getItem(), monitor);
		processed++;
	}
	System.out.println("Processed results: " + processed);
}

The code has very little exception handling and you might want to enhance that.

With this small tool you can synchronize all workitems of a specific type. I hope the code helps some RTC Administrator out there to save some time.

Advertisements

About rsjazz

Hi, my name is Ralph. I work for IBM and help colleagues and customers with adopting the Jazz technologies.
This entry was posted in Jazz, RTC, RTC Extensibility and tagged , , , , , . Bookmark the permalink.

7 Responses to Using an Expression to Synchronize Attributes for Work Items of a Specific Type

  1. Pingback: Using Work Item Queries for Automation | rsjazz

  2. Hi Ralph,

    great tip – we’ve had problems with RTC attribute synchronization so your post is really useful and informative 🙂

    /Frank

    • rsjazz says:

      Frank, that is great to hear. I had it sitting in my backlog for some time now and couldn’t get to publish it. I assume a lot of others have already created something similar.
      Please be aware, with very few effort you could also add this to the Eclipse menus.

  3. AndyJ says:

    Hi, Ralph. . . Very useful, as always! One problem – the code link gives me a 404. Do you still have it around?

  4. Joe says:

    Ralph,

    Thanks a ton for this. I have one small addition, and one question.

    For the addition, it’s important to note that after running the “updateWorkItemType” method you must also save the working copy to persist the synchronization. (I hope that saves someone some time)

    On another note, I was wondering how I can find out if a work item needs to be synchronized. Similar to the “Check attributes usage in repository” button in eclipse client. Is there a Java API equivalent of that? Mostly I’m interested because one of the projects I work on has 40,000+ work items, and I’d like to only have to sync the work items that are out of sync to help run the script faster.

    Thanks in advance!

    • rsjazz says:

      Since the code runs in a workItemOperation, for all I know it will save the work item automatically, if there is a change.

      You could look at all work items and try to find out if it has all the attributes it should have. It is probably more efficient to just use the button in the Eclipse UI if you add an attribute or run the sync script then.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s