It's all about the answers!

Ask a question

Is it possible to migrate an RTC Project Area to a different Process Parent programmatically?


Sefa Sevtekin (2345) | asked Jul 30 '14, 1:26 p.m.
edited Aug 04 '14, 9:19 a.m. by Geoffrey Clemm (30.1k23035)
 Is it possible to migrate an RTC project area to a newer version of the process parent using the REST API or RTC SDK?

Thanks,
Sefa

Accepted answer


permanent link
sam detweiler (12.5k6189201) | answered Jul 31 '14, 6:53 p.m.
edited Aug 01 '14, 10:35 a.m.
yes, here is my sample commandline code that does this.. (it also dumps out the process xml for the project
| this only does one project at a time, or ALL that have a parent (use * as the current project name)
but you could modify it to take a list, or discover which one need to be modified, or.. many other ways..

uses the client api

parms are server userid password project_name_to_change new_parent_project_name

package com.sd.tools;

import java.io.ByteArrayOutputStream;
import java.io.FileOutputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import org.eclipse.core.runtime.IProgressMonitor;

import com.ibm.team.repository.client.IContentManager;
import com.ibm.team.repository.client.IItemManager;
import com.ibm.team.repository.client.ITeamRepository;
import com.ibm.team.repository.client.TeamPlatform;
import com.ibm.team.repository.common.IContent;
import com.ibm.team.repository.common.TeamRepositoryException;
import com.ibm.team.process.client.*;
import com.ibm.team.process.common.IProjectArea;
import com.ibm.team.process.common.IProjectAreaHandle;
import com.ibm.team.process.internal.common.impl.ProjectAreaImpl;

@SuppressWarnings("restriction")
public class GetProjectSource
{

    /**
     * key used to store project process configuration source
     */
    static String keyname = "com.ibm.team.internal.process.compiled.xml";

    public static void main(String[] args)
    {
        String url = null; // repository address
        String userid = null; // userid
        String password = null; // password
        String ProjectType = null; // * or name of project

        String newProjectParent = null; // name of new process parent project,
                                        // optional

        if (args.length < 4)
        {
            System.out.println("Parameters are" +
                "URL of repository\n" +
                "Userid of Admin user\n" +
                "Password of Admin user\n"+
                "project scope\n" +
                "    * for all projects (save all project source)\n" +
                "    specific Name of project to locate\n" +
                "\n" +   
                "optional:\n" +
                "    new parent project name"
                );
            return;
        }
        url = args[0];
        userid = args[1];
        password = args[2];
        // under eclipse * parm sends in junk
        ProjectType = args[3].equalsIgnoreCase("foo") ? "*" : args[3];
        newProjectParent = args[4];

        // startup the teamplatform runtime, if not already
        if (!TeamPlatform.isStarted())
            TeamPlatform.startup();
        try
        {
            // create required Monitor
            SysoutProgressMonitor sPm = new SysoutProgressMonitor();

            // login
            if (login(url, userid, password, sPm) != null)
            {
                // get the repository object where we are connecting
                ITeamRepository repo = getRepository(url);

                // get the list of projects
                // * means all
                // specific name means only that one.. case sensitive I think
                List<IProjectArea> projectList = getProjectArea(repo, sPm,
                        ProjectType);

                System.out.println(" there are " + projectList.size()
                        + " projects");

                // loop thru the list of projects, if any
                for (int i = 0; i < projectList.size(); i++)
                {
                    // get the project area
                    IProjectArea ip = projectList.get(i);

                    //IDevelopmentLineHandle[] idl =ip.getDevelopmentLines();
                    // IIterationTypeHandle[] iii = ip.getIterationTypes();

                    System.out.println("\nproject name = " + ip.getName());
                   
                    //IDevelopmentLine ixl =(IDevelopmentLine) idl[0].getFullState();
                    //IIterationHandle iih = ixl.getCurrentIteration();
                    //IIteration iif = (IIteration) iih.getFullState();
                    //IIterationHandle[] iip = ixl.getIterations();
                   
                    // get the process data
                    @SuppressWarnings("unchecked")
                    Map<Object, Object> pd = ip.getProcessData();

                    // get the content Manager
                    IContentManager icm = repo.contentManager();
                    // get the process config content object
                    IContent processSource = (IContent) pd.get(keyname);
                    if (processSource != null)
                    {
                        System.out.println("have xml source");
                        saveXMLSource(ip, processSource, icm, sPm);
                    }                   

                    IProjectArea ipi = (IProjectArea) ip.getWorkingCopy();
                    // call the internal only method to get the parent process
                    // provider.. if any
                    IProjectAreaHandle iparenthandle = ((ProjectAreaImpl) ipi)
                            .getProcessProvider();
                    // if there was a parent
                    if (iparenthandle != null)
                    {
                        // get it
                        IProjectArea parentProject = (IProjectArea) (repo
                                .itemManager().fetchCompleteItem(iparenthandle,
                                IItemManager.DEFAULT, sPm));
                        System.out.println("have parent project name = "
                                + parentProject.getName());
                        // if we are changing the parent
                        if (newProjectParent != null)
                        {
                            // find the new one
                            List<IProjectArea> plist = getProjectArea(repo,
                                    sPm, newProjectParent);
                            // if we found it
                            if (plist.size() > 0)
                            {
                                // get its handle
                                IProjectAreaHandle newParentHandle = (IProjectAreaHandle) plist
                                        .get(0);
                                // always checking
                                if (newParentHandle != null)
                                {
                                    // set the provider field
                                    ((ProjectAreaImpl) ipi)
                                            .setProcessProvider(newParentHandle);
                                    // save the project area
                                    getProcessItemService(repo).save(
                                            (IProjectArea) ipi, sPm);
                                }
                            }
                        }
                    }
                }
            }
            else
            {
                System.out.println("unable to logon to " + url + " as "
                        + userid);
            }
        }
        catch (Exception ex)
        {
            System.out.println("exception=" + ex.toString());
        }

    }

    // save the process source for the project
    private static void saveXMLSource(IProjectArea ip, IContent ic,
            IContentManager icm, SysoutProgressMonitor sPm)
    {
        // make an output stream for the content manager
        OutputStream os = new ByteArrayOutputStream();
        // get the content of the content object.
        try
        {
            icm.retrieveContent(ic, os, sPm);

            // write xml content to file
            // project name + data name
            FileOutputStream fo = new FileOutputStream(ip.getName() + "."
                    + keyname);
            // write
            fo.write(os.toString().getBytes(), 0, os.toString().length());
            // close
            fo.close();
        }
        catch (Exception e)
        {
            e.printStackTrace();
        }
    }

    // login to the repository
    public static ITeamRepository login(String url, final String userid,
            final String password, IProgressMonitor monitor)
            throws TeamRepositoryException
    {

        getRepository(url).registerLoginHandler(
                new ITeamRepository.ILoginHandler()
                {
                    public ILoginInfo challenge(ITeamRepository repository)
                    {
                        return new ILoginInfo()
                        {
                            public String getUserId()
                            {
                                return userid;
                            }

                            public String getPassword()
                            {
                                return password;
                            }
                        };
                    }
                });

        monitor.subTask("Contacting " + url);
        getRepository(url).login(monitor);
        monitor.subTask("Connected");

        return getRepository(url);
    }

    // worker function repository
    private static ITeamRepository repo1 = null;

    private static ITeamRepository getRepository(String url)
    {
        if (repo1 == null)
        {
            repo1 = TeamPlatform.getTeamRepositoryService().getTeamRepository(
                    url);
        }
        return repo1;
    }

    // worker function process item service
    private static IProcessItemService processitemservice = null;

    private static IProcessItemService getProcessItemService(
            ITeamRepository repo)
    {
        if (processitemservice == null)
        {
            processitemservice = (IProcessItemService) repo
                    .getClientLibrary(IProcessItemService.class);
        }
        return processitemservice;
    }

    public static List<IProjectArea> getProjectArea(ITeamRepository repo,
            IProgressMonitor monitor, String projectAreaName)
            throws TeamRepositoryException
    {
        List<IProjectArea> projectareaonly = new ArrayList<IProjectArea>();

        @SuppressWarnings("unchecked")
        // get all the projects in this repository
        List<IProjectArea> projectAreas = getProcessItemService(repo)
                .findAllProjectAreas(null, monitor);

        // if Not ALL projects
        if (!projectAreaName.equalsIgnoreCase("*"))
        {
            for (int i = 0; i < projectAreas.size(); i++)
            {
                // get next preoject from array
                IProjectArea projectArea = projectAreas.get(i);

                // if the names are equal, case sensitive
                if (projectArea.getName().equals(projectAreaName))
                {
                    // return this one project to the caller
                    System.out.println("Found " + projectAreaName);
                    projectareaonly.add(projectArea);
                    break;
                }
                else if (i + 1 == projectAreas.size())
                {
                    System.out.println("Failed to find requested project '"
                            + projectAreaName + "'");
                }
            }
            return projectareaonly;
        }
        else
            projectareaonly = projectAreas;
        return projectareaonly;
    }
}

Sefa Sevtekin selected this answer as the correct answer

3 other answers



permanent link
Ralph Schoon (61.4k33643) | answered Jul 31 '14, 3:23 a.m.
FORUM ADMINISTRATOR / FORUM MODERATOR / JAZZ DEVELOPER
Hi Sefa,

this is currently not possible or at least very hard to do.
You would have to:
  1. Identify the changes between the old template and the new template in the process XML
  2. Identify the customizations you did in the current process XML.
  3. Merge the changes you found in 1 into the process XML without affecting your customizations.

I would consider this very hard.

I believe if you upgrade a server, the most essential changes needed are done to your process in project areas.


Comments
Geoffrey Clemm commented Aug 04 '14, 9:21 a.m.
FORUM ADMINISTRATOR / FORUM MODERATOR / JAZZ DEVELOPER

Note: Apparently Sefa meant "process parent", not "process template".   I've updated the question to fix the terminology.


permanent link
Jim Ruehlin (79114) | answered Jul 31 '14, 4:44 p.m.
JAZZ DEVELOPER
 Hi Sefa,

I'm guessing that what you want to do is update the project configuration with new process information from a more recent template. If so, updating the template won't help you. Updating templates doesn't change process configurations created from those templates.

APIs relevant to templates can be seen in the Process Component Scope page.

What are you trying to accomplish by updating the process template? We might be able to solve your problem in another way.

You may want to think about using process sharing instead, depending on what you're trying to accomplish. Process sharing can provide more flexibility and support for changing the process for multiple projects.

- Jim

Comments
Sefa Sevtekin commented Jul 31 '14, 5:26 p.m.

Hi Jim,


Here is what we want to do. We want to have a master process template an share it with other project areas. Once we have an updated master process template we want to project areas to point to the new updated master process template. Does it make sense?

 


Geoffrey Clemm commented Aug 04 '14, 9:21 a.m.
FORUM ADMINISTRATOR / FORUM MODERATOR / JAZZ DEVELOPER

Note: Apparently Sefa meant "process parent", not "process template".   I've updated the question to fix the terminology.


permanent link
Geoffrey Clemm (30.1k23035) | answered Aug 04 '14, 12:14 a.m.
FORUM ADMINISTRATOR / FORUM MODERATOR / JAZZ DEVELOPER
I suggest using process sharing, not by updating the process source of your project area.
For details, see: https://www-01.ibm.com/support/knowledgecenter/SSCP65_5.0.0/com.ibm.jazz.platform.doc/topics/c_sharing_project_area_process.html?lang=en


Comments
sam detweiler commented Aug 04 '14, 7:32 a.m. | edited Aug 04 '14, 7:35 a.m.

that is what he said he wanted to do

"We want to have a master process template an share it with other project areas. Once we have an updated master process template we want to project areas to point to the new updated master process template."

he wanted a way to change the parent (master) project pointer in batch instead of manually.


Geoffrey Clemm commented Aug 04 '14, 9:18 a.m.
FORUM ADMINISTRATOR / FORUM MODERATOR / JAZZ DEVELOPER

The original question was about migrating to a newer version of the "process template".  A lot of folks (not you :-) confuse the "process template" of a project area (i.e. the template that initialized the project area), with the "parent (master) project area" of the project area, so I just wanted to make sure that this question doesn't confuse anyone.   Since Seva accepted your answer, it must have been a terminology glitch in the original question, so I'll go ahead and update the question (to match your correct answer :-).

Your answer


Register or to post your answer.