404 while trying to use a JIRA Scriptrunner custom REST endpoint

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

This widget could not be displayed.

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. 

This widget could not be displayed.

I updated my question.

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

This widget could not be displayed.

are you using Data Center?

This widget could not be displayed.

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?

This widget could not be displayed.

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.

This widget could not be displayed.

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

Did you check the application logs for errors?

This widget could not be displayed.

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.

This widget could not be displayed.

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)
This widget could not be displayed.

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.

This widget could not be displayed.

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?

This widget could not be displayed.

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.

This widget could not be displayed.

what versions of ScriptRunner and JIRA?

This widget could not be displayed.

JIRA 7.1.8
ScriptRunner 4.3.6

This widget could not be displayed.

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

This widget could not be displayed.

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.

This widget could not be displayed.

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
This widget could not be displayed.

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!

This widget could not be displayed.

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. 

This widget could not be displayed.

Hi Amedee,

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

regards, Thanos

This widget could not be displayed.

Hello Amedee Van Gasse,

 

do you already have a solution?

This widget could not be displayed.

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

Suggest an answer

Log in or Sign up to answer
Community showcase
Posted Tuesday in Jira

What modern development practices are at the heart of how your team delivers software?

Hey Community mates! Claire here from the Software Product Marketing team. We all know software development changes rapidly, and it's often tough to keep up. But from our research, we've found the h...

84 views 0 1
Join discussion

Atlassian User Groups

Connect with like-minded Atlassian users at free events near you!

Find a group

Connect with like-minded Atlassian users at free events near you!

Find my local user group

Unfortunately there are no AUG chapters near you at the moment.

Start an AUG

You're one step closer to meeting fellow Atlassian users at your local meet up. Learn more about AUGs

Groups near you