Commit 1540f45f authored by Matija Obreza's avatar Matija Obreza

Transferred code from org.genesys2.oauth-client

parent 1e52d35b
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>org.genesys2</groupId>
<artifactId>client-api</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>Genesys Client</name>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>org.genesys2</groupId>
<artifactId>client-api</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>Genesys Client</name>
<packaging>jar</packaging>
<properties>
<jdk.target>1.6</jdk.target>
<jdk.source>1.6</jdk.source>
<show.deprecations>true</show.deprecations>
<scribe.version>1.3.5</scribe.version>
</properties>
<dependencies>
<dependency>
<groupId>org.scribe</groupId>
<artifactId>scribe</artifactId>
<version>${scribe.version}</version>
</dependency>
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.17</version>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>3.1</version>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-io</artifactId>
<version>1.3.2</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.2.3</version>
</dependency>
</dependencies>
</project>
\ No newline at end of file
/**
* Copyright 2013 Global Crop Diversity Trust
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
**/
package org.genesys2.client.oauth;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.net.Authenticator;
import java.net.ConnectException;
import java.net.PasswordAuthentication;
import java.net.SocketTimeoutException;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;
import java.util.Scanner;
import java.util.concurrent.TimeUnit;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.log4j.LogManager;
import org.apache.log4j.Logger;
import org.genesys2.client.oauth.api.GenesysApi;
import org.scribe.builder.ServiceBuilder;
import org.scribe.exceptions.OAuthConnectionException;
import org.scribe.exceptions.OAuthException;
import org.scribe.model.OAuthRequest;
import org.scribe.model.Response;
import org.scribe.model.Token;
import org.scribe.model.Verb;
import org.scribe.model.Verifier;
import org.scribe.oauth.OAuthService;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ArrayNode;
import com.fasterxml.jackson.databind.node.ObjectNode;
public class GenesysClient {
private static final Logger _log = LogManager
.getLogger(GenesysClient.class);
private static final Token EMPTY_TOKEN = null;
private static final String SCOPE = "read,write";
private static final String OOB_CALLBACK = "oob";
private File propertiesFile;
private static ObjectMapper mapper = new ObjectMapper();
private OAuthService service;
private Token accessToken;
private Token refreshToken;
private Properties properties;
private Scanner in = new Scanner(System.in);
private String apiUrl;
private GenesysApi genesysApi;
public GenesysClient() {
}
public static void main(String[] args) {
_log.info("Hello World!");
GenesysClient genesysClient = new GenesysClient();
genesysClient.loadProperties("client.properties");
genesysClient.run();
}
public void loadProperties(String propertiesFileName) {
// .properties file location
propertiesFile = new File(propertiesFileName);
Properties properties = new Properties();
FileInputStream fis = null;
try {
_log.info("Loading " + propertiesFile.getAbsolutePath());
fis = new FileInputStream(propertiesFile);
properties.load(fis);
// Keep properties
this.properties = properties;
} catch (FileNotFoundException e) {
_log.warn(e, e);
} catch (IOException e) {
_log.error(e, e);
} finally {
IOUtils.closeQuietly(fis);
}
final String baseUrl = this.properties.getProperty("base.url");
this.genesysApi = new GenesysApi(baseUrl,
properties.getProperty("client.key"),
properties.getProperty("client.secret"));
this.apiUrl = baseUrl + this.properties.getProperty("api.url");
final String httpAuth = this.properties.getProperty("http.auth");
if (StringUtils.isNotBlank(httpAuth) && httpAuth.contains(":")) {
_log.warn("Using HTTP AUTH " + httpAuth);
Authenticator.setDefault(new Authenticator() {
protected PasswordAuthentication getPasswordAuthentication() {
return new PasswordAuthentication(
httpAuth.split(":", 2)[0],
httpAuth.split(":", 2)[1].toCharArray());
}
});
}
// CropHub auth service
this.service = new ServiceBuilder().provider(this.genesysApi)
.apiKey(properties.getProperty("client.key"))
.apiSecret(properties.getProperty("client.secret"))
.callback(OOB_CALLBACK).scope(SCOPE).build();
this.accessToken = makeToken(this.properties
.getProperty("access.token"));
this.refreshToken = makeToken(this.properties
.getProperty("refresh.token"));
}
private Token makeToken(String tokenKey) {
if (StringUtils.isBlank(tokenKey))
return null;
return new Token(tokenKey, "");
}
private void run() {
checkPreconditions();
try {
System.out.println("/me: " + query("/me"));
doWork();
} catch (OAuthAuthenticationException e) {
e.printStackTrace();
System.err.println("Auth problem.");
}
}
private void doWork() throws OAuthAuthenticationException {
String line = null;
do {
System.out.println("1 Datasets");
System.out.println("2 Traits");
System.out.println("0 Custom");
System.out.println("Q QUIT");
line = in.nextLine();
if ("1".equals(line))
doDatasets();
else if ("2".equals(line))
doTraits();
else if ("0".equals(line))
doCustom();
} while (!"Q".equalsIgnoreCase(line));
}
private void doCustom() throws OAuthAuthenticationException {
System.out.print("URL: ");
String url = in.nextLine();
System.out.print("Method [GET]: ");
String method = StringUtils.defaultIfBlank(in.nextLine(), "GET");
System.out.println("JSON: ");
String data = StringUtils.defaultIfBlank(in.nextLine(), null);
// Exec
System.out.println("Put dataset: "
+ query(Verb.valueOf(method), url, null, data));
}
private void doTraits() throws OAuthAuthenticationException {
String line = null;
do {
System.out.println("1 List parameters");
System.out.println("2 List my methods");
System.out.println("9 List all methods");
System.out.println("3 Add method");
System.out.println("0 Back");
line = in.nextLine();
if ("1".equals(line))
System.out.println("/parameters: " + query("/descriptors"));
else if ("2".equals(line))
System.out.println("/mymethods: " + query("/mymethods"));
else if ("3".equals(line))
addMethod();
else if ("9".equals(line))
System.out.println("/methods: " + query("/methods"));
else if ("0".equalsIgnoreCase(line))
return;
} while (!("0".equalsIgnoreCase(line)));
}
private void doDatasets() throws OAuthAuthenticationException {
String line = null;
do {
System.out.println("1 List");
System.out.println("2 Add");
System.out.println("3 Add data");
System.out.println("4 Add RAW");
System.out.println("0 Back");
line = in.nextLine();
if ("1".equals(line))
System.out.println("/datasets: " + query("/datasets"));
else if ("2".equals(line))
addDataset();
else if ("3".equals(line))
addDatasetData();
else if ("4".equals(line))
addDatasetRaw();
else if ("0".equalsIgnoreCase(line))
return;
} while (!("0".equalsIgnoreCase(line)));
}
private void addMethod() throws OAuthAuthenticationException {
ObjectNode datasetJson = mapper.createObjectNode();
System.out.println("Method description: ");
datasetJson.put("description", in.nextLine());
System.out.println("UOM: ");
datasetJson
.put("unit", StringUtils.defaultIfBlank(in.nextLine(), null));
System.out.println("Field name: ");
datasetJson.put("fieldName",
StringUtils.defaultIfBlank(in.nextLine(), null));
System.out.println("Field type: (0=String, 1=Double, 2=Long)");
int fieldType = Integer.parseInt(in.nextLine());
datasetJson.put("fieldType", fieldType);
if (fieldType == 0) {
System.out.println("Field size: ");
datasetJson.put("fieldSize", Integer.parseInt(in.nextLine()));
}
System.out.println("Options: ");
datasetJson.put("options",
StringUtils.defaultIfBlank(in.nextLine(), null));
System.out.println("Range: ");
datasetJson.put("range",
StringUtils.defaultIfBlank(in.nextLine(), null));
System.err.println(datasetJson.toString());
// make a dataset
System.out.println("Put method: "
+ query(Verb.PUT, "/methods", null, datasetJson.toString()));
}
private void addDataset() throws OAuthAuthenticationException {
ObjectNode datasetJson = mapper.createObjectNode();
System.out.println("WIEWS Code: ");
datasetJson.put("institute", in.nextLine());
System.out.println("Dataset title: ");
datasetJson.put("title", in.nextLine());
System.out.println("Dataset description: ");
datasetJson.put("description", in.nextLine());
System.err.println(datasetJson.toString());
// make a dataset
System.out.println("Put dataset: "
+ query(Verb.PUT, "/datasets", null, datasetJson.toString()));
}
private void addDatasetData() throws OAuthAuthenticationException {
ObjectNode datasetJson = mapper.createObjectNode();
System.out.println("Dataset ID: ");
long datasetId = Long.parseLong(in.nextLine());
System.out.println("WIEWS Code: ");
datasetJson.put("instCode", in.nextLine());
System.out.println("Data data: ");
datasetJson.put("data", in.nextLine());
System.err.println(datasetJson.toString());
// make a dataset
System.out.println("Put dataset: "
+ query(Verb.PUT, "/datasets/" + datasetId + "/data", null,
datasetJson.toString()));
}
private void addDatasetRaw() throws OAuthAuthenticationException {
System.out.println("Dataset ID: ");
long datasetId = Long.parseLong(in.nextLine());
System.out.println("JSON: ");
String json = in.nextLine();
System.err.println(json);
// make a dataset
System.out.println("Put dataset: "
+ query(Verb.PUT, "/datasets/" + datasetId + "/data", null,
json));
}
private void authenticate() {
String authorizationUrl = service.getAuthorizationUrl(EMPTY_TOKEN);
System.out.println("Authorization URL: \n" + authorizationUrl);
System.out.print("\nVerifier: ");
Verifier verifier = new Verifier(in.nextLine());
System.out.println();
// Trade the Request Token and Verfier for the Access Token
accessToken = service.getAccessToken(EMPTY_TOKEN, verifier);
_log.info("ACCESS TOKEN: " + accessToken.getToken() + " sec="
+ accessToken.getSecret() + " raw="
+ accessToken.getRawResponse());
this.properties.put("access.token", accessToken.getToken());
// Get refresh token ()
Token refreshToken = genesysApi.getRefreshToken(accessToken);
if (refreshToken != null) {
this.properties.put("refresh.token", refreshToken.getToken());
} else {
this.properties.remove("refresh.token");
}
saveProperties();
}
private void checkPreconditions() {
boolean restart = false;
if (StringUtils.isBlank(properties.getProperty("client.key"))) {
System.out.print("Provide client key: ");
properties.put("client.key", in.nextLine());
restart = true;
}
if (StringUtils.isBlank(properties.getProperty("client.secret"))) {
System.out.print("Provide client secret: ");
properties.put("client.secret", in.nextLine());
restart = true;
}
if (StringUtils.isBlank(properties.getProperty("api.url"))) {
System.out.print("Provide API url: ");
properties.put("api.url", in.nextLine());
restart = true;
}
if (restart) {
saveProperties();
_log.warn("Properties udpated, please restart CLI application");
System.exit(-1);
}
}
private void saveProperties() {
FileOutputStream fis = null;
try {
fis = new FileOutputStream(propertiesFile);
this.properties.store(fis, "OAuth client properties");
} catch (IOException e) {
_log.error(e);
} finally {
IOUtils.closeQuietly(fis);
}
}
private String query(String url) throws OAuthAuthenticationException,
PleaseRetryException {
return query(Verb.GET, url, null, null);
}
private String query(Verb method, String url,
Map<String, String> queryString, String postBody)
throws OAuthAuthenticationException, PleaseRetryException {
if (accessToken == null) {
refreshAccessToken();
}
for (int i = 0; i < 2; i++) {
OAuthRequest request = new OAuthRequest(method, this.apiUrl + url);
if (queryString != null && queryString.size() > 0) {
for (String key : queryString.keySet()) {
request.addQuerystringParameter(key, queryString.get(key));
}
}
if (_log.isDebugEnabled()) {
_log.debug(method + " " + request.getCompleteUrl());
}
if (postBody != null) {
// System.err.println("Adding data: " + data);
request.addPayload(postBody);
request.addHeader("Content-Type", "application/json");
}
service.signRequest(accessToken, request);
request.setConnectionKeepAlive(true);
request.setConnectTimeout(10, TimeUnit.SECONDS);
request.setReadTimeout(30, TimeUnit.SECONDS);
Response response = null;
try {
response = request.send();
} catch (OAuthConnectionException e) {
_log.warn(e.getMessage(), e);
if (e.getCause() instanceof ConnectException) {
throw new PleaseRetryException(e.getMessage());
} else if (e.getCause() instanceof SocketTimeoutException) {
throw new PleaseRetryException(e.getMessage());
} else {
}
}
String responseBody = response.getBody();
if (response.isSuccessful()) {
return responseBody + "\n";
} else {
if (response.getCode() == 401) {
_log.warn("Response error: " + response.getCode());
System.err.println(responseBody);
if (i == 0) {
refreshAccessToken();
} else {
throw new OAuthAuthenticationException("Unauthorized");
}
} else {
_log.error(method + " " + request.getCompleteUrl());
_log.error(postBody);
_log.error("HTTP response code: " + response.getCode());
_log.error("Response: " + responseBody);
if (responseBody
.contains("Deadlock found when trying to get lock; try restarting transaction")
|| responseBody
.contains("nested exception is org.hibernate.exception.LockAcquisitionException: could not execute statement")) {
throw new PleaseRetryException(responseBody);
} else
throw new RuntimeException("Unexpected error: "
+ responseBody);
}
}
}
return null;
}
private void refreshAccessToken() {
if (this.refreshToken != null) {
_log.info("Using Refresh Token to get new access token");
try {
accessToken = genesysApi.getAccessToken(this.refreshToken);
_log.info("Got new Access Token!");
this.properties.put("access.token", accessToken.getToken());
saveProperties();
} catch (OAuthException e) {
_log.info("Refresh token didn't work: " + e.getMessage());
authenticate();
}
} else {
authenticate();
}
}
public String accessionExists(String instCode, String acceNumb, String genus)
throws OAuthAuthenticationException {
try {
HashMap<String, String> queryString = new HashMap<String, String>();
queryString.put("acceNumb", acceNumb);
return query(Verb.GET, new URI(null, null, "/acn/exists/"
+ instCode + "/" + genus, null).toString(), queryString,
null);
} catch (URISyntaxException e) {
e.printStackTrace();
return null;
}
}
public static ObjectNode makeAid3(String instCode, String genus,
String acceNumb) {
ObjectNode json = mapper.createObjectNode();
json.put("instCode", instCode);
json.put("acceNumb", acceNumb);
json.put("genus", genus);
return json;
}
public String updateMLS(String instCode, Collection<ObjectNode> accns)
throws OAuthAuthenticationException {
ArrayNode arr = mapper.createArrayNode();
for (ObjectNode accn : accns) {
arr.add(accn);
}
_log.debug("Sending: " + arr);
return query(Verb.PUT, "/acn/" + instCode + "/update", null,
arr.toString());
}
public String accessionExists(String instCode, Collection<ObjectNode> accns)
throws OAuthAuthenticationException {
ArrayNode arr = mapper.createArrayNode();
for (ObjectNode accn : accns) {
arr.add(accn);
}
_log.debug("Sending: " + arr);
return query(Verb.PUT, "/acn/" + instCode + "/check", null,
arr.toString());