public static WorkItem UpdateWorkItemFields(int WIId, Dictionary <string, object> Fields)
 {
     try
     {
         JsonPatchDocument patchDocument = new JsonPatchDocument();
         foreach (var key in Fields.Keys)
         {
             JsonPatchOperation Jsonpatch = new JsonPatchOperation()
             {
                 Operation = Operation.Replace,
                 Path      = "/fields/" + key,
                 Value     = Fields[key]
             };
             if (!patchDocument.Contains(Jsonpatch))
             {
                 patchDocument.Add(Jsonpatch);
             }
         }
         if (patchDocument.Count != 0)
         {
             return(WitClient.UpdateWorkItemAsync(patchDocument, WIId).Result);
         }
         else
         {
             return(null);
         }
     }
     catch (Exception E)
     {
         throw (E);
     }
 }
        /// <summary>
        /// Validates the path for the operation.
        /// </summary>
        protected static void ValidatePath(JsonPatchOperation operation)
        {
            // Path cannot be null, but it can be empty.
            if (operation.Path == null)
            {
                throw new VssPropertyValidationException("Path", PatchResources.PathCannotBeNull());
            }

            // If it is not empty and does not start with /, this is an error per RFC.
            if (!operation.Path.StartsWith(PathSeparator) && !string.IsNullOrEmpty(operation.Path))
            {
                throw new VssPropertyValidationException("Path", PatchResources.PathInvalidStartValue());
            }

            // Ending in / is not valid..
            if (operation.Path.EndsWith(PathSeparator))
            {
                throw new VssPropertyValidationException("Path", PatchResources.PathInvalidEndValue());
            }

            // Only add operations allow insert.
            if (operation.Operation != Operation.Add)
            {
                if (operation.Path.EndsWith(EndOfIndex))
                {
                    throw new VssPropertyValidationException("Path", PatchResources.InsertNotSupported(operation.Operation));
                }
            }
        }
        private WitBatchRequest GenerateWitBatchRequestFromWorkItem(WorkItem sourceWorkItem)
        {
            Dictionary <string, string> headers = new Dictionary <string, string>();

            headers.Add("Content-Type", "application/json-patch+json");

            JsonPatchDocument jsonPatchDocument = CreateJsonPatchDocumentFromWorkItemFields(sourceWorkItem);

            JsonPatchOperation insertIdAddOperation = GetInsertBatchIdAddOperation();

            jsonPatchDocument.Add(insertIdAddOperation);

            // add hyperlink to source WorkItem
            string             sourceWorkItemApiEndpoint = ClientHelpers.GetWorkItemApiEndpoint(this.migrationContext.Config.SourceConnection.Account, sourceWorkItem.Id.Value);
            JsonPatchOperation addHyperlinkAddOperation  = MigrationHelpers.GetHyperlinkAddOperation(sourceWorkItemApiEndpoint, sourceWorkItem.Rev.ToString());

            jsonPatchDocument.Add(addHyperlinkAddOperation);

            string json = JsonConvert.SerializeObject(jsonPatchDocument);

            string workItemType = jsonPatchDocument.Find(a => a.Path.Contains(FieldNames.WorkItemType)).Value as string;

            var witBatchRequest = new WitBatchRequest();

            witBatchRequest.Method  = "PATCH";
            witBatchRequest.Headers = headers;
            witBatchRequest.Uri     = $"/{this.migrationContext.Config.TargetConnection.Project}/_apis/wit/workItems/${workItemType}?{this.QueryString}";
            witBatchRequest.Body    = json;

            return(witBatchRequest);
        }
        public static PatchOperation <TModel> CreateFromJson(JsonPatchOperation operation)
        {
            if (operation != null)
            {
                switch (operation.Operation)
                {
                case Operation.Add:
                    return(AddPatchOperation <TModel> .CreateFromJson(operation));

                case Operation.Replace:
                    return(ReplacePatchOperation <TModel> .CreateFromJson(operation));

                case Operation.Test:
                    return(TestPatchOperation <TModel> .CreateFromJson(operation));

                case Operation.Remove:
                    return(RemovePatchOperation <TModel> .CreateFromJson(operation));

                default:
                    throw new PatchOperationFailedException(PatchResources.MoveCopyNotImplemented());
                }
            }

            throw new VssPropertyValidationException("Operation", PatchResources.InvalidOperation());
        }
        private void WorkItemTypeChange(MigrationTools._EngineV1.DataContracts.WorkItemData targetWorkItem, bool skipToFinalRevisedWorkItemType, string finalDestType, MigrationTools._EngineV1.DataContracts.RevisionItem revision, MigrationTools._EngineV1.DataContracts.WorkItemData currentRevisionWorkItem, string destType)
        {
            //If the work item already exists and its type has changed, update its type. Done this way because there doesn't appear to be a way to do this through the store.
            if (!skipToFinalRevisedWorkItemType && targetWorkItem.Type != finalDestType)

            {
                Debug.WriteLine($"Work Item type change! '{targetWorkItem.Title}': From {targetWorkItem.Type} to {destType}");
                var typePatch = new JsonPatchOperation()
                {
                    Operation = Microsoft.VisualStudio.Services.WebApi.Patch.Operation.Add,
                    Path      = "/fields/System.WorkItemType",
                    Value     = destType
                };
                var datePatch = new JsonPatchOperation()
                {
                    Operation = Microsoft.VisualStudio.Services.WebApi.Patch.Operation.Add,
                    Path      = "/fields/System.ChangedDate",
                    Value     = currentRevisionWorkItem.ToWorkItem().Revisions[revision.Index].Fields["System.ChangedDate"].Value
                };

                var patchDoc = new JsonPatchDocument
                {
                    typePatch,
                    datePatch
                };
                _witClient.UpdateWorkItemAsync(patchDoc, int.Parse(targetWorkItem.Id), bypassRules: true).Wait();
            }
        }
        public override void WriteJson(JsonWriter writer, JsonPatchOperation value, JsonSerializer serializer)
        {
            JToken t = JToken.FromObject(value);

            if (t.Type != JTokenType.Object)
            {
                t.WriteTo(writer);
            }
            else
            {
                writer.WriteStartObject();
                writer.WritePropertyName("op");
                writer.WriteValue(value.Operation.ToString().ToLower());
                writer.WritePropertyName("path");
                writer.WriteValue(value.Path);
                if (!string.IsNullOrEmpty(value.From))
                {
                    writer.WritePropertyName("from");
                    writer.WriteValue(value.From);
                }
                writer.WritePropertyName("value");
                t = JToken.FromObject(value.Value);
                t.WriteTo(writer);
                writer.WriteEndObject();
            }
        }
