It's all about the answers!

Ask a question

Determining Build Definitions Associated with a Specific Project Area


Jason Bouknight (111) | asked May 02 '14, 3:10 p.m.
Using the 4.0.5 Client API's, I have a handle to a specific ProjectArea. I am having difficulty using the API's to list the names of all the Build Definitions associated with this particular Project Area. Lots of scouring of this forum and other sources have haven't helped me connect the dots yet.

Any advice and guidance is greatly appreciated.

12 answers



permanent link
sam detweiler (12.5k6195201) | answered May 02 '14, 3:20 p.m.
see the post in
https://jazz.net/forum/questions/131724/how-to-use-order-by-clause-in-query-using-java-api

by Nick at Jan 29, 9:46 a.m.

permanent link
Jason Bouknight (111) | answered May 02 '14, 3:42 p.m.
 Getting closer, I think...but that post doesn't work entirely. getProcessAreaHandles(...) is not defined and I don't see the connection to a ProjectArea object that I hold a reference to.

Thanks

Comments
sam detweiler commented May 02 '14, 3:50 p.m.

IProjectArea extends IProcessArea. 
so, you only have 1. instead of a list.

    IItemHandleInputArg[] itemHandleArgs = new IItemHandleInputArg[1];

     itemHandleArgs[0] = your_processarea_handle;




permanent link
Jason Bouknight (111) | answered May 02 '14, 4:15 p.m.
 Closer - I think, but for this:

 ItemQueryIterator<ibuilddefinitionhandle> iter = new ItemQueryIterator<ibuilddefinitionhandle>(

                ClientFactory.getTeamBuildClient(repository), query, processAreaHandles);


processAreaHandles isn't available. Substituting with itemHandleArgs compiles, but ultimately results in a ClassCastException during run-time.


Comments
sam detweiler commented May 02 '14, 4:28 p.m.

it was in the supplied code

  IProcessAreaHandle[] processAreaHandles = getProcessAreaHandles(repository, subMonitor.newChild(1));

u would do

  IProcessAreaHandle[] processAreaHandles = new IProcessAreaHandle[1];


permanent link
Jason Bouknight (111) | answered May 02 '14, 5:11 p.m.
So with all that, I ended up with this:

        SubMonitor subMonitor = SubMonitor.convert(myProgressMonitor, 4);
        
        // get the team areas for the connected project areas in the repo and
        // use them to narrow the search
        IProcessAreaHandle[] processAreaHandles = new IProcessAreaHandle[1]; 
        processAreaHandles[0] = projectAreaHandle; 
        
        // create the query
        IBuildDefinitionQueryModel buildDefinitionQueryModel = IBuildDefinitionQueryModel.ROOT;
        final IItemQuery query = IItemQuery.FACTORY.newInstance(buildDefinitionQueryModel);
        
        // IProjectArea extends IProcessArea        
        IItemHandleInputArg[] itemHandleArgs = new IItemHandleInputArg[processAreaHandles.length];
        for (int i = 0; i < processAreaHandles.length; i++) {
            itemHandleArgs[i] = query.newItemHandleArg();
        }

        IPredicate filter = ((BuildDefinitionQueryModel) buildDefinitionQueryModel).processArea()._in(itemHandleArgs);
        query.filter(filter);
        query.orderByDscUsingLocale(buildDefinitionQueryModel.id());

        // get the results
        IItemManager itemManager = repo.itemManager();
        ItemQueryIterator<IBuildDefinitionHandle> iter = new ItemQueryIterator<IBuildDefinitionHandle>(
                ClientFactory.getTeamBuildClient(repo), query, processAreaHandles);
        LinkedList<IBuildDefinition> buildDefinitions = new LinkedList<IBuildDefinition>();
        float size = iter.size(subMonitor.newChild(1));
        subMonitor.setWorkRemaining((int) (3 * Math.ceil(size / IQueryService.ITEM_QUERY_MAX_PAGE_SIZE)));
        while (iter.hasNext(subMonitor.newChild(1))) {
            List<IBuildDefinitionHandle> definitionHandles = iter.next(IQueryService.ITEM_QUERY_MAX_PAGE_SIZE, subMonitor.newChild(1));
            buildDefinitions.addAll(itemManager.fetchCompleteItemsPermissionAware(definitionHandles, IItemManager.DEFAULT, subMonitor.newChild(1)).getRetrievedItems());
        }
        Object[] buildsForProjectArea = buildDefinitions.toArray(new IBuildDefinition[buildDefinitions.size()]);

Compiled. No ClassCastException. Got '0'.

In debug, I learned the While loop was never executing - in-part due because the 'size' variable is set to 0. This ultimately translates to workremaining=0 after the associated calculation hits.

