Jira Rest API call from a Java plugin

I am trying to call the REST API “rest/applinks/1.0/entitylink/”, which is a private API. I am able to use it from Fiddler, with an Authorization header, and it works frine. However, I would like to use it from my plugin’s Java code. This is my code.

String baseURL = ComponentAccessor.getApplicationProperties().getString(APKeys.JIRA_BASEURL);
String url = baseURL + “/” + restURL;
LoggerUtil.addDebug("Sending PUT request to Jira: " + restURL);

  HttpClient client = HttpClientBuilder.create().build();
  HttpPut putRequest = new HttpPut(url);

  putRequest.addHeader("accept", "application/json");
  StringEntity input = new StringEntity(jsonParamString, StandardCharsets.UTF_8);
  input.setContentType("application/json");
  putRequest.setEntity(input);
  HttpResponse response = client.execute(putRequest);
  LoggerUtil.addDebug("Jira PUT Request code status: " + response.getStatusLine().getStatusCode());

  if (response.getStatusLine().getStatusCode() != 200) {
  	setCodeError(response.getStatusLine().getStatusCode());
  	LoggerUtil.addError("Jira PUT request status: " + response.getStatusLine().getStatusCode() + ", " + response.getStatusLine().getReasonPhrase());
  }

  BufferedReader br = new BufferedReader(new InputStreamReader((response.getEntity().getContent())));

  String output;
  StringBuffer result = new StringBuffer();
  while ((output = br.readLine()) != null) {
  	result.append(output);
  }

However, I get a 401 Unauthorized error. I suppose it’s because I did not include the Authorization header, but I do not really know how to include it since I do not have the current user’s credentials. I might be able to fetch the current logged in user, but I am pretty sure I can’t fetch his password… How can I do a REST call using his user? Or maybe even do a REST call with no users, but with admin permissions.

SAL to the rescue!

Take a look at Unable to compile due to com.atlassian.sal.api.net - #3 by daniel

If you use SAL’s httpclient you can have it do the magic using applicationlinkservice.

I used that in the past to call a Confluence REST API from a Jira plugin using the Application Link. However, in this case, I wished to call a Jira REST API from Jira.

this.applicationLinkService.getApplicationLinks(JiraApplicationType.class))

Won’t that line of ode return an empty list if there are none? Because there won’t be an application link from itself to itself. Or worse, could it return a list of application links to other instances of Jira?

You’re correct - it will return an empty list if there isn’t anything, but you can create application links between Jira instances so it can return those as well - so if you’re trying to Jira1 -> Jira2 - then it would fit your need.

Can you describe the environment you’re trying to make calls between?

I have a Jira instance, on which the plugin is installed, linked to a Confluence instance, with an application link.
I am trying to create a project link (entity link) between a Jira project and a Confluence space. So I fetch the apllication links of type Confluence, find the right one to get its id. Then, I would have like to call the Jira REST API (from the instance I am currently on, because the service to create such a link is not exposed) with the information about the Jira project and Confluence space. Like the follwing (PUT request):

http://192.168.21.240:2050/rest/applinks/1.0/entitylink/com.atlassian.applinks.api.application.jira.JiraProjectEntityType/PROJECTKEY/?reciprocate=true

{
“applicationId”:“64fe1278-9c25-392b-98a5-bde14ef61027”,
“key”:“SPACEKEY”,
“name”:“my space”,
“typeId”:“confluence.space”,
“isPrimary”:true
}

I considered using the SAL to do the same REST call on the Confluence API, but I had difficulties getting the appplication link id (the one from Confluence to Jira, because even if it’s the same link, it’s not the same id since the direction is inverted) to do the call’s body.

Hi @mathieu.yargeau, did you find a solution to this?
I am also trying to get some resource via REST from within Jira (java code) but from the same Jira instance (basically i want to access the REST API of another installed add-on) and can’t figure it out

1 Like

Hello,

How exactly did you use that to call the confluence API from the Jira Plugin? Do you have to create a separate Confluence plugin or write some methods in Jira to connect to Confluence?

Hello @trishna.tilwani

(Sorry for not answering with the same account as I posted before)

You don’t have to create a Confluence plugin if what you want to do can be done through Confluence’s REST API. You cannot call the Confluence’s API directly though, in that case, you would have to create a Confluence plugin.

Here is a small example of how we called the Confluence’s REST API from a Jira Plugin using the application link between Jira and Confluence. This example gets a Confluence page with its space key.

import com.atlassian.sal.api.net.Request.MethodType;
import com.atlassian.applinks.api.ApplicationLink;
import com.atlassian.applinks.api.ApplicationLinkRequest;
import com.atlassian.applinks.api.ApplicationLinkRequestFactory;
import com.atlassian.applinks.api.application.confluence.ConfluenceApplicationType;
import com.atlassian.jira.applinks.JiraApplicationLinkService;

private final JiraApplicationLinkService appLinkService;

ApplicationLink confluenceAppLink = this.appLinkService.getPrimaryApplicationLink(ConfluenceApplicationType.class);
ApplicationLinkRequestFactory requestFactory = confluenceAppLink.createAuthenticatedRequestFactory();

ApplicationLinkRequest request = requestFactory.createRequest(MethodType.GET, “rest/api/space/” + spaceKey + “?expand=homepage”);
request.addHeader(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON);
String json_result = request.execute(new DefaultApplicationLinkResponseHandler(this.i18nResolver));

Hi @myargeau

Thank you so much for your reply.

I have two doubts -

  1. What I need is to call my Confluence’s REST API through my JIRA plugin. For this do I need to create a Confluence plugin? If so, what kind?
  2. I am running into this error - ‘The type com.atlassian.jira.extension.Startable cannot be resolved. It is indirectly referenced from required .class files’ when I am passing the ConfluenceApplicationType.class to the getPrimaryApplicationLink() method

Hope you help me with these. Thank you!

I never saw that error before. Normally, just the following dependency should be enough for using the application links.

    <dependency>
        <groupId>com.atlassian.applinks</groupId>
        <artifactId>applinks-api</artifactId>
        <version>3.2</version>
        <scope>provided</scope>
    </dependency>

You don’t have to create a Confluence plugin if you only need the Confluence REST API, you can make the calls trough the application link. That way, you don’t have to provide the credentials.

Hi @myargeau

I tried adding the above dependency and even tried several other ways, yet the same error persists.
I am using Jira Cloud and Confluence Cloud versions and building my Jira Plugin through connect-spring-boot app. Does your solution work for my above specifications?

Any help is welcome, I’ve been struggling with this for days. Thank you.

Oh. To be honest, I never developped anything for the Cloud versions, so I wouldn’t know. However, this is supposed to work with the Server version.

I’m looking for a solution to this topic. Any update? Thanks

Would like some help on this too. Trying to call from one JIRA Plugin to a REST API served from another JIRA Plugin (on the same server instance). I’m not able to create an ApplicationLink between a JIRA instance and itself. Or is there another way to call HTTP GET using the credentials of the logged in user?

one thing we were doing is to intercept the header on the controller and take over any cookies/authorization headers for the service call on another end point of jira.
if you will run this from some scheduled job I think there is no other way then to introduce technical user and store his credentials in a way you could inject into REST call, since impersonation works only for java api calls not rest calls.
If the other JIra plugin by any chance made public their java api you can use ComponentImport techniques to get direct access to jira plugin functionality (some of the most popular ones do have public java api).