How to find the list of user stories under a given iteration and a given project using rally rest api

java, rally, rest

Solution

Given a project:

String projectRef = "/project/1234";

You may scope your requests as follows:

iterationRequest.setProject(projectRef);

or

storyRequest.setProject(projectRef);

If you scoped a story request to a project, then you may query on stories by traversing Iteration.Name if you know the iteration already:

storyRequest.setQueryFilter(new QueryFilter("Iteration.Name", "=", "my Iteration 1"));

Here is a more complex example that returns stories assigned to iterations that fall within the timbox of a specific release. If, for example, you have 4 iterations per release, this code will return stories assigned to all four iterations.

If you code against the sandbox, replace the value in the host variable accordingly.

public class FindIterationsByReleaseDateAndStories {

    public static void main(String[] args) throws URISyntaxException, IOException {


        String host = "https://rally1.rallydev.com";
            String username = "user@co.com";
            String password = "secret";
            String projectRef = "/project/12352608219";
            String applicationName = "Find Iterations by Release Dates and Stories";

            RallyRestApi restApi = null;

        try {
                restApi = new RallyRestApi(
                        new URI(host),
                        username,
                        password);
                restApi.setApplicationName(applicationName); 

                System.out.println(restApi.getWsapiVersion()); 

                QueryRequest  releaseRequest = new QueryRequest("Release");
                releaseRequest.setFetch(new Fetch("ReleaseStartDate", "ReleaseDate"));
                releaseRequest.setScopedDown(false);
                releaseRequest.setScopedUp(false);
                releaseRequest.setProject(projectRef);
                releaseRequest.setQueryFilter(new QueryFilter("Name", "=", "r1"));

                QueryResponse releaseQueryResponse = restApi.query(releaseRequest);
                int numberOfReleasesInProject = releaseQueryResponse.getTotalResultCount();
                System.out.println(numberOfReleasesInProject);
                JsonObject releaseJsonObject = releaseQueryResponse.getResults().get(0).getAsJsonObject();
                System.out.println(releaseJsonObject.get("ReleaseStartDate"));
                System.out.println(releaseJsonObject.get("ReleaseDate"));

                String rsd = releaseJsonObject.get("ReleaseStartDate").getAsString();
                String rd = releaseJsonObject.get("ReleaseDate").getAsString();

                QueryRequest  iterationRequest = new QueryRequest("Iteration");
                iterationRequest.setFetch(new Fetch("Name","StartDate","EndDate"));
                iterationRequest.setScopedDown(false);
                iterationRequest.setScopedUp(false);
                iterationRequest.setProject(projectRef);
                iterationRequest.setQueryFilter(new QueryFilter("StartDate", ">=", rsd).and(new QueryFilter("EndDate", "<=", rd)));

                QueryResponse iterationQueryResponse = restApi.query(iterationRequest);
                int numberOfIteraitons = iterationQueryResponse.getTotalResultCount();
                System.out.println("numberOfIteraitons " + numberOfIteraitons);
                if(numberOfIteraitons >0){
                    for (int i=0;i<numberOfIteraitons;i++){
                        JsonObject iterationJsonObject = iterationQueryResponse.getResults().get(i).getAsJsonObject();
                        String iterationName = iterationJsonObject.get("Name").getAsString();
                        System.out.println("iteration: " + iterationName);
                        QueryRequest storyRequest = new QueryRequest("HierarchicalRequirement");
                        storyRequest.setProject(projectRef);
                        storyRequest.setFetch(new Fetch(new String[] {"Name", "FormattedID","ScheduleState"}));
                        storyRequest.setLimit(1000);
                        storyRequest.setScopedDown(false);
                        storyRequest.setScopedUp(false);
                        storyRequest.setQueryFilter(new QueryFilter("Iteration.Name", "=", iterationName));

                        QueryResponse storyQueryResponse = restApi.query(storyRequest);
                        System.out.println("Number of stories in " + iterationName + " :" + storyQueryResponse.getTotalResultCount());

                        for (int j=0; j<storyQueryResponse.getResults().size();j++){
                            JsonObject storyJsonObject = storyQueryResponse.getResults().get(j).getAsJsonObject();
                            System.out.println("Name: " + storyJsonObject.get("Name") + " FormattedID: " + storyJsonObject.get("FormattedID") + " ScheduleState: " + storyJsonObject.get("ScheduleState"));
                        }
                    }
                }       
        }
        finally{
            if (restApi != null) {
                restApi.close();
            }
        }

    }
}

UPDATE: as far as your question in the comment, the code above is equivalent of

https://rally1.rallydev.com/slm/webservice/v2.0/hierarchicalrequirement?query=((Iteration.Name = i1) AND (Project = /project/12352608219))

There are other ways to achive the same result. Iteration name may not be unique, hence the second condition by project ref. In the code the request's project is set first, that's why the query itself uses one condition, but effectively there are two. If you know your iteration's ref, or ObjectID then the same result will be returned from (Iteration = /iteration/123456789), and there is no need to filter by project since a reference or ObjectID are unique.

WS API doc is interactive.Test your queries in WS API and copy the resulting query URLs from the address bar if you want to see how queries are formed:

-Query in the context of the intended object: click on the work item type in the Object Model, e.g. Defect or HierarchicalRequirement before typing your query in the query box.

-Enter a query in a box, e.g (Iteration.Name = i1)

-Click on Query button

-Results are displayed in the window from which you can copy query URL from address bar of your browser.

Problem

I am able to get the iterations under the project object. Now how do I get the iteration I need under that project and then drill down to the stories in that iteration using the JAVA toolkit? https://sandbox.rallydev.com/slm/webservice/v2.0/project/7191194697/iterations

Original source