how can I query for releases / iterations via rally c# api? - rally

I am trying to query on both Release and Iteration so I can fill out a drop down list with these various values. I'm not quite sure how to do this, however. What are the members of the object that come back via the query if we are able to do this? (Name, FormattedID, CreationDate, etc). Do we just create a new request of type "Release" and "Iteration" ?
Thanks!

Here is a code that queries on releases based on a project reference. If this project is not in a default workspace of the user that runs the code we either need to hardcode the workspace reference or get it from the project.
class Program
{
static void Main(string[] args)
{
RallyRestApi restApi;
restApi = new RallyRestApi("user#co.com", "TopSecret1984", "https://rally1.rallydev.com", "1.40");
var projectRef = "/project/22222222"; //use your project OID
DynamicJsonObject itemWorkspace = restApi.GetByReference(projectRef, "Workspace");
var workspaceRef = itemWorkspace["Workspace"]["_ref"];
Dictionary<string, string> result = new Dictionary<string, string>();
try
{
Request request = new Request("Release");
request.ProjectScopeDown = false;
request.ProjectScopeUp = false;
request.Workspace = workspaceRef;
request.Fetch = new List<string>()
{
"Name"
};
// request.Query = new Query("Project.ObjectID", Query.Operator.Equals, "22222222"); //also works
request.Query = new Query("Project", Query.Operator.Equals, projectRef);
QueryResult queryResult = restApi.Query(request);
foreach (var r in queryResult.Results)
{
Console.WriteLine("Name: " + r["Name"]);
}
}
catch
{
Console.WriteLine("problem!");
}
}
}
}

Related

How to use the continuationtoken in TFS 2015 Object Model: GetBuildsAsync?

I am using the following code
BuildHttpClient service = new BuildHttpClient(tfsCollectionUri,
new Microsoft.VisualStudio.Services.Common.VssCredentials(true));
var asyncResult = service.GetBuildsAsync(project: tfsTeamProject);
var queryResult = asyncResult.Result;
This returns only the first 199 builds.
Looks like in need to use the continuationtoken but am not sure how to do this. The docs say that the REST API will return the token. I am using the Object Model, and am looking for how to retrieve the token!
I am using Microsoft.TeamFoundationServer.Client v 14.102.0; Microsoft.TeamFoundationServer.ExtendedClient v 14.102.0, Microsoft.VisualStudio.Service.Client v 14.102.0 and Microsoft.VisualStudio.Services.InteractiveClient v 14.102.0
Question
How do I use the continuation token **when using the TFS Object model?
The continuationToken is in the response header after the first call to the API:
x-ms-continuationtoken: xxxx
It can not be retrieved from .net client library. You have to use the rest api to retrieve the header information. Here is an example for your reference:
using System;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Threading.Tasks;
namespace GetBuilds
{
class Program
{
public static void Main()
{
Task t = GetBuilds();
Task.WaitAll(new Task[] { t });
}
private static async Task GetBuilds()
{
try
{
var username = "xxxxx";
var password = "******";
using (var client = new HttpClient())
{
client.DefaultRequestHeaders.Accept.Add(
new System.Net.Http.Headers.MediaTypeWithQualityHeaderValue("application/json"));
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Basic",
Convert.ToBase64String(
System.Text.ASCIIEncoding.ASCII.GetBytes(
string.Format("{0}:{1}", username, password))));
using (HttpResponseMessage response = client.GetAsync(
"http://tfs2015:8080/tfs/DefaultCollection/teamproject/_apis/build/builds?api-version=2.2").Result)
{
response.EnsureSuccessStatusCode();
string responseBody = await response.Content.ReadAsStringAsync();
Console.WriteLine(responseBody);
}
}
}
catch (Exception ex)
{
Console.WriteLine(ex.ToString());
}
}
}
}
You have to use 'GetBuildsAsync2', which returns an IPagedList. You can retrieve the ContinuationToken from the IPagedList:
// Iterate to get the full set of builds
string continuationToken = null;
List<Build> builds = new List<Build>();
do
{
IPagedList<Build> buildsPage = service.GetBuildsAsync2(tfsTeamProject, continuationToken: continuationToken).Result;
//add the builds
builds.AddRange(buildsPage);
//get the continuationToken for the next loop
continuationToken = buildsPage.ContinuationToken;
}
while (continuationToken != null);

Create Defect in Rally using REST API and C#