Beispiel #7
0
        private JsonPatchOperation GetAddHyperlinkWithCommentOperation(IList <WorkItem> targetWorkItems, WorkItemMigrationState state, int sourceId, int targetId, WorkItem sourceWorkItem, ISet <string> enabledPhaseStatuses)
        {
            IList <WorkItemRelation> targetRelations = targetWorkItems.First(a => a.Id == targetId).Relations;

            foreach (WorkItemRelation targetRelation in targetRelations)
            {
                if (RelationHelpers.IsRelationHyperlinkToSourceWorkItem(context, targetRelation, sourceId))
                {
                    string hyperlink = context.WorkItemIdsUris[sourceId];

                    // only store the enabled phase statuses
                    RevAndPhaseStatus newRevAndPhaseStatus = new RevAndPhaseStatus();
                    newRevAndPhaseStatus.Rev         = sourceWorkItem.Rev.Value;
                    newRevAndPhaseStatus.PhaseStatus = enabledPhaseStatuses;
                    state.RevAndPhaseStatus          = newRevAndPhaseStatus;

                    // get the key even if its letter case is different but it matches otherwise
                    string idKeyFromFields = targetRelation.Attributes.GetKeyIgnoringCase(Constants.RelationAttributeId);
                    object attributeId     = targetRelation.Attributes[idKeyFromFields];

                    JsonPatchOperation addHyperlinkWithCommentOperation = MigrationHelpers.GetHyperlinkAddOperation(hyperlink, newRevAndPhaseStatus.GetCommentRepresentation(), attributeId);
                    return(addHyperlinkWithCommentOperation);
                }
            }

            throw new Exception($"Could not find hyperlink to source work item on target work item with id: {targetId}. Expected source work item id: {sourceId}");
        }
        private WitBatchRequest GenerateWitBatchRequestFromWorkItem(WorkItem sourceWorkItem, int targetId)
        {
            Dictionary <string, string> headers = new Dictionary <string, string>();

            headers.Add("Content-Type", "application/json-patch+json");

            JsonPatchDocument jsonPatchDocument = CreateJsonPatchDocumentFromWorkItemFields(sourceWorkItem);

            string hyperlink   = this.migrationContext.WorkItemIdsUris[sourceWorkItem.Id.Value];
            object attributeId = migrationContext.TargetIdToSourceHyperlinkAttributeId[targetId];

            JsonPatchOperation addHyperlinkWithCommentOperation = MigrationHelpers.GetHyperlinkAddOperation(hyperlink, sourceWorkItem.Rev.ToString(), attributeId);

            jsonPatchDocument.Add(addHyperlinkWithCommentOperation);

            string json            = JsonConvert.SerializeObject(jsonPatchDocument);
            var    witBatchRequest = new WitBatchRequest();

            witBatchRequest.Method  = "PATCH";
            witBatchRequest.Headers = headers;
            witBatchRequest.Uri     = $"/_apis/wit/workItems/{targetId}?{this.QueryString}";
            witBatchRequest.Body    = json;

            return(witBatchRequest);
        }
