Forums

Articles
Create
cancel
Showing results for 
Search instead for 
Did you mean: 

Insight automation delete object method

Stijn Everink
I'm New Here
I'm New Here
Those new to the Atlassian Community have posted less than three times. Give them a warm welcome!
February 24, 2022

Hi!

We are trying to create a Groovy script that is triggered by an Insight automation rule that when a user is added to an object of a specific type, it automatically also adds users to all related objects of a different specific type.

For example, when on a Collaboration Partner object a user is added, for all related Organizations add those Organizations to the user. Vice versa for deleting users.

What we have now is a script that is able to do the 'add' function, but we are facing some challenges with the 'delete' function. The challenge is that the REST-API endpoint to remove users from an organisation requires the users to be included in the body of a DELETE request. This causes a problem in our Groovy script, because neither the HTTPBuilder nor the RestClient supports adding a body to a DELETE request. See example below.

```import groovyx.net.http.ContentType
import groovyx.net.http.HTTPBuilder
import groovyx.net.http.Method
import groovy.json.\*

import com.atlassian.jira.component.ComponentAccessor

def url = ComponentAccessor.getApplicationProperties\(\).getString\("jira.baseurl"\)
def endpoint = "/rest/servicedeskapi/organization/1/user"
def username = "admin"
def password = "password"
def encoded = "$username:$password".toString\(\).bytes.encodeBase64\(\).toString\(\)
def httpBuilder = new HTTPBuilder(url\)
def jsonSlurper = new JsonSlurper\(\)

def formattedJson
def returnResponse
try \{
    httpBuilder.request(Method.DELETE, ContentType.JSON\) \{
        headers."Authorization" = "Basic $encoded"
        headers."Accept" = "application/json"
        headers."X-ExperimentalApi" = "opt-in"

        body = \[usernames: \['some@user.nl'] ]

        uri.path = endpoint

        response.success = \{ response, json \->
            if \(json\) \{
                returnResponse = json
                formattedJson = JsonOutput.toJson(json\)
            }
        }
        response.failure = \{ resp, data \->
            if \(data\) \{
                returnResponse = \[error: "Failed to make http request to $url/$endpoint", statusLine: resp.statusLine, data: data]
            } else \{
                returnResponse = \[error: "Failed to make http request to $url/$endpoint", statusLine: resp.statusLine]
            }
        }
    }
} catch(e\)\{
    returnResponse = \[error: "Some other error occured: $e"]
}

if \(formattedJson\) \{
    log.warn(formattedJson.toString\(\)\)
} else \{
    log.warn(returnResponse.toString\(\)\)
}```

Which returns:
```error:Some other error occured: java.lang.IllegalArgumentException: Cannot set a request body for a DELETE method```

Do you know if there is a way to send a DELETE request with a body in Groovy or is there another endpoint available that doesn't require a DELETE method with a body?

1 answer

0 votes
PD Sheehan
Rising Star
Rising Star
Rising Stars are recognized for providing high-quality answers to other users. Rising Stars receive a certificate of achievement and are on the path to becoming Community Leaders.
April 23, 2022

That might be a limitation of the HttpBuilder class. Having a body in a delete method goes against the REST specifications.

You could look for other libraries that might allow that.

But why don't you just use the java api?

import com.atlassian.jira.component.ComponentAccessor
def classLoader = ComponentAccessor.pluginAccessor.classLoader
Class OrganizationServiceClass = classLoader.findClass('com.atlassian.servicedesk.api.organization.OrganizationService')
def organizationService = ComponentAccessor.getOSGiComponentInstanceOfType(OrganizationServiceClass)

def userToDelete = ComponentAccessor.userManager.getUserByName('username') //name of user to remove
def adminUser = ComponentAccessor.userManager.getUserByName('adminUser') //user with permission to manage orgs
def org = organizationService.getById(adminUser, 1)
def updateParams = organizationService.newUsersOrganizationUpdateParametersBuilder()
.organization(org)
.users([userToDelete].toSet())
.build()
organizationService.removeUsersFromOrganization(adminUser, updateParams)

 

And when you need to access the REST api of the current instance from within java/groovy, there is a way to do it that doesn't involve storing your password in the code (not very secure)

import com.atlassian.jira.component.ComponentAccessor
import com.atlassian.jira.config.properties.APKeys
import com.atlassian.sal.api.net.Request
import com.atlassian.sal.api.net.TrustedRequest
import com.atlassian.sal.api.net.TrustedRequestFactory
import groovy.json.JsonBuilder
import groovyx.net.http.URIBuilder

def baseUrl = ComponentAccessor.applicationProperties.getString(APKeys.JIRA_BASEURL)
def currentUser = ComponentAccessor.jiraAuthenticationContext.loggedInUser
def trustedRequestFactory = ComponentAccessor.getOSGiComponentInstanceOfType(TrustedRequestFactory)

def payload = [usernames:['some@user.nl']]

def url = "$baseUrl/rest/servicedeskapi/organization/1/user"
def request = trustedRequestFactory.createTrustedRequest(Request.MethodType.DELETE, url ) as TrustedRequest
request.addTrustedTokenAuthentication(new URIBuilder(baseUrl).host, currentUser.username)
request.setHeader("Content-Type", 'application/json')
request.setRequestBody(new JsonBuilder(payload).toString())
request.execute()

Actually, this method may work with the DELETE and a body object.

Suggest an answer

Log in or Sign up to answer