Add Atlassian functions for interaction with JIRA API

Add functions needed to post JIRA comments. Functions to
post comments with versions of artifacts based on
artifact-metadata format.

Related-To: PRODX-3678

Change-Id: Ia61a282f9ecab7269eeabcb6ddb53422b5eef0d6
diff --git a/src/com/mirantis/mk/Atlassian.groovy b/src/com/mirantis/mk/Atlassian.groovy
new file mode 100644
index 0000000..ef28862
--- /dev/null
+++ b/src/com/mirantis/mk/Atlassian.groovy
@@ -0,0 +1,97 @@
+package com.mirantis.mk
+
+/**
+ *
+ * Send HTTP request to JIRA REST API.
+ *
+ * @param uri (string) JIRA url to post message to
+ * @param auth (string) authentication data
+ * @param method (string) HTTP method to call. Default: GET
+ * @param message (string) payload to send to JIRA
+ *
+ * @return map with two elements:
+ *   - responseCode
+ *   - responseText
+ *
+**/
+def callREST (String uri, String auth, String method = 'GET', String message = null) {
+    String authEnc = auth.bytes.encodeBase64()
+    def req = new URL(uri).openConnection()
+    req.setRequestMethod(method)
+    req.setRequestProperty('Content-Type', 'application/json')
+    req.setRequestProperty('Authorization', "Basic ${authEnc}")
+    if (message) {
+        req.setDoOutput(true)
+        req.getOutputStream().write(message.getBytes('UTF-8'))
+    }
+    Integer responseCode = req.getResponseCode()
+    String responseText = ''
+    if (responseCode == 200) {
+        responseText = req.getInputStream().getText()
+    }
+    req = null // to reset the connection
+    return [ 'responseCode': responseCode, 'responseText': responseText ]
+}
+
+/**
+ *
+ * Exract JIRA ticket numbers from the commit
+ * message for Gerrit change request.
+ *
+ * @param commitMsg string to parse for JIRA ticket IDs
+ * @param matcherRegex (string) regex to match JIRA issue IDs in commitMsg. Default: '([A-Z]+-[0-9]+)'
+ *
+ * @return list of JIRA ticket IDs
+ *
+**/
+
+List extractJIRA(String commitMsg, String matcherRegex = '([A-Z]+-[0-9]+)') {
+  String msg = commitMsg.decodeBase64()
+  def matcher = (msg =~ matcherRegex)
+  List tickets = []
+
+  matcher.each{ tickets.add(it[0]) }
+  return tickets
+}
+
+/**
+ *
+ * Post a text message in comments to a JIRA issue.
+ *
+ * @param uri (string) JIRA url to post message to
+ * @param auth (string) authentication data
+ * @param message (string) payload to post to a JIRA issue as comment
+ * @param restrictPostTo string represents JIRA space name to which posting is restricted. Default: PRODX
+ *
+**/
+
+def postComment(String uri, String auth, String message, String restrictPostTo = 'PRODX') {
+    String messageBody = message.replace('"', '\\"')
+    String commentMsg = """{"body": "${messageBody}"}""".replace('\n', '\\n')
+    String jiraSpace = uri.split('/').last().split('-').first()
+
+    // Skip adding worklog entry for some namespaces
+    if ( jiraSpace == restrictPostTo ) {
+        callREST("${uri}/worklog", auth, 'POST', commentMsg)
+    }
+}
+
+/**
+ *
+ * Post comment to list of JIRA issues.
+ *
+ * @param uri (string) base JIRA url, each ticket ID appends to it
+ * @param auth (string) authentication data
+ * @param message (string) payload to post to JIRA issues as comment
+ * @param tickets list of ticket IDs to post message to
+ *
+**/
+
+def postMessageToTickets(String uri, String auth, String message, List tickets) {
+    tickets.each{
+        if ( callREST("${uri}/${it}", auth)['responseCode'] == 200 ) {
+            println "Updating ${uri}/${it} ...".replaceAll('rest/api/2/isse', 'browse')
+            postComment("${uri}/${it}", auth, message)
+        }
+    }
+}