Work with Linked Applications
HAPI provides a simpler method of working with other Atlassian products that have been connected via Application Links (app link). HAPI is optimised for the most common integration solutions, such as making requests over an app link configured with OAuth (with impersonation) authentication.
The steps to making a request over an app link are:
- Select the app link. For example
ApplicationLinks.primaryJiraLink
, orApplicationLinks.getByName('Dogfood Jira')
- Execute a request using the extension method
com.adaptavist.hapi.jira.extensions.ApplicationLinkExtensions#executeRequest
Making requests to a Jira app link
In the following example, make a request to get the current user via the primary Jira app link. The primary Jira app link is the Jira application link that is marked with PRIMARY when you're on the Application links page.
import static com.atlassian.sal.api.net.Request.MethodType.GET
def result = ApplicationLinks.primaryJiraLink.executeRequest(GET, '/rest/auth/1/session') as Map
def userName = result.name
The result is coerced to a Map, List, or whatever is appropriate. If you request XML, you will be returned a groovy.util.slurpersupport.GPathResult
.
Making requests as a different user
You can make the request as a different user by utilizing Users.runAs
, for example :
import static com.atlassian.sal.api.net.Request.MethodType.GET
def result = Users.runAs('anuser') {
ApplicationLinks.primaryJiraLink.executeRequest(GET, '/rest/auth/1/session') as Map
}
assert result.name == 'anuser'
Making a POST request
You can make a POST request as well as GET requests (as we have done previously). To make a POST request set the Content-Type
header, typically to application/json
, and provide a Map or List to setEntity
, this converts to JSON automatically. In the following example we're making a POST request and creating an issue in the connected Jira instance.
See the documentation for creating an issue here.
import static com.atlassian.sal.api.net.Request.MethodType.POST
def result = ApplicationLinks.primaryJiraLink.executeRequest(POST, '/rest/api/2/issue') {
setHeader('Content-Type', 'application/json')
setEntity([
fields: [
project : [
key: 'SR',
],
summary : 'Help me!',
issuetype: [
name: 'Task'
]
]
])
} as Map
def issueKey = result.key
Creating attachments in Jira
In the following example we're creating an attachment for a specific issue in the connected Jira instance.
import static com.atlassian.sal.api.net.Request.MethodType.POST
import com.atlassian.sal.api.net.RequestFilePart
// note the 'file' string as the second argument is important, and should not be anything other than 'file'
def filePart = new RequestFilePart(new File('/path/to/screenshot.png'), 'file')
def issueKey = 'SR-100'
ApplicationLinks.primaryJiraLink.executeRequest(POST, "/rest/api/2/issue/${issueKey}/attachments") {
addHeader("X-Atlassian-Token", "no-check")
setFiles([filePart])
}
Working with Confluence
In the following example we're using the Confluence REST API to create a page, and then add an attachment to that page.
To find the key for your confluence space, in confluence go to Space tools > Overview.
import static com.atlassian.sal.api.net.Request.MethodType.POST
import com.atlassian.sal.api.net.RequestFilePart
def confluenceLink = ApplicationLinks.primaryConfluenceLink
def pageResponse = confluenceLink.executeRequest(POST, 'rest/api/content') {
setHeader('Content-Type', 'application/json')
setEntity([
type : 'page',
title: 'new page',
space: [
key: 'AAA'
],
body : [
storage: [
value : "<p>This is <br/> a new page</p>",
representation: "storage"
]
]
])
} as Map
def pageId = pageResponse.id
def filePart = new RequestFilePart(new File('/path/to/screenshot.png'), 'file')
confluenceLink.executeRequest(POST, "rest/api/content/${pageId}/child/attachment") {
addHeader("X-Atlassian-Token", "no-check")
setFiles([filePart])
}
Handling errors
If a request is not successful (that is, a response status code greater than 400 or less than 200), an exception is thrown. The response body will be parsed into a Map or whatever is appropriate. In the following example, not all mandatory fields have been entered for creating an issue.
import static com.atlassian.sal.api.net.Request.MethodType.POST
import com.adaptavist.hapi.platform.applinks.exceptions.AppLinkResponseException
try {
def result = ApplicationLinks.primaryJiraLink.executeRequest(POST, '/rest/api/2/issue') {
setHeader('Content-Type', 'application/json')
setEntity([
fields: [
// note: project is missing
summary : 'Help me!',
issuetype: [
name: 'Task'
]
]
])
} as Map
} catch (AppLinkResponseException e) {
assert (e.entity as Map<String, Map>).errors.project == 'project is required'
assert e.response.statusCode == 500
}
You also have access to the Response object through the exception, as shown.