Scriptrunner rest end point - create issue

kumar sam November 10, 2017

Hi

I would like to create a rest end point in scriptrunner. This should accept projectname, username  and description as input parameters ( may be more later) and create jira issue.

 

Started to write along the following lines:

import com.atlassian.jira.bc.issue.IssueService;
import com.atlassian.jira.component.ComponentAccessor;
import com.atlassian.jira.issue.IssueInputParameters;
import com.onresolve.scriptrunner.runner.rest.common.CustomEndpointDelegate
import groovy.json.JsonBuilder
import groovy.transform.BaseScript

import javax.ws.rs.core.MultivaluedMap
import javax.ws.rs.core.Response

@BaseScript CustomEndpointDelegate delegate

doSomething(httpMethod: "GET", groups: ["jira-administrators"]) { MultivaluedMap queryParams, String body ->

ComponentAccessor.userManager.getUserByName("admin");
IssueService issueService = ComponentAccessor.getIssueService();


IssueInputParameters issueInputParameters = issueService.newIssueInputParameters();

issueInputParameters.setSummary("This is a summary");



return Response.ok(new JsonBuilder([abc: 42]).toString()).build();
}

 

While I am trying to figure this out, do anyone have sample code to create issue from paramters &  A sample test input ...

 

Thanks

 

4 answers

1 accepted

1 vote
Answer accepted
Alexey Matveev
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.
November 10, 2017

Hello, 

You would read parameters with the following line

 String projectName = queryParams.getFirst("projectname").toString()

And so on for all of your parameters. 

You can find an example how to create an issue here

https://community.atlassian.com/t5/Jira-questions/Error-creating-JIRA-tickets-via-groovy-script-set-up-as-a/qaq-p/5113

Alexey Matveev
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.
November 10, 2017

If you need a specific example,  kindly ask

kumar sam November 10, 2017

Thanks Alexey Matveev

I have looked at the link when I googled and took few lines from there..

I am specifically looking for one sample script which can show me how to create issue from input parameters 

and

How the script is called

That way I can use that sample to create rest of my scripts.

I need to write few scripts like this, first I started down known path of creating rest plugin, but when I was reading up chanced upon scriptrunner capability and thought it is much easier this way.

Alexey Matveev
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.
November 11, 2017

Ок. A more detailed example on how to create issue with inputparameters you can find here

https://community.atlassian.com/t5/Jira-questions/How-to-create-issues-in-jira-programmatically-inside-a-listener/qaq-p/352020

Just put it inside your rest endpoint script template. Add to your script a part where you read passed parameters as I explained in my first reply. Then you can call the script by making a call like this

Http(s)://yourjira/rest/scriptrunner/latest/custom/doSomething?projectname=test&username=testuser&descriltion=testdescriptiin

AbrahamA
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.
November 11, 2017

thanks

quick question before I try

if the description is big or if I want to to put description of issue as well would I be putting post instead of get? For my do something method signature

Alexey Matveev
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.
November 11, 2017

From the technical point of view it does not matter if you execute GET, POST, PUT or DELETE. In any case your rest endpoint will work fine. It matters only from the logical point of view. If you create a new issue it would be a POST. But it will work with GET as well.

You can put description of the issue as an additional parameter to the call url. For example, add &issuedescription="my issue description".

On the other hand you could use a json to pass your parameters. For example:

{projectname="projectname", username="username", projectdesc="project description", issuedesc="issuedescription"}

In this case you would analyze body parameter in your REST endpoint:

def mapper = new ObjectMapper()
    def bean = mapper.readValue(body, PriorityJsonBean)
    def projectname =  bean.projectname
    def username = bean.username
and so on

 But if you pass a json and make a call POST or PUT or DELTE, then you can not just call your rest endpoint from the browser. You would need something like curl or firebug.

So, I would begin with a simple GET and pass parameters without a json string. If it works, you can make it a POST and pass parameters via JSON.

kumar sam November 11, 2017

 

Made good progress. Now I am able to create issue from browser url like this:

 

http://localhost:8080/rest/scriptrunner/latest/custom/restCreateIssue?projectname=MPJ&issuetype=bug&reporterid=admin&summary=mysteingdescr&description=mydescription1

 

Here is the code:

import com.atlassian.jira.bc.issue.IssueService
import com.atlassian.jira.component.ComponentAccessor
import com.atlassian.jira.issue.Issue
import com.atlassian.jira.issue.IssueInputParameters
import com.atlassian.jira.issue.index.IssueIndexManager
import com.atlassian.jira.user.ApplicationUser
import com.atlassian.jira.user.util.UserManager
import com.atlassian.jira.util.ErrorCollection

import com.atlassian.jira.issue.IssueInputParameters;
import com.atlassian.jira.project.Project;
import com.atlassian.jira.issue.issuetype.IssueType;