I am trying to programatically create a defect in Rally using C#. Below is my code and errors i am getting is
Error in creating defect!!!
Cannot parse object reference from "Unspecified"
Code:
RallyRestApi restApi;
restApi = new RallyRestApi(webServiceVersion: "v2.0");
//after successful authentication...
String workspaceRef = "/workspace/12345";
String projectRef = "/project/78321";
DynamicJsonObject badDefect = new DynamicJsonObject();
newDefect["Name"] = "Defect " + DateTime.Now;
newDefect["Project"] = projectRef ;
newDefect["Environment"] = "test branch";
newDefect["c_DefectSourceNEW"] = "old";
newDefect["Severity"] = "minor";
newDefect["Release"] = "Unspecificed";
CreateResult createResult = restApi.Create("Defect", newDefect);
if (createResult.Success == true)
{
Console.WriteLine("Defect created Successfully!!!");
}
else
{
Console.WriteLine("Error in creating defect!!!");
}
foreach (string s in createResult.Errors)
{
Console.WriteLine(s);
}
Can some one suggest what i might be doing incorrectly and in general the correct way to sepcify "Release" value for a defect???
All object relationships in wsapi are represented by refs. So you just need to set the value as its ref rather than its name, much like you're already doing with workspace and project.
Thanks Kyle for inputs. Since the Release ID was mandatory i solved by below for Release Input:
Request reRequest = new Request("Release");
reRequest.Workspace = workspaceRef;
reRequest.Query = new Query("Project", Query.Operator.Equals, projectRef);
QueryResult queryResult = restApi.Query(reRequest);
string reprojectRef = null;
foreach (DynamicJsonObject result in queryResult.Results)
{
reprojectRef = result["_ref"];
Console.WriteLine(reprojectRef);
Console.WriteLine("Name: " + result["Name"]);
if (result["Name"] == "MyReleaseName")
{
newDefect["Release"] = result["_ref"];
}
}

TFS API to create a TFS Group and set permissions?

Hello I'm trying to use TFS API to create a new group, for it I have this code:
var teamProjects = this.VersionControlServer.GetAllTeamProjects(false);
foreach (var teamProject in teamProjects)
{
var result = _gss.CreateApplicationGroup(teamProject.ArtifactUri.AbsoluteUri, "NewGroup","TestDescription");
//NOW I WANT TO SET THE PERMISSIONS FOR THIS GROUP
}
As I need to set the permission "Edit project-level information" for this group I tried lot of methods and different approaches, but anything seems to solve my need. This for example:
var ProjectSecurityToken = AuthorizationSecurityConstants.ProjectSecurityPrefix + teamProject.ArtifactUri.AbsoluteUri;
var groupACL = securityNamespace.QueryAccessControlList(ProjectSecurityToken, new[] {list[4].Descriptor}, false);
securityNamespace.SetAccessControlEntry(ProjectSecurityToken, new Microsoft.TeamFoundation.Framework.Client.AccessControlEntry(list[4].Descriptor, 115, 0), true);
I had hard-coded "list[4]" because it was the group I just created, I need some help to see what is wrong in my code. I get no error message and it doesn't work as well.
I can get the permissions been set via following code:
using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.TeamFoundation.Client;
using Microsoft.TeamFoundation.Server;
using Microsoft.TeamFoundation.VersionControl.Client;
using Microsoft.TeamFoundation.Framework.Client;
namespace API
{
class Program
{
static void Main(string[] args)
{
string project = "http://xxx.xxx.xxx.xxx:8080/tfs";
TfsTeamProjectCollection tpc = new TfsTeamProjectCollection(new Uri(project));
var tps = tpc.GetService<VersionControlServer>();
var ttt = tps.GetTeamProject("ProjectName");
ISecurityService securityService = tpc.GetService<ISecurityService>();
System.Collections.ObjectModel.ReadOnlyCollection<SecurityNamespace> securityNamespaces = securityService.GetSecurityNamespaces();
IGroupSecurityService gss = tpc.GetService<IGroupSecurityService>();
Identity SIDS = gss.ReadIdentity(SearchFactor.AccountName, "GroupName", QueryMembership.Expanded);//GourName format: [ProjectName]\\GourpName
IdentityDescriptor id = new IdentityDescriptor("Microsoft.TeamFoundation.Identity", SIDS.Sid);
List<SecurityNamespace> securityList = securityNamespaces.ToList<SecurityNamespace>();
string securityToken;
foreach (SecurityNamespace sn in securityList)
{
if (sn.Description.DisplayName == "Project")
{
securityToken = "$PROJECT:" + ttt.ArtifactUri.AbsoluteUri;
sn.SetPermissions(securityToken, id, 115, 0, true);
}
}
}
}
}

Permissions error creating rally milestone when using API Key

