Update TFS Web with a Python script - json

How can I update a certain field in tfs web with Python?
I have connected to tfs and have received an HTML response.
I have a json with the data that I would like to insert to tfs testCases field.
JSON:
data = json.loads(url.read().decode()) (Json external data)
HTML:
tfsResponse = requests.get(tfsApi, auth=HttpNtlmAuth(username, password))
if tfsResponse.ok:
print(tfsResponse)
soup = BeautifulSoup(tfsResponse.text, 'lxml')
How can I do it?

It's not able to directly use Jenkins automation tests results to update TFS test case.
You need use Rest API to handle this. You need to extract the test results fist then update them to TFS server.
With using below Rest API:
PATCH https://dev.azure.com/{organization}/{project}/_apis/test/Runs/{runId}/results?api-version=5.1
Sample body
[
{
"state": "Completed",
"testPoint": {
"id": 10
},
"outcome": "Passed",
"testCase": {
"id": 4567
}
}
]
If you want to use code, a code snippet for your reference, should similar to Python:
try
{
var u = new Uri("https://{My Account}.visualstudio.com");
VssCredentials c = new VssCredentials(new Microsoft.VisualStudio.Services.Common.VssBasicCredential(string.Empty, "PAT"));
var connection = new VssConnection(u, c);
var testClient = connection.GetClient<TestManagementHttpClient>();
int testpointid = 1;
string teamProject = "MyProjectName";
RunCreateModel run = new RunCreateModel(name: "TestCase Name", plan: new Microsoft.TeamFoundation.TestManagement.WebApi.ShallowReference("TestPlan Id"), pointIds: new int[] { testpointid });
TestRun testrun = testClient.CreateTestRunAsync(run, teamProject).Result;
TestCaseResult caseResult = new TestCaseResult() { State = "Completed", Outcome = "passed", Id = 100000 };
var testResults = testClient.UpdateTestResultsAsync(new TestCaseResult[] { caseResult }, teamProject, testrun.Id).Result;
RunUpdateModel runmodel = new RunUpdateModel(state: "Completed");
TestRun testRunResult = testClient.UpdateTestRunAsync(runmodel, teamProject, testrun.Id, runmodel).Result;
}
catch (AggregateException e)
{
Console.WriteLine(e.InnerException.Message);
}

Related

Error while linking Cloud Revit file using ExternalResourceReference - The ExternalResourceReference is not in a format that's supported by its server

I would like to link a cloud model into another Revit Model for Revit 2021 and below. After lots of exploration, one of my colleague was able to use ExternalResourceReference to successfully link the model for one of the project in Revit 2020(below is the code). But when I try to use the same code in a Revit 2021 project I'm receiving the following error:
The ExternalResourceReference (resourceReference) is not in a format that is supported by its server
var linkCloudPath = doc.GetCloudModelPath(); // the cloudpath of a BIM360 model
Guid linkedmodelguid = linkCloudPath.GetModelGUID();
Guid linkedprojectguid = linkCloudPath.GetProjectGUID();
Dictionary<string, string> Dictionary_ExternalResource = new Dictionary<string, string>(){
{"LinkedModelModelId", modelGuid.ToString()},
{"LinkedModelProjectId", projGuid.ToString()}
};
Dictionary<string, Guid> servers = new Dictionary<string, Guid>();
foreach (var service in ExternalServiceRegistry.GetServices())
{
if (service.Name == "External Resource Service")
{
IList<Guid> server_ids = service.GetRegisteredServerIds();
foreach (var server_id in server_ids)
{
servers.Add(service.GetServer(server_id).GetName(), server_id);
}
}
}
Guid BIM360ServerID = servers["BIM 360"];
ExternalResourceReference ERS = new ExternalResourceReference(BIM360ServerID, Dictionary_ExternalResource, "", "");
RevitLinkOptions options = new RevitLinkOptions(false);
LinkLoadResult result = RevitLinkType.Create(gcdoc, ERS, options); // error in this line
RevitLinkInstance.Create(gcdoc, result.ElementId);
There is no change in the code anywhere between 2020 & 2021.
I recommend to check ExternalResourceReference by calling RevitLinkType.GetExternalResourceReferences() from the link type, which has been set to BIM 360 model, so that you can get all information required.
With my testing, the below format was returned. ServerId can be used from getting ExternalServiceRegistry.GetServices() int the same manner you have tried.
{
"ServerId": "XXXXX",
"ReferenceInformation": {
"ForgeDmItemUrn": "urn:adsk.wipprod:dm.lineage:XXXXX",
"ForgeDmProjectId": "b.XXXXX",
"LinkedModelModelId": "XXXXX",
"LinkedModelProjectId": "XXXXX",
"LinkedModelRegion": "US"
},
"Version": "",
"InSessionPath": "BIM 360://XXXXX"
}
Please note that there may have been some special-casing for cloud links.
Turns out that I just needed to add region the dictionary Dictionary_ExternalResource
Dictionary<string, string> Dictionary_ExternalResource = new Dictionary<string, string>(){
{"LinkedModelRegion","US" }, // added this line
{"LinkedModelModelId", modelGuid},
{"LinkedModelProjectId", projGuid}
};

