Beispiel #1
0
        /// <summary>
        /// Returns a single JIRA issue by its KEY. Includes all fields and child collections (e.g. comments)
        /// </summary>
        /// <param name="issueKey">The JIRA issue key</param>
        /// <param name="jiraCreateMetaData">The creation meta-data</param>
        /// <returns>The JIRA issue object</returns>
        public JiraIssue GetIssueByKey(string issueKey, JiraCreateMetaData jiraCreateMetaData)
        {
            string result = RunQuery(resource: JiraResource.issue, argument: issueKey, method: "GET");

            LogTraceEvent(this.eventLog, result, EventLogEntryType.SuccessAudit);

            //First deserialize into a generic JObject;
            JObject jIssue = JObject.Parse(result);

            //For the standard fields we use the standard deserializer
            JiraIssue issue = jIssue.ToObject <JiraIssue>();

            //We need to get a handle on the fields meta-data for use later
            JObject jIssueTypeFields = null;

            if (jiraCreateMetaData != null)
            {
                JiraProject project = jiraCreateMetaData.Projects.FirstOrDefault(p => p.Id == issue.Fields.Project.Id);
                if (project != null)
                {
                    IssueType issueType = project.IssueTypes.FirstOrDefault(t => t.Id == issue.Fields.IssueType.Id);
                    if (issueType != null)
                    {
                        //See if we are missing any required properties
                        jIssueTypeFields = issueType.Fields;
                    }
                }
            }


            //Now we need to get the custom fields from the JObject directly
            JObject jFields = (JObject)jIssue["fields"];

            if (jFields != null)
            {
                foreach (JProperty jProperty in jFields.Properties())
                {
                    //Make sure it's a custom field
                    if (jProperty.Name.StartsWith(JiraCustomFieldValue.CUSTOM_FIELD_PREFIX))
                    {
                        JiraCustomFieldValue customFieldValue = new JiraCustomFieldValue(jProperty.Name);
                        CustomPropertyValue  cpv = new CustomPropertyValue();

                        //We need to try and match the type of value
                        if (jProperty.Value != null && jProperty.Value.Type != JTokenType.None && jProperty.Value.Type != JTokenType.Null)
                        {
                            LogTraceEvent(eventLog, String.Format("Found custom field '{0}' of JProperty type " + jProperty.Value.Type, jProperty.Name), EventLogEntryType.Information);
                            if (jProperty.Value.Type == JTokenType.Array && jProperty.Value is JArray)
                            {
                                //Iterate through the list of values
                                List <string> listOptionValueNames = new List <string>();

                                JArray jOptions = (JArray)jProperty.Value;
                                foreach (JToken jToken in jOptions)
                                {
                                    if (jToken is JObject)
                                    {
                                        JObject jOption = (JObject)jToken;
                                        //If we have an object that has an ID property then we have a multi-list
                                        if (jOption["id"] != null && jOption["id"].Type == JTokenType.String)
                                        {
                                            LogTraceEvent(eventLog, String.Format("Found custom field '{0}' that is an array of objects with ID field ({1})", jProperty.Name, jOption["id"].Type), EventLogEntryType.Information);
                                            string id = (string)jOption["id"];
                                            if (!String.IsNullOrEmpty(id))
                                            {
                                                //Need to convert into an integer and set the list value
                                                int idAsInt;
                                                if (Int32.TryParse(id, out idAsInt))
                                                {
                                                    LogTraceEvent(eventLog, String.Format("Looking for custom field value name that matches custom field {0} option value id {1}", jProperty.Name, idAsInt), EventLogEntryType.Information);
                                                    string optionName = LookupCustomFieldOptionName(idAsInt, jIssueTypeFields, customFieldValue.CustomFieldName);
                                                    listOptionValueNames.Add(optionName);
                                                    LogTraceEvent(eventLog, String.Format("Found JIRA custom field {2} value name that matches custom field {0} option value id {1}", jProperty.Name, idAsInt, optionName), EventLogEntryType.Information);
                                                }
                                            }
                                        }
                                    }
                                }

                                if (listOptionValueNames.Count > 0)
                                {
                                    cpv.CustomPropertyType = CustomPropertyValue.CustomPropertyTypeEnum.MultiList;
                                    cpv.MultiListValue     = listOptionValueNames;
                                }
                            }
                            else if (jProperty.Value.Type == JTokenType.Object)
                            {
                                //If we have an object that has an ID property then we have a single-list
                                //If we have a 'name' property then we have a user field
                                if (jProperty.Value is JObject)
                                {
                                    JObject jOption = (JObject)jProperty.Value;
                                    if (jOption["id"] != null && jOption["id"].Type == JTokenType.String)
                                    {
                                        LogTraceEvent(eventLog, String.Format("Found custom field '{0}' that is an object with ID field ({1})", jProperty.Name, jOption["id"].Type), EventLogEntryType.Information);
                                        string id = (string)jOption["id"];
                                        if (!String.IsNullOrEmpty(id))
                                        {
                                            //Need to convert into an integer and get the name from the meta-data
                                            int idAsInt;
                                            if (Int32.TryParse(id, out idAsInt))
                                            {
                                                LogTraceEvent(eventLog, String.Format("Looking for custom field value name that matches custom field {0} option value id {1}", jProperty.Name, idAsInt), EventLogEntryType.Information);
                                                string optionName = LookupCustomFieldOptionName(idAsInt, jIssueTypeFields, customFieldValue.CustomFieldName);
                                                cpv.CustomPropertyType = CustomPropertyValue.CustomPropertyTypeEnum.List;
                                                cpv.StringValue        = optionName;
                                                LogTraceEvent(eventLog, String.Format("Found JIRA custom field {2} value name that matches custom field {0} option value id {1}", jProperty.Name, idAsInt, optionName), EventLogEntryType.Information);
                                            }
                                        }
                                    }
                                    else if (jOption["name"] != null && jOption["name"].Type == JTokenType.String)
                                    {
                                        LogTraceEvent(eventLog, String.Format("Found custom field '{0}' that is an object with NAME field ({1})", jProperty.Name, jOption["name"].Type), EventLogEntryType.Information);
                                        string username = (string)jOption["name"];
                                        if (!String.IsNullOrEmpty(username))
                                        {
                                            cpv.StringValue        = username;
                                            cpv.CustomPropertyType = CustomPropertyValue.CustomPropertyTypeEnum.User;
                                        }
                                    }
                                }
                            }
                            else if (jProperty.Value.Type == JTokenType.Boolean)
                            {
                                //Simple integer property
                                cpv.CustomPropertyType = CustomPropertyValue.CustomPropertyTypeEnum.Boolean;
                                cpv.BooleanValue       = (bool?)jProperty.Value;
                            }
                            else if (jProperty.Value.Type == JTokenType.Integer)
                            {
                                //Simple integer property
                                cpv.CustomPropertyType = CustomPropertyValue.CustomPropertyTypeEnum.Integer;
                                cpv.IntegerValue       = (int?)jProperty.Value;
                            }
                            else if (jProperty.Value.Type == JTokenType.Float)
                            {
                                //Simple float property
                                cpv.CustomPropertyType = CustomPropertyValue.CustomPropertyTypeEnum.Decimal;
                                cpv.DecimalValue       = (decimal?)((float?)jProperty.Value);
                            }
                            else if (jProperty.Value.Type == JTokenType.Date)
                            {
                                //Simple date/time property
                                cpv.CustomPropertyType = CustomPropertyValue.CustomPropertyTypeEnum.Date;
                                cpv.DateTimeValue      = (DateTime?)jProperty.Value;
                            }
                            else if (jProperty.Value.Type == JTokenType.String)
                            {
                                //Simple string property
                                cpv.CustomPropertyType = CustomPropertyValue.CustomPropertyTypeEnum.Text;
                                cpv.StringValue        = (string)jProperty.Value;
                            }
                        }
                        customFieldValue.Value = cpv;
                        issue.CustomFieldValues.Add(customFieldValue);
                    }
                }
            }

            return(issue);
        }
