|
/*! UTF8 */ |
|
//Автор: mdemyanov |
|
//Дата создания: 2019-04-08 |
|
//Код: |
|
//Код модуля: jiraRest |
|
//Назначение: |
|
/** |
|
* Базовые методы для интеграции с JIRA |
|
* @param JIRA_URL адрес сервера |
|
* @param API версия API |
|
* @param LOGIN логин пользователя |
|
* @param TOKEN пароль пользователя |
|
*/ |
|
//Версия: 4.8.* |
|
//Категория: |
|
import groovy.transform.Field |
|
import groovyx.net.http.HTTPBuilder |
|
import groovyx.net.http.ContentType |
|
import org.apache.http.entity.mime.HttpMultipartMode |
|
import org.apache.http.entity.mime.MultipartEntity |
|
import org.apache.http.entity.mime.content.ByteArrayBody |
|
import org.apache.commons.io.FileUtils |
|
import org.slf4j.Logger |
|
import org.slf4j.LoggerFactory |
|
import static groovyx.net.http.ContentType.JSON |
|
import static groovyx.net.http.Method.POST |
|
import static groovyx.net.http.Method.PUT |
|
//Параметры------------------------------------------------------ |
|
@Field String JIRA_URL = 'https://company.atlassian.net/' |
|
@Field String API = 'rest/api/2/' |
|
@Field String LOGIN = 'user@email.ru' |
|
@Field String TOKEN = 'tokenFromAtlassianId' |
|
|
|
class Jira { |
|
static final Logger LOGGER = LoggerFactory.getLogger(Jira.class) |
|
static final String ISSUE_PATH = 'issue/' |
|
static final String OBJ_COMMENT_PATH = '/comment' |
|
static final String OBJ_FILE_PATH = "/attachments" |
|
static final String LOGGER_PRE_MSG = '[Модуль интеграции с JIRA] ' |
|
static final String CREATE_ERROR = 'ошибка создания объекта' |
|
static final String EDIT_ERROR = 'ошибка редактирования объекта' |
|
static final String GET_ERROR = 'ошибка получения объекта' |
|
static final String ADD_FILE_ERROR = 'ошибка добавления файла' |
|
static final String FILE_ERROR = 'ошибка скачивания файла' |
|
static final List SUCCESS_CODES = [200, 201, 204] |
|
|
|
HTTPBuilder client |
|
String authString |
|
|
|
|
|
Jira(String baseUrl, String login, String pass) { |
|
client = new HTTPBuilder(baseUrl) |
|
authString = "${login}:${pass}".getBytes().encodeBase64().toString() |
|
client.setHeaders([Authorization: "Basic $authString"]) |
|
client.ignoreSSLIssues() |
|
} |
|
|
|
/** |
|
* Функция для создания issue. |
|
* @param fields - ассоциативный массив полей для заполнения |
|
* @return объект Issue |
|
*/ |
|
Issue createIssue(Map fields) { |
|
Map body = [ |
|
fields: fields |
|
] |
|
Issue issue |
|
try { |
|
client.post(path: ISSUE_PATH, |
|
requestContentType: JSON, |
|
body: body |
|
) { response, reader -> |
|
if (SUCCESS_CODES.contains(response.statusLine.statusCode)) { |
|
issue = new Issue(this, reader) |
|
} else { |
|
LOGGER.error("$LOGGER_PRE_MSG$CREATE_ERROR (сервер ответил: ${response.statusLine})") |
|
} |
|
} |
|
} catch (Exception e) { |
|
LOGGER.error(LOGGER_PRE_MSG + CREATE_ERROR, e) |
|
} |
|
return issue |
|
} |
|
/** |
|
* Функция для редактирования issue. |
|
* @param id - идентификатор issue в Jira |
|
* @param fields - ассоциативный массив полей для заполнения |
|
* @return объект Issue |
|
*/ |
|
Issue editIssue(String id, Map fields) { |
|
Map bodies = [ |
|
fields: fields |
|
] |
|
Issue issue |
|
try { |
|
|
|
client.request(PUT) { request -> |
|
uri.path = ISSUE_PATH + id |
|
requestContentType = JSON |
|
body = bodies |
|
|
|
response.success = |
|
{ |
|
resp -> |
|
if (resp.statusLine.statusCode == 204) { |
|
LOGGER.info(LOGGER_PRE_MSG + 'Отредактирована заявка' + resp.getEntity()?.content.text) |
|
} |
|
} |
|
response.failure = { |
|
resp -> |
|
LOGGER.error(LOGGER_PRE_MSG + EDIT_ERROR + resp.statusLine) |
|
} |
|
} |
|
} |
|
catch (Exception e) { |
|
LOGGER.error("$LOGGER_PRE_MSG ошибка редактирования issue: ${id}", e) |
|
} |
|
return issue |
|
} |
|
/** |
|
* Функция для получения issue. |
|
* @param id - идентификатор issue в Jira |
|
* @param query - необязательный параметр с опциями поиска |
|
* (https://docs.atlassian.com/software/jira/docs/api/REST/8.1.0/?_ga=2.89757272.2131659664.1554716400-1621280212.1547636494#api/2/issue-getIssue) |
|
* @return объект Issue |
|
*/ |
|
Issue getIssue(String id, Map query = [:]) { |
|
Issue issue |
|
try { |
|
client.get(path: ISSUE_PATH + id, query: query) { response, reader -> |
|
issue = new Issue(this, reader) |
|
} |
|
} catch (Exception e) { |
|
LOGGER.error(LOGGER_PRE_MSG + GET_ERROR, e) |
|
} |
|
return issue |
|
} |
|
/** |
|
* Функция для добавления комментария к заявке в Jira. |
|
* @param id - идентификатор issue в Jira |
|
* @param text - текст комментария |
|
* @return массив с ответом сервера |
|
*/ |
|
Map addCommentToIssue(String id, String text) { |
|
def result |
|
try { |
|
result = client.post( |
|
path: ISSUE_PATH + id + OBJ_COMMENT_PATH, |
|
requestContentType: JSON, |
|
body: [ |
|
body: text |
|
] |
|
) |
|
} |
|
catch (Exception e) { |
|
LOGGER.error("$LOGGER_PRE_MSG ошибка добавления комментария к issue: ${id}", e) |
|
} |
|
return result |
|
} |
|
def getTransition(String from, String to){ |
|
def status = utils.findFirst('reference$status', ['title': to]) |
|
if(status==null){ |
|
LOGGER.error("Переход в статус ${to} не описан в справочнике.") |
|
return -1 |
|
} |
|
return status.jira |
|
} |
|
|
|
def getFile(String content){ |
|
File file = File.createTempFile("dlup", ".dat") |
|
def res |
|
try { |
|
client.get(uri: content, contentType: ContentType.BINARY) { response, reader -> |
|
|
|
FileUtils.copyInputStreamToFile(reader, file) |
|
res = FileUtils.readFileToByteArray(file) |
|
|
|
} |
|
} catch (Exception e) { |
|
LOGGER.error(LOGGER_PRE_MSG + FILE_ERROR, e) |
|
} |
|
return res |
|
} |
|
|
|
|
|
/** |
|
* Функция для получения комментариев из заявки в Jira. |
|
* @param id - идентификатор issue в Jira |
|
* @return массив с ответом сервера |
|
*/ |
|
Map getCommentsFromIssue(String id) { |
|
def result |
|
try { |
|
result = client.get( |
|
path: ISSUE_PATH + id + OBJ_COMMENT_PATH, |
|
requestContentType: JSON |
|
) |
|
} |
|
catch (Exception e) { |
|
LOGGER.error("$LOGGER_PRE_MSG ошибка получения комментариев issue: ${id}", e) |
|
} |
|
return result |
|
} |
|
/** |
|
* Функция для добавления файла к заявке в Jira. |
|
* @param id - идентификатор issue в Jira |
|
* @param file - файл в системе NSMP |
|
* @return Функция ничего не возвращает. |
|
*/ |
|
void addFileToIssue(String id, def file, def bytefile) { |
|
try { |
|
def content = new ByteArrayBody(bytefile, file.mimeType, file.title) |
|
client.request(POST) { request -> |
|
uri.path = ISSUE_PATH + id + OBJ_FILE_PATH |
|
headers.'X-Atlassian-Token' = 'nocheck' |
|
requestContentType: "multipart/form-data" |
|
|
|
MultipartEntity multiPartContent = new MultipartEntity(HttpMultipartMode.BROWSER_COMPATIBLE) |
|
multiPartContent.addPart("file", content) |
|
request.setEntity(multiPartContent) |
|
response.success = |
|
{ |
|
resp -> |
|
if (resp.statusLine.statusCode == 200) { |
|
LOGGER.info(LOGGER_PRE_MSG + 'добавлен файл' + resp.getEntity()?.content.text) |
|
} |
|
} |
|
response.failure = { |
|
resp -> |
|
LOGGER.error(LOGGER_PRE_MSG + ADD_FILE_ERROR + resp.statusLine) |
|
} |
|
} |
|
} |
|
catch (Exception e) { |
|
LOGGER.error("$LOGGER_PRE_MSG ошибка добавления файла к issue: ${id}", e) |
|
} |
|
} |
|
/** |
|
* Функция для добавления файлов к заявке в Jira. |
|
* @param id - идентификатор issue в Jira |
|
* @param file - коллекция файлов в системе NSMP |
|
* @return Функция ничего не возвращает. |
|
*/ |
|
void addFilesToIssue(String id, List files) { |
|
files.each { file -> addFileToIssue(id, file) } |
|
} |
|
} |
|
|
|
class Issue { |
|
Jira jira |
|
Map data |
|
|
|
Issue(Jira jiraObject, Map issueData) { |
|
jira = jiraObject |
|
data = issueData |
|
} |
|
|
|
String getId() { return data.id } |
|
|
|
String getKey() { return data.key } |
|
|
|
String getSelf() { return data.self } |
|
/** |
|
* Функция для получения issue. |
|
* @param query - необязательный параметр с опциями поиска |
|
* (https://docs.atlassian.com/software/jira/docs/api/REST/8.1.0/?_ga=2.89757272.2131659664.1554716400-1621280212.1547636494#api/2/issue-getIssue) |
|
* @return объект Issue |
|
*/ |
|
Issue getIssue() { |
|
return jira.getIssue(id) |
|
} |
|
/** |
|
* Функция для редактирования issue. |
|
* @param fields - ассоциативный массив полей для заполнения |
|
* @return объект Issue |
|
*/ |
|
Issue editIssue(Map fields) { |
|
return jira.editIssue(id, fields) |
|
} |
|
/** |
|
* Функция для добавления комментария к заявке в Jira. |
|
* @param text - текст комментария |
|
* @return массив с ответом сервера |
|
*/ |
|
Map addCommentToIssue(String text) { |
|
return jira.addCommentToIssue(id, text) |
|
} |
|
/** |
|
* Функция для получения комментариев из заявки в Jira. |
|
* @return массив с ответом сервера |
|
*/ |
|
Map getCommentsFromIssue() { |
|
return jira.getCommentsFromIssue(id) |
|
} |
|
/** |
|
* Функция для добавления файла к заявке в Jira. |
|
* @param file - файл в системе NSMP |
|
* @return Функция ничего не возвращает. |
|
*/ |
|
void addFileToIssue(def file) { |
|
jira.addFileToIssue(file) |
|
} |
|
/** |
|
* Функция для добавления файлов к заявке в Jira. |
|
* @param file - коллекция файлов в системе NSMP |
|
* @return Функция ничего не возвращает. |
|
*/ |
|
void addFilesToIssue(List files) { |
|
jira.addFilesToIssue(files) |
|
} |
|
} |
|
//Функции-------------------------------------------------------- |
|
/** |
|
* Получить экземпляр объекта для работы с JIRA |
|
* @param baseUrl - адрес инсталляции Jira + версия API, например, 'https://testerj.atlassian.net/' |
|
* @param login - логин |
|
* @param pass - пароль |
|
* @return Jira объект с базовыми методами взаимодействия с сервером |
|
* Примеры вызова метода: |
|
* - modules.jiraRest.jira - вернет объект с параметрами по умолчанию, зашитими в модуль (JIRA_URL, LOGIN и тд) |
|
* - modules.jiraRest.getJira(login, pass) - вернет объект для заданного логина и пароля |
|
*/ |
|
Jira getJira() { |
|
return new Jira(JIRA_URL + API, LOGIN, TOKEN) |
|
} |
|
Jira getJira(String login, String pass) { |
|
return new Jira(JIRA_URL + API, login, pass) |
|
} |
Добрый день!
Хотел уточнить в описании модуля (Скрипт №1) в строке 161 значение reference$status это элемент системы Naumen SD ? И что это за элемент?