Unfortunately, changing the last block to remove the SubMonitor (tring to simplify this) doesn't resolve the issue as the lookup actions still returns 0. Given the system has many well-defined build definitions, there is still clearly an error in the code.

        // get the results
        IItemManager itemManager = repo.itemManager();
        ItemQueryIterator<IBuildDefinitionHandle> iter = new ItemQueryIterator<IBuildDefinitionHandle>(
                ClientFactory.getTeamBuildClient(repo), query, processAreaHandles);
        LinkedList<IBuildDefinition> buildDefinitions = new LinkedList<IBuildDefinition>();
        List<IBuildDefinitionHandle> definitionHandles = iter.next(IQueryService.ITEM_QUERY_MAX_PAGE_SIZE, myProgressMonitor);
            buildDefinitions.addAll(itemManager.fetchCompleteItemsPermissionAware(definitionHandles, IItemManager.DEFAULT, myProgressMonitor).getRetrievedItems());
        Object[] buildsForProjectArea = buildDefinitions.toArray(new IBuildDefinition[buildDefinitions.size()]);

Thanks for the assistance so far,
Jason

permanent link
Jason Bouknight (111) | answered May 04 '14, 5:11 p.m.
I've continued to study the code. It's becoming clearer, but please note the following details:

// size becomes 0
float size = iter.size(subMonitor.newChild(1));

// Evaluates to setWorkRemaining(0)
subMonitor.setWorkRemaining((int) (3 * Math.ceil(size / IQueryService.ITEM_QUERY_MAX_PAGE_SIZE))); 

// Never executes because hasNext(....) returns FALSE)
while (iter.hasNext(subMonitor.newChild(1))) {  // FALSE

Putting the WHILE loop aside, even a single execution returns an Iterator with 0 objects.

Could there be a bug where ProcessAreaHandles aren't handled correctly by the ItemQueryIterator? 




permanent link
sam detweiler (12.5k6195201) | answered May 04 '14, 5:25 p.m.
try this one I just wrote
private static ArrayList<IBuildDefinition> getBuildDefinitionsforProjectArea(IProjectAreaHandle iprja)
    {
        Boolean allProperties = true;
        // allocate space for results
        ArrayList<IBuildDefinition> allbe = new ArrayList<IBuildDefinition>();
        ITeamRepository repo= (ITeamRepository)iprja.getOrigin();
        // get the data interface
        ITeamBuildClient buildClient = (ITeamBuildClient) repo.getClientLibrary(ITeamBuildClient.class);

        try
        {
            IBuildDefinitionQueryModel queryModel = IBuildDefinitionQueryModel.ROOT;
            // create a query for build engines
            IItemQuery query = IItemQuery.FACTORY.newInstance(queryModel);
            // allocate space for the parameter
            IItemHandleInputArg[] itemHandleArgs = new IItemHandleInputArg[]{query.newItemHandleArg()};
            // the query filter
            IPredicate filter = ((BuildDefinitionQueryModel) queryModel).processArea()._in(itemHandleArgs);
            // set the combined filter
            query.filter(filter);
            // no parameters required
            IItemQueryPage queryPage = buildClient.queryItems(query,
            // com.ibm.team.repository.common.service.IQueryService.EMPTY_PARAMETERS,
                    new Object[]{iprja}, IQueryService.ITEM_QUERY_MAX_PAGE_SIZE, null);

            // if there are build definitions defined

            if (queryPage.getResultSize() != 0)
            {
                while (queryPage != null)
                {
                    IFetchResult fetchResult = null;
                    if (allProperties == true)
                    {
                        fetchResult = repo.itemManager().fetchCompleteItemsPermissionAware(queryPage.getItemHandles(),
                                IItemManager.DEFAULT, null);
                    }
                    else
                    {
                        final String[] all_properties = new String[]
                        { IBuildEngine.PROPERTY_ACTIVE, IBuildEngine.PROPERTY_BUILD_ENGINE_ACTIVITY,
                                IBuildEngine.PROPERTY_DESCRIPTION, IBuildEngine.PROPERTY_ENGINE_CONTACT_INTERVAL,
                                IBuildEngine.PROPERTY_ID, IBuildEngine.PROPERTY_PROCESS_AREA,
                                IBuildEngine.PROPERTY_SUPPORTED_BUILD_DEFINITIONS,
                                IBuildEngine.PROPERTY_SUPPORTS_CANCELLATION, IBuildEngine.PROPERTY_USE_TEAM_SCHEDULER,
                                IBuildEngine.PROPERTY_PROPERTIES, IBuildEngine.PROPERTY_CONFIGURATION_ELEMENTS };
                       
                        fetchResult = repo.itemManager().fetchPartialItemsPermissionAware(queryPage.getItemHandles(),
                                IItemManager.DEFAULT, Arrays.asList(all_properties), null);
                    }

                    // add these to the list
                    allbe.addAll(fetchResult.getRetrievedItems());

                    if (queryPage.hasNext())
                    {
                        queryPage = (IItemQueryPage) buildClient.fetchPage(queryPage.getToken(),
                                queryPage.getNextStartPosition(), queryPage.getSize(), null);
                    }
                    else
                    {
                        queryPage = null;
                    }
                }
            }
        }
        catch (Exception ex)
        {
            System.out.println("build exception=" + ex.getMessage());
        }
        return allbe;
    }


permanent link
Jason Bouknight (111) | answered May 04 '14, 6:08 p.m.
 Thanks, Scott. I dropped in your code unmodified. The main conditional test

if (queryPage.getResultSize() != 0) 

fals to pass because no records appear (getResultSize returns 0); however, I am 100% sure that the listed Project Area name is correct because A) the wrong name generates an exception message and B) the thick client shows 100+ Build Definitions when you navigate in the Team Artifacts views to <Project Area Name> -> Builds.

