Extracting data from JIRA using Clojure and REST

March 2, 2012 at 10:45 pm | Posted in Clojure, Programming | 2 Comments

I have previously written two posts about getting data from JIRA. In the first one I described how you can do that in Ruby. In the other one I used JavaScript to import JIRA data directly into Google Documents. Both methods worked and both heavily rely on the SOAP interface that JIRA offers. However, as of JIRA version 5 a REST interface is the preferred way. So I decided to try this using Clojure.

Initially this seemed to be very straightforward. I have been using a well-written Clojure lib that provides an Async Http Client in the past to extract for example Twitter stream data. So it would only take a couple of minutes to setup a new Clojure project, use basic authentication to connect to a JIRA instance at work and extract all the data I needed. Well, it didn’t.

My first goal was to list all projects. On the commandline I successfully used:

$ curl -u user:password https://intranet.mycompany.com/jira/rest/api/latest/project

In Clojure, using the aforementioned library that would become:

(ns jira.core
  (:require [http.async.client :as c])
  (:use [clojure.data.json :only (read-json)]))

(def jira-project-url "https://intranet.mycompany.com/jira/rest/api/latest/project")

(defn get-all-projects
  "Return all projects from JIRA"
  (with-open [client (c/create-client) :auth {:user "user" :password "password"}]
    (let [response (c/GET client jira-project-url)]
      (c/await response)
      (read-json (c/string response)))))

However, this always returns an empty vector and I still haven’t found out why. So I started to looking for an alternative. I imagined a better way would be to setup a session, retrieve a session cookie and use that for subsequent calls. I’ll begin with showing the end result:

(ns jira.core
  (:require [http.async.client :as c])
  (:use [clojure.data.json :only (read-json json-str)]))

(def session-url "https://intranet.mycompany.com/jira/rest/auth/latest/session")

(defn login
  "Login into JIRA"
  [username password]
  (with-open [client (c/create-client)]
    (let [response (c/POST client session-url
                           :headers {:Content-Type "application/json"}
                           :body (json-str {:username username :password password}))]
      (c/await response)
      (c/cookies response))))

This is more or less the Clojure equivalent of:

$ curl -c cookie_jar -H “Content-Type: application/json” -d ‘{“username” : “user”, “password” : “password”}’ https://intranet.mycompany.com/jira/rest/auth/latest/session

With this implementation of login that returns a session cookie I rewrote get-all-projects to:

(defn get-all-projects
  "Return all projects from JIRA"
  (with-open [client (c/create-client)]
    (let [response (c/GET client jira-project-url :cookies cookies)]
      (c/await response)
      (read-json (c/string response)))))

This version works perfectly and enables me to write compact code like:

(def session (login "user" "password"))
(map :name (get-all-projects session))

This example generates a map with the abbreviated names of all projects currently in JIRA.

Right now the code is mostly proof of concept. As soon as it is cleaned up a bit I will start a new project on GitHub to share it. Enjoy!


RSS feed for comments on this post. TrackBack URI

  1. In your first code snippet, on lines 10-11, didn’t you specify the auth information in the wrong area?

  2. I was trying to do something similar, but authenticating to Jenkins using http basic auth. Seems I needed the :preemptive true option to :auth.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

Create a free website or blog at WordPress.com.
Entries and comments feeds.

%d bloggers like this: