With JIRA5, a lot of the operations can be done using the REST API and here is the full list of operations supported.
But if you are yet unsure on how to invoke these REST operations from a Java client, read on...
Before boring you further, I must say that the best Java client for JIRA REST APIs is JRJC - The JIRA Rest Java Client supported by Atlassian. But at least for now, it doesn't support all the Issue CRUD methods. I must add that it won't be long before they are added (or is available when you re reading it!).
Still, what if you want to create another client? Without the dependency on something like JRJC? Let us look at a rather simple option - Using Jersey to write a REST Client.
I have mentioned about JRJC in my book but the following part is probably missing from the book. Considering the JIRA5 REST capabilities, it is never too late to write something about it, is it?
As mentioned before, I am just going to look at Jersey and see how we can write a simple client. Let us start with creating a simple maven project. Following is the dependency that needs to be added for using the jersey client libraries.
<dependency>
<groupId>com.sun.jersey</groupId>
<artifactId>jersey-client</artifactId>
<version>1.8</version>
</dependency>
Change the version as appropriate!
Consider a simple scenario. We need to get a list of all projects in a JIRA instance. As per the API docs, the REST url is /rest/api/2/project and it is a GET operation. Following are the steps:
- Choose the authentication style. We are going to use the basic authentication as that is the simplest to explain. But if you are interested, there is an explanation of OAuth dance here.
- Create the basic authentication String. We will be using it in the REST call.
String auth = new String(Base64.encode("username:password")); - Instantiate a Jersey Client and create a Web resource that is capable of building requests to send to the REST resource and process responses returned from the resource.
Client client = Client.create();
WebResource webResource = client.resource("http://localhost:8080/rest/api/2/project");
Here the url used is the base url of JIRA + the rest resource url. - Obtain the response using the webResource after setting the required parameters like authentication type, media type etc.
ClientResponse response = webResource.header("Authorization", "Basic " + auth).type("application/json").accept("application/json").get(ClientResponse.class);
As you can see, we have set the basic authentication parameters in the header which includes the authentication String we created in Step 2. You can add even custom values in the header as long as the server can use it but in our case that is not required.
The media type we used is application/json as that is the one supported by JIRA REST methods.
We are also using the get method here and accepts the response into the ClientResponse class.
That's it! We have sent the request and got the response. It is now only a matter of making sure the response is what is expected. The easiest thing to do is to check the status code in the response. For example, a response code in the 200 range is normally successful where as 401, for example, indicates invalid authentication error!
A good list of status codes can be found here.
You can get the status code and check it like this:
int statusCode = response.getStatus();
if (statusCode == 401) {
throw new AuthenticationException("Invalid Username or Password");
}
And what is the status code is fine? If you are expecting a response, like in our case - list of projects, we can get the result as shown:
String response = response.getEntity(String.class);
Here the response will be in json format since that is what is given back by JIRA. Remember, the media type we set was application/json!
A sample output is here:
[
{
"self": "http://localhost:8080/rest/api/2/project/DEMO",
"id": "10000",
"key": "DEMO",
"name": "DEMO",
"avatarUrls": {
"16x16": "http://localhost:8080/secure/projectavatar?size=small&pid=10000&avatarId=10011",
"48x48": "http://localhost:8080/secure/projectavatar?pid=10000&avatarId=10011"
}
},
{
"self": "http://localhost:8080/rest/api/2/project/TEST",
"id": "10001",
"key": "TEST",
"name": "TEST",
"avatarUrls": {
"16x16": "http://localhost:8080/secure/projectavatar?size=small&pid=10001&avatarId=10011",
"48x48": "http://localhost:8080/secure/projectavatar?pid=10001&avatarId=10011"
}
}
]
As you can see, the response here is a JSON array and you can now extract the details from here as you wish! Here is small example of extracting the key and name.
We will use JSON in java for this. The dependency to be added is:
<dependency>
<groupId>org.json</groupId>
<artifactId>json</artifactId>
<version>20090211</version>
</dependency>
You can simply extract the key and name as follows:
JSONArray projectArray = new JSONArray(jsonResponse);
for (int i = 0; i < projectArray.length(); i++) {
JSONObject proj = projectArray.getJSONObject(i);
System.out.println("Key:"+proj.getString("key")+", Name:"+proj.getString("name"));
}
So, that was a simple GET example. How about creating/updating/deleting an issue? I have taken these examples because they use POST/PUT/DELETE operations.
Creating an issue
As per the docs, we need to POST the fields required to create the issue to the REST resource. The url is http://localhost:8080/rest/api/2/issue and the simple json input with just summary, project and issuetype details will be something like this:
{"fields":{"project":{"key":"DEMO"},"summary":"REST Test","issuetype":{"name":"Bug"}}}
Everything else remains the same expect that we will be using post method with the above data.
private static String invokePostMethod(String auth, String url, String data) throws AuthenticationException, ClientHandlerException {
Client client = Client.create();
WebResource webResource = client.resource(url);
ClientResponse response = webResource.header("Authorization", "Basic " + auth).type("application/json")
.accept("application/json").post(ClientResponse.class, data);
int statusCode = response.getStatus();
if (statusCode == 401) {
throw new AuthenticationException("Invalid Username or Password");
}
return response.getEntity(String.class);
}
Updating an issue
The url will have the issue key we need to edit: http://localhost:8080/rest/api/2/issue/DEMO-13. A simple example of json data to change the assignee will be:
{"fields":{"assignee":{"name":"test"}}}
Everything else remains same except that we use the PUT method:
private static void invokePutMethod(String auth, String url, String data) throws AuthenticationException, ClientHandlerException {
Client client = Client.create();
WebResource webResource = client.resource(url);
ClientResponse response = webResource.header("Authorization", "Basic " + auth).type("application/json")
.accept("application/json").put(ClientResponse.class, data);
int statusCode = response.getStatus();
if (statusCode == 401) {
throw new AuthenticationException("Invalid Username or Password");
}
}
Note that we are not returning any response here since the REST method doesn't return anything. The status code of 204 indicates 'No Content'.
Deleting an issue
As you would expect, this doesn't need any additional data as the url has the issue key in it: http://localhost:8080/rest/api/2/issue/DEMO-13. The operation is DELETE as opposed to PUT.
private static void invokeDeleteMethod(String auth, String url) throws AuthenticationException, ClientHandlerException {
Client client = Client.create();
WebResource webResource = client.resource(url);
ClientResponse response = webResource.header("Authorization", "Basic " + auth).type("application/json")
.accept("application/json").delete(ClientResponse.class);
int statusCode = response.getStatus();
if (statusCode == 401) {
throw new AuthenticationException("Invalid Username or Password");
}
}
Well, that wraps up the basics. Everything else is just an extension of this. https://developer.atlassian.com/display/JIRADEV/JIRA+REST+API+Tutorials has a whole lot of examples with data for each operation. Also attached to this post is the Java project we used for this post.
Don't forget to have a look at the JIRA Development Cookbook.
| rest-client.zip |


RSS Feed