Schema Extension Value is always NULL when updating through Microsoft Graph SDK

Step 1:
Created GraphServiceClient using Microsoft.Graph 4.9.0 and Microsoft.Graph.Core 2.0.5 SDK
var scopes = new[] { "https://graph.microsoft.com/.default" };
ClientSecretCredential clientSecretCredential = new ClientSecretCredential(tenantId, clientId, clientSecret, new ClientSecretCredentialOptions()
{
AuthorityHost = AzureAuthorityHosts.AzurePublicCloud
});`
GraphServiceClient graphServiceClient = new GraphServiceClient(clientSecretCredential, scopes);
Step 2:
And created a custom schema extension like below.
SchemaExtension schemaExtension = new SchemaExtension()
{
Id = "data1",
Description = "creating test schema extn",
TargetTypes = new List<string>()
{
"User"
},
Properties = new List<ExtensionSchemaProperty>()
{
new ExtensionSchemaProperty()
{
Name ="prop1",
Type ="String"
}
}
};
Step 3:
Updated the Schema extension status to "Available"
var updatedExtn = await graphServiceClient
.SchemaExtensions[schemaExtension.Id].Request()
.UpdateAsync(new SchemaExtension()
{
Status = "Available"
});
Step 4:
Create Class for extension data
public class data1
{
// You must serialize your property names to camelCase if your SchemaExtension describes as such.
[JsonProperty(NullValueHandling = NullValueHandling.Ignore, PropertyName = "prop1", Required = Newtonsoft.Json.Required.Default)]
public string Prop1 { get; set; }
}
Step 5:
Find the User and add the created schema extension to the user
IDictionary<string, object> extensionInstance = new Dictionary<string, object>();
// The below line is not working. but doesn't throw error
extensionInstance.Add(schemaExtension.Id, new data1 { prop1 = "testing" });
var usrCollection = await graphServiceClient.Users
.Request()
.Filter($"userPrincipalNames eq '{adelev_Mail}'")
.GetAsync();
var usr = usrCollection.FirstOrDefault();
if(usr != null)
{
usr.AdditionalData.Add(extensionInstance);
var updatedUser = await graphServiceClient.Users[usr.Id]
.Request()
.UpdateAsync(usr);
}
Step 6:
When you try to retrieve the extension the value is NULL.
User updatedUser = await graphServiceClient.Users[usr.Id].Request()
.Select($"id, {schemaExtension.Id}")
.GetAsync();
But it works with API using Graph Explorer.
PATCH https://graph.microsoft.com/v1.0/users/{userId}
{
"extXXXXXXXX_data1":
{
"prop1" : "testing"
}
}
Please let me know if I'm missing anything here. Any help here is much appreciated.
You should accessing the data on AdditionalData property. Try looking at user.AdditionalData in your result. Here is a screenshot with my example.
Getting User with Schema extension from Graph explorer.
While using the SDK, i access my custom data in user.AdditionalData
Check this thread - Graph SDK and SchemaExtensions for details.

How do I post multiline message using Teams Webhooks?

I have a webhook setup to post a message to one of our Teams Team channels. I'm using one of the teams webhook examples given here: https://learn.microsoft.com/en-us/microsoftteams/platform/task-modules-and-cards/cards/cards-reference#hero-card .
The problem I have is that I am unable to display multiple lines. In the example below, I'd like to separate out 'Test1' and 'Test2' on separate lines. However, using \n or \n in the JSON didn't translate to multi line format in Teams. Screenshot outcome attached below.
"type": "message",
"attachments": [
{
"contentType": "application/vnd.microsoft.card.hero",
"content": {
"title": "Alerts",
"text": "*Test1 \n *Test\n",
"buttons": [
{
"type": "openUrl",
"title": "Open in SumoLogic",
"value": ""
}
]
}
}
]
}
What is the way to send a multi-line message to Teams using webhook? Any guidance here is appreciated.
Please try using \n\n and check.
I know this is an old post, but if anyone still needs this you can use AdaptiveCards
$ using AdaptiveCards;
AdaptiveCard card = new AdaptiveCard("1.5");
card.AdditionalProperties.Add("$schema", "http://adaptivecards.io/schemas/adaptive-card.json");
var msTeamsWidthOption = new { width = "Full" };
card.AdditionalProperties.Add("msteams", msTeamsWidthOption);
AdaptiveTextBlock titleBlock = new AdaptiveTextBlock
{
Size = AdaptiveTextSize.Large,
Weight = AdaptiveTextWeight.Bolder,
Wrap = true,
Text = title
};
AdaptiveTextBlock messageBlock = new AdaptiveTextBlock
{
Wrap = true,
Text = message
};
card.Body.Add(titleBlock);
card.Body.Add(messageBlock);
AdaptiveCardWrapper adaptiveCardWrapper = new AdaptiveCardWrapper
{
attachments = new List<Attachments> { new Attachments { content = card} }
};
var address = Environment.GetEnvironmentVariable("WebhookUrl");
var content = new StringContent(JsonConvert.SerializeObject(adaptiveCardWrapper), Encoding.UTF8, "application/json");
var response = await _httpClient.PostAsync(address, content);
You can use line breaks within a string with "Wrap = true", or you can add multiple cards to a single message. Or both.
https://learn.microsoft.com/en-us/microsoftteams/platform/webhooks-and-connectors/how-to/connectors-using?tabs=cURL#send-adaptive-cards-using-an-incoming-webhook

JSON.Lua json.encode return nil

I'm new to LUA and tried learning coding this language with Garrys Mod.
I want to get the messages from the Garrys Mod chat and send them into a Discord channel with a webhook.
It works, but I tried expanding this project with embeded messages. I need JSON for this and used json.lua as a library.
But as soon as I send a message I retrieve the following error message:
attempt to index global 'json' (a nil value)
The code that causes the error is the following:
json.encode({ {
["embeds"] = {
["description"] = text,
["author"] = {
["name"] = ply:Nick()
},
},
} }),
The complete code:
AddCSLuaFile()
json = require("json")
webhookURL = "https://discordapp.com/api/webhooks/XXX"
local DiscordWebhook = DiscordWebhook or {}
hook.Add( "PlayerSay", "SendMsg", function( ply, text )
t_post = {
content = json.encode({ {
["embeds"] = {
["description"] = text,
["author"] = {
["name"] = ply:Nick()
},
},
} }),
username = "Log",
}
http.Post(webhookURL, t_post)
end )
I hope somebody can help me
Garry's Mod does provide two functions to work with json.
They are:
util.TableToJSON( table table, boolean prettyPrint=false )
and
util.JSONToTable( string json )
There is no need to import json and if I recall correctly it isn't even possible.
For what you want to do you need to build your arguments as a table like this:
local arguments = {
["key"] = "Some value",
["42"] = "Not always the answer",
["deeper"] = {
["my_age"] = 22,
["my_name"] = getMyName()
},
["even more"] = from_some_variable
and then call
local args_as_json = util.TableToJSON(arguments)
Now you can pass args_as_json to your
http.Post( string url, table parameters, function onSuccess=nil, function onFailure=nil, table headers={} )

remove duplicate entries while executing repeated job to save json data in mongo

I am having following structure currently present in my database, i am executing a service to fetch data from REST api and storing it to my database , so that i can use it to display it frequently on UI as like caching a data
db.countDetails.find().pretty()
{
"_id" : ObjectId("5670xxxx"),
"totalProjectCount" : 53,
"activeProjectCount" : 29,
"completedProjectCount" : 1,
"userCount" : 85
}
{
"_id" : ObjectId("5670ea97f14c717a903e8423"),
"totalProjectCount" : 48,
"activeProjectCount" : 41,
"completedProjectCount" : 0,
"userCount" : 123
}
My collection is going to remain same only values will be going to change, so please suggest me a way in which i can place the updated values in mongo and at the same time i can fetch data on my UI
my new values might be like
db.countDetails.find().pretty()
{
"_id" : ObjectId("5670xxxx"),
"totalProjectCount" : 23,
"activeProjectCount" : 17,
"completedProjectCount" : 1,
"userCount" : 60
}
{
"_id" : ObjectId("5670ea97f14c717a903e8423"),
"totalProjectCount" : 45,
"activeProjectCount" : 40,
"completedProjectCount" : 0,
"userCount" : 113
}
function to fetch data from REST api
def getCount(String companyName, String apiKey) {
//declaration section
List returnList = []
int totalProjectCount = 0 //variable to hold total no of projects value
int activeProjectCount = 0 //variable to hold total active projects value
int completedProjectCount = 0 //variable to hold total completed projects value
int userCount = 0 //variable to hold total active user count
String userAPIKey = apiKey //user API key for authorization
String method = 'GET' //method of request
String totalProjectURL = "https://"+ companyName + ".teamwork.com/projects.json?status=ALL" // Url to access All projects
StringBuilder out = getConnection(totalProjectURL, method, userAPIKey) //String builder to hold result
//catching result into json
JSONObject object = new JSONObject(out.toString()) //JSON object to store String in json format
totalProjectCount = object.projects.length()
String activeProjectCountURL = "https://"+ companyName + ".teamwork.com/projects.json?status=ACTIVE" // Url to access Active projects
out = getConnection(activeProjectCountURL, method, userAPIKey)
//catching result into json
object = new JSONObject(out.toString())
activeProjectCount = object.projects.length()
String completedProjectCountURL = "https://"+ companyName + ".teamwork.com/projects.json?status=COMPLETED" // Url to access completed projects
out = getConnection(completedProjectCountURL, method, userAPIKey)
//catching result into json
object = new JSONObject(out.toString())
completedProjectCount = object.projects.length()
String peopleURL = "https://"+ companyName + ".teamwork.com/people.json" // Url to access total active users
out = getConnection(peopleURL, method, userAPIKey)
//catching result into json
object = new JSONObject(out.toString())
userCount = object.people.length()
Map returnMap = [:]
returnMap.put('totalProjectCount', totalProjectCount)
returnMap.put('activeProjectCount', activeProjectCount)
returnMap.put('completedProjectCount', completedProjectCount)
returnMap.put('userCount', userCount)
addCount(returnMap, 'curo', 'countDetails')
println('project count successfully saved.')
}
function to add countDetails to mongo
def addCount(Map userMap, String dbName, String collectionName) {
try {
DB db = mongo.getDB(dbName)
DBCollection table = db.getCollection(collectionName)
table.insert(userMap as BasicDBObject)
def srvcResponseObj = [ responseStatus : "pass", responseCode : 200 ]
return srvcResponseObj
}
catch (Exception e)
{
println "Exception related to Mongo add record"
e.printStackTrace()
def srvcResponseObj = [ responseStatus : "fail", responseCode: 400 ]
return srvcResponseObj
}
}
function to fetch data from mongo
def fetchCountDetails(String databaseName, String collectionName) {
println 'inside fetch count details'
try {
DB db = mongo.getDB(databaseName)
DBCollection table = db.getCollection(collectionName)
DBCursor cursor = table.find()
Map returnCountMap = [:]
List temp = []
int cursorCounter = 0
while(cursor.hasNext()) {
Map temporaryMap = [:]
BasicDBObject doc = (BasicDBObject) cursor.next()
doc.remove('_id')
temp.add(doc)
cursorCounter++
}
returnCountMap.put('totalProjectCount', temp.totalProjectCount.sum())
returnCountMap.put('activeProjectCount',temp.activeProjectCount.sum())
returnCountMap.put('completedProjectCount',temp.completedProjectCount.sum())
returnCountMap.put('userCount',temp.userCount.sum())
if(cursorCounter>1)
println "Multiple objects found for eventID"
if(cursorCounter==0)
println "No objects found for eventID"
return returnCountMap
}
catch (Exception e)
{
println "Exception related to Mongo >> fetchUserDetails"
e.printStackTrace()
def srvcResponseObj = [ responseStatus : "fail", responseCode: 400 ]
return srvcResponseObj
}
}
now i am making request to REST api after fixed amount of interval and my response gets changed in terms of values, but if i call the add function again and again my documents get duplicated in mongodb and my expected result is that my new values gets reflected in mongodb