Beispiel #9
0
        public async Task <IEnumerable <JsonPatchOperation> > Process(IMigrationContext migrationContext, IBatchMigrationContext batchContext, WorkItem sourceWorkItem, WorkItem targetWorkItem)
        {
            IList <JsonPatchOperation> jsonPatchOperations = new List <JsonPatchOperation>();

            if (sourceWorkItem.Relations == null)
            {
                return(jsonPatchOperations);
            }

            IList <WorkItemRelation> sourceWorkItemLinkRelations = GetWorkItemLinkRelations(migrationContext, sourceWorkItem.Relations);

            if (sourceWorkItemLinkRelations.Any())
            {
                foreach (WorkItemRelation sourceWorkItemLinkRelation in sourceWorkItemLinkRelations)
                {
                    int linkedSourceId   = ClientHelpers.GetWorkItemIdFromApiEndpoint(sourceWorkItemLinkRelation.Url);
                    int targetWorkItemId = targetWorkItem.Id.Value;
                    int linkedTargetId;

                    if (!migrationContext.SourceToTargetIds.TryGetValue(linkedSourceId, out linkedTargetId))
                    {
                        continue;
                    }

                    string       comment         = MigrationHelpers.GetCommentFromAttributes(sourceWorkItemLinkRelation);
                    WorkItemLink newWorkItemLink = new WorkItemLink(linkedTargetId, sourceWorkItemLinkRelation.Rel, false, false, comment, 0);

                    JsonPatchOperation workItemLinkAddOperation = MigrationHelpers.GetWorkItemLinkAddOperation(migrationContext, newWorkItemLink);
                    jsonPatchOperations.Add(workItemLinkAddOperation);
                }
            }

            return(jsonPatchOperations);
        }
 private static void _CheckProperty(this object obj, JsonPatchOperation operation, string propertyName, List <string> errors)
 {
     if (obj != null)
     {
         return;
     }
     errors.Add($"Operation '{operation}' requires a {propertyName}.");
 }
Beispiel #11
0
        /// <summary>
        /// Removes the specified path.
        /// </summary>
        /// <param name="patchDoc">The patch document.</param>
        /// <param name="path">The path.</param>
        public static void Remove(this JsonPatchDocument patchDoc, string path)
        {
            var patch = new JsonPatchOperation {
                Operation = Operation.Remove, Path = JsonHelpers.SanitizePath(path)
            };

            patchDoc.Add(patch);
        }
Beispiel #12
0
        public async Task <IEnumerable <JsonPatchOperation> > Process(IMigrationContext migrationContext, IBatchMigrationContext batchContext, WorkItem sourceWorkItem, WorkItem targetWorkItem)
        {
            IList <JsonPatchOperation> jsonPatchOperations     = new List <JsonPatchOperation>();
            JsonPatchOperation         addPostMoveTagOperation = AddPostMoveTag(migrationContext, sourceWorkItem);

            jsonPatchOperations.Add(addPostMoveTagOperation);
            return(jsonPatchOperations);
        }
Beispiel #13
0
        /// <param name="data">JSON-formatted data</param>
        public JsonPatch BuildJsonPatch(JsonPatchOperation operation, string data, string path)
        {
            var jsonPatch = new JsonPatch(operation, path)
            {
                Data = data
            };

            return(jsonPatch);
        }
Beispiel #14
0
        public static JsonPatchOperation GetRelationRemoveOperation(int existingRelationIndex)
        {
            JsonPatchOperation jsonPatchOperation = new JsonPatchOperation();

            jsonPatchOperation.Operation = Operation.Remove;
            jsonPatchOperation.Path      = $"/{Constants.Relations}/{existingRelationIndex}";

            return(jsonPatchOperation);
        }
