404 while trying to use a JIRA Scriptrunner custom REST endpoint

Amedee Van Gasse September 8, 2016

Copy/paste from my Stack Overflow question:

 

I am trying to add a custom JIRA REST endpoint with Script Runner.

The REST endpoint needs to set user properties: a list of users is provided, and for each user a list of user properties.

This is the script I have cobbled together so far:

import com.atlassian.jira.component.ComponentAccessor
import com.atlassian.jira.bc.user.search.UserSearchService
import com.atlassian.sal.api.user.UserManager
import com.onresolve.scriptrunner.runner.rest.common.CustomEndpointDelegate

import groovy.json.JsonBuilder
import groovy.json.JsonSlurper
import groovy.transform.BaseScript

import javax.servlet.http.HttpServletRequest
import javax.ws.rs.core.MultivaluedMap
import javax.ws.rs.core.Response

@BaseScript CustomEndpointDelegate delegate

setUserProperties(httpMethod: "POST", groups: ["jira-administrators"])
{ MultivaluedMap queryParams, String body, HttpServletRequest request ->

def userPropertyManager = ComponentAccessor.getUserPropertyManager()
def userManager = ComponentAccessor.getUserManager()
def userSearchService = ComponentAccessor.getComponent(UserSearchService.class)

def json = new JsonSlurper().parseText(body)
def propertyCount = 0
def customerList = new ArrayList<>()
json.each {
aCustomer ->
def user = userManager.getUserByName(aCustomer.name.toString())
aCustomer.properties.each { aProperty ->
userPropertyManager.getPropertySet(user).setString("jira.meta." + aProperty.key.toString(), aProperty.value.toString())
propertyCount++
}
customerList.add(user)
}

def response = new ArrayList<>()
response.add( new JsonSlurper().parseText('{ "properties_changed": ' + propertyCount + ' }') )
response.add( customerList )

return Response.ok( new JsonBuilder(response).toPrettyString() ).build();
}

A previous (working) iteration of this script, running on another server, used email addresses, see http://stackoverflow.com/questions/36698657/how-to-get-a-user-by-email-in-jira-script-runner. But, as stated above, now I'm not getting users by email address but by username.

This is the userprops.json file I use to test:

[
  {
    "name": "felicity.smoak",
    "email": "felicity.smoak@queenconsolidated.com",
    "properties": {
      "Company": "Queen Consolidated",
      "Foo": "bar"
    }
  },
  {
    "name": "johnny.cash",
    "email": "johnny.cash@nashville.com",
    "properties": {
      "Company": "Nashville",
      "Nickname": "The Man In Black"
    }
  }
]

I test with this curl command:

 

curl -X POST \
  -i \
  -H "X-Atlassian-Token: nocheck" \
  -H "Content-type: text/json" \
  --data "@userprops.json" \
  -u "$JIRA_USER":"$JIRA_PASSWORD" \
  http://"$JIRA_SERVER"/rest/scriptrunner/latest/custom/setUserProperties

This is the output:

HTTP/1.1 404 Not Found
Server: nginx
Date: Wed, 07 Sep 2016 14:55:38 GMT
Content-Type: application/json;charset=UTF-8
Content-Length: 0
Connection: keep-alive
X-AREQUESTID: 0123456789
X-ASEN: SEN-123456789
Set-Cookie: JSESSIONID=1A2B3C4D5E6F1A2B3C4D5E6F1A2B3C4D5E6F; Path=/; Secure; HttpOnly
X-Seraph-LoginReason: OK
Set-Cookie: atlassian.xsrf.token=ABCD-EFGH-IJKL-MNOP|abcdef0123456789abcdef0123456789abcdef0123456789|lin; Path=/; Secure
X-ASESSIONID: xyz123
X-AUSERNAME: amedee.vangasse
Cache-Control: no-cache, no-store, no-transform
X-Content-Type-Options: nosniff

So it's not finding the REST endpoint where I should find it according to the Scriptrunner documentation.
If I use any URL that I *know* to be wrong, then I get an expected "Oops, you've found a dead link." error page. Only with the correct URL I get a 404 + no other output.

Also, when I add the doSomething sample and try to GET that, I get a 404 and a content length of 0. Doing a GET on any other wrong URL gives me a 404 AND a content length of a few KiB.

21 answers

0 votes
Amedee Van Gasse December 22, 2016

No, I do not have a solution. No time. When I have a solution, I will notify in this thread.

0 votes
Dominik December 22, 2016

Hello Amedee Van Gasse,

 

do you already have a solution?

0 votes
Thanos Batagiannis _Adaptavist_
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.
December 2, 2016

Hi Amedee,

I deleted your previous account, please try to create a new one.

regards, Thanos

0 votes
Amedee Van Gasse December 2, 2016

Hi Jamie!
I tried to create an account with my email address amedee.vangasse@itextpdf.com, but that account already exists, apparently.

I tried to get a password reset link (twice), but the email didn't arrive. Yes I checked the spam folder. 

