/* *------------------------------------------------------------------------------ * Copyright (C) 2017 University of Dundee & Open Microscopy Environment. * All rights reserved. * * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * *------------------------------------------------------------------------------ */ package training; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.util.ArrayList; import java.util.Collection; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Map.Entry; import javax.json.Json; import javax.json.JsonArray; import javax.json.JsonObject; import javax.json.JsonObjectBuilder; import javax.json.JsonReader; import javax.json.JsonString; import javax.json.JsonStructure; import javax.json.JsonValue; import org.apache.http.HttpException; import org.apache.http.HttpResponse; import org.apache.http.NameValuePair; import org.apache.http.client.ClientProtocolException; import org.apache.http.client.HttpClient; import org.apache.http.client.entity.UrlEncodedFormEntity; import org.apache.http.client.methods.HttpGet; import org.apache.http.client.methods.HttpPost; import org.apache.http.client.methods.HttpPut; import org.apache.http.client.protocol.HttpClientContext; import org.apache.http.client.utils.URIBuilder; import org.apache.http.entity.ContentType; import org.apache.http.entity.StringEntity; import org.apache.http.impl.client.BasicCookieStore; import org.apache.http.impl.client.HttpClients; import org.apache.http.message.BasicNameValuePair; import org.apache.http.protocol.BasicHttpContext; /** * An example for using the OMERO JSON API with Java * * Run it with command line parameters: * --omero.webhost=http://[OMERO.Web URL] * --omero.servername=[SERVER_NAME] * --omero.user=[USERNAME] * --omero.pass=[PASSWORD] * * This example client needs additional dependencies: * Java API for JSON Processing (https://javaee.github.io/jsonp/): * * Apache HTTPComponents (https://hc.apache.org/index.html): * * * * * @author Dominik Lindner      d.lindner@dundee.ac.uk */ public class JSONClient { /** The base API URL */ private String baseURL; /** The base URL used for requests, including API version */ private String requestURL; /** The URLs the API provides */ private Map serviceURLs; /** The http client */ private HttpClient httpClient; /** The http context */ private BasicHttpContext httpContext; /** The CSRF token **/ private String token; /** * Creates a new JSON client * * @param baseURL * The base API URL */ public JSONClient(String baseURL) { this.baseURL = baseURL; this.httpClient = HttpClients.createDefault(); this.httpContext = new BasicHttpContext(); BasicCookieStore cookieStore = new BasicCookieStore(); cookieStore.clear(); this.httpContext.setAttribute(HttpClientContext.COOKIE_STORE, cookieStore); } /** * Get the available API versions * * @return See above * @throws Exception * If something went wrong */ public List getVersion() throws Exception { JsonObject json = (JsonObject) get(baseURL); JsonArray jarray = json.getJsonArray("data"); List result = new ArrayList(); for (JsonValue value : jarray) { result.add((JsonObject) value); } JsonObject server = result.get(result.size() - 1); this.requestURL = server.getJsonString("url:base").getString(); return result; } /** * Get the available URLs provided by the API * * @return See above * @throws Exception * If something went wrong */ public Map getURLs() throws Exception { JsonObject json = (JsonObject) get(requestURL); this.serviceURLs = new HashMap(); for (Entry entry : json.entrySet()) { this.serviceURLs.put(entry.getKey(), ((JsonString) entry.getValue()).getString()); } return this.serviceURLs; } /** * Get the accessible servers * * @return See above * @throws Exception * If something went wrong */ public Map getServers() throws Exception { Map result = new HashMap(); String url = serviceURLs.get("url:servers"); JsonObject json = (JsonObject) get(url); JsonArray data = json.getJsonArray("data"); for (int i = 0; i < data.size(); i++) { JsonObject server = data.getJsonObject(i); result.put(server.getString("server"), server.getInt("id")); } return result; } /** * Request a CSRF token * * @return The CSRF token * @throws Exception * If something went wrong */ private String getCSRFToken() throws Exception { String url = serviceURLs.get("url:token"); JsonObject json = (JsonObject) get(url); return json.getJsonString("data").getString(); } /** * Log in a server * * @param username * The username * @param password * The password * @param serverId * The server id * @return See above * @throws Exception * If something went wrong */ public JsonObject login(String username, String password, int serverId) throws Exception { // make sure we have all the necessary URLs getVersion(); getURLs(); // make sure we have a CSRF token if (this.token == null) this.token = getCSRFToken(); String url = serviceURLs.get("url:login"); Map params = new HashMap(); params.put("server", "" + serverId); params.put("username", username); params.put("password", password); try { JsonObject response = (JsonObject) post(url, params); JsonObject ctx = response.getJsonObject("eventContext"); return ctx; } catch (Exception e) { e.printStackTrace(); } return null; } /** * List the available datasets * * @return See above * @throws Exception * If something went wrong */ public Collection listDatasets() throws Exception { List result = new ArrayList(); String url = serviceURLs.get("url:datasets"); JsonObject json = (JsonObject) get(url); JsonArray data = json.getJsonArray("data"); for (int i = 0; i < data.size(); i++) { result.add(data.getJsonObject(i)); } return result; } /** * List the images of a certain dataset * * @param datasetId * The dataset id * @return See above * @throws Exception * If something went wrong */ public Collection listImages(int datasetId) throws Exception { List result = new ArrayList(); Map params = new HashMap(); params.put("dataset", "" + datasetId); String url = serviceURLs.get("url:images"); JsonObject json = (JsonObject) get(url, params); JsonArray data = json.getJsonArray("data"); for (int i = 0; i < data.size(); i++) { result.add(data.getJsonObject(i)); } return result; } /** * Update an object * * @param object * The JSON object * @return The updated object * @throws Exception * If something went wrong */ public JsonObject update(JsonObject object) throws Exception { String url = serviceURLs.get("url:save"); JsonObject updatedObject = (JsonObject) put(url, object); return updatedObject; } /** * Perform a get request * * @param urlString * The request URL * @return The response * @throws Exception * Exception If something went wrong */ private JsonStructure get(String urlString) throws Exception { return get(urlString, null); } /** * Perform a GET request * * @param urlString * The request URL * @param params * The parameters * @return The response * @throws Exception * If something went wrong */ private JsonStructure get(String urlString, Map params) throws Exception { HttpGet httpGet = null; if (params == null || params.isEmpty()) httpGet = new HttpGet(urlString); else { URIBuilder builder = new URIBuilder(urlString); for (Entry e : params.entrySet()) { builder.addParameter(e.getKey(), e.getValue()); } httpGet = new HttpGet(builder.build()); } HttpResponse res = httpClient.execute(httpGet); try (JsonReader reader = Json.createReader(new BufferedReader( new InputStreamReader(res.getEntity().getContent())))) { return reader.read(); } } /** * Perform a PUT request * * @param url * The request URL * @param data * The JSON data * @return The response * @throws HttpException * If something went wrong * @throws ClientProtocolException * If something went wrong * @throws IOException * If something went wrong */ private JsonStructure put(String url, JsonObject data) throws HttpException, ClientProtocolException, IOException { HttpPut httpPut = new HttpPut(url); if (data != null) { StringEntity requestEntity = new StringEntity(data.toString(), ContentType.APPLICATION_JSON); httpPut.setEntity(requestEntity); } httpPut.addHeader("X-CSRFToken", this.token); HttpResponse res = httpClient.execute(httpPut); if (res.getStatusLine().getStatusCode() != 200) throw new HttpException("PUT failed. URL: " + url + " Status:" + res.getStatusLine()); try (JsonReader reader = Json.createReader(new BufferedReader( new InputStreamReader(res.getEntity().getContent())))) { return reader.read(); } } /** * Perform a POST request * * @param url * The request URL * @param params * The paramters * @return The response * @throws HttpException * If something went wrong * @throws ClientProtocolException * If something went wrong * @throws IOException * If something went wrong */ private JsonStructure post(String url, Map params) throws HttpException, ClientProtocolException, IOException { HttpPost httpPost = new HttpPost(url); if (params != null && !params.isEmpty()) { List nvps = new ArrayList(); for (Entry entry : params.entrySet()) { nvps.add(new BasicNameValuePair(entry.getKey(), entry .getValue())); } httpPost.setEntity(new UrlEncodedFormEntity(nvps)); } httpPost.addHeader("X-CSRFToken", this.token); HttpResponse res = httpClient.execute(httpPost); if (res.getStatusLine().getStatusCode() != 200) throw new HttpException("POST failed. URL: " + url + " Status:" + res.getStatusLine()); try (JsonReader reader = Json.createReader(new BufferedReader( new InputStreamReader(res.getEntity().getContent())))) { return reader.read(); } } public static void main(String[] args) throws Exception { String baseURL = ""; String username = ""; String password = ""; String servername = ""; for (int i = 0; i < args.length; i++) { try { if (args[i].startsWith("--omero.webhost")) { baseURL = args[i].substring(args[i].indexOf('=') + 1); baseURL += "/api"; } else if (args[i].startsWith("--omero.servername")) servername = args[i].substring(args[i].indexOf('=') + 1); else if (args[i].startsWith("--omero.user")) username = args[i].substring(args[i].indexOf('=') + 1); else if (args[i].startsWith("--omero.pass")) password = args[i].substring(args[i].indexOf('=') + 1); } catch (Exception e) { e.printStackTrace(); } } if (baseURL.isEmpty() || username.isEmpty() || password.isEmpty() || servername.isEmpty()) { throw new IllegalArgumentException( "No omero.webhost, omero.user, omero.pass or omero.servername specified."); } JSONClient client = new JSONClient(baseURL); List versions = client.getVersion(); System.out.println("API versions:"); for (JsonObject version : versions) System.out.println(version); System.out.println("URLs:"); Map urls = client.getURLs(); for (Entry url : urls.entrySet()) System.out.println(url.getKey() + " : " + url.getValue()); System.out.println("Servers:"); Map servers = client.getServers(); for (Entry server : servers.entrySet()) System.out.println(server.getKey() + " : " + server.getValue()); System.out.println("Log in to server " + servername + ":"); JsonObject ctx = client.login(username, password, servers.get(servername)); System.out.println("Logged in: " + ctx); System.out.println("Datasets:"); Collection datasets = client.listDatasets(); for (JsonObject dataset : datasets) { System.out.println(dataset); } JsonObject dataset = datasets.iterator().next(); int datasetId = dataset.getJsonNumber("@id").intValue(); System.out.println("Images in dataset " + datasetId + ":"); Collection images = client.listImages(datasetId); for (JsonObject image : images) { System.out.println(image); } JsonObjectBuilder builder = Json.createObjectBuilder(); for (String key : dataset.keySet()) { if (key.equals("Name")) builder.add(key, "New dataset name"); else builder.add(key, dataset.get(key)); } JsonObject modifiedDataset = builder.build(); System.out.println("Update name of dataset: " + dataset); modifiedDataset = client.update(modifiedDataset); System.out.println(modifiedDataset); System.out.println("Revert name change again"); dataset = client.update(dataset); System.out.println(dataset); } }