TargetProject in .Net Rally API 2.0 is NULL - rally

Request request = new Request("Milestone");
request.Project = ConfigurationManager.AppSettings["RootProject"];
request.ProjectScopeDown = true;
request.Fetch = new List<string>()
{
"ObjectId",
"FormattedID",
"Name",
"TargetDate",
"c_ApplicationName",
"c_Type",
"TargetProject",
"TotalArtifactCount",
"Notes",
"c_ProductName"
};
QueryResult queryResult = Api.Query(r);
The TargetProject is coming as NULL for some Milestones, whereas the Project is selected in UI for Rally. This is not the case with all Milestones though. Not sure why some do not have this value.

This is a holdover from some changes in the way milestones are linked to projects. The TargetProject attribute is deprecated and should no longer be used. Milestones now either have an empty Projects collection (workspace wide) or a specific set of projects.

Related

How to add HasReadLink to OData entity?

In OData when an entity had a media type, we should return along with the entity:
"odata.mediaReadLink": "Employees(1)/$value"
"odata.mediaContentType": "image/jpeg",
ref: http://docs.oasis-open.org/odata/odata-json-format/v4.0/cs01/odata-json-format-v4.0-cs01.html
I am using aspnet core and OData, but I cannot find the way to do this, well, at least not simply as I would expect this to be.
Below I show how I create the model builder, I add media type to the entity Assessment and then I try to specify the HasReadLink, but when I get an entity by Id, I do not receive back the odata media read link.
var builder = new ODataConventionModelBuilder(serviceProvider);
//This adds HasStream true in the metadata
var assessmentEntityType = builder.EntityType<Assessment>();
assessmentEntityType.MediaType();
var assessmentEntitySetConfiguration = builder.EntitySet<Assessment>(nameof(Assessment) + "s");
// Does not produce effects getting the entity by id
// UPDATE: this code below does have effect only if i set false in the second
// parameter, but anyway this has nothing to do with the media read link
assessmentEntitySetConfiguration.HasReadLink(c =>
{
return new Uri("/not-shown");
}, true);
// see NavigationSourceLinkBuilderAnnotation
// https://github.com/OData/WebApi/blob/d02bc61ea7b31ada1e54abbeebbecb3c5df0e3ac/src/Microsoft.AspNet.OData.Shared/Builder/NavigationSourceLinkBuilderAnnotation.cs
assessmentEntitySetConfiguration.EntityType
.Filter(QueryOptionSetting.Allowed, nameof(Assessment.IsDeleted))
.Filter(QueryOptionSetting.Disabled, nameof(Assessment.Description));
What am I missing?
I could not find an online example to do this in aspnet core, I found some old example to do it in net framework but it is hacky.
UPDATE 1:
In the OData for .net Framework I used SetHasDefaultStream to achieve this.
example:
var model = modelBuilder.GetEdmModel();
var answerTypeName = typeof(Answer).FullName;
var answerType = (IEdmEntityType) model.FindDeclaredType(answerTypeName);
model.SetHasDefaultStream(answerType, true);
In the new core I don't have an option to set the default stream.
I asked the same on OData.net Github project: https://github.com/OData/odata.net/issues/1555

SwaggerUI not adding ApiKey to Header with Swashbuckle (5.x)

I am using Swashbuckle.AspNetCore 5.0.0 to generate Swagger documentation for my .Net Core WebApi project, and for the most part, everything is going fine.
I have set up some simple authentication using ApiKey, and that is working good.
Where I am having problems now is getting Swagger to add an ApiKey into the header of my requests. I followed the instructions for added the ApiKey security Definition/requirement, as mentioned in these various posts:
API key in header with swashbuckle
Empty authorization header on requests for Swashbuckle.AspNetCore
How to force Swagger/Swashbuckle to append an API key?
However, the ApiKey value is never added to the Header.
This is what I have in my startup:
c.AddSecurityDefinition("ApiKey",
new OpenApiSecurityScheme
{
Description = "ApiKey must appear in header",
Type = SecuritySchemeType.ApiKey,
Name = Constants.ApiKeyHeaderName,
In = ParameterLocation.Header
});
and
c.AddSecurityRequirement(new OpenApiSecurityRequirement
{
{
new OpenApiSecurityScheme
{
Name = Constants.ApiKeyHeaderName,
Type = SecuritySchemeType.ApiKey,
In = ParameterLocation.Header
},
new List<string>()}
});
I was struggling myslef with this one but figured out that besides adding proper Reference, you have to also specify Scheme in definition, this is the code that is working for me correctly:
c.AddSecurityDefinition("ApiKey", new OpenApiSecurityScheme()
{
Name = "x-api-key",
In = ParameterLocation.Header,
Type = SecuritySchemeType.ApiKey,
Description = "Authorization by x-api-key inside request's header",
Scheme = "ApiKeyScheme"
});
var key = new OpenApiSecurityScheme()
{
Reference = new OpenApiReference
{
Type = ReferenceType.SecurityScheme,
Id = "ApiKey"
},
In = ParameterLocation.Header
};
var requirement = new OpenApiSecurityRequirement
{
{ key, new List<string>() }
};
c.AddSecurityRequirement(requirement);
Important tip is name in AddSecurityDefinition must be the same as Id in OpenApiReference. name can be every string.
OK, I was finally able to get this to work. I needed to add an instance of OpenApiReference to the OpenApiSecurityScheme object provided to c.AddSecurityRequirement()
Reference = new OpenApiReference { Type = ReferenceType.SecurityScheme, Id = "ApiKeyAuth" }
I have to say that the documentation on this is a bit confusing. Probably not in small part due to the fact that anything posted on the internet is there forever, and so many posts that I found on this whole thing were no longer applicable due to changes in the framework :)
Now I just need to figure out how to send another header value along with the api-key, and I'll be done with this part