Beispiel #2
0
        /// <summary>
        /// Adds a JIRA Issue into the system
        /// </summary>
        /// <param name="jiraIssue">The issue object</param>
        /// <param name="jiraCreateMetaData">The creation meta-data</param>
        ///
        public JiraIssueLink CreateIssue(JiraIssue jiraIssue, JiraCreateMetaData jiraCreateMetaData)
        {
            //First convert from the JiraIssue to a generic json object
            JObject jsonIssue = JObject.FromObject(jiraIssue);

            JObject jsonIssueFields  = (JObject)jsonIssue["fields"];
            JObject jIssueTypeFields = null;

            //Next validate the fields
            List <string> messages = new List <string>();
            //Find the current project and issue type in the meta-data
            IssueType issueType = null;

            if (jiraCreateMetaData != null && jsonIssueFields != null)
            {
                JiraProject project = jiraCreateMetaData.Projects.FirstOrDefault(p => p.Id == jiraIssue.Fields.Project.Id);
                if (project != null)
                {
                    issueType = project.IssueTypes.FirstOrDefault(t => t.Id == jiraIssue.Fields.IssueType.Id);
                    if (issueType != null)
                    {
                        //See if we are missing any required properties (not custom fields at this point)
                        jIssueTypeFields = issueType.Fields;
                        foreach (KeyValuePair <string, JToken> field in issueType.Fields)
                        {
                            string fieldName = field.Key;
                            JToken fieldVaue = field.Value;
                            bool   required  = fieldVaue["required"].Value <bool>();
                            if (required && !fieldName.Contains(JiraCustomFieldValue.CUSTOM_FIELD_PREFIX) && !jsonIssueFields.Properties().Any(p => p.Name == fieldName))
                            {
                                messages.Add(String.Format("JIRA field '{0}' is required for project '{1}' and issue type {2} but was not provided.", fieldName, jiraIssue.Fields.Project.Key, jiraIssue.Fields.IssueType.Id));
                            }
                        }

                        //Remove any properties that are not listed in the meta-data (never issue-type)
                        List <string> fieldsToRemove = new List <string>();
                        foreach (KeyValuePair <string, JToken> field in jsonIssueFields)
                        {
                            string fieldName = field.Key;
                            if (issueType.Fields[fieldName] == null && fieldName != "issuetype")
                            {
                                fieldsToRemove.Add(fieldName);  //Remove the property
                            }
                        }

                        //Now do the removes
                        foreach (string fieldToRemove in fieldsToRemove)
                        {
                            jsonIssueFields.Remove(fieldToRemove);
                        }
                    }
                }
            }

            //Throw an exception if we have any messages
            if (messages.Count > 0)
            {
                throw new ApplicationException(String.Join(" \n", messages));
            }

            //Now we need to add the custom properties, which are not automatically serialized
            foreach (JiraCustomFieldValue jiraCustomFieldValue in jiraIssue.CustomFieldValues)
            {
                if (jiraCustomFieldValue.Value != null)
                {
                    int    id        = jiraCustomFieldValue.CustomFieldId;
                    string fieldName = jiraCustomFieldValue.CustomFieldName;

                    //Make sure JIRA expects this field for this issue type
                    if (issueType != null && issueType.Fields[fieldName] != null)
                    {
                        //Add to the issue json fields, handling the appropriate types correctly
                        switch (jiraCustomFieldValue.Value.CustomPropertyType)
                        {
                        case CustomPropertyValue.CustomPropertyTypeEnum.Boolean:
                            if (jiraCustomFieldValue.Value.BooleanValue.HasValue)
                            {
                                jsonIssueFields.Add(fieldName, jiraCustomFieldValue.Value.BooleanValue.Value);
                            }
                            break;

                        case CustomPropertyValue.CustomPropertyTypeEnum.Date:
                            if (jiraCustomFieldValue.Value.DateTimeValue.HasValue)
                            {
                                jsonIssueFields.Add(fieldName, jiraCustomFieldValue.Value.DateTimeValue.Value);
                            }
                            break;

                        case CustomPropertyValue.CustomPropertyTypeEnum.Decimal:
                            if (jiraCustomFieldValue.Value.DecimalValue.HasValue)
                            {
                                jsonIssueFields.Add(fieldName, jiraCustomFieldValue.Value.DecimalValue.Value);
                            }
                            break;

                        case CustomPropertyValue.CustomPropertyTypeEnum.Integer:
                            if (jiraCustomFieldValue.Value.IntegerValue.HasValue)
                            {
                                jsonIssueFields.Add(fieldName, jiraCustomFieldValue.Value.IntegerValue.Value);
                            }
                            break;

                        case CustomPropertyValue.CustomPropertyTypeEnum.List:
                        {
                            //JIRA expects an object with an 'id' property set
                            if (!String.IsNullOrEmpty(jiraCustomFieldValue.Value.StringValue))
                            {
                                //Need to lookup the id of the custom field option
                                int?customFieldOptionId = LookupCustomFieldOptionId(jiraCustomFieldValue.Value.StringValue, jIssueTypeFields, jiraCustomFieldValue.CustomFieldName);
                                if (customFieldOptionId.HasValue)
                                {
                                    JObject jOption = new JObject();
                                    jOption["id"] = customFieldOptionId.Value.ToString();
                                    jsonIssueFields.Add(fieldName, jOption);
                                }
                            }
                        }
                        break;

                        case CustomPropertyValue.CustomPropertyTypeEnum.MultiList:
                        {
                            //JIRA expects an array of objects with an 'id' property set
                            if (jiraCustomFieldValue.Value.MultiListValue.Count > 0)
                            {
                                JArray jOptions = new JArray();
                                foreach (string optionName in jiraCustomFieldValue.Value.MultiListValue)
                                {
                                    //Need to lookup the id of the custom field option
                                    int?customFieldOptionId = LookupCustomFieldOptionId(optionName, jIssueTypeFields, jiraCustomFieldValue.CustomFieldName);
                                    if (customFieldOptionId.HasValue)
                                    {
                                        JObject jOption = new JObject();
                                        jOption["id"] = customFieldOptionId.Value.ToString();
                                        jOptions.Add(jOption);
                                    }
                                }
                                jsonIssueFields.Add(fieldName, jOptions);
                            }
                        }
                        break;

                        case CustomPropertyValue.CustomPropertyTypeEnum.Text:
                        {
                            if (!String.IsNullOrEmpty(jiraCustomFieldValue.Value.StringValue))
                            {
                                jsonIssueFields.Add(fieldName, jiraCustomFieldValue.Value.StringValue);
                            }
                        }
                        break;

                        case CustomPropertyValue.CustomPropertyTypeEnum.User:
                        {
                            //JIRA expects a user object with an 'name' property set
                            if (!String.IsNullOrEmpty(jiraCustomFieldValue.Value.StringValue))
                            {
                                JObject jUser = new JObject();
                                jUser["name"] = jiraCustomFieldValue.Value.StringValue;
                                jsonIssueFields.Add(fieldName, jUser);
                            }
                        }
                        break;
                        }
                    }
                }
            }

            string json = JsonConvert.SerializeObject(jsonIssue, Formatting.Indented, new JsonSerializerSettings {
                NullValueHandling = NullValueHandling.Ignore
            });

            LogTraceEvent(this.eventLog, json, EventLogEntryType.Information);
            json = RunQuery(JiraResource.issue, null, json, "POST");

            JiraIssueLink jiraIssueLink = JsonConvert.DeserializeObject <JiraIssueLink>(json);

            return(jiraIssueLink);
        }