how to start development with JIRA ?

Prabu Sivagnanam May 19, 2019

Myself Salesforce developer, want to create integration between Salesforce & JIRA...As of now doing POC on this (I already did 1 POC by using 3rd party -Service Rocket connectors,but our management dont' want since the connectors are paid), our company using JIRA server version..So how can I proceed with this since i know only salesforce part and dont have any idea how to start development with JIRA ? even i don't know whether jira is customizable ?, what language its built on?,where to type code?...I didn't find any proper document for this.. mobile: +91 9080487629

1 answer

1 accepted

0 votes
Answer accepted
Prakhar Srivastav {Appfire}
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.
May 19, 2019

@Prabu Sivagnanam 

The answer may change based on the complexity of what you want to achieve. But if you are proficient on Salesforce then I will suggest to write your code in Salesforce and interact with JIRA via REST APIs.

Regards

Prakhar

Prabu Sivagnanam May 19, 2019

Thank you Prakhar for your quick response!

 

Yes i followed what you saying here by putting all the coding efforts in Salesforce side (both pushing the issues to JIRA & pulling the issues from JIRA)...But the business fine with first half approch but not with second half of my approach.. instead of pulling from JIRA  by salesforce code via Rest API Call they want to set up a mechanism in JIRA itself to get it pushed to salesforce whenever new record or created in JIRA

 

FYI the demo which i shown to business on my POC :https://drive.google.com/file/d/1VR_iHIcrTNcDhO3-bAp--Dc24vyE6mHo/view?usp=sharing

 

Note- I made a integration between 'issue' object in JIRA & the custom object 'JiraIssue' which i created in SFDC.(All coding i did in saleforce side only,since i dont know JIRA development)

i just did 2 things in salesfoce

****1.Pushing issue to the JIRA , From Salesforce****

Trigger on salesforce object 'JiraIssue' - whenever this record created in saleforce , i am creating the same issue in Jira by using REST API Call (url = jira_host + '/rest/api/2/issue/')

****2.Pulling issue from JIRA, From Salesforce****

Running a batch job in Salesforce periodically and pulling the issue from JIRA and inserting or updating in salesforce , by using the REST API Call (url = 'https://prabusmi.atlassian.net/rest/api/2/search?jql='+ '&fields=' + fieldsQuery + '&startAt='+ startAt +'&maxResults='+maxResults;)


But business fine with the step 1, But in the step 2 they feeling it better to pushing the issue from JIRA whenever update happens in issue record instead of pulling from salesforce by batch,

 

Can I have your mail id ? or can you ping me at +91 9080487629

Prakhar Srivastav {Appfire}
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.
May 20, 2019

@Prabu Sivagnanam 

I understand that you want to push jira issue data to salesforce in step 2 but you have not mentioned when : 

 I assume that you want to push single issue data in its issue lifecycle , so for example if an issue is created or change workflow status then you can use something called as post function in jira.

Since you do not want to use any plugin so you can develop a post function using Atlassian SDK in Java (though it will have a steep learning curve).

Usually most of the JIRA instances have some kind of groovy scripting plugin available (like scriptrunner). You can check with your JIRA Admin and utilise this to create a groovy script post function which will update Salesfore.

My personal email id is prax0724@gmail.com

Regards

Prakhar

Like Prabu Sivagnanam likes this
Prabu Sivagnanam May 20, 2019

as of now i'm going through the document https://developer.atlassian.com/server/jira/platform/getting-started/

Can you give me any documentation on develop a post function using Atlassian SDK in Java & groovy script post function  if you have ?  

 

Regards,

Prabu

Prakhar Srivastav {Appfire}
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.
May 20, 2019
Like Prabu Sivagnanam likes this
Prabu Sivagnanam May 21, 2019

Hi Prakhar,

 

Thank you so much for your inputs, i will follow the links given by you right away, will connect with you again if I get any query..Btw today I have created my first JIRA-Confluence plugin.

 

Regards,

Prabu

Prakhar Srivastav {Appfire}
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.
May 21, 2019

@Prabu Sivagnanam 

That is great to hear. Happy Learning !!

Prabu Sivagnanam May 21, 2019

Hi Prakhar,

 

Today i  practicing the add workflow  extension topic in the link given by you https://developer.atlassian.com/server/jira/platform/creating-workflow-extensions/#part-2-create-the-workflow-post-function

 

it seems i made mistake somewhere in the code while doing it manually so just cloned it from the repository to my folder ( git clone https://bitbucket.org/atlassian_tutorial/tutorial-jira-add-workflow-extensions )

but Build is failed & getting the below error ,i wonder why i am getting error even after cloning the repository itself in my local

Build Error in JIRA.png

 

How to fix this ?

 

Regards,

Prabu

Prakhar Srivastav {Appfire}
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.
May 22, 2019

@Prabu Sivagnanam 

The problem can be because of AMPS incompatibility. AMPS is maven wrapper that comes with your Atlassian SDK.

There are 2 ways now :

  • Look to make your sdk compatible to the code
  • Or I will suggest to work with your installed sdk , step by step.

 

Regards

Prakhar

Prabu Sivagnanam May 22, 2019

Hi Prakhar,

it is worked by using the command atlas-run -u 6.3.21  instead of  atlas-run

 

 

As the instructions given in the below link

https://community.atlassian.com/t5/Jira-questions/Failed-to-run-plugin-Couldn-t-detect-an-AMPS-product-to-dispatch/qaq-p/917687

https://ecosystem.atlassian.net/browse/ATLASSDK-147

 

Regards,

Prabu

Prabu Sivagnanam May 23, 2019

Hi Prakhar,

Can you give me the code which implemented on JIRA to some other system integration..so it may helpful for me to modify it according to my JIRA - SFDC POC

Regards,
Prabu

Prakhar Srivastav {Appfire}
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.
May 24, 2019

Hi @Prabu Sivagnanam 

I am not very sure what you are expecting here. But if you have successfully developed a sample post function , then in that post function you just need to call your other system (in this case salesforce api) based on your need.

In the code you also have the access to the the issue object so you can extract the information from there.

If you just want to call the salesforce API and don't need to run any complex logic then it may be easier to use webhooks as postfunction. You can read the details about webhooks in the following documentation.

https://developer.atlassian.com/server/jira/platform/webhooks/

 

Regards

Prakhar

Prabu Sivagnanam May 27, 2019

Hi @Prakhar Srivastav {Appfire} ,

 

Thanks for your reply, I will check on webhooks. (sorry for bothering you again and again but i have no other way)

Today i have worked on workflow post functions, but Getting this issue while click on close issue or Resolve issue or Start Progress

Communications Breakdown

The JIRA server could not be contacted. This may be a temporary glitch or the server may be down.

Close this dialog and press refresh in your browser

 

Getting this issue whilw click on close issue or Resolve issue or Start Progress.png

 

Regards,

Prabu

Prabu Sivagnanam May 30, 2019

Hi Prakhar,

 

Today I have added Adaptavist Scriptrunner plugin in my Localhost & trying to write some small Listeners and saving it then try to testing it by updating the issue record...

 

Am I Going in right direction ? Can we write the Workflow post functions under this Script Listeners ?

 

First Scriptrunner1.png

First Script runner.png

 

Regards,

Prabu

Prabu Sivagnanam June 2, 2019

Hi Prakhar,

Thank you so much for your help without your guidance this time i might be clueless

Today I have successfully executed my first Groovy script & desired output (Note:Last week even i dont know where to type the groovy script).Hope I can build from here

 

Updating issue via Groovy script Listener.png

 

Since Script Listener itself doing the the needed things I can do the pushing JIRA issue to salesforce from Script listener instead of going for workflow post function right ?

 

Regards,

Prabu

Prabu Sivagnanam June 3, 2019

 

Hi Prakhar,

Now I able to push the issue from JIRA to Salesforce by Groovy Script Listener.

Able to push the issue from JIRA to Salesforce.png

below is the groovy script i used

 


import com.atlassian.jira.component.ComponentAccessor
import com.atlassian.jira.issue.IssueManager
import com.atlassian.jira.issue.Issue
import com.atlassian.jira.issue.MutableIssue
import com.opensymphony.workflow.InvalidInputException
import java.sql.Timestamp;
import com.atlassian.jira.issue.customfields.manager.OptionsManager
import com.atlassian.jira.issue.customfields.option.Option
import groovy.time.*
import com.atlassian.jira.issue.IssueManager
import com.atlassian.jira.event.type.EventDispatchOption
import com.atlassian.crowd.embedded.api.User

import com.atlassian.jira.util.json.JSONObject


import com.atlassian.jira.ComponentManager;
import com.atlassian.jira.issue.CustomFieldManager;
import com.atlassian.jira.issue.fields.CustomField;


import org.apache.http.Header;
import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpDelete;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.message.BasicHeader;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.HttpStatus;
import org.apache.http.util.EntityUtils;
import org.apache.http.client.ClientProtocolException;

import groovy.json.*;
import groovy.*;
import groovy.json.JsonBuilder

def customFieldManager = ComponentAccessor.getCustomFieldManager()
def issueManager = ComponentAccessor.getIssueManager()

MutableIssue mIssue = issue
Issue NormalIssue= issue
//Issue mIssue = issue


String USERNAME = "prabu.mxian@gmail.com";
String PASSWORD = "Sivagnanam_1986zNTSLZwP4ZmvtF7hPt6e5Yj8V";
String LOGINURL = "https://login.salesforce.com";
String GRANTSERVICE = "/services/oauth2/token?grant_type=password";
String CLIENTID = "3MVG9ZL0ppGP5UrCXsOh.d6l68oKQ_R7KCt_esx6L4Z8kCeY883R3jHngpUPR9BxyRrcudwCv_IehQVO2ek8Q";
String CLIENTSECRET = "C8ADB489D581847B59022FF4802F43B13ABF889FA9E40FF59B27F59E7E1A5FAA";
String REST_ENDPOINT = "/services/data" ;

String API_VERSION = "/v32.0" ;
String baseUri;
Header oauthHeader;
Header prettyPrintHeader = new BasicHeader("X-PrettyPrint", "1");

String JiraIssueId ;
String JiraIssueName;
String JiraIssueDescription;
String JiraIssueIssuetype;
String JiraIssueProject_Id;
String JiraIssueIssue_Key;
String JiraIssueSummary;

HttpClient httpclient = HttpClientBuilder.create().build();

// Assemble the login request URL

String loginURL = LOGINURL +
GRANTSERVICE +
"&client_id=" + CLIENTID +
"&client_secret=" + CLIENTSECRET +
"&username=" + USERNAME +
"&password=" + PASSWORD;


// Login requests must be POSTs

HttpPost httpPost = new HttpPost(loginURL);
HttpResponse response = null;

try {

// Execute the login POST request

response = httpclient.execute(httpPost);

}catch (ClientProtocolException cpException) {

cpException.printStackTrace();

} catch (IOException ioException) {

ioException.printStackTrace();

}

int statusCode = response.getStatusLine().getStatusCode();
String getResult = EntityUtils.toString(response.getEntity());
def json =getResult
def parsedJson = new groovy.json.JsonSlurper().parseText(json);

// JSONObject jsonObject = null;
String loginAccessToken = parsedJson.access_token;
String loginInstanceUrl = parsedJson.instance_url;
String tokenType=parsedJson.token_type;
String Signature=parsedJson.signature;

baseUri = loginInstanceUrl + REST_ENDPOINT + API_VERSION ;
oauthHeader = new BasicHeader("Authorization", "OAuth " + loginAccessToken) ;

String uri = baseUri + "/sobjects/JiraIssue__c/";
/**************************/
//create the JSON object containing the new JIRA_Issue details.

JSONObject JiraIssue = new JSONObject();

JiraIssue.put("Description__c", mIssue.getDescription());
//JiraIssue.put("Issuetype__c", cFieldValue);
JiraIssue.put("Project_Id__c", mIssue.getProjectObject());
JiraIssue.put("Summary__c", mIssue.getSummary());
// JiraIssue.put("Issue_Key__c", "Bug");

//Construct the objects needed for the request
HttpClient httpClient = HttpClientBuilder.create().build();
HttpPost httpPostCreate = new HttpPost(uri);
httpPostCreate.addHeader(oauthHeader);
httpPostCreate.addHeader(prettyPrintHeader);
// The message we are going to post
StringEntity body = new StringEntity(JiraIssue.toString(1));
body.setContentType("application/json");
httpPostCreate.setEntity(body);
//Make the request
HttpResponse responseCreate = httpClient.execute(httpPostCreate);
//Process the results
int statusCodeCreate = responseCreate.getStatusLine().getStatusCode();
/***************************/

Prabu Sivagnanam June 3, 2019

Hi Prakhaar,

 

Now I able to push the issue from JIRA to Salesforce by JIRA Groovy script listener.

Able to push the issue from JIRA to Salesforce.png

 

The code i developed for it

 

import com.atlassian.jira.component.ComponentAccessor
import com.atlassian.jira.issue.IssueManager
import com.atlassian.jira.issue.Issue
import com.atlassian.jira.issue.MutableIssue
import com.opensymphony.workflow.InvalidInputException
import java.sql.Timestamp;
import com.atlassian.jira.issue.customfields.manager.OptionsManager
import com.atlassian.jira.issue.customfields.option.Option
import groovy.time.*
import com.atlassian.jira.issue.IssueManager
import com.atlassian.jira.event.type.EventDispatchOption
import com.atlassian.crowd.embedded.api.User

import com.atlassian.jira.util.json.JSONObject


import com.atlassian.jira.ComponentManager;
import com.atlassian.jira.issue.CustomFieldManager;
import com.atlassian.jira.issue.fields.CustomField;


import org.apache.http.Header;
import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpDelete;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.message.BasicHeader;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.HttpStatus;
import org.apache.http.util.EntityUtils;
import org.apache.http.client.ClientProtocolException;

import groovy.json.*;
import groovy.*;
import groovy.json.JsonBuilder

def customFieldManager = ComponentAccessor.getCustomFieldManager()
def issueManager = ComponentAccessor.getIssueManager()

MutableIssue mIssue = issue
Issue NormalIssue= issue
//Issue mIssue = issue


String USERNAME = "prabu.mxian@gmail.com";
String PASSWORD = "Sivagnanam_1986zNTSLZwP4ZmvtF7hPt6e5Yj8V";
String LOGINURL = "https://login.salesforce.com";
String GRANTSERVICE = "/services/oauth2/token?grant_type=password";
String CLIENTID = "3MVG9ZL0ppGP5UrCXsOh.d6l68oKQ_R7KCt_esx6L4Z8kCeY883R3jHngpUPR9BxyRrcudwCv_IehQVO2ek8Q";
String CLIENTSECRET = "C8ADB489D581847B59022FF4802F43B13ABF889FA9E40FF59B27F59E7E1A5FAA";
String REST_ENDPOINT = "/services/data" ;

String API_VERSION = "/v32.0" ;
String baseUri;
Header oauthHeader;
Header prettyPrintHeader = new BasicHeader("X-PrettyPrint", "1");

String JiraIssueId ;
String JiraIssueName;
String JiraIssueDescription;
String JiraIssueIssuetype;
String JiraIssueProject_Id;
String JiraIssueIssue_Key;
String JiraIssueSummary;

HttpClient httpclient = HttpClientBuilder.create().build();

// Assemble the login request URL

String loginURL = LOGINURL +
GRANTSERVICE +
"&client_id=" + CLIENTID +
"&client_secret=" + CLIENTSECRET +
"&username=" + USERNAME +
"&password=" + PASSWORD;


// Login requests must be POSTs

HttpPost httpPost = new HttpPost(loginURL);
HttpResponse response = null;

try {

// Execute the login POST request

response = httpclient.execute(httpPost);

}catch (ClientProtocolException cpException) {

cpException.printStackTrace();

} catch (IOException ioException) {

ioException.printStackTrace();

}

int statusCode = response.getStatusLine().getStatusCode();
String getResult = EntityUtils.toString(response.getEntity());
def json =getResult
def parsedJson = new groovy.json.JsonSlurper().parseText(json);

// JSONObject jsonObject = null;
String loginAccessToken = parsedJson.access_token;
String loginInstanceUrl = parsedJson.instance_url;
String tokenType=parsedJson.token_type;
String Signature=parsedJson.signature;

baseUri = loginInstanceUrl + REST_ENDPOINT + API_VERSION ;
oauthHeader = new BasicHeader("Authorization", "OAuth " + loginAccessToken) ;

String uri = baseUri + "/sobjects/JiraIssue__c/";
/**************************/
//create the JSON object containing the new JIRA_Issue details.

JSONObject JiraIssue = new JSONObject();

JiraIssue.put("Description__c", mIssue.getDescription());
//JiraIssue.put("Issuetype__c", cFieldValue);
JiraIssue.put("Project_Id__c", mIssue.getProjectObject());
JiraIssue.put("Summary__c", mIssue.getSummary());
// JiraIssue.put("Issue_Key__c", "Bug");

//Construct the objects needed for the request
HttpClient httpClient = HttpClientBuilder.create().build();
HttpPost httpPostCreate = new HttpPost(uri);
httpPostCreate.addHeader(oauthHeader);
httpPostCreate.addHeader(prettyPrintHeader);
// The message we are going to post
StringEntity body = new StringEntity(JiraIssue.toString(1));
body.setContentType("application/json");
httpPostCreate.setEntity(body);
//Make the request
HttpResponse responseCreate = httpClient.execute(httpPostCreate);
//Process the results
int statusCodeCreate = responseCreate.getStatusLine().getStatusCode();
/***************************/

Prabu Sivagnanam June 5, 2019

in my start of POC i connected with JIRA cloud from Salesforce using OAuth by making use of the API token Generated by JIRA cloud and used that token from salesforce in the initial request..but now actually our business want to do it for JIRA Server not for JIRA cloud.

// f9rHPdeHiFgDCq8RPgr0591A is the security token from Atlassian account profile --> Manage your Account-->Security-->API token-->Create and manage API tokens--> Manage your account-->API tokens


username = 'prabu.s@mookambikainfo.com';
password = 'f9rHPdeHiFgDCq8RPgr0591A';
jira_host = 'https://prabusmi.atlassian.net';
auth_header = 'Basic ' + EncodingUtil.base64Encode(Blob.valueOf(username + ':' + password));

url = jira_host + '/rest/api/2/issue/';
cls_issue issue_Obj=new cls_issue();

json=SYSTEM.JSON.serialize(issue_Obj);

Http http = new Http();
HttpRequest req = new HttpRequest();
req.setHeader('Content-Type', 'application/json');
req.setHeader('Accept','application/json');
req.setHeader('Authorization', auth_header);
req.setHeader('X-Atlassian-Token', 'nocheck');
req.setMethod('POST');
req.setbody(json);

req.setEndpoint(url);
HTTPResponse response = http.send(req);

 

Above Apex code is for connecting with JIRA from Salesforce by using API Token given by JIRA and implementing OAuth

But Jira Server does not provide those specific types of API tokens that can be used in basic auth, like Jira Cloud does.

Just now i have did code(in Salesforce  for connecting with JIRA using Basic Authentication.

-------------------------------------------------------------------------------------------------

I able to connect with the app which is hosted on web server which having internet address.

HTTP h = new HTTP();

HTTPRequest r = new HTTPRequest();

r.setEndpoint('https://workflowtest.ghx.com/rest/api/2/issue/createmeta');
Blob headerValue = Blob.valueOf('Uname' + ':' + 'Pwd');

String authorizationHeader = 'Basic ' + EncodingUtil.base64Encode(headerValue);
System.debug('authorizationHeader : '+authorizationHeader );
r.setHeader('Authorization', authorizationHeader);
r.setMethod('GET');
HTTPResponse resp = h.send(r);

 

Output : I able to connect with the JIRA server hosted on Web  - workflowtest.ghx.com

-----------------------------------------------------------------------------------------------

But unable to connect with my localhost:2990(actually my business asked me to do POC in the local)

HTTP h = new HTTP();

HTTPRequest r = new HTTPRequest();
//http://localhost:2990/jira/rest/api/2/issue/TP-7
r.setEndpoint('http://192.168.3.43:2990/jira/rest/api/2/issue/TP-7');
//r.setEndpoint('http://localhost:2990/jira/plugins/servlet/restbrowser#/');
Blob headerValue = Blob.valueOf('admin' + ':' + 'admin');

String authorizationHeader = 'Basic ' + EncodingUtil.base64Encode(headerValue);
System.debug('authorizationHeader : '+authorizationHeader );
r.setHeader('Authorization', authorizationHeader);
r.setMethod('GET');
HTTPResponse resp = h.send(r);

I told the business as below

********************************** *

Output: I tried many combination here  by changing URI of the Localhost URI many ways but always getting [Status=Forbidden, StatusCode=403], So it seems i cant connect with localhost from salesforce since salesforce can't resolve the URL in Local host

************************************

FYI I able to connect with workflowtest.ghx.com(Jira Server version) with Basic Authorization from salesforce (instead of OAuth which i used previously connecting to Jira cloud from Salesforce)....I trying to replicate the same Basic Authorization with Jira which running in my localhost,

From Salesforce we can't connect with application which is hosted in localhost ,Salesforce can connect with the applications only hosted on internet web server...So Can I use workflowtest.ghx.com for POC purpose ?

But business replied as below

**********************************

sorry, dont want to POC work in workflowtest.ghx.com(Jira Server version) 

Prabu Sivagnanam June 19, 2019

Hi @Prakhar Srivastav {Appfire} , @Alec Jasanovsky ,  I would like to say thank you guys,

Done with my Salesforce -- JIRA integration POC

 

Demo Video of MY POC: https://drive.google.com/file/d/10MsHbK9kHH-0YmI7aaEJv66YkzqdRavp/view?usp=sharing

Salesforce & JIRA Code of my POC : https://drive.google.com/file/d/1sUepNqdIEoo3n9P6yfdI-wDOYxXtb_RE/view?usp=sharing

 

Thank you so much guys!

 

Regards,

Prabu

Prabu S December 17, 2019

The demo video & code i have shared in the previous link not accessible anymore since I left that company, so i am sharing the code from my developer sandbox and sharing it  from my personal google drive

 

https://drive.google.com/open?id=1JbsshKEYeDEELF6mRXj2kANqsz0MbfYR

amol_navthale March 31, 2020

Hi Prabu,

 

it containg rar with 1kb , no files in rar.

Could you please add, it will be great help.

Suggest an answer

Log in or Sign up to answer