Три способа обновить запрос в Jira из ScriptRunner, используя Jira Java API
В этой статье будут рассмотрены три способа обновления запроса в Jira, используя Jira Java API.
Я буду использовать следующие методы Jira Java API:
- Issue.setCustomFieldValue (CustomField customField, Object value)
- CustomField.updateValue (FieldLayoutItem fieldLayoutItem, Issue issue, ModifiedValue modifiedValue, IssueChangeHolder issueChangeHolder)
- IssueService.update (ApplicationUser user, IssueService.UpdateValidationResult updateValidationResult)
Будут приведены примеры скриптов для обновления всех типов кастомных полей, доступных в Jira из «коробки», с таблицей, в которой указаны отличия работы рассматриваемых методов друг от друга.
Все скрипты я протестировал на Jira 7.7.0 в консоли скриптов плагина Adaptivist ScriptRunner 5.3.7. Целью статьи было не написание «чистого кода», а изложение принципов работы с запросами.
Тексты скриптов можно скачать здесь.
Были созданы следующие кастомные поля:
Способ 1 Issue.setCustomFieldValue (CustomField customField, Object value)
Ниже приведен скрипт для изменения полей.
import com.atlassian.jira.component.ComponentAccessor
import com.atlassian.jira.event.type.EventDispatchOption
import java.sql.Date
import com.atlassian.jira.issue.customfields.option.Option
import com.atlassian.jira.issue.Issue
import com.atlassian.jira.issue.fields.CustomField
import com.atlassian.jira.issue.label.Label
import com.atlassian.jira.bc.user.search.UserSearchService
import com.atlassian.jira.bc.user.search.UserSearchParams
import com.atlassian.jira.user.ApplicationUser
def issue = ComponentAccessor.getIssueManager().getIssueByCurrentKey("BP-7")
def user = ComponentAccessor.getJiraAuthenticationContext().getLoggedInUser()
// Получаем ссылки на кастомные поля
def singleline_field = ComponentAccessor.getCustomFieldManager().getCustomFieldObjectByName("singleline_field")
def datetimepicker_field = ComponentAccessor.getCustomFieldManager().getCustomFieldObjectByName("datetimepicker_field")
def checkbox_field = ComponentAccessor.getCustomFieldManager().getCustomFieldObjectByName("checkbox_field")
def number_field = ComponentAccessor.getCustomFieldManager().getCustomFieldObjectByName("number_field")
def labels_field = ComponentAccessor.getCustomFieldManager().getCustomFieldObjectByName("labels_field")
def multi_grouppicker_field = ComponentAccessor.getCustomFieldManager().getCustomFieldObjectByName("multi_grouppicker_field")
def multiline_field = ComponentAccessor.getCustomFieldManager().getCustomFieldObjectByName("multiline_field")
def datepicker_field = ComponentAccessor.getCustomFieldManager().getCustomFieldObjectByName("datepicker_field")
def userpicker_field = ComponentAccessor.getCustomFieldManager().getCustomFieldObjectByName("userpicker_field")
def radiobuttons_field = ComponentAccessor.getCustomFieldManager().getCustomFieldObjectByName("radiobuttons_field")
def selectlist_cascading_field = ComponentAccessor.getCustomFieldManager().getCustomFieldObjectByName("selectlist_cascading_field")
def select_singlechoice_field = ComponentAccessor.getCustomFieldManager().getCustomFieldObjectByName("select_singlechoice_field")
def selectlist_multichoice_field = ComponentAccessor.getCustomFieldManager().getCustomFieldObjectByName("selectlist_multichoice_field")
def url_field = ComponentAccessor.getCustomFieldManager().getCustomFieldObjectByName("url_field")
// устанавливаем значения полей
issue.setCustomFieldValue(singleline_field, "test 1")
issue.setCustomFieldValue(datetimepicker_field, new Date(Calendar.getInstance().getTime().getTime()))
issue.setCustomFieldValue(checkbox_field, getOptions(issue, checkbox_field, ["option 1", "option 2"]))
issue.setCustomFieldValue(number_field, (Double) 1)
issue.setCustomFieldValue(labels_field, [new Label(null, issue.getId(), labels_field.getIdAsLong(), "Label")] as Set)
issue.setCustomFieldValue(multi_grouppicker_field, [ComponentAccessor.getGroupManager().getGroup("jira-software-users")])
issue.setCustomFieldValue(multiline_field, "test 1")
issue.setCustomFieldValue(datepicker_field, new Date(Calendar.getInstance().getTime().getTime()))
issue.setCustomFieldValue(userpicker_field, findUser("admin"))
issue.setCustomFieldValue(radiobuttons_field, getOptions(issue, checkbox_field, ["option 1"]).get(0))
issue.setCustomFieldValue(selectlist_cascading_field, getCascadingOptions(issue, selectlist_cascading_field))
issue.setCustomFieldValue(select_singlechoice_field, getOptions(issue, select_singlechoice_field, ["option 1"]).get(0))
issue.setCustomFieldValue(selectlist_multichoice_field, getOptions(issue, selectlist_multichoice_field, ["option 1", "option 2"]))
issue.setCustomFieldValue(url_field, "http://google.com")
// применяем изменения
ComponentAccessor.getIssueManager().updateIssue(user, issue, EventDispatchOption.ISSUE_UPDATED, false)
// получем опции для кастомных полей типа radio button, checkbox and select
def List
Для того, чтобы обнулить поле, необходимо установить значение null. Например, вот так:
issue.setCustomFieldValue(singleline_field, null)
Способ 2 CustomField.updateValue (FieldLayoutItem fieldLayoutItem, Issue issue, ModifiedValue modifiedValue, IssueChangeHolder issueChangeHolder)
Ниже приведен скрипт для изменения полей:
import com.atlassian.jira.component.ComponentAccessor
import com.atlassian.jira.event.type.EventDispatchOption
import java.sql.Date
import com.atlassian.jira.issue.customfields.option.Option
import com.atlassian.jira.issue.Issue
import com.atlassian.jira.issue.fields.CustomField
import com.atlassian.jira.issue.label.Label
import com.atlassian.jira.bc.user.search.UserSearchService
import com.atlassian.jira.bc.user.search.UserSearchParams
import com.atlassian.jira.user.ApplicationUser
import com.atlassian.jira.issue.util.DefaultIssueChangeHolder
import com.atlassian.jira.issue.ModifiedValue
def issue = ComponentAccessor.getIssueManager().getIssueByCurrentKey("BP-7")
def user = ComponentAccessor.getJiraAuthenticationContext().getLoggedInUser()
// Получаем ссылки на кастомные поля
def singleline_field = ComponentAccessor.getCustomFieldManager().getCustomFieldObjectByName("singleline_field")
def datetimepicker_field = ComponentAccessor.getCustomFieldManager().getCustomFieldObjectByName("datetimepicker_field")
def checkbox_field = ComponentAccessor.getCustomFieldManager().getCustomFieldObjectByName("checkbox_field")
def number_field = ComponentAccessor.getCustomFieldManager().getCustomFieldObjectByName("number_field")
def labels_field = ComponentAccessor.getCustomFieldManager().getCustomFieldObjectByName("labels_field")
def multi_grouppicker_field = ComponentAccessor.getCustomFieldManager().getCustomFieldObjectByName("multi_grouppicker_field")
def multiline_field = ComponentAccessor.getCustomFieldManager().getCustomFieldObjectByName("multiline_field")
def datepicker_field = ComponentAccessor.getCustomFieldManager().getCustomFieldObjectByName("datepicker_field")
def userpicker_field = ComponentAccessor.getCustomFieldManager().getCustomFieldObjectByName("userpicker_field")
def radiobuttons_field = ComponentAccessor.getCustomFieldManager().getCustomFieldObjectByName("radiobuttons_field")
def selectlist_cascading_field = ComponentAccessor.getCustomFieldManager().getCustomFieldObjectByName("selectlist_cascading_field")
def select_singlechoice_field = ComponentAccessor.getCustomFieldManager().getCustomFieldObjectByName("select_singlechoice_field")
def selectlist_multichoice_field = ComponentAccessor.getCustomFieldManager().getCustomFieldObjectByName("selectlist_multichoice_field")
def url_field = ComponentAccessor.getCustomFieldManager().getCustomFieldObjectByName("url_field")
// вносим изменения. Изменения будут применены сразу
singleline_field.updateValue(null, issue, new ModifiedValue("", (Object) "Test 1"), new DefaultIssueChangeHolder())
datetimepicker_field.updateValue(null, issue, new ModifiedValue("", (Object) new Date(Calendar.getInstance().getTime().getTime())), new DefaultIssueChangeHolder())
checkbox_field.updateValue(null, issue, new ModifiedValue("", (Object) getOptions(issue, checkbox_field, ["option 1", "option 2"])), new DefaultIssueChangeHolder())
number_field.updateValue(null, issue, new ModifiedValue("", (Object) (Double) 1), new DefaultIssueChangeHolder())
labels_field.updateValue(null, issue, new ModifiedValue("", (Object) ([new Label(null, issue.getId(), labels_field.getIdAsLong(), "Label")] as Set)), new DefaultIssueChangeHolder())
multi_grouppicker_field.updateValue(null, issue, new ModifiedValue("", (Object) [ComponentAccessor.getGroupManager().getGroup("jira-software-users")]), new DefaultIssueChangeHolder())
multiline_field.updateValue(null, issue, new ModifiedValue("", (Object) "test 1"), new DefaultIssueChangeHolder())
datepicker_field.updateValue(null, issue, new ModifiedValue("", (Object) new Date(Calendar.getInstance().getTime().getTime())), new DefaultIssueChangeHolder())
userpicker_field.updateValue(null, issue, new ModifiedValue("", (Object) findUser("admin")), new DefaultIssueChangeHolder())
radiobuttons_field.updateValue(null, issue, new ModifiedValue("", (Object) getOptions(issue, checkbox_field, ["option 1"]).get(0)), new DefaultIssueChangeHolder())
selectlist_cascading_field.updateValue(null, issue, new ModifiedValue("", (Object) getCascadingOptions(issue, selectlist_cascading_field)), new DefaultIssueChangeHolder())
select_singlechoice_field.updateValue(null, issue, new ModifiedValue("", (Object) getOptions(issue, select_singlechoice_field, ["option 1"]).get(0)), new DefaultIssueChangeHolder())
selectlist_multichoice_field.updateValue(null, issue, new ModifiedValue("", (Object) getOptions(issue, selectlist_multichoice_field, ["option 1", "option 2"])), new DefaultIssueChangeHolder())
url_field.updateValue(null, issue, new ModifiedValue("", (Object) "http://google.com"), new DefaultIssueChangeHolder())
// получаем опции для кастомные полей типа radio button, checkbox and select
def List
Для того, чтобы обнулить поле, необходимо установить значение null. Например, вот так:
singleline_field.updateValue(null, issue, new ModifiedValue("", null), new DefaultIssueChangeHolder())
Способ 3 IssueService.update (ApplicationUser user, IssueService.UpdateValidationResult updateValidationResult)
Ниже приведен скрипт для изменения полей:
import com.atlassian.jira.issue.IssueInputParameters
import com.atlassian.jira.bc.issue.IssueService
import com.atlassian.jira.bc.issue.IssueService.UpdateValidationResult
import com.atlassian.jira.bc.issue.IssueService.IssueResult
import com.atlassian.jira.component.ComponentAccessor
import com.atlassian.jira.issue.customfields.option.Option
import com.atlassian.jira.issue.Issue
import com.atlassian.jira.issue.fields.CustomField
import com.atlassian.jira.issue.label.Label
import com.atlassian.jira.bc.user.search.UserSearchService
import com.atlassian.jira.bc.user.search.UserSearchParams
import com.atlassian.jira.user.ApplicationUser
import java.text.SimpleDateFormat
def issue = ComponentAccessor.getIssueManager().getIssueByCurrentKey("BP-7")
def user = ComponentAccessor.getJiraAuthenticationContext().getLoggedInUser()
// Получаем ссылки на кастомные поля
def singleline_field = ComponentAccessor.getCustomFieldManager().getCustomFieldObjectByName("singleline_field")
def datetimepicker_field = ComponentAccessor.getCustomFieldManager().getCustomFieldObjectByName("datetimepicker_field")
def checkbox_field = ComponentAccessor.getCustomFieldManager().getCustomFieldObjectByName("checkbox_field")
def number_field = ComponentAccessor.getCustomFieldManager().getCustomFieldObjectByName("number_field")
def labels_field = ComponentAccessor.getCustomFieldManager().getCustomFieldObjectByName("labels_field")
def multi_grouppicker_field = ComponentAccessor.getCustomFieldManager().getCustomFieldObjectByName("multi_grouppicker_field")
def multiline_field = ComponentAccessor.getCustomFieldManager().getCustomFieldObjectByName("multiline_field")
def datepicker_field = ComponentAccessor.getCustomFieldManager().getCustomFieldObjectByName("datepicker_field")
def userpicker_field = ComponentAccessor.getCustomFieldManager().getCustomFieldObjectByName("userpicker_field")
def radiobuttons_field = ComponentAccessor.getCustomFieldManager().getCustomFieldObjectByName("radiobuttons_field")
def selectlist_cascading_field = ComponentAccessor.getCustomFieldManager().getCustomFieldObjectByName("selectlist_cascading_field")
def select_singlechoice_field = ComponentAccessor.getCustomFieldManager().getCustomFieldObjectByName("select_singlechoice_field")
def selectlist_multichoice_field = ComponentAccessor.getCustomFieldManager().getCustomFieldObjectByName("selectlist_multichoice_field")
def url_field = ComponentAccessor.getCustomFieldManager().getCustomFieldObjectByName("url_field")
IssueService issueService = ComponentAccessor.getComponent(IssueService.class);
IssueInputParameters issueInputParameters = issueService.newIssueInputParameters();
// устанавливаем значения кастомных полей
issueInputParameters
.addCustomFieldValue(singleline_field.getId(), "Test 1")
.addCustomFieldValue(datetimepicker_field.getId(), new SimpleDateFormat("d/MMM/yy hh:mm a").format(new Date()))
.addCustomFieldValue(checkbox_field.getId(), getOptionsAsString(issue, checkbox_field, ["option 1"]))
.addCustomFieldValue(number_field.getId(), "1")
.addCustomFieldValue(labels_field.getId(), "Label")
.addCustomFieldValue(multi_grouppicker_field.getId(), "jira-software-users")
.addCustomFieldValue(multiline_field.getId(), "Test 2")
.addCustomFieldValue(datepicker_field.getId(), new SimpleDateFormat("d/MMM/yy").format(new Date()))
.addCustomFieldValue(userpicker_field.getId(), "admin")
.addCustomFieldValue(radiobuttons_field.getId(), getOptionsAsString(issue, radiobuttons_field, ["option 1"]))
.addCustomFieldValue(selectlist_cascading_field.getId(), getCascadingOptions(issue, selectlist_cascading_field).get("parent").toString())
.addCustomFieldValue(selectlist_cascading_field.getId() + ":1", getCascadingOptions(issue, selectlist_cascading_field).get("1").toString())
.addCustomFieldValue(select_singlechoice_field.getId(), getOptionsAsString(issue, select_singlechoice_field, ["option 1"]))
.addCustomFieldValue(selectlist_multichoice_field.getId(), getOptionsAsString(issue, selectlist_multichoice_field, ["option 1"]))
.addCustomFieldValue(url_field.getId(), "http://google.com")
// мы устанавливаем не все значения для запроса, поэтому мы должны явно это указать
issueInputParameters.setRetainExistingValuesWhenParameterNotProvided(true,true)
// проверяем корректность наших данных для обновления запроса
UpdateValidationResult updateValidationResult = issueService.validateUpdate(user, issue.getId(), issueInputParameters);
if (updateValidationResult.isValid())
{
// применяем изменения
IssueResult updateResult = issueService.update(user, updateValidationResult);
if (!updateResult.isValid())
{
log.error("error updateResult: " + updateResult.getErrorCollection().toString())
}
} else {
log.error("error: updateValidationResult" + updateValidationResult.getErrorCollection().toString())
}
// получаем опции для кастомных полей radio button, checkbox and select
def List
Для того, чтобы обнулить поле, необходимо установить значение null. Например, вот так:
.addCustomFieldValue(singleline_field.getId(), null)