Beispiel #15
0
        internal JsonPatchDocument CreatePatchDocument()
        {
            var result = new JsonPatchDocument();

            var keys = _fieldValues.Keys.ToList();

            if (_initialFieldValues != null)
            {
                keys = keys.Union(_initialFieldValues.Keys).Distinct().OrderBy(_ => _).ToList();
            }

            keys.Remove(SystemField.WorkItemType);
            keys.Remove(SystemField.Project);

            foreach (var key in keys)
            {
                object initialValue = null;

                _initialFieldValues?.TryGetValue(key, out initialValue);
                var hasNewValue = _fieldValues.TryGetValue(key, out var value);

                if (initialValue == null && value != null)
                {
                    var operation = new JsonPatchOperation
                    {
                        Operation = Operation.Add,
                        Path      = $"/fields/{key}",
                        Value     = EncodeValueForJSonDocument(value)
                    };
                    result.Add(operation);
                }
                else if (hasNewValue)
                {
                    if (value == null)
                    {
                        var operation = new JsonPatchOperation
                        {
                            Operation = Operation.Remove,
                            Path      = $"/fields/{key}"
                        };
                        result.Add(operation);
                    }
                    else
                    {
                        var operation = new JsonPatchOperation
                        {
                            Operation = Operation.Replace,
                            Path      = $"/fields/{key}",
                            Value     = EncodeValueForJSonDocument(value)
                        };
                        result.Add(operation);
                    }
                }
            }
            return(result);
        }
Beispiel #16
0
 /// <summary>
 /// Better use JsonPatchManager for convenience.
 /// </summary>
 internal JsonPatch(JsonPatchOperation operation, string path)
 {
     this.Operation = operation;
     this.Path = path;
     _setMethod = SetMethod.None;
     if (operation == JsonPatchOperation.Remove)
     {
         this.Data = "null";
     }
 }
Beispiel #17
0
        public static JsonPatchOperation GetRelationAddOperation(WorkItemRelation relation)
        {
            JsonPatchOperation jsonPatchOperation = new JsonPatchOperation();

            jsonPatchOperation.Operation = Operation.Add;
            jsonPatchOperation.Path      = $"/{Constants.Relations}/-";
            jsonPatchOperation.Value     = relation;

            return(jsonPatchOperation);
        }
Beispiel #18
0
 /// <summary>
 /// Better use JsonPatchManager for convenience.
 /// </summary>
 internal JsonPatch(JsonPatchOperation operation, string path)
 {
     this.Operation = operation;
     this.Path      = path;
     _setMethod     = SetMethod.None;
     if (operation == JsonPatchOperation.Remove)
     {
         this.Data = "null";
     }
 }
Beispiel #19
0
        /// <summary>
        /// Replaces the specified path.
        /// </summary>
        /// <param name="patchDoc">The patch document.</param>
        /// <param name="path">The path.</param>
        /// <param name="value">The value.</param>
        public static void Replace(this JsonPatchDocument patchDoc, string path, object value)
        {
            var patch = new JsonPatchOperation
            {
                Operation = Operation.Replace,
                Path      = JsonHelpers.SanitizePath(path),
                Value     = value
            };

            patchDoc.Add(patch);
        }
Beispiel #20
0
        /// <summary>
        /// Adds the specified path.
        /// </summary>
        /// <param name="patchDoc">The patch document.</param>
        /// <param name="path">The path.</param>
        /// <param name="value">The value.</param>
        /// <returns>A JsonPatchDocument.</returns>
        public static JsonPatchDocument Add(this JsonPatchDocument patchDoc, string path, object value)
        {
            var patch = new JsonPatchOperation
            {
                Operation = Operation.Add, Path = JsonHelpers.SanitizePath(path), Value = value
            };

            patchDoc.Add(patch);

            return(patchDoc);
        }
        public static JsonPatchOperation AddLink(this JsonPatchDocument source, WorkItemRelation relation)
        {
            var op = new JsonPatchOperation()
            {
                Operation = Operation.Add, Path = "/relations/-", Value = relation
            };

            source.Add(op);

            return(op);
        }
        public static JsonPatchOperation UpdateField(this JsonPatchDocument source, string fieldName, object newValue)
        {
            var op = new JsonPatchOperation()
            {
                Operation = Operation.Replace, Path = ToFieldPath(fieldName), Value = newValue
            };

            source.Add(op);

            return(op);
        }
        /// <summary>
        /// Validates and returns the type for the operation.
        /// </summary>
        /// <param name="operation"></param>
        /// <returns></returns>
        protected static Type ValidateAndGetType(JsonPatchOperation operation)
        {
            var type = GetType(typeof(TModel), operation.Path);

            if (type == null)
            {
                throw new VssPropertyValidationException("Path", PatchResources.UnableToEvaluatePath(operation.Path));
            }

            return(type);
        }
