Determining Build Definitions Associated with a Specific Project Area
![]()
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
![]()
Here is a simple stand-alone program to demonstrate the issue. When running as a Java Application, it takes 4 parameters in this order:
This is contains all of the work from above, but it still does not work with RTC 4.0.5:
package rtc.test;
import java.net.URI;
import java.util.ArrayList;
import java.util.Arrays;
import org.eclipse.core.runtime.IProgressMonitor;
import com.ibm.team.build.client.ITeamBuildClient;
import com.ibm.team.build.common.model.IBuildDefinition;
import com.ibm.team.build.common.model.IBuildEngine;
import com.ibm.team.build.common.model.query.IBaseBuildDefinitionQueryModel.IBuildDefinitionQueryModel;
import com.ibm.team.build.internal.common.model.query.BaseBuildDefinitionQueryModel.BuildDefinitionQueryModel;
import com.ibm.team.process.client.IProcessClientService;
import com.ibm.team.process.common.IProjectArea;
import com.ibm.team.process.common.IProjectAreaHandle;
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.IFetchResult;
import com.ibm.team.repository.common.TeamRepositoryException;
import com.ibm.team.repository.common.query.IItemQuery;
import com.ibm.team.repository.common.query.IItemQueryPage;
import com.ibm.team.repository.common.query.ast.IItemHandleInputArg;
import com.ibm.team.repository.common.query.ast.IPredicate;
import com.ibm.team.repository.common.service.IQueryService;
import com.ibm.ws.bpm.build.rtc.RTCLoginHandler;
import com.ibm.ws.bpm.build.rtc.SysoutProgressMonitor;
public class ProjectAreaBuildDefs {
private String username = null;
private String password = null;
private String repoUri = null;
private String projectAreaName = null;
// RTC CLient API Objects
private IProgressMonitor myProgressMonitor;
private ITeamRepository repo;
public ProjectAreaBuildDefs() throws Exception {
super();
}
public static void main(String[] args) {
try {
ProjectAreaBuildDefs engine = new ProjectAreaBuildDefs();
engine.setRepository(args[0]);
engine.setUsername(args[1]);
engine.setPassword(args[2]);
engine.setProjectAreaName(args[3]);
engine.execute();
} catch (Exception e) {
e.printStackTrace();
}
}
private void init() throws Exception {
try {
myProgressMonitor = new SysoutProgressMonitor();
TeamPlatform.startup();
repo = TeamPlatform.getTeamRepositoryService().getTeamRepository(repoUri);
repo.registerLoginHandler(new RTCLoginHandler(username, password));
repo.login(myProgressMonitor);
} catch (TeamRepositoryException e) {
System.out.println(e.getMessage());
TeamPlatform.shutdown();
throw new Exception("Could not initialize the RTC Client API...");
}
}
private void displayParameters() {
System.out.println("Specified Repository: " + this.repoUri);
System.out.println("User: " + this.username);
System.out.println("Password: xxxxxxxx");
System.out.println("Project Area Name: " + this.projectAreaName);
System.out.println();
}
private void execute() throws Exception {
displayParameters();
try {
init();
IProcessClientService processClient = (IProcessClientService) repo.getClientLibrary(IProcessClientService.class);
URI uri = URI.create(this.projectAreaName.replaceAll(" ", "%20"));
IProjectArea iprja = (IProjectArea) processClient.findProcessArea(uri, null, null);
listProjectAreaBuildDefinitions(iprja);
} catch (TeamRepositoryException e) {
e.printStackTrace();
/* Handle repository exceptions such as login problems here. */
} finally {
repo.logout();
TeamPlatform.shutdown();
}
}
// Working with support to fix this
private ArrayList<IBuildDefinition> listProjectAreaBuildDefinitions(IProjectAreaHandle iprja) throws TeamRepositoryException {
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;
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
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
int numResults = queryPage.getResultSize();
//System.out.println("Num Results: " + numResults);
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());
}
System.out.println("*****Returned: " + allbe.size());
return allbe;
}
public void setUsername(String username) {
this.username = username;
}
public void setPassword(String password) {
this.password = password;
}
public void setRepository(String repository) {
this.repoUri = repository;
}
public void setProjectAreaName(String projectAreaName) {
this.projectAreaName = projectAreaName;
}
}
|
![]()
Sorry, I should have been clearer.
When I use the reduced query (above) that doesn't have ANY parameters (including a ProjectArea), I get the FULL list of BuildDefinitions. Make sense.
When I use the full query+filter that takes ProbjectArea as an argument, I get back 0 results.
|
![]()
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).
|
![]()
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 |
![]()
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
|
![]()
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; } |
![]()
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?
|
![]()
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
|