Commit 4c124256 authored by Matija Obreza's avatar Matija Obreza

Upgraded to scribe-java:4.2.0

parent 09ecefe3
Pipeline #2746 passed with stage
in 26 seconds
<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">
<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.genesys-pgr</groupId>
......@@ -41,7 +42,6 @@
<nexus-staging-maven-plugin.version>1.6.8</nexus-staging-maven-plugin.version>
<show.deprecations>true</show.deprecations>
<scribe.version>1.3.7</scribe.version>
</properties>
......@@ -88,9 +88,9 @@
<dependencies>
<dependency>
<groupId>org.scribe</groupId>
<artifactId>scribe</artifactId>
<version>${scribe.version}</version>
<groupId>com.github.scribejava</groupId>
<artifactId>scribejava-core</artifactId>
<version>4.2.0</version>
</dependency>
<dependency>
<groupId>log4j</groupId>
......@@ -134,6 +134,7 @@
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
<version>4.3.6</version>
<scope>test</scope>
</dependency>
</dependencies>
......
......@@ -21,7 +21,6 @@ import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.net.SocketException;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Map.Entry;
......@@ -38,13 +37,12 @@ import com.fasterxml.jackson.databind.node.IntNode;
import com.fasterxml.jackson.databind.node.NullNode;
import com.fasterxml.jackson.databind.node.ObjectNode;
import com.fasterxml.jackson.databind.node.TextNode;
import com.github.scribejava.core.model.Verb;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.log4j.LogManager;
import org.apache.log4j.Logger;
import org.scribe.exceptions.OAuthConnectionException;
import org.scribe.model.Verb;
/**
* Simple command line interface to Genesys.
......@@ -69,7 +67,7 @@ public class CLI {
private static ObjectMapper mapper = new ObjectMapper();
/** The genesys client. */
private final GenesysClient genesysClient = new GenesysClient();
private GenesysClient genesysClient;
/** The ignored fields. */
private static Set<String> ignoredFields;
......@@ -93,7 +91,7 @@ public class CLI {
_log.info("Hello World!");
final CLI cli = new CLI();
cli.loadProperties("client.properties");
cli.genesysClient = GenesysClient.build(cli.loadProperties("client.properties"));
cli.run();
}
......@@ -111,13 +109,11 @@ public class CLI {
} catch (final OAuthAuthenticationException e) {
_log.error("Failed to fetch /me", e);
authenticate();
} catch (final OAuthConnectionException e) {
if (e.getCause() != null && e.getCause() instanceof SocketException) {
_log.error("Could not connect to host");
try {
authenticate();
} catch (OAuthAuthenticationException e1) {
_log.error("Failed to authenticate", e1);
return;
} else {
_log.error(e.getMessage(), e);
}
} catch (final Throwable e) {
_log.error(e.getMessage(), e);
......@@ -566,8 +562,10 @@ public class CLI {
/**
* Authenticate.
*
* @throws OAuthAuthenticationException
*/
private void authenticate() {
private void authenticate() throws OAuthAuthenticationException {
final String authorizationUrl = genesysClient.getAuthorizationUrl();
System.out.println("Authorization URL: \n" + authorizationUrl);
......@@ -604,8 +602,9 @@ public class CLI {
* Load properties.
*
* @param propertiesFileName the properties file name
* @return
*/
private void loadProperties(final String propertiesFileName) {
private Properties loadProperties(final String propertiesFileName) {
// .properties file location
propertiesFile = new File(propertiesFileName);
......@@ -626,7 +625,7 @@ public class CLI {
IOUtils.closeQuietly(fis);
}
genesysClient.loadProperties(properties);
return properties;
}
}
......@@ -19,8 +19,6 @@ package org.genesys2.client.oauth;
import java.io.File;
import java.io.IOException;
import java.io.Serializable;
import java.net.Authenticator;
import java.net.PasswordAuthentication;
import java.net.URI;
import java.net.URISyntaxException;
import java.nio.charset.Charset;
......@@ -31,7 +29,7 @@ import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.UUID;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.ExecutionException;
import com.fasterxml.jackson.annotation.JsonInclude.Include;
import com.fasterxml.jackson.core.JsonParseException;
......@@ -43,25 +41,20 @@ import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;
import com.fasterxml.jackson.databind.node.ArrayNode;
import com.fasterxml.jackson.databind.node.ObjectNode;
import com.github.scribejava.core.builder.ServiceBuilder;
import com.github.scribejava.core.model.OAuth2AccessToken;
import com.github.scribejava.core.model.OAuthRequest;
import com.github.scribejava.core.model.Response;
import com.github.scribejava.core.model.Verb;
import com.github.scribejava.core.oauth.OAuth20Service;
import org.apache.commons.io.FileUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.http.HttpHeaders;
import org.apache.http.entity.ContentType;
import org.apache.log4j.LogManager;
import org.apache.log4j.Logger;
import org.genesys2.client.oauth.api.GenesysApi;
import org.genesys2.client.oauth.api.accession.AccessionJson;
import org.genesys2.client.oauth.api.images.RepositoryImage;
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;
/**
* Genesys API client using Scribe.
......@@ -71,32 +64,17 @@ public class GenesysClient {
/** The Constant _log. */
private static final Logger _log = LogManager.getLogger(GenesysClient.class);
/** The Constant SCOPE. */
private static final String SCOPE = "read,write";
/** The mapper. */
private static ObjectMapper objectMapper;
/** The service. */
private OAuthService service;
private final OAuth20Service service;
/** GenesysTokens: access- and refreshToken. */
private GenesysTokens tokens = new GenesysTokens();
/** The genesys api. */
private GenesysApi genesysApi;
/** The api key. */
private String apiKey;
/** The api secret. */
private String apiSecret;
/** Socket connect timeout. */
private int connectTimeout = 20;
/** Socket read timeout. */
private int readTimeout = 120;
/** Base URL of Genesys */
private String baseUrl;
/** UTF8 charset */
private static Charset CHARSET_UTF8 = Charset.forName("UTF8");
......@@ -112,72 +90,9 @@ public class GenesysClient {
/**
* Instantiates a new genesys client.
*/
public GenesysClient() {
}
/**
* Sets the read timeout.
*
* @param readTimeout the new read timeout
*/
public void setReadTimeout(final int readTimeout) {
this.readTimeout = readTimeout;
}
/**
* Gets the read timeout.
*
* @return the read timeout
*/
public int getReadTimeout() {
return readTimeout;
}
/**
* Sets the connect timeout.
*
* @param connectTimeout the new connect timeout
*/
public void setConnectTimeout(final int connectTimeout) {
this.connectTimeout = connectTimeout;
}
/**
* Gets the connect timeout.
*
* @return the connect timeout
*/
public int getConnectTimeout() {
return connectTimeout;
}
/**
* Sets the base url.
*
* @param baseUrl the base url
* @return the genesys client
*/
public GenesysClient setBaseUrl(final String baseUrl) {
genesysApi.setBaseUrl(baseUrl);
return this;
}
/**
* Sets the genesys api.
*
* @param genesysApi the new genesys api
*/
public void setGenesysApi(final GenesysApi genesysApi) {
this.genesysApi = genesysApi;
}
/**
* Gets the genesys api.
*
* @return the genesys api
*/
public GenesysApi getGenesysApi() {
return genesysApi;
public GenesysClient(final String baseUrl, final String clientId, final String clientSecret, final String callbackUrl, String scope) {
this.baseUrl = baseUrl;
service = new ServiceBuilder(clientId).apiSecret(clientSecret).callback(callbackUrl).scope(scope).build(new GenesysApi(baseUrl));
}
/**
......@@ -185,45 +100,23 @@ public class GenesysClient {
*
* @param properties the properties
*/
public void loadProperties(final Properties properties) {
public static GenesysClient build(final Properties properties) {
final String baseUrl = properties.getProperty("base.url");
genesysApi.setBaseUrl(baseUrl);
final String httpAuth = properties.getProperty("http.auth");
if (StringUtils.isNotBlank(httpAuth) && httpAuth.contains(":")) {
_log.warn("Using HTTP AUTH " + httpAuth);
Authenticator.setDefault(new Authenticator() {
@Override
protected PasswordAuthentication getPasswordAuthentication() {
return new PasswordAuthentication(httpAuth.split(":", 2)[0], httpAuth.split(":", 2)[1].toCharArray());
}
});
}
tokens = new GenesysTokens();
GenesysTokens tokens = new GenesysTokens();
tokens.setAccessToken(properties.getProperty("access.token"));
tokens.setRefreshToken(properties.getProperty("refresh.token"));
// CropHub auth service
connect(properties.getProperty("client.key"), properties.getProperty("client.secret"), properties.getProperty("client.callback"));
// Genesys client instance auth service
return new GenesysClient(baseUrl, properties.getProperty("client.key"), properties.getProperty("client.secret"), properties.getProperty("client.callback"),
properties.getProperty("client.scope"));
}
/**
* Connect.
*
* @param clientId the client id
* @param clientSecret the client secret
* @param callbackUrl the callback URL for web-based clients. Use "oob" for out-of-band
* authentication.
*/
public void connect(final String clientId, final String clientSecret, final String callbackUrl) {
apiKey = clientId;
apiSecret = clientSecret;
service = new ServiceBuilder().provider(genesysApi).apiKey(clientId).apiSecret(clientSecret).callback(callbackUrl).scope(SCOPE).build();
public String getAuthorizationUrl() {
return service.getAuthorizationUrl();
}
/**
* Sets the tokens.
*
......@@ -288,7 +181,7 @@ public class GenesysClient {
if (StringUtils.isBlank(postBody)) {
return query(method, url, queryString, null, null);
} else {
return query(method, url, queryString, ContentType.APPLICATION_JSON.withCharset(CHARSET_UTF8).getMimeType(), postBody.getBytes(CHARSET_UTF8));
return query(method, url, queryString, HttpConstants.APPLICATION_JSON_UTF8, postBody.getBytes(CHARSET_UTF8));
}
}
......@@ -305,7 +198,7 @@ public class GenesysClient {
*/
private String query(final Verb method, final String url, final Map<String, String> queryString, final Serializable object)
throws GenesysApiException, JsonProcessingException {
return query(method, url, queryString, ContentType.APPLICATION_JSON.withCharset(CHARSET_UTF8).getMimeType(), objectMapper.writeValueAsBytes(object));
return query(method, url, queryString, HttpConstants.APPLICATION_JSON_UTF8, objectMapper.writeValueAsBytes(object));
}
private String query(final Verb method, final String url, final Map<String, String> queryString, final String contentType, final byte[] postBody) throws GenesysApiException {
......@@ -335,55 +228,54 @@ public class GenesysClient {
if (_log.isTraceEnabled()) {
_log.trace("Body: " + new String(postBody));
}
request.addPayload(postBody);
request.setPayload(postBody);
}
service.signRequest(tokens.accessToken(), request);
request.setConnectionKeepAlive(true);
request.setConnectTimeout(connectTimeout, TimeUnit.SECONDS);
request.setReadTimeout(readTimeout, TimeUnit.SECONDS);
request.setCharset("UTF-8");
request.setCharset("UTF-8");
Response response = null;
try {
response = request.send();
} catch (final OAuthConnectionException e) {
throw e;
}
service.signRequest(tokens.accessToken(), request);
response = service.execute(request);
final String responseBody = response.getBody();
final String responseBody = response.getBody();
_log.debug("HTTP status code " + response.getCode());
_log.debug("HTTP status code " + response.getCode());
if (response.getCode() >= 200 && response.getCode() < 300) {
_log.debug("Returning response body");
return responseBody;
} else {
if (response.getCode() == 301 || response.getCode() == 302) {
_log.debug("Redirect: " + response.getHeader(HttpHeaders.LOCATION));
throw new HttpRedirectException(response.getHeader(HttpHeaders.LOCATION));
}
if (response.getCode() == 401) {
_log.warn("Response error: " + response.getCode());
System.err.println(responseBody);
if (i == 0) {
refreshAccessToken();
} else {
throw new OAuthAuthenticationException("Unauthorized");
}
if (response.getCode() >= 200 && response.getCode() < 300) {
_log.debug("Returning response body");
return responseBody;
} 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")
|| responseBody.contains("nested exception is org.hibernate.exception.LockTimeoutException: could not execute statement")) {
throw new PleaseRetryException(responseBody);
if (response.getCode() == 301 || response.getCode() == 302) {
_log.debug("Redirect: " + response.getHeader(HttpConstants.LOCATION));
throw new HttpRedirectException(response.getHeader(HttpConstants.LOCATION));
}
if (response.getCode() == 401) {
_log.warn("Response error: " + response.getCode());
System.err.println(responseBody);
if (i == 0) {
refreshAccessToken();
} else {
throw new OAuthAuthenticationException("Unauthorized");
}
} else {
throw new GenesysApiException("Unexpected error: " + responseBody);
_log.error(method + " " + request.getCompleteUrl());
_log.error(new String(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")
|| responseBody.contains("nested exception is org.hibernate.exception.LockTimeoutException: could not execute statement")) {
throw new PleaseRetryException(responseBody);
} else {
throw new GenesysApiException("Unexpected error: " + responseBody);
}
}
}
} catch (final Throwable e) {
e.printStackTrace();
throw new GenesysApiException(e.getMessage());
}
}
return null;
......@@ -396,7 +288,7 @@ public class GenesysClient {
* @return the api url
*/
private String getApiUrl(final String url) {
return genesysApi.getBaseUrl().concat("/api/v0").concat(url);
return baseUrl.concat("/api/v0").concat(url);
}
/**
......@@ -408,11 +300,11 @@ public class GenesysClient {
if (tokens.hasRefreshToken()) {
_log.info("Using Refresh Token to get new access token");
try {
final Token accessToken = genesysApi.getAccessToken(apiKey, apiSecret, tokens.getRefreshToken());
tokens.setAccessToken(accessToken.getToken());
OAuth2AccessToken accessToken = service.refreshAccessToken(tokens.getRefreshToken());
tokens.setAccessToken(accessToken.getAccessToken());
_log.info("Got new Access Token!");
} catch (final OAuthException e) {
} catch (Throwable e) {
_log.info("Refresh token didn't work: " + e.getMessage());
throw new OAuthAuthenticationException("Refresh token not valid, please re-authenticate");
}
......@@ -484,8 +376,8 @@ public class GenesysClient {
/**
* Update accession information with new values provided in the JSON string. In case of
* {@link PleaseRetryException}, this method will attempt to re-send the data 5 times before
* giving up.
* {@link PleaseRetryException}, this method will attempt to re-send the data 5 times before giving
* up.
*
* @param instCode the WIEWS institute code
* @param jsonAccessionList the JSON array of accessions
......@@ -648,31 +540,28 @@ public class GenesysClient {
return query(Verb.POST, "/acn/" + instCode + "/delete", null, jsonAccessionIdList);
}
/**
* Gets the authorization url.
*
* @return the authorization url
*/
public String getAuthorizationUrl() {
return service.getAuthorizationUrl(null);
}
/**
* Obtain access and refresh tokens with verifier code.
*
* @param verifierCode the verifier code
* @throws OAuthAuthenticationException
*/
public void authenticate(final String verifierCode) {
final Verifier verifier = new Verifier(verifierCode);
final Token accessToken = service.getAccessToken(null, verifier);
public void authenticate(final String verifierCode) throws OAuthAuthenticationException {
try {
OAuth2AccessToken accessToken = service.getAccessToken(verifierCode);
_log.info("ACCESS TOKEN: " + accessToken.getAccessToken() + " scope=" + accessToken.getScope() + " raw=" + accessToken.getRawResponse());
_log.info("ACCESS TOKEN: " + accessToken.getToken() + " sec=" + accessToken.getSecret() + " raw=" + accessToken.getRawResponse());
final String refreshToken = accessToken.getRefreshToken();
_log.info("REFRESH TOKEN: " + refreshToken);
final Token refreshToken = genesysApi.getRefreshToken(accessToken);
_log.info("REFRESH TOKEN: " + refreshToken.getToken() + " sec=" + refreshToken.getSecret() + " raw=" + refreshToken.getRawResponse());
tokens.setAccessToken(accessToken.getAccessToken());
tokens.setRefreshToken(refreshToken);
tokens.setAccessToken(accessToken.getToken());
tokens.setRefreshToken(refreshToken.getToken());
} catch (IOException | InterruptedException | ExecutionException e) {
_log.error("Auth error", e);
throw new OAuthAuthenticationException(e.getMessage());
}
}
/**
......@@ -1105,8 +994,8 @@ public class GenesysClient {
}
/**
* List existing image galleries for INSTCODE. The response is paginated, provide
* <code>page</code> argument to request a specific page.
* List existing image galleries for INSTCODE. The response is paginated, provide <code>page</code>
* argument to request a specific page.
*
* @param instCode institute code (MCPD INSTCODE)
* @param page 1 for first page
......
......@@ -18,8 +18,9 @@ package org.genesys2.client.oauth;
import java.io.Serializable;
import com.github.scribejava.core.model.OAuth2AccessToken;
import org.apache.commons.lang.StringUtils;
import org.scribe.model.Token;
/**
* A place to keep the tokens for the session.
......@@ -36,7 +37,7 @@ public class GenesysTokens implements Serializable {
private String refreshToken = null;
/** The _access token. */
private Token _accessToken = null;
private OAuth2AccessToken _accessToken = null;
/**
* Gets the access token.
......@@ -54,7 +55,7 @@ public class GenesysTokens implements Serializable {
*/
public void setAccessToken(final String accessToken) {
this.accessToken = accessToken;
_accessToken = new Token(accessToken, "");
_accessToken = new OAuth2AccessToken(accessToken);
}
/**
......@@ -98,7 +99,7 @@ public class GenesysTokens implements Serializable {
*
* @return the token
*/
public Token accessToken() {
public OAuth2AccessToken accessToken() {
return _accessToken;
}
}
package org.genesys2.client.oauth;
public class HttpConstants {
public static final String APPLICATION_JSON_UTF8 = "application/json;charset=utf8";
public static final String LOCATION = "Location";
}
......@@ -16,64 +16,25 @@
package org.genesys2.client.oauth.api;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.apache.http.HttpHeaders;
import org.apache.log4j.LogManager;
import org.apache.log4j.Logger;
import org.genesys2.client.oauth.GenesysApiException;
import org.scribe.builder.api.DefaultApi20;
import org.scribe.exceptions.OAuthException;
import org.scribe.extractors.AccessTokenExtractor;
import org.scribe.extractors.JsonTokenExtractor;
import org.scribe.model.OAuthConfig;
import org.scribe.model.OAuthConstants;
import org.scribe.model.OAuthRequest;
import org.scribe.model.Response;