Again, not sure if this is a bug, but 4.0.5 is the version for both the client API's and server in-use.

Continued appreciated for the assistance,
Jason

permanent link
sam detweiler (12.5k6195201) | answered May 04 '14, 7:58 p.m.
edited May 04 '14, 7:59 p.m.
haven't tried on 4.0.5.. have 4.0.3 and 4.0.6

try this little change.. (the 1st and last lines are the same, section in the middle changes a tiny bit )

            IItemQuery query = IItemQuery.FACTORY.newInstance(queryModel);
            // objects of build definition type, shouldn't be needed
            IPredicate isBuildDefType = queryModel._isTypeOf(IBuildDefinition.ITEM_TYPE);
            // allocate space for the parameter
            IItemHandleInputArg[] itemHandleArgs = new IItemHandleInputArg[]{query.newItemHandleArg()};
            // the query filter
            IPredicate filter = ((BuildDefinitionQueryModel) queryModel).processArea()._in(itemHandleArgs);
            // set the combined filter
            query.filter(filter._and(isBuildDefType));
            // no parameters required

permanent link
Jason Bouknight (111) | answered May 05 '14, 8:02 a.m.
Hi Sam,

With this change, queryPage.getResultSize() still returns 0 and so the first conditional/IF test fails to execute.

In order to isolate the problem, I tweaked this query to find ALL build definitions - regardless of Project Area.

...
 try 
    { 
    IBuildDefinitionQueryModel queryModel = IBuildDefinitionQueryModel.ROOT; 
    // create a query for build engines 
   IItemQuery query = IItemQuery.FACTORY.newInstance(queryModel); 
   IItemQueryPage queryPage = buildClient.queryItems(query, 
            com.ibm.team.repository.common.service.IQueryService.EMPTY_PARAMETERS,                          IQueryService.ITEM_QUERY_MAX_PAGE_SIZE, null);

With this, queryPage.getResultSize() returns a value equal to the # of build def's for the entire server. Great!

This leads me to believe that the process/mechanism to filter by associated Project Area isn't 'clicking' just yet.

Thanks,
Jason

Comments
sam detweiler commented May 05 '14, 8:05 a.m. | edited May 05 '14, 8:11 a.m.

well, nice to know you have some results at last.. similar code has been working fine on 3.0 and 4.0

so, it sounds like the project area handle is wrong.. how did u get that?
this is what my code usually does
ITeamRepository Server = TeamPlatform.getTeamRepositoryService().getTeamRepository(serverURI);
            processClient = (IProcessClientService) Server
                    .getClientLibrary(IProcessClientService.class);

            IProjectArea iprja = null;

            URI projuri = URI.create(projectAreaName.replaceAll(" ", "%20"));
            iprja= (IProjectArea) processClient.findProcessArea(projuri, null, null);


permanent link
Jason Bouknight (111) | answered May 05 '14, 8:36 a.m.
I'm getting the full UNFILTERD list - independent of the Project Area. I need to know which of these BuildDefinitions are associated with ProjectArea 'ABC' vs. which ones are not.

I was originally calling .getProjectArea() on the returned result from findProcessArea(..). I've since changed that to align to your approach, but the # of items is the same (even when I restore the previous filtering code).

Comments
sam detweiler commented May 05 '14, 10:05 a.m.

All or none depending if project is supplied or not? 

Your answer


Register or to post your answer.


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.