import org.apache.log4j.Category;
import com.atlassian.jira.issue.index.IssueIndexingService;

import com.atlassian.jira.issue.IssueInputParameters;
import com.onresolve.scriptrunner.runner.rest.common.CustomEndpointDelegate
import groovy.json.JsonBuilder
import groovy.transform.BaseScript

import javax.ws.rs.core.MultivaluedMap
import javax.ws.rs.core.Response

@BaseScript CustomEndpointDelegate delegate

restCreateIssue(httpMethod: "GET") { MultivaluedMap queryParams, String body ->

/* Define a Logger */
def Category log = Category.getInstance("com.sam.issueCReate")
log.setLevel(org.apache.log4j.Level.DEBUG)

/* Read input parameters from rest call */
String projectName = queryParams.getFirst("projectname").toString();
String issueTypeName = queryParams.getFirst("issuetype").toString();
String reporterId = queryParams.getFirst("reporterid").toString();
String issueSummary = queryParams.getFirst("summary").toString();
String issueDescription = queryParams.getFirst("description").toString();


/* Get correspoding objcts */
Project project = ComponentAccessor.getProjectManager().getProjectObjByKey(projectName)
def myIssueType = ComponentAccessor.issueTypeSchemeManager.getIssueTypesForProject(project).find{it.name=="Task"}


IssueService issueService = ComponentAccessor.getIssueService();
IssueInputParameters inputParameters = issueService.newIssueInputParameters();

UserManager userManager = ComponentAccessor.getUserManager();
def issueManager = ComponentAccessor.getIssueManager();

inputParameters
.setProjectId(project.getId())
.setIssueTypeId(myIssueType.getId())
.setReporterId(reporterId)
.setSummary(issueSummary)
.setDescription(issueDescription);

// No logged in user for groovy script
ApplicationUser curUser = userManager.getUserByKey(reporterId);

IssueService.CreateValidationResult createValidationResult = issueService.validateCreate(curUser, inputParameters)

def issueIndexingService = ComponentAccessor.getComponent(IssueIndexingService);

if(!createValidationResult.isValid()){
ErrorCollection errorCollection = createValidationResult.getErrorCollection();
return errorCollection.toString()
}
else{
IssueService.IssueResult createResult = issueService.create(curUser, createValidationResult);
log.debug ("Issue created is:"+createResult.getIssue());
issueIndexingService.reIndex(issueManager.getIssueObject(createResult.getIssue().getId()));
}


}

 

 Questions:

1. I am not able to use the passed issueType even though it is a valid issueType. I am getting null pointer exception on this line

.setIssueTypeId(myIssueType.getId())

 thats why I have hardcoded issuetype like this:

def myIssueType = ComponentAccessor.issueTypeSchemeManager.getIssueTypesForProject(project).find{it.name=="Task"}

2.  I am trying make a post call using Postman tool like this:

postman_call.JPG

But it is erroring out.

 

3. Also how do I send issue success or issue failed message depending on the case, I tried Response Object but was getting issues ..

Can you please take a look.

Thanks for all the help.

Abe

kumar sam November 11, 2017

Creating JSON body:

{
"projectname":"MPJ",
"issuetype":"bug",
"reporterid":"admin",
"summary":"jsonsummary1",
"description":"json description"
}

and modifying read like:

import com.atlassian.jira.issue.fields.rest.json.beans.PriorityJsonBean;
import org.codehaus.jackson.map.ObjectMapper;

/* Reading from JSN Body, if request is JSON */
def mapper = new ObjectMapper()
def bean = mapper.readValue(body, PriorityJsonBean)
def projectName = bean.projectname
def issueTypeName = bean.issuetype
def reporterId = bean.reporterid
def issueSummary = bean.summary
def issueDesciption = bean.description

it is giving error:

[Static Issue Type Checking] No such property projectname for class com.atlassian.jira.issue.fields.rest.json.beans.PriorityJsonBean

Alexey Matveev
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.
November 11, 2017

Hello,

Yes, you correctly modified JSON.  

1.  You need to modify the following string like that

def myIssueType = ComponentAccessor.issueTypeSchemeManager.getIssueTypesForProject(project).find{it.name== issueTypeName}

You have to pass "Task" to issuetypename parameter in your REST call

2. You get unauthorized error. When you call your Rest function from the browser, you are authenticated by the same session as in the browser but in Postman you need to pass authentication parameter in the header. Search how you can modify the header in Postman and add to the header the following parameter:

Parameter name: Authorization

Parameter value: <authstring>

You get authstring the following way

convert "username:password" to Base64 then authstirng= "Basic " + "your converted "username:password". You can read more about basic authentication in Jira here:

https://developer.atlassian.com/jiradev/jira-apis/jira-rest-apis/jira-rest-api-tutorials/jira-rest-api-example-basic-authentication

3. You can query parameters from the JSON playload like this

add import groovy.json.JsonSlurper 

then you would query projectname with the following line

def jsonSlurper = new JsonSlurper()
def object = jsonSlurper.parseText(body)
def projectname = ((Map) object).projectname

If I did not answered all your question or you have further questions, then ask.

Alexey Matveev
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.
November 11, 2017

I use SoapUI to play with REST. if you install SOAP UI, I can help you with header settings

Alexey Matveev
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.
November 11, 2017

I forgot about returning errors. You can read more here about it

https://stackoverflow.com/questions/4687271/jax-rs-how-to-return-json-and-http-status-code-together

kumar sam November 12, 2017

Thanks for all the help.

Found that 

createResult.getIssue()  //Always returns null
// if(createResult.getIssue() == null) createResult.getIssue()
//return Response.status(Response.Status.NOT_FOUND).entity("createResult.getIssue() is null ").build();
import com.atlassian.jira.bc.issue.IssueService
import com.atlassian.jira.component.ComponentAccessor
import com.atlassian.jira.issue.Issue
import com.atlassian.jira.issue.IssueInputParameters
import com.atlassian.jira.issue.index.IssueIndexManager
import com.atlassian.jira.user.ApplicationUser
import com.atlassian.jira.user.util.UserManager
import com.atlassian.jira.util.ErrorCollection

import com.atlassian.jira.issue.IssueInputParameters;
import com.atlassian.jira.project.Project;
import com.atlassian.jira.issue.issuetype.IssueType;

import org.apache.log4j.Category;
import com.atlassian.jira.issue.index.IssueIndexingService;

import com.atlassian.jira.issue.IssueInputParameters;
import com.onresolve.scriptrunner.runner.rest.common.CustomEndpointDelegate
import groovy.json.JsonBuilder
import groovy.transform.BaseScript

import javax.ws.rs.core.MultivaluedMap
import javax.ws.rs.core.Response

@BaseScript CustomEndpointDelegate delegate

restCreateIssue(httpMethod: "GET") { MultivaluedMap queryParams, String body ->

/* Define a Logger */
def Category log = Category.getInstance("com.sam.issueCReate")
log.setLevel(org.apache.log4j.Level.DEBUG)

/* Read input parameters from rest call */
String projectName = queryParams.getFirst("projectname").toString();
String issueTypeName = queryParams.getFirst("issuetype").toString();
String reporterId = queryParams.getFirst("reporterid").toString();
String issueSummary = queryParams.getFirst("summary").toString();
String issueDescription = queryParams.getFirst("description").toString();


/* Get correspoding objcts */
Project project = ComponentAccessor.getProjectManager().getProjectObjByKey(projectName)
def myIssueType = ComponentAccessor.issueTypeSchemeManager.getIssueTypesForProject(project).find{it.name=="Task"}
//def myIssueType = ComponentAccessor.issueTypeSchemeManager.getIssueTypesForProject(project).find{it.name== issueTypeName}


if(project == null)
return Response.status(Response.Status.NOT_FOUND).entity("Project Id not found for: " + issueTypeName).build();

if(myIssueType == null)
return Response.status(Response.Status.NOT_FOUND).entity("IssueType Id not found for: " + issueTypeName).build();



IssueService issueService = ComponentAccessor.getIssueService();
IssueInputParameters inputParameters = issueService.newIssueInputParameters();

UserManager userManager = ComponentAccessor.getUserManager();
def issueManager = ComponentAccessor.getIssueManager();

inputParameters
.setProjectId(project.getId())
.setIssueTypeId(myIssueType.getId())
.setReporterId(reporterId)
.setSummary(issueSummary)
.setDescription(issueDescription);


// No logged in user for groovy script
ApplicationUser curUser = userManager.getUserByKey(reporterId);

//return Response.status(Response.Status.NOT_FOUND).entity("User r: " + curUser).build();

IssueService.CreateValidationResult createValidationResult = issueService.validateCreate(curUser, inputParameters)

def issueIndexingService = ComponentAccessor.getComponent(IssueIndexingService);

if(!createValidationResult.isValid()){
ErrorCollection errorCollection = createValidationResult.getErrorCollection();
return Response.status(Response.Status.NOT_FOUND).entity("Entity not found for UUID: " + errorCollection.toString()).build();
// return errorCollection.toString()
}
else{

IssueService.IssueResult createResult = issueService.create(curUser, createValidationResult);
// if(createResult.getIssue() == null) createResult.getIssue()
//return Response.status(Response.Status.NOT_FOUND).entity("createResult.getIssue() is null ").build();
return Response.ok("Issue created", "application/json").build();
// log.debug ("Issue created is:"+createResult.getIssue());
issueIndexingService.reIndex(issueManager.getIssueObject(createResult.getIssue().getId()));
String json = "Issue created is:"+createResult.getIssue();
return Response.ok(json, "application/json").build();
}


}

