CFP-Tool – aus E-Mails JIRA Tickets mittels REST erstellen


November 29, 2013 · Java, Technologie · von: Michael Schütz

Die offene Technologie-Konferenz BED-Con findet seit 2011 jährlich in Berlin statt. zaunberg unterstützt tatkräftig bei der Organisation, Planung und Durchführung der Konferenz.

Neben vielen verschiedenen und spannenden Aufgaben ist jedoch eine immer wiederkehrende Aufgabe besonders mühsam: Bevor das offene Programmkomitee sämtliche Talk-Einreichungen begutachten und diese bewerten kann, müssen alle eingegangenen E-Mails in ein kollaboratives Software-Tool, in unserem Fall JIRA, eingepflegt werden. Dies bedeutet, dass Spam-Nachrichten aussortiert, alle eingereichten Talk-Vorschläge überprüft und anschließend in JIRA eingepflegt werden müssen. Bei über 150 Einreichungen mit steigender Tendenz handelt es sich hierbei um eine nerven- und zeitraubende Copy-and-Paste-Aufgabe, die jeden noch so ausdauernden Copy-and-Paste-Arm irgendwann ermüden lässt.

Also genau das Richtige für ein Software-Tool!


Das von uns entwickelte Call-For-Paper-Werkzeug (CFP) verbindet sich mit einem konfigurierten E-Mail-Konto, liest alle E-Mails eines bestimmten Verzeichnisses ein und erstellt anschließend vollautomatisch neue JIRA-Issues. Nach der Verarbeitung werden alle bearbeiteten E-Mails in ein anderes Verzeichnis verschoben. Zusätzlich erzeugt das Tool zwei verschiedene Übersichtstabellen, die in zwei unterschiedlichen Textdateien abgelegt werden. Diese Übersichtstabellen listen alle Speaker sowie Talks auf und verlinken diese automatisch mit den zuvor angelegten Issues im JIRA. Die Tabellen werden vom Tool so formatiert, dass sie bequem ins Confluence kopiert werden können und keine Nachbearbeitung mehr benötigen.

Wie das Tool das macht

Unser Webformular ist so gestaltet, dass es zwei verschiedene E-Mails versendet. So wird eine lesefreundlich formatierte E-Mail und zusätzlich eine XML-formatierte E-Mail erzeugt und versendet. Der Inhalt einer entsprechend formatierten E-Mail sieht dann zum Beispiel wie folgt aus:

	
		
			Cave
			Johnson
			johnson@test.com
			twitterLink
			xingLink
			Aperture Science
			CEO
		
		JUnit Tests
		Test your App with JUnit.
		en
		short
	

Nach dem Einsendeschluss wird das Tool manuell ausgeführt. Es verbindet sich zunächst mit dem konfigurierten E-Mail-Konto und liest alle XML-formatierten E-Mails ein, die sich im entsprechenden Verzeichnis befinden. Damit die Verbindung zum E-Mail-Konto aufgebaut werden kann, muss als erstes ein MailAuthenticator implementiert werden, der die Klasse javax.mail.Authenticator wie folgt erweitert:

public class MyMailAuthenticator 
		extends javax.mail.Authenticator {
	private String username;
	private String password;
	
	public MyMailAuthenticator(String username, 
				String password) {
		this.username = username;
		this.password = password;
	}
	
    public PasswordAuthentication getPasswordAuthentication() {
       return new PasswordAuthentication(username, password);
    }
}

Als nächstes müssen zwei Properties gesetzt und die Session erzeugt werden.

this.props = System.getProperties();
this.props.put("mail.imap.host", host);
this.props.put("mail.imap.auth", "true");

Session session = Session.getDefaultInstance(props, 
				new MyMailAuthenticator(username, password));

Anschließend kann auf das E-Mail-Konto zugegriffen und das Verzeichnis ausgelesen werden.

this.store = session.getStore("imap");
this.store.connect();	
this.folder = this.store.getFolder(MAIN_FOLDER);		
this.folder = openFolder(this.folder, folderPath);
this.folder.open(Folder.READ_ONLY);
Message[] messages = this.folder.getMessages();

Die messages enthalten im Content-Bereich die XML-formatierten Informationen, welche direkt ausgelesen und in eine entsprechenden Entität umgewandelt werden müssen.

Nun kann das Tool mit Hilfe des REST-Frameworks Jersey die Issues in JIRA anlegen. Da dies natürlich nicht jeder beliebige Benutzer des Internets machen und können soll, ist diese Aktion durch eine Basic Authentication geschützt. Aus diesem Grund wird ein Basic-Authentication-String erzeugt, der anschließend bei jeder Anfrage im Header übertragen werden muss.

authString = "Basic "+ new String(Base64.encode(username 
					+":"+ password));

Nun kann der Zugriff auf die REST-Schnittstelle erfolgen und die Daten zum Erstellen eines neuen Issues übergeben werden.

WebResource webResource = client.resource(url);
ClientResponse response = webResource.header(HEADER_AUTH, 
						authString)
				.type(type).accept(accept)
				.post(ClientResponse.class, data);

checkStatusCode(response);
return response.getEntity(String.class);

Normalerweise ist es bequemer, JAXB für die Erzeugung des JSON-Formats zu verwenden, da es in den meisten Fällen viel Arbeit abnehmen kann. Bei diesem Tool wurde sich jedoch dafür entschieden, den JSON-String selbst zu erzeugen. Dadurch entfällt das Nachbauen der Objektstruktur.

Als Ergebnis wird eine ClientResponse zurückgegeben, welche zum einen den HTTP-Statuscode, sowie das Ergebnis enthält. In diesem Fall wird das Ergebnis ebenfalls als String empfangen und mit Hilfe des JSON-Frameworks GSON in ein einfaches Objekt transformiert.

Nachdem alle Issues erstellt wurden, generiert das Tool aus den zurück erhaltenen Informationen, wie z.B. die Issues-Keys, die Übersichtstabelle für Confluence. Die Tabellen werden in separaten Textdateien gespeichert, welche direkt ins Confluence kopiert werden können. Nach dem alle Issues und Tabellen erstellt wurden, werden alle verarbeiteten E-Mails in ein anderes Verzeichnis geschoben.

Fazit

Für die nerven- und zeitraubende Copy-and-Paste-Aufgabe konnte dank der von JIRA bereitgestellten REST-Schnittstelle ein einfaches aber sehr praktisches Tool in kurzer Zeit entwickelt werden. Dafür wurde das REST-Framework Jersey eingesetzt, mit dessen Hilfe auch diese Aufgabe schnell und einfach erledigt werden konnte.
Dieses Beispiel verdeutlicht, dass es sich lohnt, REST-Schnittstellen bereitzustellen, um die Integration mit beliebigen anderen Anwendungen zu erleichtern. Das Projekt hat aber auch gezeigt, dass die zu übertragenen Datentypen möglichst einfach gehalten werden sollten, um eine einfache Integration zu ermöglichen.

Für interessierte Leser haben wir den kompletten Quellcode in unserem Github-Repository als Open-Source veröffentlicht.

Tags: , , , ,