0 votes
Amedee Van Gasse December 2, 2016

Hi Thanos,

I get a 404 from that curl.
FYI, our JIRA doesn't run in a /jira/ directory. I tried again with  

curl -u user:passw -i http://localhost:8086/jira/rest/scriptrunner/latest/custom/doSomething

Again, 404:

HTTP/1.1 404 Not Found
Server: Apache-Coyote/1.1
X-AREQUESTID: 902x526221x1
X-ASEN: SEN-2166625
Set-Cookie: JSESSIONID=D1D4107EDD4125562944B45D904801E7; Path=/; Secure; HttpOnly
X-Seraph-LoginReason: OK
Set-Cookie: atlassian.xsrf.token=BZJX-HAWK-8XBK-FU0I|d6c88fab27986dd38cef61a00e89a910dcaee394|lin; Path=/; Secure
X-ASESSIONID: 100ydx0
X-AUSERNAME: amedee.vangasse
Cache-Control: no-cache, no-store, no-transform
X-Content-Type-Options: nosniff
Content-Type: application/json;charset=UTF-8
Content-Length: 0
Date: Fri, 02 Dec 2016 14:02:10 GMT

I also tried 

curl -u user:passw -i 
https://jira.itextsupport.com/rest/scriptrunner/latest/custom/doSomething

 

That also gave me a 404, but this time coming from nginx (as expected).

 

 

Hi Jamie,

I will create a ticket right away!

0 votes
Thanos Batagiannis _Adaptavist_
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.
October 27, 2016

Hi amedee, 

Something is missing from your curl, try

Could you please try to curl 

curl -u user:passw -i http://localhost:8086/jira/rest/scriptrunner/latest/custom/doSomething
0 votes
JamieA
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.
September 12, 2016

If you prefer create a ticket at https://productsupport.adaptavist.com/servicedesk/customer/portal/2 and we can schedule a web conf to get to the bottom of it.

0 votes
JamieA
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.
September 12, 2016

Can you check all the plugin modules are enabled? Have you tried things like restarting etc?

0 votes
Amedee Van Gasse September 9, 2016

JIRA 7.1.8
ScriptRunner 4.3.6

0 votes
JamieA
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.
September 9, 2016

what versions of ScriptRunner and JIRA?

0 votes
Amedee Van Gasse September 9, 2016

JIRA is running on port 8086. When I ssh into the server, I get this:

curl -i http://localhost:8086/rest/scriptrunner/latest/custom/doSomething

HTTP/1.1 404 Not Found
Server: Apache-Coyote/1.1
X-AREQUESTID: 810x1441x1
X-ASEN: SEN-2166625
Set-Cookie: atlassian.xsrf.token=BZJX-HAWK-8XBK-FU0I|9f21ec4c9d74d7861016f904ba91ebbaacc7ac79|lout; Path=/; Secure
X-AUSERNAME: anonymous
Cache-Control: no-cache, no-store, no-transform
X-Content-Type-Options: nosniff
Content-Type: application/json;charset=UTF-8
Content-Length: 0
Date: Fri, 09 Sep 2016 11:30:31 GMT

I definitely have the jira-administrators group.

0 votes
JamieA
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.
September 9, 2016

I don't understand it. Is it possible to try to use curl to hit tomcat directly, rather than going through your reverse proxy? Is it possible it could be blocking it? Do you have definitely have the jira-administrators group?

0 votes
Amedee Van Gasse September 8, 2016

I deleted my own script and only kept the doSomething demo script. I still get a 404 on https://jira.itextsupport.com/rest/scriptrunner/latest/custom/doSomethingAs long as I get a 404 there, it doesn't make sense to try and debug my own custom script.

0 votes
Amedee Van Gasse September 8, 2016

I made a small change to the script and I got this error in atlassian-jira.log.

2016-09-09 11:01:43,683 http-nio-8086-exec-23 ERROR amedee.vangasse 661x42160x1 qq01uq 213.224.9.178,127.0.0.1 /rest/scriptrunner/latest/custom/customadmin/com.onresolve.scriptrunner.canned.common.rest.CustomRestEndpoint [c.
a.p.r.c.error.jersey.ThrowableExceptionMapper] Uncaught exception thrown by REST service: Cannot get property 'name' on null object

