Hello,
In my custom plugin I need to send REST requests to an external api (not jira).
JIRA already bundles jersey (version 1.0.2?) to allow you to add REST resources (endpoints) to your own plugin. It does not seem to include the jersey-client library though.
I've had some difficulties with dependency conflicts and JIRA's OSGI container before.
What is the recommended approach?
Any help appreciated,
Glenn
Community moderators have prevented the ability to post new answers.
Travis's answer is a starting point, but there is little documentation about all of this. I spend some time reading through the rest-api-module source code and tests and played with it for a bit. Here is some more useful info:
To make the requestFactory component available in your plugin, add this to your attlassian-plugin.xml:
<component-import key="requestFactory" interface="com.atlassian.sal.api.net.RequestFactory" />
In your rest client class, you then create a Request object:
Request request = requestFactory.createRequest(Request.MethodType.GET, URL_PATH_TO_YOUR_REST_RESOURCE);
The Request interface has several methods to execute your request:
/** * Executes the request. * * @param responseHandler Callback handler of the response. * @throws ResponseProtocolException If the server returned a malformed response * @throws ResponseTimeoutException If a connection timeout or read timeout occurred * @throws ResponseTransportException If an I/O error occurred in request transport * @throws ResponseException For all errors not otherwise specified */ void execute(ResponseHandler<RESP> responseHandler) throws ResponseException; /** * Executes a request and if response is successful, returns response as a string. @see {@link Response#getResponseBodyAsString()} * * @return response as String * @throws ResponseStatusException If the server returned a response that contained an error code * @throws ResponseProtocolException If the server returned a malformed response * @throws ResponseTimeoutException If a connection timeout or read timeout occurred * @throws ResponseTransportException If an I/O error occurred in request transport * @throws ResponseException For all errors not otherwise specified */ String execute() throws ResponseException; /** * Executes the request and returns a result value. * * @param responseHandler Callback handler of the response. * @throws ResponseProtocolException If the server returned a malformed response * @throws ResponseTimeoutException If a connection timeout or read timeout occurred * @throws ResponseTransportException If an I/O error occurred in request transport * @throws ResponseException For all errors not otherwise specified * @since v2.2.0 */ <RET> RET executeAndReturn(ReturningResponseHandler<RESP, RET> responseHandler) throws ResponseException;
If you want the reponse as a String, you can simply call request.execute(). However, if you want to leverage atlassian-rest-module's automatic unmarshalling of JAXB annotated entities, then you need to call request.executeAndReturn(ReturningResponseHandler<RESTP, RET> responseHandler).
Afaik, the SAL api does not provide an implementation of a ReturningResponseHandler, so you need to roll your own. For example:
public class MyReponseHandler<RET> implements ReturningResponseHandler<Response, RET> { private final Class<RET> entity; public MyReponseHandler(Class<RET> entity) { this.entity = entity; } @Override public RET handle(Response response) throws ResponseException { return response.getEntity(entity); } }
Then in your rest client class, you can create an instance of your ReturningResponseHandler that is typed for your entity (in this example, the entity class is Hello, which contains JAXB annotations):
this.responseHandler = new MyReponseHandler(Hello.class);
and you can execute your request:
Hello hello = (Hello)request.executeAndReturn(responseHandler);
Note that you still have to cast the result to the correct type, but it wil unmarshal correctly.
Hopefully this saves someone some time
How to authenticate the REST call for the logged in user before sending them when I tried using addTrustedTokenAuthentication() function, i get this error saying "method lookup failed for selector". What can be the problem?
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
I am trying to use the requestFactory, but I fail to properly instantiate it. The only example I find on Google are with Application Link ( to target Jira end point or confluence ).
Would someone a code snippet to properly instantiate it ?
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
@Florian Maupas
Working for me:
@Scanned
@Component
public class ARTService {
private final RequestFactory requestFactory;
@Inject
public ARTService(@ComponentImport RequestFactory requestFactory) {
this.requestFactory = requestFactory;
}
}
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
Atlassian ships Shared Access Layer with all the products, guidance would to be leverage SAL's RequestFactory
to handle remote communications, including REST calls.
You are welcomed to try and bundle jersey-client as a private module for your add-on, but it's not impossible you will run into issues doing so.
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
How to authenticate the REST call for the logged in user before sending them when I tried using addTrustedTokenAuthentication() function, i get this error saying "method lookup failed for selector". What can be the problem?
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.