I want to get all the workitems related to a particular release from rally in C#

We are working on a project to create reports from rally. I like to get all the workitems under a particular release and for that I tried to give release.name equals R.. but still it is getting all the work items. Could you please guide me with source code.
What you need to do is grab the _ref pointer that points to the work items associated with a particular release. This _ref pointer is retrieved when you query a given release for its "TypeDefinitions" field.
RallyRestApi restApi = new RallyRestApi();
restApi.Authenticate("UserName", "PassWord", "ServerURL", proxy: null, allowSSO: false);
Request request = new Request("release");
request.Fetch = new List<string>() { "Name", "Description", "FormattedID", "TypeDefinitions" };
request.Query = new Query("Name", Query.Operator.Equals, "ReleaseName");
QueryResult queryResult = restApi.Query(request);
var typeDefsUrl = "";
foreach (var result in queryResult.Results)
{
// Get the ref that points to your work items
typeDefsUrl = result["TypeDefinitions"]["_ref"];
}
From there you can use the Request object's CreateFromUrl to create an additional request who's response will be your collection of work items.
Request typeDefRequest = Request.CreateFromUrl(typeDefsUrl);
QueryResult typeDefsResult = restApi.Query(typeDefRequest);
foreach (var result in typeDefsResult.Results)
{
// Process your work items
}
If you grab the latest release of the .Net Rest Api the documentation has been extensively updated including code examples.

Unable to query a different workspace

I was trying to follow this post to query a testcase in a workspace("/workspace/6749437088") that is not the default workspace but the query is not returning that testcase and in fact, not returning anything. Below is the code I am using. If I do a query with 'not equal' the test cases, I notice that it is returning test cases in the user's default workspace. I am using C# and using Rally Rest API Runtime v4.0.30319 and ver 1.0.15.0. Any suggestions? Thanks.
Inserting test case result using Java Rally Rest API failing when workspace is different from default set on account
private string GetRallyObj_Ref(string ObjFormttedId)
{
string tcref = string.Empty;
try
{
string reqType = _Helper.GetRallyRequestType(ObjFormttedId.Substring(0, 2).ToLower());
Request request = new Request(reqType);
request.Workspace = "/workspace/6749437088";
request.Fetch = new List<string>()
{
//Here other fields can be retrieved
"Workspace",
"Name",
"FormattedID",
"ObjectID"
};
//request.Project = null;
string test = request.Workspace;
request.Query = new Query("FormattedID", Query.Operator.Equals, ObjFormttedId);
QueryResult qr = _RallyApi.Query(request);
string objectid= string.Empty;
foreach (var rslt in qr.Results)
{
objectid = rslt.ObjectID.ToString();
break;
}
tcref = "/"+reqType+"/" + objectid;
}
catch (Exception ex)
{
throw ex;
}
return tcref;
Sorry, I found out the issue. I was feeding the code a project ref#, not a workspace ref #. I found out the correct workspace by using pieces of the code in the answer part of this post: Failed when query users in workspace via Rally Rest .net api by querying the workspace refs of the username I am using and there I found out the correct workspace ref. Thanks, Kyle anyway.
The code above seems like it should work. This may be a defect- I'll look into that. In the meantime if you are just trying to read a specific object from Rally by Object ID you should be able to do so like this:
restApi.GetByReference('/testcase/12345',
'Results, 'Verdict', 'Duration' //fetch fields);

How to create a Task belonging to an Iteration using Rally Api and .NET

I am new to the Rally API and just having some trouble creating a Task using the Rally.RestApi library. I need to create a Task (using .NET) and associate it with a User Story (in which the User Story belongs to a certain Iteration).
Do I have to get the User Story first, then add a Task to it? How would I do that?
Thanks.
All objects in Rally have a unique url called a ref.
You just need the story's ref to associate the two:
RallyRestApi restApi = new RallyRestApi("myuser#company.com", "password",
"https://rally1.rallydev.com", "1.27");
DynamicJsonObject newTask = new DynamicJsonObject();
newTask["Name"] = "My New Task";
newTask["WorkProduct"] = "/hierarchicalrequirement/12345"; //your story ref here
CreateResult createResult = restApi.Create("task", newTask);