Beispiel #24
0
        public async Task <IEnumerable <JsonPatchOperation> > Process(IMigrationContext migrationContext, IBatchMigrationContext batchContext, WorkItem sourceWorkItem, WorkItem targetWorkItem)
        {
            IList <JsonPatchOperation> jsonPatchOperations = new List <JsonPatchOperation>();
            AttachmentReference        aRef = await UploadAttachmentsToTarget(migrationContext, sourceWorkItem);

            JsonPatchOperation revisionHistoryAttachmentAddOperation = MigrationHelpers.GetRevisionHistoryAttachmentAddOperation(aRef, sourceWorkItem.Id.Value);

            jsonPatchOperations.Add(revisionHistoryAttachmentAddOperation);

            return(jsonPatchOperations); // We could just return one item, but we make an IList to be consistent
        }
Beispiel #25
0
        public static new PatchOperation <TModel> CreateFromJson(JsonPatchOperation operation)
        {
            ValidatePath(operation);
            ValidateType(operation);

            if (operation.Value != null)
            {
                throw new VssPropertyValidationException("Value", PatchResources.ValueNotNull());
            }

            return(new RemovePatchOperation <TModel>(operation.Path));
        }
Beispiel #26
0
        public async Task <IEnumerable <JsonPatchOperation> > Process(IMigrationContext migrationContext, IBatchMigrationContext batchContext, WorkItem sourceWorkItem, WorkItem targetWorkItem)
        {
            var jsonPatchOperations = new List <JsonPatchOperation>();
            var attachments         = await UploadAttachmentsToTarget(migrationContext, sourceWorkItem);

            foreach (var attachment in attachments)
            {
                JsonPatchOperation revisionHistoryAttachmentAddOperation = MigrationHelpers.GetRevisionHistoryAttachmentAddOperation(attachment, sourceWorkItem.Id.Value);
                jsonPatchOperations.Add(revisionHistoryAttachmentAddOperation);
            }

            return(jsonPatchOperations);
        }
        private JsonPatchOperation CreateTags(string path, List <string> tags)
        {
            var cleanList = tags.Where(x => x.Length > 0);

            var mytags = new JsonPatchOperation
            {
                Operation = Operation.Add,
                Path      = path,
                Value     = string.Join(",", cleanList),
            };

            return(mytags);
        }
Beispiel #28
0
        public static new PatchOperation <TModel> CreateFromJson(JsonPatchOperation operation)
        {
            ValidatePath(operation);

            var value = ValidateAndGetValue(operation);

            if (value == null)
            {
                throw new VssPropertyValidationException("Value", PatchResources.ValueCannotBeNull());
            }

            return(new AddPatchOperation <TModel>(operation.Path, value));
        }
Beispiel #29
0
        public static JsonPatchOperation GetJsonPatchOperationReplaceForField(KeyValuePair <string, object> field)
        {
            string key   = field.Key;
            object value = field.Value;

            JsonPatchOperation jsonPatchOperationAdd = new JsonPatchOperation()
            {
                Operation = Operation.Replace,
                Path      = $"/{Constants.Fields}/{key}",
                Value     = value
            };

            return(jsonPatchOperationAdd);
        }
Beispiel #30
0
        public void Remove_Success(object input, string path, string expectedJson)
        {
            var patchOperations = new JsonPatchOperation[]
            {
                new JsonPatchRemoveOperation
                {
                    Path = path
                }
            };

            var output = Patch(input, patchOperations);

            output.ShouldBeJson(expectedJson);
        }
Beispiel #31
0
        public void Test_Success(object input, string path, object value, string expectedJson)
        {
            var patchOperations = new JsonPatchOperation[]
            {
                new JsonPatchTestOperation
                {
                    Path  = path,
                    Value = value
                }
            };

            var output = Patch(input, patchOperations);

            output.ShouldBeJson(expectedJson);
        }