Not sure why it returns null, I have commented that out and everything is fine. Any insight why that might be null?

I wanted to return issue info back.

I have installed open source version of SoapUI. I will code as you suggested to red input and try first before I ask you..

Thanks

Abe

kumar sam November 12, 2017

 

 

For some reason createResult.getIssue() is returning null. So I am returning before that and it is fine, issue is getting created in Jira. Not sure why createResult.getIssue() is null -- Any idea

IssueService.IssueResult createResult = issueService.create(curUser, createValidationResult);
// if(createResult.getIssue() == null) createResult.getIssue()
//return Response.status(Response.Status.NOT_FOUND).entity("createResult.getIssue() is null ").build();
return Response.ok("Issue created", "application/json").build();
// log.debug ("Issue created is:"+createResult.getIssue());
issueIndexingService.reIndex(issueManager.getIssueObject(createResult.getIssue().getId()));
String json = "Issue created is:"+createResult.getIssue();
return Response.ok(json, "application/json").build();

kumar sam November 12, 2017

I have installed opensource SoapUI, I will work on it and ask you question after that.

Thanks a lot for support.

Updated code so far:

import com.atlassian.jira.bc.issue.IssueService
import com.atlassian.jira.component.ComponentAccessor
import com.atlassian.jira.issue.Issue
import com.atlassian.jira.issue.IssueInputParameters
import com.atlassian.jira.issue.index.IssueIndexManager
import com.atlassian.jira.user.ApplicationUser
import com.atlassian.jira.user.util.UserManager
import com.atlassian.jira.util.ErrorCollection

import com.atlassian.jira.issue.IssueInputParameters;
import com.atlassian.jira.project.Project;
import com.atlassian.jira.issue.issuetype.IssueType;

import org.apache.log4j.Category;
import com.atlassian.jira.issue.index.IssueIndexingService;

import com.atlassian.jira.issue.IssueInputParameters;
import com.onresolve.scriptrunner.runner.rest.common.CustomEndpointDelegate
import groovy.json.JsonBuilder
import groovy.transform.BaseScript

import javax.ws.rs.core.MultivaluedMap
import javax.ws.rs.core.Response

@BaseScript CustomEndpointDelegate delegate

restCreateIssue(httpMethod: "GET") { MultivaluedMap queryParams, String body ->

/* Define a Logger */
def Category log = Category.getInstance("com.sam.issueCReate")
log.setLevel(org.apache.log4j.Level.DEBUG)

/* Read input parameters from rest call */
String projectName = queryParams.getFirst("projectname").toString();
String issueTypeName = queryParams.getFirst("issuetype").toString();
String reporterId = queryParams.getFirst("reporterid").toString();
String issueSummary = queryParams.getFirst("summary").toString();
String issueDescription = queryParams.getFirst("description").toString();


/* Get correspoding objcts */
Project project = ComponentAccessor.getProjectManager().getProjectObjByKey(projectName)
def myIssueType = ComponentAccessor.issueTypeSchemeManager.getIssueTypesForProject(project).find{it.name=="Task"}
//def myIssueType = ComponentAccessor.issueTypeSchemeManager.getIssueTypesForProject(project).find{it.name== issueTypeName}


if(project == null)
return Response.status(Response.Status.NOT_FOUND).entity("Project Id not found for: " + issueTypeName).build();

if(myIssueType == null)
return Response.status(Response.Status.NOT_FOUND).entity("IssueType Id not found for: " + issueTypeName).build();



IssueService issueService = ComponentAccessor.getIssueService();
IssueInputParameters inputParameters = issueService.newIssueInputParameters();

UserManager userManager = ComponentAccessor.getUserManager();
def issueManager = ComponentAccessor.getIssueManager();

inputParameters
.setProjectId(project.getId())
.setIssueTypeId(myIssueType.getId())
.setReporterId(reporterId)
.setSummary(issueSummary)
.setDescription(issueDescription);


// No logged in user for groovy script
ApplicationUser curUser = userManager.getUserByKey(reporterId);

//return Response.status(Response.Status.NOT_FOUND).entity("User r: " + curUser).build();

IssueService.CreateValidationResult createValidationResult = issueService.validateCreate(curUser, inputParameters)

def issueIndexingService = ComponentAccessor.getComponent(IssueIndexingService);

if(!createValidationResult.isValid()){
ErrorCollection errorCollection = createValidationResult.getErrorCollection();
return Response.status(Response.Status.NOT_FOUND).entity("Entity not found for UUID: " + errorCollection.toString()).build();
// return errorCollection.toString()
}
else{

IssueService.IssueResult createResult = issueService.create(curUser, createValidationResult);
// if(createResult.getIssue() == null) createResult.getIssue()
//return Response.status(Response.Status.NOT_FOUND).entity("createResult.getIssue() is null ").build();
return Response.ok("Issue created", "application/json").build();
// log.debug ("Issue created is:"+createResult.getIssue());
issueIndexingService.reIndex(issueManager.getIssueObject(createResult.getIssue().getId()));
String json = "Issue created is:"+createResult.getIssue();
return Response.ok(json, "application/json").build();
}


}
Alexey Matveev
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.
November 12, 2017