java.lang.NullPointerException: Cannot get property 'name' on null object

        at org.codehaus.groovy.runtime.NullObject.getProperty(NullObject.java:60)

        at org.codehaus.groovy.runtime.InvokerHelper.getProperty(InvokerHelper.java:172)

        at org.codehaus.groovy.runtime.callsite.NullCallSite.getProperty(NullCallSite.java:47)

        at org.codehaus.groovy.runtime.callsite.AbstractCallSite.callGetProperty(AbstractCallSite.java:296)

        at com.onresolve.scriptrunner.runner.RestEndpointManager$_onFullSystemStart_closure5.doCall(RestEndpointManager.groovy:141)

        ... 3 filtered

        at java.lang.reflect.Method.invoke(Method.java:497)

        at org.codehaus.groovy.reflection.CachedMethod.invoke(CachedMethod.java:93)

        at groovy.lang.MetaMethod.doMethodInvoke(MetaMethod.java:325)

        at org.codehaus.groovy.runtime.metaclass.ClosureMetaClass.invokeMethod(ClosureMetaClass.java:294)

        at groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:1021)

        at groovy.lang.Closure.call(Closure.java:426)

        at groovy.lang.Closure.call(Closure.java:442)

        at org.codehaus.groovy.runtime.DefaultGroovyMethods.each(DefaultGroovyMethods.java:2030)

        at org.codehaus.groovy.runtime.DefaultGroovyMethods.each(DefaultGroovyMethods.java:2015)

        at org.codehaus.groovy.runtime.DefaultGroovyMethods.each(DefaultGroovyMethods.java:2056)

        at org.codehaus.groovy.runtime.dgm$162.invoke(Unknown Source)

        at org.codehaus.groovy.runtime.callsite.PojoMetaMethodSite$PojoMetaMethodSiteNoUnwrapNoCoerce.invoke(PojoMetaMethodSite.java:274)

        at org.codehaus.groovy.runtime.callsite.PojoMetaMethodSite.call(PojoMetaMethodSite.java:56)

        at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCall(CallSiteArray.java:48)

        at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:113)

        at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:125)

        at com.onresolve.scriptrunner.runner.RestEndpointManager.onFullSystemStart(RestEndpointManager.groovy:131)

        at com.onresolve.scriptrunner.runner.rest.common.UserCustomScriptEndpoint.refresh(UserCustomScriptEndpoint.groovy:364)

        at com.onresolve.scriptrunner.runner.rest.common.UserCustomScriptEndpoint.saveConfiguredItems(UserCustomScriptEndpoint.groovy:359)

        at com.onresolve.scriptrunner.runner.rest.common.UserCustomScriptEndpoint.addListener(UserCustomScriptEndpoint.groovy:127)

        ... 3 filtered

        at java.lang.reflect.Method.invoke(Method.java:497)

        at com.sun.jersey.spi.container.JavaMethodInvokerFactory$1.invoke(JavaMethodInvokerFactory.java:60)

        ... 13 filtered

        at com.atlassian.plugins.rest.module.RestDelegatingServletFilter$JerseyOsgiServletContainer.doFilter(RestDelegatingServletFilter.java:154)

        ... 1 filtered

        at com.atlassian.plugins.rest.module.RestDelegatingServletFilter.doFilter(RestDelegatingServletFilter.java:68)

        ... 86 filtered

        at com.atlassian.jira.security.JiraSecurityFilter.doFilter(JiraSecurityFilter.java:70)

        ... 16 filtered

        at com.atlassian.plugins.rest.module.servlet.RestSeraphFilter.doFilter(RestSeraphFilter.java:37)

        ... 73 filtered

        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)

        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)

        at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)

        at java.lang.Thread.run(Thread.java:745)
0 votes
Amedee Van Gasse September 8, 2016

In atlassian-jira.log I only have a WARN about X-Atlassian-Token, that the nocheck value has been deprecated since rest 3.0.0 in favor of no-check. I made that change but alas, it made no difference.

0 votes
JamieA
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.
September 8, 2016

"Data Center" is clustered jira, I think you would know if you were using it.

Did you check the application logs for errors?

0 votes
Amedee Van Gasse September 8, 2016

I have enabled HTTP access log in JIRA and get these 2 lines when I curl setUserProperties:

127.0.0.1 i614x41877x1 amedee.vangasse [09/sep/2016:10:14:50 +0200] "POST https://JIRA_SERVER/rest/scriptrunner/latest/custom/setUserProperties HTTP/1.0" - - - - "cirl/7.47.0" "97ojs1"
127.0.0.1 i614x41877x1 amedee.vangasse [09/sep/2016:10:14:50 +0200] "POST https://JIRA_SERVER/rest/scriptrunner/latest/custom/setUserProperties HTTP/1.0" 404 0 0,0390 - "cirl/7.47.0" "97ojs1"

The same for doSomething.

0 votes
Amedee Van Gasse September 8, 2016

I am using JIRA Software.

Our hosting provider is running the JIRA server in a data center, but I don't see how the physical infrastructure is relevant? Or is "Data Center" something else?

0 votes
JamieA
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.
September 8, 2016

are you using Data Center?

0 votes
Amedee Van Gasse September 8, 2016

I updated my question.

The doSomething sample also gives me a 404 and a content length of 0.

0 votes
JamieA
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.
September 8, 2016

Can you try to add a new one and click the example which is called "simple get" or something, then submit. That should give you a link "doSomething" which you can click from the browser. Can you try that so we can get a bit further. 

Suggest an answer

Log in or Sign up to answer