internal static WorkItemRequest Parse(JObject payload) { var result = new WorkItemRequest(); try { if (payload.Property("eventType") == null) { result.Error = $"Could not determine event type for message: {payload}"; } else { result.EventType = (string)payload["eventType"]; result.EventId = (string)payload["id"]; // TODO in the future we will use also the Organization level if (payload.Property("resourceContainers") == null) { // bloody Test button result.Error = $"Test button generates bad messages: do not use with this service."; } else { // VSTS sprint 100 or so introduced the Account, but TFS 2015.3 stil lacks it if (payload.SelectToken("resourceContainers.account") != null) { result.AccountId = (string)payload["resourceContainers"]["account"]["id"]; } } if (payload.Property("resourceVersion") == null) { result.Error = $"Missing resourceVersion data."; } else { result.SchemaVersion = (string)payload["resourceVersion"]; if (result.SchemaVersion != "1.0") { result.Error = $"Unsupported resourceVersion '{result.SchemaVersion}'."; } } result.CollectionId = (string)payload["resourceContainers"]["collection"]["id"]; result.TfsCollectionUri = (string)payload["resourceContainers"]["collection"]["baseUrl"]; result.ProjectId = (string)payload["resourceContainers"]["project"]["id"]; result.TeamProjectUri = (string)payload["resourceContainers"]["project"]["baseUrl"]; // not always true... result.WorkItemId = (int)payload["resource"]["id"]; /* TODO * ["resource"]["fields"]["System.TeamProject"] * rules out using 'Minimal' for 'Resource detail to send' * search a solution!!! */ switch (result.EventType) { case "workitem.created": result.ChangeType = Core.Interfaces.ChangeTypes.New; if (payload.SelectToken("resource.fields") != null) { // this requires an ALL payload result.TeamProject = (string)payload["resource"]["fields"]["System.TeamProject"]; } else { result.Error = $"TFS Aggregator requires 'All' for 'Resource details to send'."; } break; case "workitem.updated": result.ChangeType = Core.Interfaces.ChangeTypes.Change; result.WorkItemId = (int)payload["resource"]["workItemId"]; if (payload.SelectToken("resource.revision.fields") != null) { // this requires an ALL payload result.TeamProject = (string)payload["resource"]["revision"]["fields"]["System.TeamProject"]; } else { result.Error = $"TFS Aggregator requires 'All' for 'Resource details to send'."; } break; case "workitem.restored": result.ChangeType = Core.Interfaces.ChangeTypes.Restore; if (payload.SelectToken("resource.fields") != null) { // this requires an ALL payload result.TeamProject = (string)payload["resource"]["fields"]["System.TeamProject"]; } else { result.Error = $"TFS Aggregator requires 'All' for 'Resource details to send'."; } break; case "workitem.deleted": result.ChangeType = Core.Interfaces.ChangeTypes.Delete; if (payload.SelectToken("resource.fields") != null) { // this requires an ALL payload result.TeamProject = (string)payload["resource"]["fields"]["System.TeamProject"]; } else { result.Error = $"TFS Aggregator requires 'All' for 'Resource details to send'."; } break; //TODO case "workitem.comment": default: result.Error = $"Unsupported eventType {result.EventType}"; break; } //switch } //if } catch (Exception e) { if (string.IsNullOrEmpty(result.Error)) { result.Error = $"Failed to parse incoming notification from TFS/VSTS. {e.Message}"; } } return(result); }
static internal WorkItemRequest Parse(JObject payload) { var result = new WorkItemRequest(); if (payload.Property("eventType") == null) { result.Error = $"Could not determine event type for message: {payload}"; } else { result.EventType = (string)payload["eventType"]; result.EventId = (string)payload["id"]; // TODO in the future we will use also the Organization level if (payload.Property("resourceContainers") == null) { // bloody Test button result.Error = $"Test button generates bad messages: do not use with this service."; } else { // VSTS sprint 100 or so introduced the Account, but TFS 2015.3 stil lacks it if (payload.SelectToken("resourceContainers.account") == null) { result.CollectionId = (string)payload["resourceContainers"]["collection"]["id"]; } else { result.AccountId = (string)payload["resourceContainers"]["account"]["id"]; } } string fullUrl = (string)payload["resource"]["url"]; result.TfsCollectionUri = fullUrl.Substring(0, fullUrl.IndexOf("_apis")); switch (result.EventType) { case "workitem.created": result.WorkItemId = (int)payload["resource"]["id"]; result.TeamProject = (string)payload["resource"]["fields"]["System.TeamProject"]; result.ChangeType = Core.Interfaces.ChangeTypes.New; break; case "workitem.updated": result.WorkItemId = (int)payload["resource"]["workItemId"]; result.TeamProject = (string)payload["resource"]["revision"]["fields"]["System.TeamProject"]; result.ChangeType = Core.Interfaces.ChangeTypes.Change; break; case "workitem.restored": result.WorkItemId = (int)payload["resource"]["id"]; result.TeamProject = (string)payload["resource"]["fields"]["System.TeamProject"]; result.ChangeType = Core.Interfaces.ChangeTypes.Restore; break; case "workitem.deleted": result.WorkItemId = (int)payload["resource"]["id"]; result.TeamProject = (string)payload["resource"]["fields"]["System.TeamProject"]; result.ChangeType = Core.Interfaces.ChangeTypes.Delete; break; default: result.Error = $"Unsupported eventType {result.EventType}"; break; } //switch } //if return(result); }