By the way, I found a better link about IssueService

https://developer.atlassian.com/jiradev/jira-platform/guides/issues/guide-performing-issue-operations

About your question, createResult is not null, it it? Does createResult.isValid() work?

Alexey Matveev
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.
November 12, 2017

Also, try to see maybe there was a error in the end. Read createResult.getErrorCollection() and have a look what is inside

2 votes
kumar sam November 15, 2017

For anyone else who come across this post here is the full script (Coutesy: Alexey)

import com.atlassian.jira.bc.issue.IssueService
import com.atlassian.jira.component.ComponentAccessor
import com.atlassian.jira.issue.Issue
import com.atlassian.jira.issue.IssueInputParameters
import com.atlassian.jira.issue.index.IssueIndexManager
import com.atlassian.jira.user.ApplicationUser
import com.atlassian.jira.user.util.UserManager
import com.atlassian.jira.util.ErrorCollection

import com.atlassian.jira.issue.IssueInputParameters;
import com.atlassian.jira.project.Project;
import com.atlassian.jira.issue.issuetype.IssueType;

import org.apache.log4j.Category;
import com.atlassian.jira.issue.index.IssueIndexingService;

import com.atlassian.jira.issue.IssueInputParameters;
import com.onresolve.scriptrunner.runner.rest.common.CustomEndpointDelegate
import groovy.json.JsonBuilder
import groovy.transform.BaseScript

import javax.ws.rs.core.MultivaluedMap
import javax.ws.rs.core.Response

/* Reading from JSON */
import com.atlassian.jira.issue.fields.rest.json.beans.PriorityJsonBean;
import org.codehaus.jackson.map.ObjectMapper;
import groovy.json.JsonSlurper;

@BaseScript CustomEndpointDelegate delegate

restCreateIssue1(httpMethod: "POST") { MultivaluedMap queryParams, String body ->

//return Response.ok("beautiful", "application/json").build();

/* Define a Logger */
def Category log = Category.getInstance("com.samsung.issueCreate")
log.setLevel(org.apache.log4j.Level.DEBUG)

/* Read input parameters from get request */

/*
String projectName = queryParams.getFirst("projectname").toString();
String issueTypeName = queryParams.getFirst("issuetype").toString();
String reporterId = queryParams.getFirst("reporterid").toString();
String issueSummary = queryParams.getFirst("summary").toString();
String issueDescription = queryParams.getFirst("description").toString();
*/

// Reading input from POST with JSON payload

def jsonSlurper = new JsonSlurper()
def object = jsonSlurper.parseText(body)
def String projectName = ((Map) object).projectname
def String issueTypeName = ((Map) object).issuetype
def String reporterId = ((Map) object).reporterid
def String issueSummary = ((Map) object).summary
def String issueDescription = ((Map) object).description

//return Response.status(Response.Status.NOT_FOUND).entity("projectName from JSON: " + projectName).build();


/* Get correspoding objcts */
Project project = ComponentAccessor.getProjectManager().getProjectObjByKey(projectName)
//def myIssueType = ComponentAccessor.issueTypeSchemeManager.getIssueTypesForProject(project).find{it.name=="Task"}
def myIssueType = ComponentAccessor.issueTypeSchemeManager.getIssueTypesForProject(project).find{it.name== issueTypeName}


if(project == null)
return Response.status(Response.Status.NOT_FOUND).entity("Project Id not found for: " + issueTypeName).build();

if(myIssueType == null)
return Response.status(Response.Status.NOT_FOUND).entity("IssueType Id not found for: " + issueTypeName).build();



IssueService issueService = ComponentAccessor.getIssueService();
IssueInputParameters inputParameters = issueService.newIssueInputParameters();

UserManager userManager = ComponentAccessor.getUserManager();
def issueManager = ComponentAccessor.getIssueManager();

inputParameters
.setProjectId(project.getId())
.setIssueTypeId(myIssueType.getId())
.setReporterId(reporterId)
.setSummary(issueSummary)
.setDescription(issueDescription);


// No logged in user for groovy script
ApplicationUser curUser = userManager.getUserByKey(reporterId);

//return Response.status(Response.Status.NOT_FOUND).entity("User r: " + curUser).build();

IssueService.CreateValidationResult createValidationResult = issueService.validateCreate(curUser, inputParameters)

def issueIndexingService = ComponentAccessor.getComponent(IssueIndexingService);

if(!createValidationResult.isValid()){
ErrorCollection errorCollection = createValidationResult.getErrorCollection();
return Response.status(Response.Status.NOT_FOUND).entity("Entity not found for UUID: " + errorCollection.toString()).build();
// return errorCollection.toString()
}
else{

IssueService.IssueResult createResult = issueService.create(curUser, createValidationResult);
if(createResult.getIssue() == null)
return Response.status(Response.Status.NOT_FOUND).entity("createResult.getIssue() is nullx "+createResult.getErrorCollection()).build();
return Response.ok("Issue created"+createResult.getIssue().getKey().toString(), "application/json").build();
// log.debug ("Issue created is:"+createResult.getIssue());
issueIndexingService.reIndex(issueManager.getIssueObject(createResult.getIssue().getId()));
String json = "Issue created is:"+createResult.getIssue();
return Response.ok(json, "application/json").build();
}


}
0 votes
kumar sam November 12, 2017