I'm trying to create rally milestones from an external app using an API Key for credential authorization, but I get the warning "Not authorized to create: Milestone" whenever I run the following code:
DynamicJsonObject toCreate = new DynamicJsonObject();
toCreate["Name"] = "test";
CreateResult createResult = restApi.Create("milestone", toCreate);
I ran the same code with defects and other rally objects without any issues, and I am able to update existing milestones. However, I still can't figure out how to create new milestones.
Assuming that ApiKey belongs to a user that has write access to the intended workspace, this code using v3.0.1 of .NET toolkit creates a Milestone in a default project of that workspace:
class Program
{
static void Main(string[] args)
{
RallyRestApi restApi = new RallyRestApi(webServiceVersion: "v2.0");
String apiKey = "_abc123";
restApi.Authenticate(apiKey, "https://rally1.rallydev.com", allowSSO: false);
String workspaceRef = "/workspace/1234";
try
{
DynamicJsonObject m = new DynamicJsonObject();
m["Name"] = "some milestone";
CreateResult result = restApi.Create(workspaceRef, "Milestone",m);
}
catch (Exception e)
{
Console.WriteLine(e);
}
}
}
UPDATE:
The issue can be related to the request's scope. See how this error is replicated and resolved using a browser rest client here.
An equivalent C# code:
class Program
{
static void Main(string[] args)
{
RallyRestApi restApi = new RallyRestApi(webServiceVersion: "v2.0");
String apiKey = "_abc123";
restApi.Authenticate(apiKey, "https://rally1.rallydev.com", allowSSO: false);
String projectRef = "/project/2222";
String workspaceRef = "/workspace/1111";
try
{
DynamicJsonObject m = new DynamicJsonObject();
m["Name"] = "some milestone xxxt";
m["TargetProject"] = projectRef;
CreateResult result = restApi.Create(workspaceRef, "Milestone",m);
m = restApi.GetByReference(result.Reference, "FormattedID");
Console.WriteLine(m["FormattedID"]);
}
catch (Exception e)
{
Console.WriteLine(e);
}
}
}

Rally: How to Map test cases with user stories using REST API?

I am writing code to create new test cases using rally restAPI.
Able to create the test cases under Test Plan & Test folder.
Now, want to map those test cases to Rally user stories.
Work product is the field to map it. But how to get the reference of user story using restAPI?
Please let me know if anyone has done in past.
In WS API user story is HierarchicalRequirement object. Query on the story, which you want to be a workproduct, and get its _ref. Then update the test case, e.g.
testCaseUpdate.addProperty("WorkProduct", storyRef);
Here is a Java example using Rally Rest toolkit for Java, but the approach is the same regardless of your choice of language or toolkit:
public class UpdateTestCase {
public static void main(String[] args) throws URISyntaxException, IOException {
String host = "https://rally1.rallydev.com";
String apiKey = "_abc123";
String workspaceRef = "/workspace/123456";
String applicationName = "RestExample_updateWorkProductOnTestCase";
RallyRestApi restApi = new RallyRestApi(new URI(host),apiKey);
restApi.setApplicationName(applicationName);
try {
String testid = "TC12";
String storyid = "US34";
QueryRequest testCaseRequest = new QueryRequest("TestCase");
testCaseRequest.setWorkspace(workspaceRef);
testCaseRequest.setFetch(new Fetch("FormattedID", "Name", "WorkProduct"));
testCaseRequest.setQueryFilter(new QueryFilter("FormattedID", "=", testid));
QueryResponse testCaseQueryResponse = restApi.query(testCaseRequest);;
if (testCaseQueryResponse.getTotalResultCount() == 0) {
System.out.println("Cannot find test case : " + testid);
return;
}
JsonObject testCaseJsonObject = testCaseQueryResponse.getResults().get(0).getAsJsonObject();
String testCaseRef = testCaseJsonObject.get("_ref").getAsString();
System.out.println(testCaseRef);
QueryRequest storyRequest = new QueryRequest("HierarchicalRequirement");
storyRequest.setWorkspace(workspaceRef);
storyRequest.setFetch(new Fetch("FormattedID", "Name"));
storyRequest.setQueryFilter(new QueryFilter("FormattedID", "=", storyid));
QueryResponse storyQueryResponse = restApi.query(storyRequest);;
if (storyQueryResponse.getTotalResultCount() == 0) {
System.out.println("Cannot find test story : " + storyid);
return;
}
JsonObject storyJsonObject = storyQueryResponse.getResults().get(0).getAsJsonObject();
String storyRef = storyJsonObject.get("_ref").getAsString();
System.out.println(storyRef);
JsonObject testCaseUpdate = new JsonObject();
testCaseUpdate.addProperty("WorkProduct", storyRef);
UpdateRequest updateTestCaseRequest = new UpdateRequest(testCaseRef,testCaseUpdate);
UpdateResponse updateTestCaseResponse = restApi.update(updateTestCaseRequest);
if (updateTestCaseResponse.wasSuccessful()) {
System.out.println("Successfully updated : " + testid + " WorkProduct after update: " + testCaseUpdate.get("WorkProduct"));
}
} finally {
restApi.close();
}
}
}