For url:

http://localhost:8080/rest/scriptrunner/latest/custom/restCreateIssue?projectname=MPJ&issuetype=bug&reporterid=admin&summary=mysteingdescr&description=mydescription1

 

 

createResult.getIssue() is null Errors: {}
Error Messages: []

 No error messages in collection.

Alexey Matveev
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.
November 12, 2017

I just tried your code. I return value from Json like this

 

return Response.ok("Issue created is" +createResult.getIssue().getId().toString(), "application/json" ).build();

It works for me. I can see the Id of the created issue. What is your Jira version?

kumar sam November 12, 2017

7.4.0 is my jira version

kumar sam November 12, 2017

ok my bad typo in the line in debug statement. Now it works fine.

I will now go on to JSON

kumar sam November 12, 2017

Here is the updated code:

 

import com.atlassian.jira.bc.issue.IssueService
import com.atlassian.jira.component.ComponentAccessor
import com.atlassian.jira.issue.Issue
import com.atlassian.jira.issue.IssueInputParameters
import com.atlassian.jira.issue.index.IssueIndexManager
import com.atlassian.jira.user.ApplicationUser
import com.atlassian.jira.user.util.UserManager
import com.atlassian.jira.util.ErrorCollection

import com.atlassian.jira.issue.IssueInputParameters;
import com.atlassian.jira.project.Project;
import com.atlassian.jira.issue.issuetype.IssueType;

import org.apache.log4j.Category;
import com.atlassian.jira.issue.index.IssueIndexingService;

import com.atlassian.jira.issue.IssueInputParameters;
import com.onresolve.scriptrunner.runner.rest.common.CustomEndpointDelegate
import groovy.json.JsonBuilder
import groovy.transform.BaseScript

import javax.ws.rs.core.MultivaluedMap
import javax.ws.rs.core.Response

/* Reading from JSON */
import com.atlassian.jira.issue.fields.rest.json.beans.PriorityJsonBean;
import org.codehaus.jackson.map.ObjectMapper;
import groovy.json.JsonSlurper;

@BaseScript CustomEndpointDelegate delegate

restCreateIssue(httpMethod: "GET") { MultivaluedMap queryParams, String body ->

/* Define a Logger */
def Category log = Category.getInstance("com.samsung.issueCreate")
log.setLevel(org.apache.log4j.Level.DEBUG)

/* Read input parameters from rest call */
/*
String projectName = queryParams.getFirst("projectname").toString();
String issueTypeName = queryParams.getFirst("issuetype").toString();
String reporterId = queryParams.getFirst("reporterid").toString();
String issueSummary = queryParams.getFirst("summary").toString();
String issueDescription = queryParams.getFirst("description").toString();
*/

def jsonSlurper = new JsonSlurper()
def object = jsonSlurper.parseText(body)
def String projectName = ((Map) object).projectname
def String issueTypeName = ((Map) object).issuetype
def String reporterId = ((Map) object).reporterid
def String issueSummary = ((Map) object).summary
def String issueDescription = ((Map) object).description

return Response.status(Response.Status.NOT_FOUND).entity("projectName from JSON: " + projectName).build();

/* Get correspoding objcts */
Project project = ComponentAccessor.getProjectManager().getProjectObjByKey(projectName)
def myIssueType = ComponentAccessor.issueTypeSchemeManager.getIssueTypesForProject(project).find{it.name=="Task"}
//def myIssueType = ComponentAccessor.issueTypeSchemeManager.getIssueTypesForProject(project).find{it.name== issueTypeName}


if(project == null)
return Response.status(Response.Status.NOT_FOUND).entity("Project Id not found for: " + issueTypeName).build();

if(myIssueType == null)
return Response.status(Response.Status.NOT_FOUND).entity("IssueType Id not found for: " + issueTypeName).build();



IssueService issueService = ComponentAccessor.getIssueService();
IssueInputParameters inputParameters = issueService.newIssueInputParameters();

UserManager userManager = ComponentAccessor.getUserManager();
def issueManager = ComponentAccessor.getIssueManager();

inputParameters
.setProjectId(project.getId())
.setIssueTypeId(myIssueType.getId())
.setReporterId(reporterId)
.setSummary(issueSummary)
.setDescription(issueDescription);


// No logged in user for groovy script
ApplicationUser curUser = userManager.getUserByKey(reporterId);

//return Response.status(Response.Status.NOT_FOUND).entity("User r: " + curUser).build();

IssueService.CreateValidationResult createValidationResult = issueService.validateCreate(curUser, inputParameters)

def issueIndexingService = ComponentAccessor.getComponent(IssueIndexingService);

if(!createValidationResult.isValid()){
ErrorCollection errorCollection = createValidationResult.getErrorCollection();
return Response.status(Response.Status.NOT_FOUND).entity("Entity not found for UUID: " + errorCollection.toString()).build();
// return errorCollection.toString()
}
else{

IssueService.IssueResult createResult = issueService.create(curUser, createValidationResult);
if(createResult.getIssue() == null)
return Response.status(Response.Status.NOT_FOUND).entity("createResult.getIssue() is nullx "+createResult.getErrorCollection()).build();
return Response.ok("Issue created"+createResult.getIssue().getKey().toString(), "application/json").build();
// log.debug ("Issue created is:"+createResult.getIssue());
issueIndexingService.reIndex(issueManager.getIssueObject(createResult.getIssue().getId()));
String json = "Issue created is:"+createResult.getIssue();
return Response.ok(json, "application/json").build();
}


kumar sam November 12, 2017

soapui_json.JPG

Can you please give some pointers to headers..

Alexey Matveev
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.
November 12, 2017

In Request 1 go to the header tab and put the parameter I was talking abou

Alexey Matveev
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.
November 12, 2017
kumar sam November 14, 2017

Just to update I am able to make get request using parameters and Authorization parameter in soapui

I am trying to figure out how to post JSON payload...

Alexey Matveev
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.
November 14, 2017

that would be the screenshot9-20image7.png

kumar sam November 14, 2017

Hello Alexey

Appreciate all your support. I have tried multiple combinations before posting here..

 

I still am not able to get the json request to jira using soapui. As it is Jira version 7 remote api accepting is by default on...

Here is the screen shot:

json_problem.png

kumar sam November 14, 2017
  • Tue Nov 14 19:27:02 PST 2017:DEBUG:Stale connection check
  • Tue Nov 14 19:27:02 PST 2017:DEBUG:Stale connection detected
  • Tue Nov 14 19:27:02 PST 2017:DEBUG:Connection closed
  • Tue Nov 14 19:27:02 PST 2017:DEBUG:Attempt 1 to execute request
  • Tue Nov 14 19:27:02 PST 2017:DEBUG:Sending request: POST /rest/scriptrunner/latest/custom/restCreateIssue HTTP/1.1
  • Tue Nov 14 19:27:02 PST 2017:DEBUG:Receiving response: HTTP/1.1 404
  • Tue Nov 14 19:27:02 PST 2017:DEBUG:Connection can be kept alive indefinitely
  • Tue Nov 14 19:27:02 PST 2017:INFO:Got response for [http://localhost:8080.:Request 1] in 35ms (17 bytes)
  • Tue Nov 14 19:27:37 PST 2017:DEBUG:Connection closed

Is the response.

kumar sam November 14, 2017

used application/json as Media Type

json_prob2.png

Alexey Matveev
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.
November 14, 2017

Hello,

There is a message on your screenshot "The content which you are trying to view can not be viewed as JSON". Choose there JSON tab.

I guess the error is 404. It means your rest call can not find  your REST endpoint. I had such problems with Scriptrunner. Try to create a new REST endpoint with the same code (change restCreateIssue to restCreateIssue1)

kumar sam November 14, 2017

Tried that but still get 404 :-(

kumar sam November 15, 2017

Ok Figured it out..

Changed first line to POST and it works.

 

A big thanks for your help Alexey.

Rodolfo So March 28, 2021

Hi kumar,

 

Can you provide the working script for this?

 

Appreciate your help on this.

0 votes
kumar sam November 12, 2017
Issue createdErrors: {}
Error Messages: [We can't create this issue for you right now, it could be due to unsupported content you've entered into one or more of the issue fields. If this situation persists, contact your administrator as they'll be able to access more specific information in the log file.]

 

For the call:

http://localhost:8080/rest/scriptrunner/latest/custom/restCreateIssue?projectname=MPJ&issuetype=bug&reporterid=admin&summary=mysteingdescr&description=mydescription1

In the log file I see this:

Caused by: org.ofbiz.core.entity.GenericDataSourceException: SQL Exception while executing the following:SELECT DISTINCT ID FROM PUBLIC.rundetails WHERE JOB_ID=? (General error: "java.lang.IllegalStateException: File corrupted in chunk 226790, expected page length =< 512, got 811808614 [1.4.185/6]"; SQL statement:
SELECT DISTINCT ID FROM PUBLIC.rundetails WHERE JOB_ID=? [50000-185])
at org.ofbiz.core.entity.jdbc.SQLProcessor.executeQuery(SQLProcessor.java:533)
at org.ofbiz.core.entity.GenericDAO.createEntityListIterator(GenericDAO.java:877)
at org.ofbiz.core.entity.GenericDAO.selectListIteratorByCondition(GenericDAO.java:857)
at org.ofbiz.core.entity.GenericHelperDAO.findListIteratorByCondition(GenericHelperDAO.java:216)
at com.atlassian.jira.ofbiz.DefaultOfBizDelegator.findListIteratorByCondition(DefaultOfBizDelegator.java:399)
... 17 more
Caused by: org.h2.jdbc.JdbcSQLException: General error: "java.lang.IllegalStateException: File corrupted in chunk 226790, expected page length =< 512, got 811808614 [1.4.185/6]"; SQL statement:
SELECT DISTINCT ID FROM PUBLIC.rundetails WHERE JOB_ID=? [50000-185]
at org.h2.message.DbException.getJdbcSQLException(DbException.java:345)
at org.h2.message.DbException.get(DbException.java:168)
at org.h2.message.DbException.convert(DbException.java:295)
at org.h2.command.Command.executeQuery(Command.java:209)
at org.apache.commons.dbcp2.DelegatingPreparedStatement.executeQuery(DelegatingPreparedStatement.java:83)
at org.apache.commons.dbcp2.DelegatingPreparedStatement.executeQuery(DelegatingPreparedStatement.java:83)
at org.ofbiz.core.entity.jdbc.SQLProcessor.executeQuery(SQLProcessor.java:527)
... 22 more
Caused by: java.lang.IllegalStateException: File corrupted in chunk 226790, expected page length =< 512, got 811808614 [1.4.185/6]
at org.h2.mvstore.DataUtils.newIllegalStateException(DataUtils.java:773)
at org.h2.mvstore.Page.read(Page.java:640)
at org.h2.mvstore.Page.read(Page.java:194)
at org.h2.mvstore.MVStore.readPage(MVStore.java:1830)
at org.h2.mvstore.MVMap.readPage(MVMap.java:736)
at org.h2.mvstore.Cursor.fetchNext(Cursor.java:150)
at org.h2.mvstore.Cursor.next(Cursor.java:50)
at org.h2.mvstore.db.TransactionStore$TransactionMap$1.fetchNext(TransactionStore.java:1396)
at org.h2.mvstore.db.TransactionStore$TransactionMap$1.next(TransactionStore.java:1435)
at org.h2.mvstore.db.MVSecondaryIndex$MVStoreCursor.next(MVSecondaryIndex.java:508)
at org.h2.index.IndexCursor.next(IndexCursor.java:277)
at org.h2.table.TableFilter.next(TableFilter.java:360)
at org.h2.command.dml.Select.queryFlat(Select.java:532)
at org.h2.command.dml.Select.queryWithoutCache(Select.java:644)
at org.h2.command.dml.Query.query(Query.java:322)
at org.h2.command.dml.Query.query(Query.java:290)
at org.h2.command.dml.Query.query(Query.java:36)
at org.h2.command.CommandContainer.query(CommandContainer.java:90)
at org.h2.command.Command.executeQuery(Command.java:197)
... 26 more
 

 

Andy Heinzer
Atlassian Team
Atlassian Team members are employees working across the company in a wide variety of roles.
November 13, 2017

Hi Kumar,

The error you posted of:

Caused by: org.h2.jdbc.JdbcSQLException: General error: "java.lang.IllegalStateException: File corrupted in chunk 226790, expected page length =< 512, got 811808614 [1.4.185/6]"; SQL statement:

This specific error message is an indication that the H2SQL database is corrupted.   I would recommend reviewing our Jira Supported platforms documentation and then selecting a supported database for Jira and using that instead.   The H2 database is known to easily be corrupted and is never recommended for a production environments.   It is the easiest to setup and that is why it is commonly used for evaluations, but in this case, I would recommend avoiding that database type to move past this specific error.

Regards,
Andy

Suggest an answer

Log in or Sign up to answer