Aligning pom artifactId to svn location
git-svn-id: https://svn.d4science.research-infrastructures.eu/gcube/trunk/Common/gxREST@178656 82a268e6-3cf1-43bd-a215-b396298e98cf
This commit is contained in:
commit
7bba7ebe6e
|
@ -0,0 +1,5 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<classpath>
|
||||
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
|
||||
<classpathentry kind="output" path="bin"/>
|
||||
</classpath>
|
|
@ -0,0 +1,23 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<projectDescription>
|
||||
<name>gxRest</name>
|
||||
<comment></comment>
|
||||
<projects>
|
||||
</projects>
|
||||
<buildSpec>
|
||||
<buildCommand>
|
||||
<name>org.eclipse.jdt.core.javabuilder</name>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
<buildCommand>
|
||||
<name>org.eclipse.m2e.core.maven2Builder</name>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
</buildSpec>
|
||||
<natures>
|
||||
<nature>org.eclipse.jdt.core.javanature</nature>
|
||||
<nature>org.eclipse.m2e.core.maven2Nature</nature>
|
||||
</natures>
|
||||
</projectDescription>
|
|
@ -0,0 +1,2 @@
|
|||
eclipse.preferences.version=1
|
||||
encoding/<project>=UTF-8
|
|
@ -0,0 +1,36 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<classpath>
|
||||
<classpathentry kind="src" output="target/classes" path="src/main/java">
|
||||
<attributes>
|
||||
<attribute name="optional" value="true"/>
|
||||
<attribute name="maven.pomderived" value="true"/>
|
||||
</attributes>
|
||||
</classpathentry>
|
||||
<classpathentry excluding="**" kind="src" output="target/classes" path="src/main/resources">
|
||||
<attributes>
|
||||
<attribute name="maven.pomderived" value="true"/>
|
||||
</attributes>
|
||||
</classpathentry>
|
||||
<classpathentry kind="src" output="target/test-classes" path="src/test/java">
|
||||
<attributes>
|
||||
<attribute name="optional" value="true"/>
|
||||
<attribute name="maven.pomderived" value="true"/>
|
||||
</attributes>
|
||||
</classpathentry>
|
||||
<classpathentry excluding="**" kind="src" output="target/test-classes" path="src/test/resources">
|
||||
<attributes>
|
||||
<attribute name="maven.pomderived" value="true"/>
|
||||
</attributes>
|
||||
</classpathentry>
|
||||
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8">
|
||||
<attributes>
|
||||
<attribute name="maven.pomderived" value="true"/>
|
||||
</attributes>
|
||||
</classpathentry>
|
||||
<classpathentry kind="con" path="org.eclipse.m2e.MAVEN2_CLASSPATH_CONTAINER">
|
||||
<attributes>
|
||||
<attribute name="maven.pomderived" value="true"/>
|
||||
</attributes>
|
||||
</classpathentry>
|
||||
<classpathentry kind="output" path="target/classes"/>
|
||||
</classpath>
|
|
@ -0,0 +1,23 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<projectDescription>
|
||||
<name>gxHTTP</name>
|
||||
<comment></comment>
|
||||
<projects>
|
||||
</projects>
|
||||
<buildSpec>
|
||||
<buildCommand>
|
||||
<name>org.eclipse.jdt.core.javabuilder</name>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
<buildCommand>
|
||||
<name>org.eclipse.m2e.core.maven2Builder</name>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
</buildSpec>
|
||||
<natures>
|
||||
<nature>org.eclipse.jdt.core.javanature</nature>
|
||||
<nature>org.eclipse.m2e.core.maven2Nature</nature>
|
||||
</natures>
|
||||
</projectDescription>
|
|
@ -0,0 +1,6 @@
|
|||
eclipse.preferences.version=1
|
||||
encoding//src/main/java=UTF-8
|
||||
encoding//src/main/resources=UTF-8
|
||||
encoding//src/test/java=UTF-8
|
||||
encoding//src/test/resources=UTF-8
|
||||
encoding/<project>=UTF-8
|
|
@ -0,0 +1,5 @@
|
|||
eclipse.preferences.version=1
|
||||
org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8
|
||||
org.eclipse.jdt.core.compiler.compliance=1.8
|
||||
org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning
|
||||
org.eclipse.jdt.core.compiler.source=1.8
|
|
@ -0,0 +1,4 @@
|
|||
gCube System - License
|
||||
------------------------------------------------------------
|
||||
|
||||
${gcube.license}
|
|
@ -0,0 +1,67 @@
|
|||
The gCube System - ${name}
|
||||
--------------------------------------------------
|
||||
|
||||
${description}
|
||||
|
||||
|
||||
${gcube.description}
|
||||
|
||||
${gcube.funding}
|
||||
|
||||
|
||||
Version
|
||||
--------------------------------------------------
|
||||
|
||||
${version} (${buildDate})
|
||||
|
||||
Please see the file named "changelog.xml" in this directory for the release notes.
|
||||
|
||||
|
||||
Authors
|
||||
--------------------------------------------------
|
||||
|
||||
* Manuele Simi (manuele.simi-AT-isti.cnr.it), Istituto di Scienza e Tecnologie dell'Informazione "A. Faedo" - CNR, Pisa (Italy).
|
||||
* Luca Frosini (luca.frosini-AT-isti.cnr.it), Istituto di Scienza e Tecnologie dell'Informazione "A. Faedo" - CNR, Pisa (Italy).
|
||||
|
||||
|
||||
Maintainers
|
||||
-----------
|
||||
|
||||
* Manuele Simi (manuele.simi-AT-isti.cnr.it), Istituto di Scienza e Tecnologie dell'Informazione "A. Faedo" - CNR, Pisa (Italy).
|
||||
* Luca Frosini (luca.frosini-AT-isti.cnr.it), Istituto di Scienza e Tecnologie dell'Informazione "A. Faedo" - CNR, Pisa (Italy).
|
||||
|
||||
Download information
|
||||
--------------------------------------------------
|
||||
|
||||
Source code is available from SVN:
|
||||
${scm.url}
|
||||
|
||||
Binaries can be downloaded from the gCube website:
|
||||
${gcube.website}
|
||||
|
||||
|
||||
Installation
|
||||
--------------------------------------------------
|
||||
|
||||
Installation documentation is available on-line in the gCube Wiki:
|
||||
${gcube.wikiRoot}/
|
||||
|
||||
|
||||
Documentation
|
||||
--------------------------------------------------
|
||||
|
||||
Documentation is available on-line in the gCube Wiki:
|
||||
${gcube.wikiRoot}/
|
||||
|
||||
|
||||
Support
|
||||
--------------------------------------------------
|
||||
|
||||
Bugs and support requests can be reported in the gCube issue tracking tool:
|
||||
${gcube.issueTracking}
|
||||
|
||||
|
||||
Licensing
|
||||
--------------------------------------------------
|
||||
|
||||
This software is licensed under the terms you may find in the file named "LICENSE" in this directory.
|
|
@ -0,0 +1,13 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE xml>
|
||||
<ReleaseNotes>
|
||||
<Changeset component="org.gcube.common.gxHTTP.1-1-1" date="${buildDate}">
|
||||
<Change></Change>
|
||||
</Changeset>
|
||||
<Changeset component="org.gcube.common.gxHTTP.1-1-0" date="2019-02-26">
|
||||
<Change>Separated plaing HTTP requests from gxRest</Change>
|
||||
</Changeset>
|
||||
<Changeset component="org.gcube.common.gxHTTP.1-0-0" date="2018-12-01">
|
||||
<Change>First Release</Change>
|
||||
</Changeset>
|
||||
</ReleaseNotes>
|
|
@ -0,0 +1,28 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE xml>
|
||||
<Resource>
|
||||
<ID />
|
||||
<Type>Service</Type>
|
||||
<Profile>
|
||||
<Description>${description}</Description>
|
||||
<Class>${serviceClass}</Class>
|
||||
<Name>${artifactId}</Name>
|
||||
<Version>1.0.0</Version>
|
||||
<Packages>
|
||||
<Software>
|
||||
<Description>${description}</Description>
|
||||
<Name>${artifactId}</Name>
|
||||
<Version>${version}</Version>
|
||||
<MavenCoordinates>
|
||||
<groupId>${groupId}</groupId>
|
||||
<artifactId>${artifactId}</artifactId>
|
||||
<version>${version}</version>
|
||||
</MavenCoordinates>
|
||||
<Type>Library</Type>
|
||||
<Files>
|
||||
<File>${build.finalName}.${project.packaging}</File>
|
||||
</Files>
|
||||
</Software>
|
||||
</Packages>
|
||||
</Profile>
|
||||
</Resource>
|
|
@ -0,0 +1,63 @@
|
|||
<?xml version="1.0"?>
|
||||
<project
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"
|
||||
xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<parent>
|
||||
<groupId>org.gcube.common</groupId>
|
||||
<artifactId>gxREST</artifactId>
|
||||
<version>1.1.2-SNAPSHOT</version>
|
||||
</parent>
|
||||
<groupId>org.gcube.common</groupId>
|
||||
<artifactId>gxHTTP</artifactId>
|
||||
|
||||
<name>gCube eXtensions to REST with HTTP</name>
|
||||
<description>gCube eXtensions to REST based on HTTP</description>
|
||||
|
||||
|
||||
<properties>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
<distroDirectory>${project.basedir}/distro</distroDirectory>
|
||||
</properties>
|
||||
|
||||
<scm>
|
||||
<connection>scm:https://svn.d4science.research-infrastructures.eu/gcube/trunk/common/${parent.artifactId}/${project.artifactId}</connection>
|
||||
<developerConnection>scm:https://svn.d4science.research-infrastructures.eu/gcube/trunk/common/${parent.artifactId}/${project.artifactId}</developerConnection>
|
||||
<url>https://svn.d4science.research-infrastructures.eu/gcube/trunk/common/${parent.artifactId}/${project.artifactId}</url>
|
||||
</scm>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.gcube.common</groupId>
|
||||
<artifactId>authorization-client</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.slf4j</groupId>
|
||||
<artifactId>slf4j-api</artifactId>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>junit</groupId>
|
||||
<artifactId>junit</artifactId>
|
||||
<version>4.12</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-assembly-plugin</artifactId>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>make-servicearchive</id>
|
||||
<phase>package</phase>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
</project>
|
|
@ -0,0 +1,263 @@
|
|||
package org.gcube.common.gxhttp.reference;
|
||||
|
||||
import java.io.DataOutputStream;
|
||||
import java.io.InputStream;
|
||||
import java.io.StringWriter;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.net.HttpURLConnection;
|
||||
import java.net.MalformedURLException;
|
||||
import java.net.URL;
|
||||
import java.net.URLEncoder;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import org.gcube.common.authorization.library.provider.SecurityTokenProvider;
|
||||
import org.gcube.common.gxhttp.request.GXHTTPStringRequest;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
/**
|
||||
* A remote connection for a {@link GXHTTPStringRequest}.
|
||||
*
|
||||
* @author Manuele Simi (ISTI-CNR)
|
||||
* @author Luca Frosini (ISTI-CNR)
|
||||
*/
|
||||
public class GXConnection {
|
||||
|
||||
public static final String APPLICATION_JSON_CHARSET_UTF_8 = "application/json;charset=UTF-8";
|
||||
public static final String PATH_SEPARATOR = "/";
|
||||
public static final String PARAM_STARTER = "?";
|
||||
public static final String PARAM_EQUALS = "=";
|
||||
public static final String PARAM_SEPARATOR = "&";
|
||||
public static final String UTF8 = "UTF-8";
|
||||
|
||||
protected static final Logger logger = LoggerFactory.getLogger(GXConnection.class);
|
||||
|
||||
public enum HTTPMETHOD {
|
||||
HEAD, GET, POST, PUT, DELETE, TRACE, PATCH, OPTIONS, CONNECT;
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return this.name();
|
||||
}
|
||||
}
|
||||
|
||||
protected final String address;
|
||||
protected String path = "", agent;
|
||||
private String queryParameters;
|
||||
private String pathParameters;
|
||||
private String body;
|
||||
private InputStream bodyAsStream;
|
||||
private Map<String, String> properties = new HashMap<>();
|
||||
private boolean extCall = false;
|
||||
|
||||
public GXConnection(String address) {
|
||||
this.address = address;
|
||||
}
|
||||
|
||||
protected void addPath(String pathPart) throws UnsupportedEncodingException {
|
||||
if (this.path.compareTo("")!=0 && !this.path.endsWith(GXConnection.PATH_SEPARATOR))
|
||||
this.path += GXConnection.PATH_SEPARATOR;
|
||||
this.path += Arrays.stream(pathPart.split(GXConnection.PATH_SEPARATOR))
|
||||
.map(part -> encodePart(part, true))
|
||||
.collect(Collectors.joining(GXConnection.PATH_SEPARATOR));
|
||||
}
|
||||
|
||||
private String encodePart(String part, boolean path) {
|
||||
try {
|
||||
// URL spaces are encoded with + for query parameter
|
||||
// URL spaces are encoded with %20 for path parts
|
||||
String encoded = URLEncoder.encode(part, GXConnection.UTF8);
|
||||
if(path) {
|
||||
encoded = encoded.replace("+","%20");
|
||||
}
|
||||
return encoded;
|
||||
} catch (UnsupportedEncodingException e) {
|
||||
return part;
|
||||
}
|
||||
}
|
||||
|
||||
private URL buildURL() throws MalformedURLException {
|
||||
|
||||
StringWriter prepareURL = new StringWriter();
|
||||
prepareURL.append(address);
|
||||
Objects.requireNonNull(path, "Null path detected in the request!");
|
||||
if (address.endsWith(PATH_SEPARATOR)) {
|
||||
if (path.startsWith(PATH_SEPARATOR)) {
|
||||
path = path.substring(1);
|
||||
}
|
||||
} else {
|
||||
if (!path.startsWith(PATH_SEPARATOR) && !path.isEmpty()) {
|
||||
prepareURL.append(PATH_SEPARATOR);
|
||||
}
|
||||
}
|
||||
prepareURL.append(path);
|
||||
if (Objects.nonNull(this.pathParameters))
|
||||
prepareURL.append(this.pathParameters);
|
||||
if (Objects.nonNull(this.queryParameters) && !this.queryParameters.isEmpty()) {
|
||||
prepareURL.append(PARAM_STARTER);
|
||||
prepareURL.append(queryParameters);
|
||||
}
|
||||
URL url = new URL(prepareURL.toString());
|
||||
if (url.getProtocol().compareTo("https") == 0) {
|
||||
url = new URL(url.getProtocol(), url.getHost(), url.getPort()==-1 ? url.getDefaultPort() : url.getPort(), url.getFile());
|
||||
}
|
||||
return url;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sends the request with the given method
|
||||
*
|
||||
* @param method
|
||||
* @return the connection
|
||||
* @throws Exception
|
||||
*/
|
||||
public HttpURLConnection send(HTTPMETHOD method) throws Exception {
|
||||
return send(this.buildURL(), method);
|
||||
}
|
||||
|
||||
private HttpURLConnection send(URL url, HTTPMETHOD method) throws Exception {
|
||||
HttpURLConnection uConn = (HttpURLConnection) url.openConnection();
|
||||
if (!this.extCall) {
|
||||
String token = SecurityTokenProvider.instance.get();
|
||||
if (Objects.isNull(token) || token.isEmpty())
|
||||
throw new IllegalStateException("The security token in the current environment is null.");
|
||||
|
||||
uConn.setRequestProperty(org.gcube.common.authorization.client.Constants.TOKEN_HEADER_ENTRY,
|
||||
token);
|
||||
}
|
||||
uConn.setDoOutput(true);
|
||||
// uConn.setRequestProperty("Content-type", APPLICATION_JSON_CHARSET_UTF_8);
|
||||
if(this.agent!=null) {
|
||||
uConn.setRequestProperty("User-Agent", this.agent);
|
||||
}
|
||||
for (String key : properties.keySet()) {
|
||||
uConn.setRequestProperty(key, properties.get(key));
|
||||
}
|
||||
uConn.setRequestMethod(method.toString());
|
||||
HttpURLConnection.setFollowRedirects(true);
|
||||
// attach the body
|
||||
if (Objects.nonNull(this.body) && (method == HTTPMETHOD.POST || method == HTTPMETHOD.PUT)) {
|
||||
DataOutputStream wr = new DataOutputStream(uConn.getOutputStream());
|
||||
wr.write(this.body.getBytes(GXConnection.UTF8));
|
||||
wr.flush();
|
||||
wr.close();
|
||||
}
|
||||
// upload the stream
|
||||
if (Objects.nonNull(this.bodyAsStream) && (method == HTTPMETHOD.POST || method == HTTPMETHOD.PUT)) {
|
||||
DataOutputStream wr = new DataOutputStream(uConn.getOutputStream());
|
||||
byte[] buffer = new byte[1024];
|
||||
|
||||
int len;
|
||||
while((len = this.bodyAsStream.read(buffer)) > 0) {
|
||||
wr.write(buffer, 0, len);
|
||||
}
|
||||
wr.flush();
|
||||
wr.close();
|
||||
}
|
||||
|
||||
int responseCode = uConn.getResponseCode();
|
||||
String responseMessage = uConn.getResponseMessage();
|
||||
logger.trace("{} {} : {} - {}", method, uConn.getURL(), responseCode, responseMessage);
|
||||
|
||||
// if we get a redirect code, we invoke the connection to the new URL
|
||||
if (responseCode == HttpURLConnection.HTTP_MOVED_TEMP || responseCode == HttpURLConnection.HTTP_MOVED_PERM
|
||||
|| responseCode == HttpURLConnection.HTTP_SEE_OTHER) {
|
||||
URL redirectURL = getURL(uConn.getHeaderField("Location"));
|
||||
logger.trace("{} is going to be redirected to {}", url.toString(), redirectURL.toString());
|
||||
return send(redirectURL, method);
|
||||
}
|
||||
return uConn;
|
||||
}
|
||||
|
||||
private URL getURL(String urlString) throws MalformedURLException {
|
||||
URL url = new URL(urlString);
|
||||
if (url.getProtocol().equals("https")) {
|
||||
url = new URL(url.getProtocol(), url.getHost(), url.getDefaultPort(), url.getFile());
|
||||
}
|
||||
return url;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param agent
|
||||
*/
|
||||
protected void setAgent(String agent) {
|
||||
this.agent = agent;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the path parameters for the connection.
|
||||
*
|
||||
* @param parameters
|
||||
*/
|
||||
public void setPathParameters(String parameters) {
|
||||
this.pathParameters = parameters;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the query parameters for the connection.
|
||||
*
|
||||
* @param parameters
|
||||
*/
|
||||
public void setQueryParameters(String parameters) {
|
||||
this.queryParameters = parameters;
|
||||
}
|
||||
|
||||
/**
|
||||
* Resets the connection.
|
||||
*/
|
||||
public void reset() {
|
||||
this.pathParameters = "";
|
||||
this.queryParameters = "";
|
||||
this.body = "";
|
||||
}
|
||||
|
||||
/**
|
||||
* The body of the request.
|
||||
*
|
||||
* @param body
|
||||
*/
|
||||
public void addBody(String body) {
|
||||
if (Objects.isNull(this.bodyAsStream))
|
||||
this.body = body;
|
||||
else
|
||||
throw new IllegalArgumentException("Cannot set the input stream because addBodyAsStream(InputStream) was already invoked.");
|
||||
}
|
||||
|
||||
/**
|
||||
* @param bodyAsStream the stream to set as input
|
||||
*/
|
||||
public void addBodyAsStream(InputStream bodyAsStream) {
|
||||
if (Objects.isNull(this.body))
|
||||
this.bodyAsStream = bodyAsStream;
|
||||
else
|
||||
throw new IllegalArgumentException("Cannot set the input stream because addBody(String) was already invoked.");
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a property as header.
|
||||
* @param name
|
||||
* @param value
|
||||
*/
|
||||
public void setProperty(String name, String value) {
|
||||
this.properties.put(name, value);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param extCall the extCall to set
|
||||
*/
|
||||
public void setExtCall(boolean extCall) {
|
||||
this.extCall = extCall;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the extCall
|
||||
*/
|
||||
public boolean isExtCall() {
|
||||
return extCall;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,101 @@
|
|||
package org.gcube.common.gxhttp.reference;
|
||||
|
||||
/**
|
||||
*
|
||||
* HTTP methods for requests.
|
||||
*
|
||||
* @author Manuele Simi (ISTI-CNR)
|
||||
*
|
||||
* @param <BODY> the type of the body request
|
||||
* @param <RESPONSE> the type of the response
|
||||
|
||||
*/
|
||||
public interface GXHTTP<BODY,RESPONSE> {
|
||||
|
||||
/**
|
||||
* Sends the PUT request to the web application.
|
||||
* @param body the body of the request
|
||||
* @return the response
|
||||
*/
|
||||
RESPONSE put(BODY body) throws Exception;
|
||||
|
||||
/**
|
||||
* Sends the PUT request to the web application with no body.
|
||||
* @return the response
|
||||
*/
|
||||
RESPONSE put() throws Exception;
|
||||
|
||||
/**
|
||||
* Sends the DELETE request to the web application.
|
||||
* @return the response
|
||||
*/
|
||||
RESPONSE delete() throws Exception;
|
||||
|
||||
/**
|
||||
* Sends the HEAD request to the web application.
|
||||
* @return the response
|
||||
*/
|
||||
RESPONSE head() throws Exception;
|
||||
|
||||
/**
|
||||
* Sends the GET request to the web application.
|
||||
* @return the response
|
||||
*/
|
||||
RESPONSE get() throws Exception;
|
||||
|
||||
/**
|
||||
* Sends the POST request to the web application.
|
||||
* @param body the body of the request
|
||||
* @return the response
|
||||
* @throws Exception
|
||||
*/
|
||||
RESPONSE post(BODY body) throws Exception;
|
||||
|
||||
/**
|
||||
* Sends the POST request to the web application with no body.
|
||||
* @return the response
|
||||
* @throws Exception
|
||||
*/
|
||||
RESPONSE post() throws Exception;
|
||||
|
||||
/**
|
||||
* Sends the TRACE request to the web application with no body.
|
||||
* @return the response
|
||||
* @throws Exception
|
||||
*/
|
||||
RESPONSE trace() throws Exception;
|
||||
|
||||
/**
|
||||
* Sends the PATCH request to the web application with no body.
|
||||
* @return the response
|
||||
* @throws Exception
|
||||
*/
|
||||
RESPONSE patch() throws Exception;
|
||||
|
||||
/**
|
||||
* Sends the OPTIONS request to the web application with no body.
|
||||
* @return the response
|
||||
* @throws Exception
|
||||
*/
|
||||
RESPONSE options() throws Exception;
|
||||
|
||||
/**
|
||||
* Sends the CONNECT request to the web application with no body.
|
||||
* @return the response
|
||||
* @throws Exception
|
||||
*/
|
||||
RESPONSE connect() throws Exception;
|
||||
|
||||
/**
|
||||
* Overrides the default security token.
|
||||
* @param token the new token
|
||||
*/
|
||||
void setSecurityToken(String token);
|
||||
|
||||
/**
|
||||
* States if the service being called in an external service (not gCube).
|
||||
* @param ext true if external, false otherwise
|
||||
*/
|
||||
void isExternalCall(boolean ext);
|
||||
|
||||
}
|
|
@ -0,0 +1,207 @@
|
|||
package org.gcube.common.gxhttp.reference;
|
||||
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.net.HttpURLConnection;
|
||||
import java.net.URLEncoder;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.Map.Entry;
|
||||
|
||||
import org.gcube.common.gxhttp.reference.GXConnection.HTTPMETHOD;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
/**
|
||||
* Builder for GXHTTP Requests.
|
||||
*
|
||||
* @author Manuele Simi (ISTI CNR)
|
||||
*
|
||||
*/
|
||||
public class GXHTTPRequestBuilder {
|
||||
|
||||
protected static final Logger logger = LoggerFactory.getLogger(GXHTTPRequestBuilder.class);
|
||||
|
||||
public GXConnection connection;
|
||||
|
||||
/**
|
||||
* Sets the identity user agent associated to the request.
|
||||
*
|
||||
* @param agent
|
||||
* @return the request
|
||||
*/
|
||||
public GXHTTPRequestBuilder from(String agent) {
|
||||
this.connection.setAgent(agent);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds s positional path parameter to the request.
|
||||
*
|
||||
* @param path
|
||||
* @return the request
|
||||
* @throws UnsupportedEncodingException
|
||||
*/
|
||||
public GXHTTPRequestBuilder path(String path) throws UnsupportedEncodingException {
|
||||
this.connection.addPath(path);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the query parameters for the request.
|
||||
*
|
||||
* @param parameters
|
||||
* the parameters that go in the URL after the address and the
|
||||
* path params.
|
||||
* @return the request
|
||||
* @throws UnsupportedEncodingException
|
||||
*/
|
||||
public GXHTTPRequestBuilder queryParams(Map<String, String> parameters) throws UnsupportedEncodingException {
|
||||
if (Objects.nonNull(parameters) && !parameters.isEmpty()) {
|
||||
StringBuilder result = new StringBuilder();
|
||||
boolean first = true;
|
||||
for (Entry<String, String> parameter : parameters.entrySet()) {
|
||||
if (first) {
|
||||
first = false;
|
||||
} else {
|
||||
result.append(GXConnection.PARAM_SEPARATOR);
|
||||
}
|
||||
result.append(URLEncoder.encode(parameter.getKey(), GXConnection.UTF8));
|
||||
result.append(GXConnection.PARAM_EQUALS);
|
||||
result.append(URLEncoder.encode(parameter.getValue(), GXConnection.UTF8));
|
||||
}
|
||||
connection.setQueryParameters(result.toString());
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Overrides the default security token.
|
||||
*
|
||||
* @param token
|
||||
*/
|
||||
public void setSecurityToken(String token) {
|
||||
if (!this.connection.isExtCall())
|
||||
this.connection.setProperty(org.gcube.common.authorization.client.Constants.TOKEN_HEADER_ENTRY, token);
|
||||
else
|
||||
throw new UnsupportedOperationException("Cannot set the security token on an external call");
|
||||
}
|
||||
|
||||
/**
|
||||
* Add headers to the request.
|
||||
*
|
||||
* @param name
|
||||
* @param value
|
||||
*/
|
||||
public GXHTTPRequestBuilder header(String name, String value) {
|
||||
this.connection.setProperty(name, value);
|
||||
return this;
|
||||
}
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see org.gcube.common.gxrest.request.GXHTTP#put()
|
||||
*/
|
||||
public HttpURLConnection put() throws Exception {
|
||||
logger.trace("Sending a PUT request...");
|
||||
return this.connection.send(HTTPMETHOD.PUT);
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see org.gcube.common.gxrest.request.GXHTTP#post()
|
||||
*/
|
||||
public HttpURLConnection post() throws Exception {
|
||||
logger.trace("Sending a POST request...");
|
||||
return this.connection.send(HTTPMETHOD.POST);
|
||||
}
|
||||
/**
|
||||
* Sends the GET request to the web application.
|
||||
*
|
||||
* @return the response
|
||||
*/
|
||||
public HttpURLConnection get() throws Exception {
|
||||
logger.trace("Sending a GET request...");
|
||||
return this.connection.send(HTTPMETHOD.GET);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sends the DELETE request to the web application.
|
||||
*
|
||||
* @return the response
|
||||
* @throws Exception
|
||||
*/
|
||||
public HttpURLConnection delete() throws Exception {
|
||||
logger.trace("Sending a DELETE request...");
|
||||
return this.connection.send(HTTPMETHOD.DELETE);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sends the HEAD request to the web application.
|
||||
*
|
||||
* @return the response
|
||||
* @throws Exception
|
||||
*/
|
||||
public HttpURLConnection head() throws Exception {
|
||||
logger.trace("Sending a HEAD request...");
|
||||
return this.connection.send(HTTPMETHOD.HEAD);
|
||||
}
|
||||
|
||||
/**
|
||||
* Clears all the parameter except the address.
|
||||
*/
|
||||
public void clear() {
|
||||
this.connection.reset();
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see org.gcube.common.gxrest.request.GXHTTP#trace()
|
||||
*/
|
||||
public HttpURLConnection trace() throws Exception {
|
||||
logger.trace("Sending a TRACE request...");
|
||||
return this.connection.send(HTTPMETHOD.TRACE);
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see org.gcube.common.gxrest.request.GXHTTP#patch()
|
||||
*/
|
||||
public HttpURLConnection patch() throws Exception {
|
||||
logger.trace("Sending a TRACE request...");
|
||||
return this.connection.send(HTTPMETHOD.PATCH);
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see org.gcube.common.gxrest.request.GXHTTP#options()
|
||||
*/
|
||||
public HttpURLConnection options() throws Exception {
|
||||
logger.trace("Sending an OPTIONS request...");
|
||||
return this.connection.send(HTTPMETHOD.OPTIONS);
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see org.gcube.common.gxrest.request.GXHTTP#connect()
|
||||
*/
|
||||
public HttpURLConnection connect() throws Exception {
|
||||
logger.trace("Sending a CONNECT request...");
|
||||
return this.connection.send(HTTPMETHOD.CONNECT);
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see org.gcube.common.gxrest.request.GXHTTP#isExternalCall(boolean)
|
||||
*/
|
||||
public void isExternalCall(boolean ext) {
|
||||
this.connection.setExtCall(ext);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,7 @@
|
|||
/**
|
||||
* GXHTTP core.
|
||||
*
|
||||
* @author Manuele Simi (ISTI CNR)
|
||||
*
|
||||
*/
|
||||
package org.gcube.common.gxhttp.reference;
|
|
@ -0,0 +1,107 @@
|
|||
package org.gcube.common.gxhttp.request;
|
||||
|
||||
import java.net.HttpURLConnection;
|
||||
|
||||
import org.gcube.common.gxhttp.reference.GXHTTPRequestBuilder;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
/**
|
||||
* Common logic across GXHTTP requests.
|
||||
*
|
||||
* @author Manuele Simi (ISTI CNR)
|
||||
*
|
||||
*/
|
||||
class GXHTTPCommonRequest {
|
||||
|
||||
protected static final Logger logger = LoggerFactory.getLogger(GXHTTPStringRequest.class);
|
||||
|
||||
protected GXHTTPRequestBuilder builder = new GXHTTPRequestBuilder();
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.gcube.common.gxhttp.reference.GXHTTP#put()
|
||||
*/
|
||||
public HttpURLConnection put() throws Exception {
|
||||
return builder.put();
|
||||
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.gcube.common.gxhttp.reference.GXHTTP#delete()
|
||||
*/
|
||||
public HttpURLConnection delete() throws Exception {
|
||||
return builder.delete();
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.gcube.common.gxhttp.reference.GXHTTP#head()
|
||||
*/
|
||||
public HttpURLConnection head() throws Exception {
|
||||
return builder.head();
|
||||
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.gcube.common.gxhttp.reference.GXHTTP#get()
|
||||
*/
|
||||
public HttpURLConnection get() throws Exception {
|
||||
return builder.get();
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.gcube.common.gxhttp.reference.GXHTTP#post()
|
||||
*/
|
||||
public HttpURLConnection post() throws Exception {
|
||||
return builder.post();
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.gcube.common.gxhttp.reference.GXHTTP#trace()
|
||||
*/
|
||||
public HttpURLConnection trace() throws Exception {
|
||||
return builder.trace();
|
||||
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.gcube.common.gxhttp.reference.GXHTTP#patch()
|
||||
*/
|
||||
public HttpURLConnection patch() throws Exception {
|
||||
return builder.patch();
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.gcube.common.gxhttp.reference.GXHTTP#options()
|
||||
*/
|
||||
public HttpURLConnection options() throws Exception {
|
||||
return builder.options();
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.gcube.common.gxhttp.reference.GXHTTP#connect()
|
||||
*/
|
||||
public HttpURLConnection connect() throws Exception {
|
||||
return builder.connect();
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.gcube.common.gxhttp.reference.GXHTTP#setSecurityToken(java.lang.String)
|
||||
*/
|
||||
public void setSecurityToken(String token) {
|
||||
builder.setSecurityToken(token);
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.gcube.common.gxhttp.reference.GXHTTP#isExternalCall(boolean)
|
||||
*/
|
||||
public void isExternalCall(boolean ext) {
|
||||
builder.isExternalCall(ext);
|
||||
}
|
||||
|
||||
/**
|
||||
* Clear up the request.
|
||||
*/
|
||||
public void clear() {
|
||||
builder.clear();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,102 @@
|
|||
package org.gcube.common.gxhttp.request;
|
||||
|
||||
import java.io.InputStream;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.net.HttpURLConnection;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
|
||||
import org.gcube.common.gxhttp.reference.GXConnection;
|
||||
import org.gcube.common.gxhttp.reference.GXHTTP;
|
||||
import org.gcube.common.gxhttp.reference.GXConnection.HTTPMETHOD;
|
||||
|
||||
/**
|
||||
* A context-aware request to a web application.
|
||||
* It supports sending streams through Put/Post requests.
|
||||
*
|
||||
* @author Manuele Simi (ISTI CNR)
|
||||
*
|
||||
*/
|
||||
public class GXHTTPStreamRequest extends GXHTTPCommonRequest
|
||||
implements GXHTTP<InputStream,HttpURLConnection> {
|
||||
|
||||
/**
|
||||
* A new request.
|
||||
*/
|
||||
private GXHTTPStreamRequest(String address) {
|
||||
builder.connection = new GXConnection(address);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new request.
|
||||
*
|
||||
* @param address
|
||||
* the address of the web app to call
|
||||
* @return the request
|
||||
*/
|
||||
public static GXHTTPStreamRequest newRequest(String address) {
|
||||
return new GXHTTPStreamRequest(address);
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.gcube.common.gxhttp.reference.GXHTTP#put(java.lang.Object)
|
||||
*/
|
||||
@Override
|
||||
public HttpURLConnection put(InputStream body) throws Exception {
|
||||
if (Objects.nonNull(body))
|
||||
builder.connection.addBodyAsStream(body);
|
||||
logger.trace("Sending a PUT request...");
|
||||
return builder.connection.send(HTTPMETHOD.PUT);
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.gcube.common.gxhttp.reference.GXHTTP#post(java.lang.Object)
|
||||
*/
|
||||
@Override
|
||||
public HttpURLConnection post(InputStream body) throws Exception {
|
||||
logger.trace("Sending a POST request...");
|
||||
if (Objects.nonNull(body))
|
||||
builder.connection.addBodyAsStream(body);
|
||||
return builder.connection.send(HTTPMETHOD.POST);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string
|
||||
* @return the request
|
||||
*/
|
||||
public GXHTTPStreamRequest from(String agent) {
|
||||
builder.from(agent) ;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param path
|
||||
* @return the request
|
||||
* @throws UnsupportedEncodingException
|
||||
*
|
||||
*/
|
||||
public GXHTTPStreamRequest path(String path) throws UnsupportedEncodingException {
|
||||
builder.path(path);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param name
|
||||
* @param value
|
||||
* @return the request
|
||||
*/
|
||||
public GXHTTPStreamRequest header(String name, String value) {
|
||||
builder.header(name, value);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param queryParams
|
||||
* @return the request
|
||||
* @throws UnsupportedEncodingException
|
||||
*/
|
||||
public GXHTTPStreamRequest queryParams(Map<String, String> queryParams) throws UnsupportedEncodingException {
|
||||
builder.queryParams(queryParams);
|
||||
return this;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,114 @@
|
|||
package org.gcube.common.gxhttp.request;
|
||||
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.net.HttpURLConnection;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
|
||||
import org.gcube.common.gxhttp.reference.GXConnection;
|
||||
import org.gcube.common.gxhttp.reference.GXHTTP;
|
||||
import org.gcube.common.gxhttp.reference.GXConnection.HTTPMETHOD;
|
||||
|
||||
/**
|
||||
* A context-aware request to a web application.
|
||||
* It supports sending strings through Put/Post requests.
|
||||
*
|
||||
* @author Manuele Simi (ISTI CNR)
|
||||
*
|
||||
*/
|
||||
public class GXHTTPStringRequest extends GXHTTPCommonRequest implements GXHTTP<String,HttpURLConnection> {
|
||||
|
||||
/**
|
||||
* A new request.
|
||||
*/
|
||||
private GXHTTPStringRequest(String address) {
|
||||
builder.connection = new GXConnection(address);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new request.
|
||||
*
|
||||
* @param address
|
||||
* the address of the web app to call
|
||||
* @return the request
|
||||
*/
|
||||
public static GXHTTPStringRequest newRequest(String address) {
|
||||
return new GXHTTPStringRequest(address);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the body of the request.
|
||||
*
|
||||
* @param body
|
||||
* @return the request
|
||||
*/
|
||||
public GXHTTPStringRequest withBody(String body) {
|
||||
builder.connection.addBody(body);
|
||||
return this;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.gcube.common.gxhttp.reference.GXHTTP#put(java.lang.Object)
|
||||
*/
|
||||
@Override
|
||||
public HttpURLConnection put(String body) throws Exception {
|
||||
if (Objects.nonNull(body))
|
||||
builder.connection.addBody(body);
|
||||
logger.trace("Sending a PUT request...");
|
||||
return builder.connection.send(HTTPMETHOD.PUT);
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.gcube.common.gxhttp.reference.GXHTTP#post(java.lang.Object)
|
||||
*/
|
||||
@Override
|
||||
public HttpURLConnection post(String body) throws Exception {
|
||||
logger.trace("Sending a POST request...");
|
||||
if (Objects.nonNull(body))
|
||||
builder.connection.addBody(body);
|
||||
return builder.connection.send(HTTPMETHOD.POST);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string
|
||||
* @return the request
|
||||
*/
|
||||
public GXHTTPStringRequest from(String agent) {
|
||||
builder.from(agent) ;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string
|
||||
* @return the request
|
||||
* @throws UnsupportedEncodingException
|
||||
*
|
||||
*/
|
||||
public GXHTTPStringRequest path(String path) throws UnsupportedEncodingException {
|
||||
builder.path(path);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param name
|
||||
* @param value
|
||||
* @return the request
|
||||
*/
|
||||
public GXHTTPStringRequest header(String name, String value) {
|
||||
builder.header(name, value);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param queryParams
|
||||
* @return the request
|
||||
* @throws UnsupportedEncodingException
|
||||
*/
|
||||
public GXHTTPStringRequest queryParams(Map<String, String> queryParams) throws UnsupportedEncodingException {
|
||||
builder.queryParams(queryParams);
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
|
@ -0,0 +1,7 @@
|
|||
/**
|
||||
* GXHTTP requests.
|
||||
*
|
||||
* @author Manuele Simi (ISTI CNR)
|
||||
*
|
||||
*/
|
||||
package org.gcube.common.gxhttp.request;
|
|
@ -0,0 +1,140 @@
|
|||
package org.gcube.common.gxhttp.util;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.ObjectInput;
|
||||
import java.io.ObjectInputStream;
|
||||
import java.io.ObjectOutputStream;
|
||||
import java.io.OutputStream;
|
||||
|
||||
/**
|
||||
* Manipulation of a response's content.
|
||||
*
|
||||
* @author Manuele Simi (ISTI CNR)
|
||||
*
|
||||
*/
|
||||
final public class ContentUtils {
|
||||
|
||||
/**
|
||||
* Converts an object to an array of bytes
|
||||
* @param obj
|
||||
* @return the bytes
|
||||
* @throws IOException
|
||||
*/
|
||||
public static byte[] toByteArray(Object obj) throws IOException {
|
||||
byte[] bytes = null;
|
||||
ByteArrayOutputStream bos = null;
|
||||
ObjectOutputStream oos = null;
|
||||
try {
|
||||
bos = new ByteArrayOutputStream();
|
||||
oos = new ObjectOutputStream(bos);
|
||||
oos.writeObject(obj);
|
||||
oos.flush();
|
||||
bytes = bos.toByteArray();
|
||||
} finally {
|
||||
if (oos != null) {
|
||||
oos.close();
|
||||
}
|
||||
if (bos != null) {
|
||||
bos.close();
|
||||
}
|
||||
}
|
||||
return bytes;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param inputStream
|
||||
* @param class1
|
||||
* @return an instance of type "type"
|
||||
* @throws IOException
|
||||
* @throws ClassNotFoundException
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public static <T> T toObject(InputStream inputStream, Class<T> class1) throws IOException, ClassNotFoundException {
|
||||
ObjectInput in = null;
|
||||
T o = null;
|
||||
try {
|
||||
in = new ObjectInputStream(inputStream);
|
||||
o = (T) in.readObject();
|
||||
} finally {
|
||||
try {
|
||||
if (in != null) {
|
||||
in.close();
|
||||
}
|
||||
} catch (IOException ex) {
|
||||
// ignore close exception
|
||||
}
|
||||
}
|
||||
return o;
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts the array of bytes into an object.
|
||||
* @param data
|
||||
* @return the object
|
||||
* @throws IOException
|
||||
* @throws ClassNotFoundException
|
||||
*/
|
||||
public Object toObject(byte[] data) throws IOException, ClassNotFoundException {
|
||||
ByteArrayInputStream in = new ByteArrayInputStream(data);
|
||||
ObjectInputStream is = new ObjectInputStream(in);
|
||||
return is.readObject();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Gets the contents of an <code>InputStream</code> as a <code>byte[]</code>.
|
||||
*
|
||||
* @param input the <code>InputStream</code> to read from
|
||||
* @return the requested byte array
|
||||
* @throws NullPointerException if the input is null
|
||||
* @throws IOException if an I/O error occurs
|
||||
*/
|
||||
public static byte[] toByteArray(final InputStream input) throws IOException {
|
||||
return _toByteArray(input);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the contents of an <code>InputStream</code> as a <code>byte[]</code>.
|
||||
* <p>
|
||||
* This method buffers the input internally, so there is no need to use a
|
||||
* <code>BufferedInputStream</code>.
|
||||
*
|
||||
* @param input the <code>InputStream</code> to read from
|
||||
* @return the requested byte array
|
||||
* @throws NullPointerException if the input is null
|
||||
* @throws IOException if an I/O error occurs
|
||||
*/
|
||||
private static byte[] _toByteArray(final InputStream input) throws IOException {
|
||||
try (final ByteArrayOutputStream output = new ByteArrayOutputStream()) {
|
||||
copyStream(input, output);
|
||||
return output.toByteArray();
|
||||
}
|
||||
}
|
||||
|
||||
private static int copyStream(final InputStream input, final OutputStream output) throws IOException {
|
||||
final byte[] buffer = new byte[1024 * 4];
|
||||
long count = 0;
|
||||
int n;
|
||||
while (-1 != (n = input.read(buffer))) {
|
||||
output.write(buffer, 0, n);
|
||||
count += n;
|
||||
}
|
||||
if (count > Integer.MAX_VALUE) {
|
||||
return -1;
|
||||
}
|
||||
return (int) count;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param bytes
|
||||
* @return the string
|
||||
*/
|
||||
public static String toString(byte[] bytes) {
|
||||
return new String(bytes);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,7 @@
|
|||
/**
|
||||
* Utilities.
|
||||
*
|
||||
* @author Manuele Simi (ISTI CNR)
|
||||
*
|
||||
*/
|
||||
package org.gcube.common.gxhttp.util;
|
|
@ -0,0 +1,116 @@
|
|||
package org.gcube.common.gxhttp;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.net.HttpURLConnection;
|
||||
import java.util.Map;
|
||||
import java.util.Properties;
|
||||
import java.util.WeakHashMap;
|
||||
|
||||
import org.gcube.common.authorization.client.Constants;
|
||||
import org.gcube.common.authorization.client.exceptions.ObjectNotFound;
|
||||
import org.gcube.common.authorization.library.AuthorizationEntry;
|
||||
import org.gcube.common.authorization.library.provider.SecurityTokenProvider;
|
||||
import org.gcube.common.gxhttp.request.GXHTTPStringRequest;
|
||||
import org.gcube.common.gxhttp.util.ContentUtils;
|
||||
import org.junit.AfterClass;
|
||||
import org.junit.Before;
|
||||
import org.junit.BeforeClass;
|
||||
import org.junit.Test;
|
||||
|
||||
|
||||
/**
|
||||
* Test cases for {@link GXHTTPStringRequest}
|
||||
*
|
||||
* @author Manuele Simi (ISTI-CNR)
|
||||
*
|
||||
*/
|
||||
public class GXHTTPStringRequestTest {
|
||||
|
||||
private GXHTTPStringRequest request;
|
||||
|
||||
public static String DEFAULT_TEST_SCOPE = "";
|
||||
|
||||
static String DEFAULT_RM_URL = "";
|
||||
|
||||
static String DEFAULT_RR_URL = "";
|
||||
|
||||
|
||||
private static boolean skipTest = false;
|
||||
|
||||
static {
|
||||
Properties properties = new Properties();
|
||||
try (InputStream input = GXHTTPStringRequestTest.class.getClassLoader().getResourceAsStream("token.props")) {
|
||||
// load the properties file
|
||||
properties.load(input);
|
||||
DEFAULT_TEST_SCOPE = properties.getProperty("DEFAULT_SCOPE_TOKEN");
|
||||
if (DEFAULT_TEST_SCOPE.isEmpty())
|
||||
skipTest = true;
|
||||
DEFAULT_RM_URL = properties.getProperty("RM_URL");
|
||||
DEFAULT_RR_URL = properties.getProperty("RR_URL");
|
||||
} catch (IOException | NullPointerException e) {
|
||||
skipTest = true;
|
||||
}
|
||||
}
|
||||
|
||||
@BeforeClass
|
||||
public static void beforeClass() throws Exception {
|
||||
setContext(DEFAULT_TEST_SCOPE);
|
||||
}
|
||||
|
||||
public static void setContext(String token) throws ObjectNotFound, Exception {
|
||||
if (DEFAULT_TEST_SCOPE.isEmpty()) {
|
||||
skipTest = true;
|
||||
return;
|
||||
}
|
||||
SecurityTokenProvider.instance.set(token);
|
||||
}
|
||||
|
||||
public static String getCurrentScope(String token) throws ObjectNotFound, Exception {
|
||||
AuthorizationEntry authorizationEntry = Constants.authorizationService().get(token);
|
||||
String context = authorizationEntry.getContext();
|
||||
return context;
|
||||
}
|
||||
|
||||
@AfterClass
|
||||
public static void afterClass() throws Exception {
|
||||
SecurityTokenProvider.instance.reset();
|
||||
}
|
||||
|
||||
/**
|
||||
* Test method for {@link org.gcube.common.gxhttp.request.GXHTTPStringRequest#newRequest(java.lang.String)}.
|
||||
*/
|
||||
@Before
|
||||
public void testNewRequest() {
|
||||
request = GXHTTPStringRequest.newRequest(DEFAULT_RM_URL).from("GXRequestTest");
|
||||
}
|
||||
|
||||
/**
|
||||
* Test method for {@link org.gcube.common.gxhttp.request.GXHTTPStringRequest#post(java.lang.String)}.
|
||||
*/
|
||||
@Test
|
||||
public void testPostString() {
|
||||
if (skipTest)
|
||||
return;
|
||||
request.clear();
|
||||
String context ="{\"@class\":\"Context\",\"header\":{\"@class\":\"Header\",\"uuid\":\"6f86dc81-2f59-486b-8aa9-3ab5486313c4\",\"creator\":null,\"modifiedBy\":\"gxRestTest\",\"creationTime\":null,\"lastUpdateTime\":null},\"name\":\"gxTest\",\"parent\":null,\"children\":[]}";
|
||||
Map<String,String> queryParams = new WeakHashMap<>();
|
||||
queryParams.put("rrURL", DEFAULT_RR_URL);
|
||||
try {
|
||||
HttpURLConnection response = request.path("gxrest")
|
||||
.header("Another header", "GXHTTPRequestTest")
|
||||
.queryParams(queryParams).post(context);
|
||||
assertTrue("Unexpected returned code.", response.getResponseCode() == 200);
|
||||
String body = ContentUtils.toString(ContentUtils.toByteArray(response.getInputStream()));
|
||||
System.out.println("Returned string " + body);
|
||||
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
fail("Failed to send a POST request");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,20 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE xml>
|
||||
<configuration>
|
||||
|
||||
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
|
||||
<encoder>
|
||||
<pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{0}: %msg%n</pattern>
|
||||
</encoder>
|
||||
</appender>
|
||||
|
||||
|
||||
<logger name="org.gcube" level="INFO" />
|
||||
<logger name="org.gcube.common.gxrest" level="TRACE" />
|
||||
|
||||
|
||||
<root level="WARN">
|
||||
<appender-ref ref="STDOUT" />
|
||||
</root>
|
||||
|
||||
</configuration>
|
|
@ -0,0 +1,36 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<classpath>
|
||||
<classpathentry kind="src" output="target/classes" path="src/main/java">
|
||||
<attributes>
|
||||
<attribute name="optional" value="true"/>
|
||||
<attribute name="maven.pomderived" value="true"/>
|
||||
</attributes>
|
||||
</classpathentry>
|
||||
<classpathentry excluding="**" kind="src" output="target/classes" path="src/main/resources">
|
||||
<attributes>
|
||||
<attribute name="maven.pomderived" value="true"/>
|
||||
</attributes>
|
||||
</classpathentry>
|
||||
<classpathentry kind="src" output="target/test-classes" path="src/test/java">
|
||||
<attributes>
|
||||
<attribute name="optional" value="true"/>
|
||||
<attribute name="maven.pomderived" value="true"/>
|
||||
</attributes>
|
||||
</classpathentry>
|
||||
<classpathentry excluding="**" kind="src" output="target/test-classes" path="src/test/resources">
|
||||
<attributes>
|
||||
<attribute name="maven.pomderived" value="true"/>
|
||||
</attributes>
|
||||
</classpathentry>
|
||||
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8">
|
||||
<attributes>
|
||||
<attribute name="maven.pomderived" value="true"/>
|
||||
</attributes>
|
||||
</classpathentry>
|
||||
<classpathentry kind="con" path="org.eclipse.m2e.MAVEN2_CLASSPATH_CONTAINER">
|
||||
<attributes>
|
||||
<attribute name="maven.pomderived" value="true"/>
|
||||
</attributes>
|
||||
</classpathentry>
|
||||
<classpathentry kind="output" path="target/classes"/>
|
||||
</classpath>
|
|
@ -0,0 +1,23 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<projectDescription>
|
||||
<name>gxRest</name>
|
||||
<comment></comment>
|
||||
<projects>
|
||||
</projects>
|
||||
<buildSpec>
|
||||
<buildCommand>
|
||||
<name>org.eclipse.jdt.core.javabuilder</name>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
<buildCommand>
|
||||
<name>org.eclipse.m2e.core.maven2Builder</name>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
</buildSpec>
|
||||
<natures>
|
||||
<nature>org.eclipse.jdt.core.javanature</nature>
|
||||
<nature>org.eclipse.m2e.core.maven2Nature</nature>
|
||||
</natures>
|
||||
</projectDescription>
|
|
@ -0,0 +1,6 @@
|
|||
eclipse.preferences.version=1
|
||||
encoding//src/main/java=UTF-8
|
||||
encoding//src/main/resources=UTF-8
|
||||
encoding//src/test/java=UTF-8
|
||||
encoding//src/test/resources=UTF-8
|
||||
encoding/<project>=UTF-8
|
|
@ -0,0 +1,5 @@
|
|||
eclipse.preferences.version=1
|
||||
org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8
|
||||
org.eclipse.jdt.core.compiler.compliance=1.8
|
||||
org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning
|
||||
org.eclipse.jdt.core.compiler.source=1.8
|
|
@ -0,0 +1,4 @@
|
|||
gCube System - License
|
||||
------------------------------------------------------------
|
||||
|
||||
${gcube.license}
|
|
@ -0,0 +1,67 @@
|
|||
The gCube System - ${name}
|
||||
--------------------------------------------------
|
||||
|
||||
${description}
|
||||
|
||||
|
||||
${gcube.description}
|
||||
|
||||
${gcube.funding}
|
||||
|
||||
|
||||
Version
|
||||
--------------------------------------------------
|
||||
|
||||
${version} (${buildDate})
|
||||
|
||||
Please see the file named "changelog.xml" in this directory for the release notes.
|
||||
|
||||
|
||||
Authors
|
||||
--------------------------------------------------
|
||||
|
||||
* Manuele Simi (manuele.simi-AT-isti.cnr.it), Istituto di Scienza e Tecnologie dell'Informazione "A. Faedo" - CNR, Pisa (Italy).
|
||||
* Luca Frosini (luca.frosini-AT-isti.cnr.it), Istituto di Scienza e Tecnologie dell'Informazione "A. Faedo" - CNR, Pisa (Italy).
|
||||
|
||||
|
||||
Maintainers
|
||||
-----------
|
||||
|
||||
* Manuele Simi (manuele.simi-AT-isti.cnr.it), Istituto di Scienza e Tecnologie dell'Informazione "A. Faedo" - CNR, Pisa (Italy).
|
||||
* Luca Frosini (luca.frosini-AT-isti.cnr.it), Istituto di Scienza e Tecnologie dell'Informazione "A. Faedo" - CNR, Pisa (Italy).
|
||||
|
||||
Download information
|
||||
--------------------------------------------------
|
||||
|
||||
Source code is available from SVN:
|
||||
${scm.url}
|
||||
|
||||
Binaries can be downloaded from the gCube website:
|
||||
${gcube.website}
|
||||
|
||||
|
||||
Installation
|
||||
--------------------------------------------------
|
||||
|
||||
Installation documentation is available on-line in the gCube Wiki:
|
||||
${gcube.wikiRoot}/
|
||||
|
||||
|
||||
Documentation
|
||||
--------------------------------------------------
|
||||
|
||||
Documentation is available on-line in the gCube Wiki:
|
||||
${gcube.wikiRoot}/
|
||||
|
||||
|
||||
Support
|
||||
--------------------------------------------------
|
||||
|
||||
Bugs and support requests can be reported in the gCube issue tracking tool:
|
||||
${gcube.issueTracking}
|
||||
|
||||
|
||||
Licensing
|
||||
--------------------------------------------------
|
||||
|
||||
This software is licensed under the terms you may find in the file named "LICENSE" in this directory.
|
|
@ -0,0 +1,13 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE xml>
|
||||
<ReleaseNotes>
|
||||
<Changeset component="org.gcube.common.gxRest.1-1-1" date="${buildDate}">
|
||||
<Change></Change>
|
||||
</Changeset>
|
||||
<Changeset component="org.gcube.common.gxRest.1-1-0" date="2019-02-26">
|
||||
<Change>Separated plaing HTTP requests from gxRest</Change>
|
||||
</Changeset>
|
||||
<Changeset component="org.gcube.common.gxRest.1-0-0" date="2018-12-01">
|
||||
<Change>First Release</Change>
|
||||
</Changeset>
|
||||
</ReleaseNotes>
|
|
@ -0,0 +1,28 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE xml>
|
||||
<Resource>
|
||||
<ID />
|
||||
<Type>Service</Type>
|
||||
<Profile>
|
||||
<Description>${description}</Description>
|
||||
<Class>${serviceClass}</Class>
|
||||
<Name>${artifactId}</Name>
|
||||
<Version>1.0.0</Version>
|
||||
<Packages>
|
||||
<Software>
|
||||
<Description>${description}</Description>
|
||||
<Name>${artifactId}</Name>
|
||||
<Version>${version}</Version>
|
||||
<MavenCoordinates>
|
||||
<groupId>${groupId}</groupId>
|
||||
<artifactId>${artifactId}</artifactId>
|
||||
<version>${version}</version>
|
||||
</MavenCoordinates>
|
||||
<Type>Library</Type>
|
||||
<Files>
|
||||
<File>${build.finalName}.${project.packaging}</File>
|
||||
</Files>
|
||||
</Software>
|
||||
</Packages>
|
||||
</Profile>
|
||||
</Resource>
|
|
@ -0,0 +1,127 @@
|
|||
<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>
|
||||
<parent>
|
||||
<groupId>org.gcube.common</groupId>
|
||||
<artifactId>gxREST</artifactId>
|
||||
<version>1.1.2-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>gxJRS</artifactId>
|
||||
<packaging>jar</packaging>
|
||||
<name>gCube eXtensions to JAX-RS</name>
|
||||
<description>gCube eXtensions to REST based on JAX-RS</description>
|
||||
|
||||
<properties>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
<distroDirectory>${project.basedir}/distro</distroDirectory>
|
||||
</properties>
|
||||
|
||||
<scm>
|
||||
<connection>scm:https://svn.d4science.research-infrastructures.eu/gcube/trunk/common/${parent.artifactId}/${project.artifactId}</connection>
|
||||
<developerConnection>scm:https://svn.d4science.research-infrastructures.eu/gcube/trunk/common/${parent.artifactId}/${project.artifactId}</developerConnection>
|
||||
<url>https://svn.d4science.research-infrastructures.eu/gcube/trunk/common/${parent.artifactId}/${project.artifactId}</url>
|
||||
</scm>
|
||||
<dependencyManagement>
|
||||
<dependencies>
|
||||
<!-- https://mvnrepository.com/artifact/org.glassfish.jersey/jersey-bom -->
|
||||
<dependency>
|
||||
<groupId>org.glassfish.jersey</groupId>
|
||||
<artifactId>jersey-bom</artifactId>
|
||||
<version>${jersey.version}</version>
|
||||
<type>pom</type>
|
||||
<scope>import</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.gcube.distribution</groupId>
|
||||
<artifactId>gcube-bom</artifactId>
|
||||
<version>LATEST</version>
|
||||
<type>pom</type>
|
||||
<scope>import</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.gcube.information-system</groupId>
|
||||
<artifactId>information-system-bom</artifactId>
|
||||
<version>LATEST</version>
|
||||
<type>pom</type>
|
||||
<scope>import</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</dependencyManagement>
|
||||
|
||||
<dependencies>
|
||||
|
||||
<dependency>
|
||||
<groupId>javax.ws.rs</groupId>
|
||||
<artifactId>javax.ws.rs-api</artifactId>
|
||||
<version>${jaxrs.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.gcube.common</groupId>
|
||||
<artifactId>gxHTTP</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.gcube.common</groupId>
|
||||
<artifactId>authorization-client</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.slf4j</groupId>
|
||||
<artifactId>slf4j-api</artifactId>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.fasterxml.jackson.core</groupId>
|
||||
<artifactId>jackson-core</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.fasterxml.jackson.core</groupId>
|
||||
<artifactId>jackson-databind</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- Test Dependency -->
|
||||
<dependency>
|
||||
<groupId>org.glassfish.jersey.core</groupId>
|
||||
<artifactId>jersey-client</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.glassfish.jersey.inject</groupId>
|
||||
<artifactId>jersey-hk2</artifactId>
|
||||
<version>2.27</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>junit</groupId>
|
||||
<artifactId>junit</artifactId>
|
||||
<version>4.12</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>ch.qos.logback</groupId>
|
||||
<artifactId>logback-classic</artifactId>
|
||||
<version>1.0.13</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-assembly-plugin</artifactId>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>make-servicearchive</id>
|
||||
<phase>package</phase>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
</project>
|
|
@ -0,0 +1,5 @@
|
|||
/**
|
||||
* @author Manuele Simi (ISTI - CNR)
|
||||
*
|
||||
*/
|
||||
package org.gcube.common.gxrest.methods;
|
|
@ -0,0 +1,202 @@
|
|||
package org.gcube.common.gxrest.request;
|
||||
|
||||
import java.io.InputStream;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
|
||||
import org.gcube.common.gxhttp.reference.GXConnection;
|
||||
import org.gcube.common.gxhttp.reference.GXHTTP;
|
||||
import org.gcube.common.gxhttp.reference.GXHTTPRequestBuilder;
|
||||
import org.gcube.common.gxhttp.reference.GXConnection.HTTPMETHOD;
|
||||
import org.gcube.common.gxrest.response.inbound.GXInboundResponse;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
/**
|
||||
* A context-aware request to a web application.
|
||||
* It supports sending streams through Put/Post requests.
|
||||
*
|
||||
* @author Manuele Simi (ISTI-CNR)
|
||||
* @author Luca Frosini (ISTI-CNR)
|
||||
*
|
||||
*/
|
||||
public class GXHTTPStreamRequest implements GXHTTP<InputStream,GXInboundResponse> {
|
||||
|
||||
protected static final Logger logger = LoggerFactory.getLogger(GXHTTPStreamRequest.class);
|
||||
|
||||
GXHTTPRequestBuilder builder = new GXHTTPRequestBuilder();
|
||||
/**
|
||||
* A new request.
|
||||
*/
|
||||
private GXHTTPStreamRequest(String address) {
|
||||
builder.connection = new GXConnection(address);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new request.
|
||||
*
|
||||
* @param address
|
||||
* the address of the web app to call
|
||||
* @return the request
|
||||
*/
|
||||
public static GXHTTPStreamRequest newRequest(String address) {
|
||||
return new GXHTTPStreamRequest(address);
|
||||
}
|
||||
/* (non-Javadoc)
|
||||
* @see org.gcube.common.gxrest.request.GXHTTP#put(java.lang.Object)
|
||||
*/
|
||||
@Override
|
||||
public GXInboundResponse put(InputStream body) throws Exception {
|
||||
if (Objects.nonNull(body))
|
||||
builder.connection.addBodyAsStream(body);
|
||||
logger.trace("Sending a PUT request...");
|
||||
return new GXInboundResponse(builder.connection.send(HTTPMETHOD.PUT));
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.gcube.common.gxrest.request.GXHTTP#post(java.lang.Object)
|
||||
*/
|
||||
@Override
|
||||
public GXInboundResponse post(InputStream body) throws Exception {
|
||||
logger.trace("Sending a POST request...");
|
||||
if (Objects.nonNull(body))
|
||||
builder.connection.addBodyAsStream(body);
|
||||
return new GXInboundResponse(builder.connection.send(HTTPMETHOD.POST));
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.gcube.common.gxrest.request.GXHTTP#put()
|
||||
*/
|
||||
@Override
|
||||
public GXInboundResponse put() throws Exception {
|
||||
return new GXInboundResponse(builder.put());
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.gcube.common.gxrest.request.GXHTTP#delete()
|
||||
*/
|
||||
@Override
|
||||
public GXInboundResponse delete() throws Exception {
|
||||
return new GXInboundResponse(builder.delete());
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.gcube.common.gxrest.request.GXHTTP#head()
|
||||
*/
|
||||
@Override
|
||||
public GXInboundResponse head() throws Exception {
|
||||
return new GXInboundResponse(builder.head());
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.gcube.common.gxrest.request.GXHTTP#get()
|
||||
*/
|
||||
@Override
|
||||
public GXInboundResponse get() throws Exception {
|
||||
return new GXInboundResponse(builder.get());
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.gcube.common.gxrest.request.GXHTTP#post()
|
||||
*/
|
||||
@Override
|
||||
public GXInboundResponse post() throws Exception {
|
||||
return new GXInboundResponse(builder.post());
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.gcube.common.gxrest.request.GXHTTP#trace()
|
||||
*/
|
||||
@Override
|
||||
public GXInboundResponse trace() throws Exception {
|
||||
return new GXInboundResponse(builder.trace());
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.gcube.common.gxrest.request.GXHTTP#patch()
|
||||
*/
|
||||
@Override
|
||||
public GXInboundResponse patch() throws Exception {
|
||||
return new GXInboundResponse(builder.patch());
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.gcube.common.gxrest.request.GXHTTP#options()
|
||||
*/
|
||||
@Override
|
||||
public GXInboundResponse options() throws Exception {
|
||||
return new GXInboundResponse(builder.options());
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.gcube.common.gxrest.request.GXHTTP#connect()
|
||||
*/
|
||||
@Override
|
||||
public GXInboundResponse connect() throws Exception {
|
||||
return new GXInboundResponse(builder.connect());
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.gcube.common.gxrest.request.GXHTTP#setSecurityToken(java.lang.String)
|
||||
*/
|
||||
@Override
|
||||
public void setSecurityToken(String token) {
|
||||
builder.setSecurityToken(token);
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.gcube.common.gxrest.request.GXHTTP#isExternalCall(boolean)
|
||||
*/
|
||||
@Override
|
||||
public void isExternalCall(boolean ext) {
|
||||
builder.isExternalCall(ext);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string
|
||||
* @return the request
|
||||
*/
|
||||
public GXHTTPStreamRequest from(String agent) {
|
||||
builder.from(agent) ;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Clear up the request.
|
||||
*/
|
||||
public void clear() {
|
||||
builder.clear();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param path
|
||||
* @return the request
|
||||
* @throws UnsupportedEncodingException
|
||||
*
|
||||
*/
|
||||
public GXHTTPStreamRequest path(String path) throws UnsupportedEncodingException {
|
||||
builder.path(path);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param name
|
||||
* @param value
|
||||
* @return the request
|
||||
*/
|
||||
public GXHTTPStreamRequest header(String name, String value) {
|
||||
builder.header(name, value);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param queryParams
|
||||
* @return the request
|
||||
* @throws UnsupportedEncodingException
|
||||
*/
|
||||
public GXHTTPStreamRequest queryParams(Map<String, String> queryParams) throws UnsupportedEncodingException {
|
||||
builder.queryParams(queryParams);
|
||||
return this;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,223 @@
|
|||
package org.gcube.common.gxrest.request;
|
||||
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
|
||||
import org.gcube.common.gxhttp.reference.GXConnection;
|
||||
import org.gcube.common.gxhttp.reference.GXHTTP;
|
||||
import org.gcube.common.gxhttp.reference.GXHTTPRequestBuilder;
|
||||
import org.gcube.common.gxhttp.reference.GXConnection.HTTPMETHOD;
|
||||
import org.gcube.common.gxrest.response.inbound.GXInboundResponse;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
|
||||
/**
|
||||
* A context-aware request to a web application.
|
||||
* It supports sending strings through Put/Post requests.
|
||||
*
|
||||
* @author Manuele Simi (ISTI-CNR)
|
||||
* @author Luca Frosini (ISTI-CNR)
|
||||
*
|
||||
*/
|
||||
public class GXHTTPStringRequest implements GXHTTP<String,GXInboundResponse> {
|
||||
|
||||
protected static final Logger logger = LoggerFactory.getLogger(GXHTTPStringRequest.class);
|
||||
|
||||
GXHTTPRequestBuilder builder = new GXHTTPRequestBuilder();
|
||||
|
||||
/**
|
||||
* A new request.
|
||||
*/
|
||||
private GXHTTPStringRequest(String address) {
|
||||
builder.connection = new GXConnection(address);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new request.
|
||||
*
|
||||
* @param address
|
||||
* the address of the web app to call
|
||||
* @return the request
|
||||
*/
|
||||
public static GXHTTPStringRequest newRequest(String address) {
|
||||
return new GXHTTPStringRequest(address);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Sets the body of the request.
|
||||
*
|
||||
* @param body
|
||||
* @return the request
|
||||
*/
|
||||
public GXHTTPStringRequest withBody(String body) {
|
||||
builder.connection.addBody(body);
|
||||
return this;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see org.gcube.common.gxrest.request.GXHTTP#put(java.lang.Object)
|
||||
*/
|
||||
@Override
|
||||
public GXInboundResponse put(String body) throws Exception {
|
||||
if (Objects.nonNull(body))
|
||||
builder.connection.addBody(body);
|
||||
logger.trace("Sending a PUT request...");
|
||||
return new GXInboundResponse(builder.connection.send(HTTPMETHOD.PUT));
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see org.gcube.common.gxrest.request.GXHTTP#post()
|
||||
*/
|
||||
@Override
|
||||
public GXInboundResponse post(String body) throws Exception {
|
||||
logger.trace("Sending a POST request...");
|
||||
if (Objects.nonNull(body))
|
||||
builder.connection.addBody(body);
|
||||
return new GXInboundResponse(builder.connection.send(HTTPMETHOD.POST));
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.gcube.common.gxrest.request.GXHTTP#put()
|
||||
*/
|
||||
@Override
|
||||
public GXInboundResponse put() throws Exception {
|
||||
return new GXInboundResponse(builder.put());
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.gcube.common.gxrest.request.GXHTTP#delete()
|
||||
*/
|
||||
@Override
|
||||
public GXInboundResponse delete() throws Exception {
|
||||
return new GXInboundResponse(builder.delete());
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.gcube.common.gxrest.request.GXHTTP#head()
|
||||
*/
|
||||
@Override
|
||||
public GXInboundResponse head() throws Exception {
|
||||
return new GXInboundResponse(builder.head());
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.gcube.common.gxrest.request.GXHTTP#get()
|
||||
*/
|
||||
@Override
|
||||
public GXInboundResponse get() throws Exception {
|
||||
return new GXInboundResponse(builder.get());
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.gcube.common.gxrest.request.GXHTTP#post()
|
||||
*/
|
||||
@Override
|
||||
public GXInboundResponse post() throws Exception {
|
||||
return new GXInboundResponse(builder.post());
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.gcube.common.gxrest.request.GXHTTP#trace()
|
||||
*/
|
||||
@Override
|
||||
public GXInboundResponse trace() throws Exception {
|
||||
return new GXInboundResponse(builder.trace());
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.gcube.common.gxrest.request.GXHTTP#patch()
|
||||
*/
|
||||
@Override
|
||||
public GXInboundResponse patch() throws Exception {
|
||||
return new GXInboundResponse(builder.patch());
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.gcube.common.gxrest.request.GXHTTP#options()
|
||||
*/
|
||||
@Override
|
||||
public GXInboundResponse options() throws Exception {
|
||||
return new GXInboundResponse(builder.options());
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.gcube.common.gxrest.request.GXHTTP#connect()
|
||||
*/
|
||||
@Override
|
||||
public GXInboundResponse connect() throws Exception {
|
||||
return new GXInboundResponse(builder.connect());
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.gcube.common.gxrest.request.GXHTTP#setSecurityToken(java.lang.String)
|
||||
*/
|
||||
@Override
|
||||
public void setSecurityToken(String token) {
|
||||
builder.setSecurityToken(token);
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.gcube.common.gxrest.request.GXHTTP#isExternalCall(boolean)
|
||||
*/
|
||||
@Override
|
||||
public void isExternalCall(boolean ext) {
|
||||
builder.isExternalCall(ext);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string
|
||||
* @return the request
|
||||
*/
|
||||
public GXHTTPStringRequest from(String agent) {
|
||||
builder.from(agent) ;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Clear up the request.
|
||||
*/
|
||||
public void clear() {
|
||||
builder.clear();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string
|
||||
* @return the request
|
||||
* @throws UnsupportedEncodingException
|
||||
*
|
||||
*/
|
||||
public GXHTTPStringRequest path(String path) throws UnsupportedEncodingException {
|
||||
builder.path(path);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param name
|
||||
* @param value
|
||||
* @return the request
|
||||
*/
|
||||
public GXHTTPStringRequest header(String name, String value) {
|
||||
builder.header(name, value);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param queryParams
|
||||
* @return the request
|
||||
* @throws UnsupportedEncodingException
|
||||
*/
|
||||
public GXHTTPStringRequest queryParams(Map<String, String> queryParams) throws UnsupportedEncodingException {
|
||||
builder.queryParams(queryParams);
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -0,0 +1,397 @@
|
|||
package org.gcube.common.gxrest.request;
|
||||
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.net.URLEncoder;
|
||||
import java.security.KeyManagementException;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.security.cert.CertificateException;
|
||||
import java.security.cert.X509Certificate;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.Map.Entry;
|
||||
|
||||
import javax.net.ssl.HostnameVerifier;
|
||||
import javax.net.ssl.SSLContext;
|
||||
import javax.net.ssl.SSLSession;
|
||||
import javax.net.ssl.TrustManager;
|
||||
import javax.net.ssl.X509TrustManager;
|
||||
import javax.ws.rs.client.Client;
|
||||
import javax.ws.rs.client.ClientBuilder;
|
||||
import javax.ws.rs.client.Entity;
|
||||
import javax.ws.rs.client.Invocation.Builder;
|
||||
import javax.ws.rs.client.WebTarget;
|
||||
import javax.ws.rs.core.MediaType;
|
||||
import javax.ws.rs.core.MultivaluedHashMap;
|
||||
import javax.ws.rs.core.MultivaluedMap;
|
||||
import javax.ws.rs.core.Response;
|
||||
|
||||
import org.gcube.common.authorization.library.provider.SecurityTokenProvider;
|
||||
import org.gcube.common.gxhttp.reference.GXConnection;
|
||||
import org.gcube.common.gxhttp.reference.GXHTTP;
|
||||
import org.gcube.common.gxrest.response.inbound.GXInboundResponse;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
/**
|
||||
* A GX request based on JAX-RS. It requires a runtime implementation of JAX-RS
|
||||
* on the classpath (e.g. Jersey) to work.
|
||||
*
|
||||
* @author Manuele Simi (ISTI CNR)
|
||||
*
|
||||
*/
|
||||
public class GXWebTargetAdapterRequest implements GXHTTP<Entity<?>,GXInboundResponse> {
|
||||
|
||||
private WebTarget adaptee;
|
||||
private static final Logger logger = LoggerFactory.getLogger(GXWebTargetAdapterRequest.class);
|
||||
private MediaType[] mediaType;
|
||||
MultivaluedMap<String, Object> headers = new MultivaluedHashMap<String, Object>();
|
||||
private boolean extCall = false;
|
||||
|
||||
/**
|
||||
* Creates a new request.
|
||||
*
|
||||
* @param address
|
||||
* the address of the web app to call
|
||||
* @return the request
|
||||
*/
|
||||
public static GXWebTargetAdapterRequest newRequest(String address) {
|
||||
return new GXWebTargetAdapterRequest(address, false);
|
||||
}
|
||||
|
||||
public static GXWebTargetAdapterRequest newHTTPSRequest(String address) {
|
||||
return new GXWebTargetAdapterRequest(address, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param address
|
||||
*/
|
||||
private GXWebTargetAdapterRequest(String address, boolean withHTTPS) {
|
||||
Client client = ClientBuilder.newClient();
|
||||
if (withHTTPS) {
|
||||
try {
|
||||
SSLContext sc = SSLContext.getInstance("TLSv1");
|
||||
System.setProperty("https.protocols", "TLSv1");
|
||||
TrustManager[] certs = new TrustManager[] { new X509TrustManager() {
|
||||
@Override
|
||||
public X509Certificate[] getAcceptedIssuers() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void checkServerTrusted(X509Certificate[] chain, String authType)
|
||||
throws CertificateException {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void checkClientTrusted(X509Certificate[] chain, String authType)
|
||||
throws CertificateException {
|
||||
}
|
||||
} };
|
||||
sc.init(null, certs, new java.security.SecureRandom());
|
||||
HostnameVerifier allHostsValid = new HostnameVerifier() {
|
||||
// insecure host verifier
|
||||
@Override
|
||||
public boolean verify(String hostname, SSLSession session) {
|
||||
return true;
|
||||
}
|
||||
};
|
||||
client = ClientBuilder.newBuilder().sslContext(sc).hostnameVerifier(allHostsValid).build();
|
||||
} catch (KeyManagementException | NoSuchAlgorithmException e) {
|
||||
client = ClientBuilder.newClient();
|
||||
}
|
||||
}
|
||||
this.adaptee = client.target(address);
|
||||
this.headers.add(org.gcube.common.authorization.client.Constants.TOKEN_HEADER_ENTRY,
|
||||
SecurityTokenProvider.instance.get());
|
||||
this.headers.add("User-Agent", this.getClass().getSimpleName());
|
||||
}
|
||||
|
||||
/**
|
||||
* Overrides the default security token.
|
||||
*
|
||||
* @param token
|
||||
* the new token
|
||||
*/
|
||||
@Override
|
||||
public void setSecurityToken(String token) {
|
||||
if (!this.extCall)
|
||||
this.headers.add(org.gcube.common.authorization.client.Constants.TOKEN_HEADER_ENTRY, token);
|
||||
|
||||
else
|
||||
throw new UnsupportedOperationException("Cannot set the security token on an external call");
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the identity user agent associated to the request.
|
||||
*
|
||||
* @param agent
|
||||
* @return the request
|
||||
*/
|
||||
public GXWebTargetAdapterRequest from(String agent) {
|
||||
this.headers.add("User-Agent", this.getClass().getSimpleName());
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets a new property in the request.
|
||||
*
|
||||
* @param name
|
||||
* the name of the property
|
||||
* @param value
|
||||
* the value of the property
|
||||
* @return the request
|
||||
*/
|
||||
public GXWebTargetAdapterRequest configProperty(String name, String value) {
|
||||
this.adaptee = this.adaptee.property(name, value);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers an instance of a custom JAX-RS component (such as an extension
|
||||
* provider or a {@link javax.ws.rs.core.Feature feature} meta-provider) to
|
||||
* be instantiated and used in the scope of this request.
|
||||
*
|
||||
* @param component
|
||||
* the component to register
|
||||
* @return the request
|
||||
*/
|
||||
public GXWebTargetAdapterRequest register(Object component) {
|
||||
this.adaptee = this.adaptee.register(component);
|
||||
return this;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers a class of a custom JAX-RS component (such as an extension
|
||||
* provider or a {@link javax.ws.rs.core.Feature feature} meta-provider) to
|
||||
* be instantiated and used in the scope of this request.
|
||||
*
|
||||
* @param component
|
||||
* the class of the component to register
|
||||
* @return the request
|
||||
*/
|
||||
public GXWebTargetAdapterRequest register(Class<?> component) {
|
||||
this.adaptee = this.adaptee.register(component);
|
||||
return this;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a positional path parameter to the request.
|
||||
*
|
||||
* @param path
|
||||
* the new token in the path
|
||||
* @return the request
|
||||
* @throws UnsupportedEncodingException
|
||||
*/
|
||||
public GXWebTargetAdapterRequest path(String path) throws UnsupportedEncodingException {
|
||||
this.adaptee = this.adaptee.path(path);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the query parameters for the request.
|
||||
*
|
||||
* @param parameters
|
||||
* the parameters that go in the URL after the address and the
|
||||
* path params.
|
||||
* @return the request
|
||||
* @throws UnsupportedEncodingException
|
||||
*/
|
||||
public GXWebTargetAdapterRequest queryParams(Map<String, Object[]> parameters) throws UnsupportedEncodingException {
|
||||
if (Objects.nonNull(parameters) && !parameters.isEmpty()) {
|
||||
for (Entry<String, Object[]> parameter : parameters.entrySet()) {
|
||||
this.adaptee = this.adaptee.queryParam(URLEncoder.encode(parameter.getKey(), GXConnection.UTF8),
|
||||
parameter.getValue());
|
||||
}
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Defines the accepted response media types.
|
||||
*
|
||||
* @param acceptedResponseTypes
|
||||
* accepted response media types.
|
||||
* @return builder for a request targeted at the URI referenced by this
|
||||
* target instance.
|
||||
*/
|
||||
public GXWebTargetAdapterRequest setAcceptedResponseType(MediaType... acceptedResponseTypes) {
|
||||
this.mediaType = acceptedResponseTypes;
|
||||
return this;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see org.gcube.common.gxrest.request.GXHTTP#delete()
|
||||
*/
|
||||
@Override
|
||||
public GXInboundResponse delete() throws Exception {
|
||||
logger.trace("Sending a DELETE request...");
|
||||
Response response = this.buildRequest().delete();
|
||||
return buildGXResponse(response);
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see org.gcube.common.gxrest.request.GXHTTP#head()
|
||||
*/
|
||||
@Override
|
||||
public GXInboundResponse head() throws Exception {
|
||||
logger.trace("Sending a HEAD request...");
|
||||
Response response = this.buildRequest().head();
|
||||
return buildGXResponse(response);
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see org.gcube.common.gxrest.request.GXHTTP#get()
|
||||
*/
|
||||
@Override
|
||||
public GXInboundResponse get() throws Exception {
|
||||
logger.trace("Sending a GET request...");
|
||||
Response response = this.buildRequest().get(Response.class);
|
||||
return buildGXResponse(response);
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds the request builder.
|
||||
*
|
||||
* @return the builder
|
||||
*/
|
||||
private Builder buildRequest() {
|
||||
Builder builder = this.adaptee.request();
|
||||
builder.headers(this.headers);
|
||||
return builder;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add an arbitrary header.
|
||||
*
|
||||
* @return the builder
|
||||
*/
|
||||
public GXWebTargetAdapterRequest header(String name, Object value) {
|
||||
headers.add(name, value);
|
||||
return this;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see org.gcube.common.gxrest.request.GXHTTP#put(java.lang.Object)
|
||||
*/
|
||||
@Override
|
||||
public GXInboundResponse put(Entity<?> body) throws Exception {
|
||||
logger.trace("Sending a PUT request...");
|
||||
if (Objects.nonNull(body))
|
||||
return buildGXResponse(this.buildRequest().put(body));
|
||||
else
|
||||
throw new IllegalArgumentException("Invalid body for the PUT request");
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see org.gcube.common.gxrest.request.GXHTTP#put()
|
||||
*/
|
||||
@Override
|
||||
public GXInboundResponse put() throws Exception {
|
||||
logger.trace("Sending a PUT request with no body...");
|
||||
return buildGXResponse(this.buildRequest().put(null));
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see org.gcube.common.gxrest.request.GXHTTP#post(java.lang.Object)
|
||||
*/
|
||||
@Override
|
||||
public GXInboundResponse post(Entity<?> body) throws Exception {
|
||||
Objects.requireNonNull(body, "Cannot send a POST request with a null body.");
|
||||
logger.trace("Sending a POST request...");
|
||||
Response response = this.buildRequest().post(body, Response.class);
|
||||
return buildGXResponse(response);
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see org.gcube.common.gxrest.request.GXHTTP#post()
|
||||
*/
|
||||
@Override
|
||||
public GXInboundResponse post() throws Exception {
|
||||
logger.trace("Sending a POST request with no body...");
|
||||
Response response = this.buildRequest().post(null, Response.class);
|
||||
return buildGXResponse(response);
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds the response.
|
||||
*
|
||||
* @param source
|
||||
* the original response returned by the JAX-RS implementation
|
||||
* @return the inbound response
|
||||
*/
|
||||
private GXInboundResponse buildGXResponse(Response source) {
|
||||
return (Objects.isNull(this.mediaType)) ? new GXInboundResponse(source)
|
||||
: new GXInboundResponse(source, this.mediaType);
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see org.gcube.common.gxrest.request.GXHTTP#trace()
|
||||
*/
|
||||
@Override
|
||||
public GXInboundResponse trace() throws Exception {
|
||||
logger.trace("Sending a TRACE request with no body...");
|
||||
Response response = this.buildRequest().trace(Response.class);
|
||||
return buildGXResponse(response);
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see org.gcube.common.gxrest.request.GXHTTP#patch()
|
||||
*/
|
||||
@Override
|
||||
public GXInboundResponse patch() throws Exception {
|
||||
throw new UnsupportedOperationException("WebTarget does not support PATCH");
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see org.gcube.common.gxrest.request.GXHTTP#options()
|
||||
*/
|
||||
@Override
|
||||
public GXInboundResponse options() throws Exception {
|
||||
logger.trace("Sending an OPTIONS request with no body...");
|
||||
Response response = this.buildRequest().options(Response.class);
|
||||
return buildGXResponse(response);
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see org.gcube.common.gxrest.request.GXHTTP#connect()
|
||||
*/
|
||||
@Override
|
||||
public GXInboundResponse connect() throws Exception {
|
||||
throw new UnsupportedOperationException("WebTarget does not support CONNECT");
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see org.gcube.common.gxrest.request.GXHTTP#isExternalCall(boolean)
|
||||
*/
|
||||
@Override
|
||||
public void isExternalCall(boolean ext) {
|
||||
this.extCall = ext;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,7 @@
|
|||
/**
|
||||
* Requests to web application.
|
||||
*
|
||||
* @author Manuele Simi (ISTI - CNR)
|
||||
*
|
||||
*/
|
||||
package org.gcube.common.gxrest.request;
|
|
@ -0,0 +1,20 @@
|
|||
package org.gcube.common.gxrest.response.entity;
|
||||
|
||||
import javax.ws.rs.core.GenericEntity;
|
||||
|
||||
/**
|
||||
* An entity to wrap {@link SerializableErrorEntity}s into a {@link WebCodeException}.
|
||||
*
|
||||
* @author Manuele Simi (ISTI CNR)
|
||||
*
|
||||
*/
|
||||
public class CodeEntity extends GenericEntity<SerializableErrorEntity> {
|
||||
|
||||
/**
|
||||
* @param entity
|
||||
*/
|
||||
public CodeEntity(SerializableErrorEntity entity) {
|
||||
super(entity);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,17 @@
|
|||
package org.gcube.common.gxrest.response.entity;
|
||||
|
||||
/**
|
||||
*
|
||||
* Values of the HTTP Entity Tag, used as the value
|
||||
* of an ETag response header.
|
||||
*
|
||||
* @author Manuele Simi (ISTI CNR)
|
||||
* @see <a href="http://www.w3.org/Protocols/rfc2616/rfc2616-sec3.html#sec3.11">HTTP/1.1 section 3.11</a>
|
||||
*/
|
||||
public final class EntityTag {
|
||||
|
||||
public static final String gxSuccess = "GXSuccessResponse";
|
||||
|
||||
public static final String gxError = "GXErrorResponse";
|
||||
|
||||
}
|
|
@ -0,0 +1,78 @@
|
|||
package org.gcube.common.gxrest.response.entity;
|
||||
|
||||
import org.gcube.common.gxrest.response.outbound.ErrorCode;
|
||||
|
||||
/**
|
||||
* An entity that can be serialized in a {@link WebCodeException}.
|
||||
*
|
||||
* @author Manuele Simi (ISTI CNR)
|
||||
*
|
||||
*/
|
||||
public class SerializableErrorEntity {
|
||||
|
||||
private int id = -1;
|
||||
private String message;
|
||||
private String exceptionClass;
|
||||
private String encodedTrace = "";
|
||||
|
||||
public SerializableErrorEntity() {}
|
||||
|
||||
/**
|
||||
* @param id
|
||||
* @param message
|
||||
*/
|
||||
public SerializableErrorEntity(ErrorCode errorCode) {
|
||||
this.id = errorCode.getId();
|
||||
this.message = errorCode.getMessage();
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param e
|
||||
*/
|
||||
public SerializableErrorEntity(Exception e) {
|
||||
this.exceptionClass = e.getClass().getCanonicalName();
|
||||
this.message = e.getMessage();
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param e
|
||||
*/
|
||||
public SerializableErrorEntity(Exception e, int lines) {
|
||||
this.exceptionClass = e.getClass().getCanonicalName();
|
||||
this.message = e.getMessage();
|
||||
this.encodedTrace = StackTraceEncoder.encodeTrace(e.getStackTrace(), lines);
|
||||
}
|
||||
|
||||
public int getId() {
|
||||
return this.id;
|
||||
}
|
||||
|
||||
|
||||
public String getMessage() {
|
||||
return this.message;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the full qualified name of the embedded {@link Exception}
|
||||
*/
|
||||
public String getExceptionClass() {
|
||||
return this.exceptionClass;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the encoded stacktrace
|
||||
*/
|
||||
public String getEncodedTrace() {
|
||||
return encodedTrace;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if a stacktrace is available.
|
||||
* @return true if a stacktrace is serialized in the entity.
|
||||
*/
|
||||
public boolean hasStackTrace() {
|
||||
return !this.encodedTrace.isEmpty();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,57 @@
|
|||
package org.gcube.common.gxrest.response.entity;
|
||||
|
||||
import java.util.StringJoiner;
|
||||
|
||||
/**
|
||||
* Encoder for {@link StackTraceElement}.
|
||||
*
|
||||
* @author Manuele Simi (ISTI-CNR)
|
||||
*
|
||||
*/
|
||||
public class StackTraceEncoder {
|
||||
|
||||
private final static String FIELD_SEPARATOR = "~~";
|
||||
|
||||
private final static String ELEMENT_SEPARATOR = "~!~";
|
||||
|
||||
private StackTraceEncoder() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Encodes the stacktrace element as string.
|
||||
*
|
||||
* @param element
|
||||
* @return the encoded element
|
||||
*/
|
||||
public static String encodeElement(StackTraceElement element) {
|
||||
return element.getClassName() + FIELD_SEPARATOR + element.getMethodName() + FIELD_SEPARATOR
|
||||
+ element.getFileName() + FIELD_SEPARATOR + element.getLineNumber();
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Decodes the string as stacktrace element.
|
||||
*
|
||||
* @param encoded
|
||||
* @return the decoded element
|
||||
*/
|
||||
public static StackTraceElement decodeElement(String encoded) {
|
||||
String[] elements = encoded.split(FIELD_SEPARATOR, 4);
|
||||
return new StackTraceElement(elements[0], elements[1], elements[2], Integer.valueOf(elements[3]));
|
||||
}
|
||||
|
||||
public static String encodeTrace(StackTraceElement[] elements, int lines) {
|
||||
StringJoiner joiner = new StringJoiner(ELEMENT_SEPARATOR);
|
||||
for (int i = 0; i < lines; i++)
|
||||
joiner.add(encodeElement(elements[i]));
|
||||
return joiner.toString();
|
||||
}
|
||||
|
||||
public static StackTraceElement[] decodeTrace(String joinedTrace) {
|
||||
String[] encodedElements = joinedTrace.split(ELEMENT_SEPARATOR);
|
||||
StackTraceElement[] elements = new StackTraceElement[encodedElements.length];
|
||||
for (int i = 0; i < encodedElements.length; i++)
|
||||
elements[i] = StackTraceEncoder.decodeElement(encodedElements[i]);
|
||||
return elements;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,7 @@
|
|||
/**
|
||||
* Core data held by a response.
|
||||
*
|
||||
* @author Manuele Simi (ISTI CNR)
|
||||
*
|
||||
*/
|
||||
package org.gcube.common.gxrest.response.entity;
|
|
@ -0,0 +1,40 @@
|
|||
package org.gcube.common.gxrest.response.inbound;
|
||||
|
||||
import org.gcube.common.gxrest.response.outbound.ErrorCode;
|
||||
|
||||
/**
|
||||
* Deserializer for {@link ErrorCode}.
|
||||
*
|
||||
* @author Manuele Simi (ISTI CNR)
|
||||
*
|
||||
*/
|
||||
final class ErrorCodeDeserializer {
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
private ErrorCodeDeserializer() {}
|
||||
|
||||
/**
|
||||
* The error code, if any
|
||||
* @return the error code or null
|
||||
*/
|
||||
protected static ErrorCode deserialize(int id, String message) {
|
||||
if (id != 1) {
|
||||
return new ErrorCode() {
|
||||
|
||||
@Override
|
||||
public String getMessage() {
|
||||
return message;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getId() {
|
||||
return id;
|
||||
}
|
||||
};
|
||||
} else
|
||||
return null;
|
||||
|
||||
}
|
||||
}
|
|
@ -0,0 +1,52 @@
|
|||
package org.gcube.common.gxrest.response.inbound;
|
||||
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.util.Objects;
|
||||
|
||||
import org.gcube.common.gxrest.response.entity.StackTraceEncoder;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
/**
|
||||
* Deserializer for {@link Exception}.
|
||||
*
|
||||
* @author Manuele Simi (ISTI CNR)
|
||||
*
|
||||
*/
|
||||
final class ExceptionDeserializer {
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
private ExceptionDeserializer() {}
|
||||
|
||||
private static final Logger logger = LoggerFactory.getLogger(ExceptionDeserializer.class);
|
||||
|
||||
/**
|
||||
* Deserializes the exception.
|
||||
*
|
||||
* @param exceptionClass the full qualified class name of the exception to deserialize
|
||||
* @param message the error message to associate to the exception
|
||||
* @return
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
protected static <E extends Exception> E deserialize(String exceptionClass, String message) {
|
||||
try {
|
||||
final Class<?>[] ctorParams = {String.class};
|
||||
return (E) Class.forName(exceptionClass).getConstructor(ctorParams).newInstance(message);
|
||||
} catch (InstantiationException | IllegalAccessException | ClassNotFoundException | IllegalArgumentException | InvocationTargetException | NoSuchMethodException | SecurityException e) {
|
||||
logger.error("Failed to deserialize: " + exceptionClass);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Enrich the exception with the stacktrace elements encoded with {@link StackTraceEncoder}
|
||||
* @param exception
|
||||
* @param joinedTrace
|
||||
*/
|
||||
protected static <E extends Exception> void addStackTrace(E exception, String joinedTrace) {
|
||||
if (Objects.nonNull(exception))
|
||||
exception.setStackTrace(StackTraceEncoder.decodeTrace(joinedTrace));
|
||||
}
|
||||
}
|
|
@ -0,0 +1,361 @@
|
|||
package org.gcube.common.gxrest.response.inbound;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.net.HttpURLConnection;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
|
||||
import javax.ws.rs.ProcessingException;
|
||||
import javax.ws.rs.core.MediaType;
|
||||
import javax.ws.rs.core.Response;
|
||||
import javax.ws.rs.core.Response.Status;
|
||||
|
||||
import org.gcube.common.gxhttp.util.ContentUtils;
|
||||
import org.gcube.common.gxrest.response.entity.EntityTag;
|
||||
import org.gcube.common.gxrest.response.entity.SerializableErrorEntity;
|
||||
import org.gcube.common.gxrest.response.outbound.ErrorCode;
|
||||
import org.gcube.common.gxrest.response.outbound.GXOutboundErrorResponse;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
/**
|
||||
* The response returned from the web application.
|
||||
*
|
||||
* @author Manuele Simi (ISTI CNR)
|
||||
*
|
||||
*/
|
||||
public class GXInboundResponse {
|
||||
|
||||
private SerializableErrorEntity entity;
|
||||
private final int responseCode;
|
||||
private String contentType = "";
|
||||
private String message = "";
|
||||
private String body = "";
|
||||
private byte[] streamedContent;
|
||||
private Map<String, List<String>> headerFields;
|
||||
private static final Logger logger = LoggerFactory.getLogger(GXInboundResponse.class);
|
||||
private boolean hasGXError = false;
|
||||
private Response source;
|
||||
private HttpURLConnection connection;
|
||||
// the content cannot be read more than one time from the response or input
|
||||
// stream
|
||||
private boolean contentAlreadyConsumed = false;
|
||||
|
||||
private boolean fromConnection = false;
|
||||
private boolean fromResponse = false;
|
||||
|
||||
/**
|
||||
* Builds a new inbound response.
|
||||
*
|
||||
* @param source
|
||||
* the original response
|
||||
*/
|
||||
public GXInboundResponse(Response source) {
|
||||
this.fromResponse = true;
|
||||
this.source = source;
|
||||
this.responseCode = source.getStatusInfo().getStatusCode();
|
||||
this.message = source.getStatusInfo().getReasonPhrase();
|
||||
this.headerFields = source.getStringHeaders();
|
||||
if (Objects.nonNull(source.getMediaType()))
|
||||
this.contentType = source.getMediaType().getType();
|
||||
try {
|
||||
if (Objects.nonNull(source.getEntityTag()) && source.getEntityTag().getValue().equals(EntityTag.gxError)) {
|
||||
this.entity = source.readEntity(SerializableErrorEntity.class);
|
||||
this.hasGXError = true;
|
||||
this.contentAlreadyConsumed = true;
|
||||
}
|
||||
} catch (ProcessingException | IllegalStateException ie) {
|
||||
// if it fails, it's likely message response
|
||||
// this.message = (String) source.getEntity();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param connection
|
||||
* the connection from which to parse the information
|
||||
* @throws IOException
|
||||
*/
|
||||
public GXInboundResponse(HttpURLConnection connection) throws IOException {
|
||||
this.fromConnection = true;
|
||||
this.connection = connection;
|
||||
this.responseCode = connection.getResponseCode();
|
||||
this.message = connection.getResponseMessage();
|
||||
this.headerFields = connection.getHeaderFields();
|
||||
this.contentType = connection.getContentType();
|
||||
// header fields are usually wrapped around double quotes
|
||||
String eTag = connection.getHeaderField("ETag");
|
||||
if (Objects.nonNull(eTag) && eTag.replaceAll("^\"|\"$", "").equals(EntityTag.gxError)) {
|
||||
logger.debug("GXErrorResponse detected.");
|
||||
this.hasGXError = true;
|
||||
try {
|
||||
this.streamedContent = ContentUtils.toByteArray(connection.getErrorStream());
|
||||
this.contentAlreadyConsumed = true;
|
||||
this.body = ContentUtils.toString(streamedContent);
|
||||
this.entity = JsonUtils.fromJson(this.body, SerializableErrorEntity.class);
|
||||
logger.trace("Response's content: " + this.body);
|
||||
} catch (Exception ioe) {
|
||||
logger.warn("No data are available in the response.");
|
||||
}
|
||||
} else {
|
||||
try {
|
||||
// this.streamedContent =
|
||||
// ContentUtils.toByteArray(connection.getInputStream());
|
||||
if (this.contentType.equals(MediaType.TEXT_PLAIN)
|
||||
|| this.contentType.equals(MediaType.APPLICATION_JSON)) {
|
||||
this.body = ContentUtils.toString(ContentUtils.toByteArray(connection.getInputStream()));
|
||||
logger.trace("Response's content: " + this.body);
|
||||
this.contentAlreadyConsumed = true;
|
||||
}
|
||||
} catch (Exception ioe) {
|
||||
logger.warn("No data are available in the response.", ioe);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds a new inbound response.
|
||||
*
|
||||
* @param source
|
||||
* the original response
|
||||
* @param expectedMediaTypes
|
||||
* the expected media type(s) in the response
|
||||
*/
|
||||
public GXInboundResponse(Response response, MediaType[] expectedMediaTypes) {
|
||||
this(response);
|
||||
if (Objects.isNull(expectedMediaTypes) || expectedMediaTypes.length == 0)
|
||||
throw new IllegalArgumentException("No expected type was set)");
|
||||
|
||||
// validate the media type
|
||||
boolean compatible = false;
|
||||
for (MediaType media : expectedMediaTypes) {
|
||||
if (Objects.nonNull(response.getMediaType()) && response.getMediaType().isCompatible(media))
|
||||
compatible = true;
|
||||
}
|
||||
if (!compatible)
|
||||
throw new IllegalArgumentException("Received MediaType is not compatible with the expected type(s)");
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if there is an {@link Exception} in the entity.
|
||||
*
|
||||
* @return true if the entity holds an exception, false otherwise
|
||||
*/
|
||||
public boolean hasException() {
|
||||
return Objects.nonNull(this.entity) && Objects.nonNull(this.entity.getExceptionClass());
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the response is in the range 4xx - 5xx
|
||||
* .
|
||||
*
|
||||
* @return true if it is an error response.
|
||||
*/
|
||||
public boolean isErrorResponse() {
|
||||
return this.getHTTPCode() >= 400 && this.getHTTPCode() < 600;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the response is in the range 2xx
|
||||
* .
|
||||
*
|
||||
* @return true if it is a success response.
|
||||
*/
|
||||
public boolean isSuccessResponse() {
|
||||
return this.getHTTPCode() >= 200 && this.getHTTPCode() < 300;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the response was generated as a {@link GXOutboundErrorResponse}
|
||||
* .
|
||||
*
|
||||
* @return true if it is an error response generated with GXRest.
|
||||
*/
|
||||
public boolean hasGXError() {
|
||||
return this.hasGXError;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the {@link Exception} inside the entity.
|
||||
*
|
||||
* @return the exception or null
|
||||
* @throws ClassNotFoundException
|
||||
* if the exception's class is not available on the classpath
|
||||
*/
|
||||
public <E extends Exception> E getException() throws ClassNotFoundException {
|
||||
if (Objects.nonNull(this.entity)) {
|
||||
E e = ExceptionDeserializer.deserialize(this.entity.getExceptionClass(), this.entity.getMessage());
|
||||
if (Objects.nonNull(e)) {
|
||||
if (this.entity.hasStackTrace())
|
||||
ExceptionDeserializer.addStackTrace(e, this.entity.getEncodedTrace());
|
||||
else
|
||||
e.setStackTrace(new StackTraceElement[] {});
|
||||
return e;
|
||||
} else
|
||||
throw new ClassNotFoundException(
|
||||
"Failed to deserialize: " + this.entity.getExceptionClass() + ". Not on the classpath?");
|
||||
} else
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if there is an {@link ErrorCode} in the entity.
|
||||
*
|
||||
* @return true if the entity holds an errorcode, false otherwise
|
||||
*/
|
||||
public boolean hasErrorCode() {
|
||||
if (Objects.nonNull(this.entity))
|
||||
return this.entity.getId() != -1;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the {@link ErrorCode} inside the entity.
|
||||
*
|
||||
* @return the error code or null
|
||||
*/
|
||||
public ErrorCode getErrorCode() {
|
||||
if (Objects.nonNull(this.entity))
|
||||
return ErrorCodeDeserializer.deserialize(this.entity.getId(), this.entity.getMessage());
|
||||
else
|
||||
return null;
|
||||
};
|
||||
|
||||
/**
|
||||
* Gets the message in the response
|
||||
*
|
||||
* @return the message
|
||||
*/
|
||||
public String getMessage() {
|
||||
return this.message;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the streamed content as a string, if possible.
|
||||
*
|
||||
* @return the content
|
||||
* @throws IOException
|
||||
* if unable to read the content
|
||||
*/
|
||||
public String getStreamedContentAsString() throws IOException {
|
||||
if (this.body.isEmpty()) {
|
||||
this.body = ContentUtils.toString(ContentUtils.toByteArray(getInputStream()));
|
||||
}
|
||||
return this.body;
|
||||
}
|
||||
|
||||
public InputStream getInputStream() throws IOException {
|
||||
if(!this.contentAlreadyConsumed) {
|
||||
if (this.fromConnection) {
|
||||
contentAlreadyConsumed = true;
|
||||
return connection.getInputStream();
|
||||
} else if (this.fromResponse) {
|
||||
contentAlreadyConsumed = true;
|
||||
return (InputStream) source.getEntity();
|
||||
}
|
||||
// This code should be never reached
|
||||
return null;
|
||||
}
|
||||
throw new IOException("Content Already Consumed");
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the content of the response as byte array.
|
||||
*
|
||||
* @return the streamedContent
|
||||
* @throws IOException
|
||||
* if unable to read the content
|
||||
*/
|
||||
public byte[] getStreamedContent() throws IOException {
|
||||
if (!this.body.isEmpty()) {
|
||||
this.streamedContent = this.body.getBytes();
|
||||
} else {
|
||||
this.streamedContent = ContentUtils.toByteArray(getInputStream());
|
||||
}
|
||||
return this.streamedContent;
|
||||
}
|
||||
|
||||
/**
|
||||
* Tries to convert the content from its Json serialization, if possible.
|
||||
*
|
||||
* @param <T>
|
||||
* the type of the desired object
|
||||
* @return an object of type T from the content
|
||||
* @throws Exception
|
||||
* if the deserialization fails
|
||||
*/
|
||||
public <T> T tryConvertStreamedContentFromJson(Class<T> raw) throws Exception {
|
||||
return JsonUtils.fromJson(this.getStreamedContentAsString(), raw);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the status code from the HTTP response message.
|
||||
*
|
||||
* @return the HTTP code
|
||||
*/
|
||||
public int getHTTPCode() {
|
||||
return this.responseCode;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the response has a CREATED (201) HTTP status.
|
||||
*
|
||||
* @return true if CREATED, false otherwise
|
||||
*/
|
||||
public boolean hasCREATEDCode() {
|
||||
return (this.getHTTPCode() == Status.CREATED.getStatusCode());
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the response has a OK (200) HTTP status.
|
||||
*
|
||||
* @return true if OK, false otherwise
|
||||
*/
|
||||
public boolean hasOKCode() {
|
||||
return (this.getHTTPCode() == Status.OK.getStatusCode());
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the response has a NOT_ACCEPTABLE (406) HTTP status.
|
||||
*
|
||||
* @return true if NOT_ACCEPTABLE, false otherwise
|
||||
*/
|
||||
public boolean hasNOT_ACCEPTABLECode() {
|
||||
return (this.getHTTPCode() == Status.NOT_ACCEPTABLE.getStatusCode());
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the response has a BAD_REQUEST (400) HTTP status.
|
||||
*
|
||||
* @return true if BAD_REQUEST, false otherwise
|
||||
*/
|
||||
public boolean hasBAD_REQUESTCode() {
|
||||
return (this.getHTTPCode() == Status.BAD_REQUEST.getStatusCode());
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an unmodifiable Map of the header fields. The Map keys are
|
||||
* Strings that represent the response-header field names. Each Map value is
|
||||
* an unmodifiable List of Strings that represents the corresponding field
|
||||
* values.
|
||||
*
|
||||
* @return a Map of header fields
|
||||
*/
|
||||
public Map<String, List<String>> getHeaderFields() {
|
||||
return this.headerFields;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the source response, if available
|
||||
* @throws UnsupportedOperationException
|
||||
* if not available
|
||||
*/
|
||||
public Response getSource() throws UnsupportedOperationException {
|
||||
if (Objects.isNull(this.source))
|
||||
new UnsupportedOperationException();
|
||||
return this.source;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,46 @@
|
|||
package org.gcube.common.gxrest.response.inbound;
|
||||
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
|
||||
/**
|
||||
* Manipulation of an {@link GXInboundResponse}'s content.
|
||||
*
|
||||
* @author Manuele Simi (ISTI CNR)
|
||||
*
|
||||
*/
|
||||
final public class JsonUtils {
|
||||
|
||||
/**
|
||||
* Deserializes the specified Json bytes into an object of the specified class
|
||||
* @param <T> the type of the desired object
|
||||
* @param json the string from which the object is to be deserialized
|
||||
* @param classOfT the class of T
|
||||
* @return an object of type T from the bytes
|
||||
* @throws Exception if the deserialization fails
|
||||
*/
|
||||
public static <T> T fromJson(byte[] bytes, Class<T> raw) throws Exception {
|
||||
try {
|
||||
ObjectMapper objectMapper = new ObjectMapper();
|
||||
return objectMapper.readValue(bytes, raw);
|
||||
} catch (Exception e) {
|
||||
throw new Exception("Cannot deserialize to the object.", e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Deserializes the specified Json bytes into an object of the specified class
|
||||
* @param <T> the type of the desired object
|
||||
* @param json the string from which the object is to be deserialized
|
||||
* @param raw the class of T
|
||||
* @return an object of type T from the bytes
|
||||
* @throws Exception if the deserialization fails
|
||||
*/
|
||||
public static <T> T fromJson(String json, Class<T> raw) throws Exception {
|
||||
try {
|
||||
ObjectMapper objectMapper = new ObjectMapper();
|
||||
return objectMapper.readValue(json, raw);
|
||||
} catch (Exception e) {
|
||||
throw new Exception("Cannot deserialize to the object.", e);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,8 @@
|
|||
/**
|
||||
* Inbound responses for client applications.
|
||||
* These responses are received at the client side following up a request sent to the web application.
|
||||
*
|
||||
* @author Manuele Simi (ISTI CNR)
|
||||
*
|
||||
*/
|
||||
package org.gcube.common.gxrest.response.inbound;
|
|
@ -0,0 +1,24 @@
|
|||
package org.gcube.common.gxrest.response.outbound;
|
||||
|
||||
import java.util.stream.Stream;
|
||||
|
||||
/**
|
||||
* Helper methods to find an error code in an enumeration implementing {@link ErrorCode}.
|
||||
*
|
||||
* @author Manuele Simi (ISTI CNR)
|
||||
*
|
||||
*/
|
||||
public class CodeFinder {
|
||||
|
||||
/**
|
||||
* Finds and convert the given code as enum value.
|
||||
* @param code the code to look for.
|
||||
* @param codes the enum values.
|
||||
* @return the code as enum value or null if the code is not found.
|
||||
*/
|
||||
public static <E extends Enum<E> & ErrorCode> E findAndConvert(ErrorCode code, E[] codes) {
|
||||
return Stream.of(codes).filter(e -> e.getId() == code.getId() && e.getMessage().equals(code.getMessage()))
|
||||
.findFirst().orElse(null);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,22 @@
|
|||
package org.gcube.common.gxrest.response.outbound;
|
||||
|
||||
/**
|
||||
* Interface for error codes.
|
||||
*
|
||||
* @author Manuele Simi (ISTI CNR)
|
||||
*
|
||||
*/
|
||||
public interface ErrorCode {
|
||||
|
||||
/**
|
||||
* Identifier of the code.
|
||||
*/
|
||||
public int getId();
|
||||
|
||||
/**
|
||||
* The message associated to the code
|
||||
* @return the message
|
||||
*/
|
||||
public String getMessage();
|
||||
|
||||
}
|
|
@ -0,0 +1,77 @@
|
|||
package org.gcube.common.gxrest.response.outbound;
|
||||
|
||||
import javax.ws.rs.WebApplicationException;
|
||||
import javax.ws.rs.core.Response;
|
||||
|
||||
/**
|
||||
* An outbound error response message for applications.
|
||||
*
|
||||
* @author Manuele Simi (ISTI CNR)
|
||||
*
|
||||
*/
|
||||
public class GXOutboundErrorResponse {
|
||||
|
||||
private GXOutboundErrorResponse() {}
|
||||
|
||||
/**
|
||||
* Throws the exception to the client.
|
||||
* @param exception
|
||||
*/
|
||||
public static void throwException(Exception exception) {
|
||||
throw new WebStreamException(exception);
|
||||
}
|
||||
|
||||
/**
|
||||
* Throws the exception to the client.
|
||||
* @param exception
|
||||
*/
|
||||
public static void throwException(Exception exception, Response.Status status) {
|
||||
throw new WebStreamException(exception, status);
|
||||
}
|
||||
|
||||
/**
|
||||
* Throws the exception to the client.
|
||||
* @param exception
|
||||
* @param keepLines number of lines in the stacktrace to keep (max is 5)
|
||||
*/
|
||||
public static void throwExceptionWithTrace(Exception exception, int keepLines, Response.Status status) {
|
||||
throw new WebStreamException(exception, keepLines, status);
|
||||
}
|
||||
|
||||
/**
|
||||
* Throws the exception to the client.
|
||||
* @param exception
|
||||
* @param keepLines number of lines in the stacktrace to keep (max is 5)
|
||||
*/
|
||||
public static void throwExceptionWithTrace(Exception exception, int keepLines) {
|
||||
throw new WebStreamException(exception, keepLines);
|
||||
}
|
||||
|
||||
/**
|
||||
* Throws the error code to the client.
|
||||
* @param code
|
||||
*/
|
||||
public static void throwErrorCode(ErrorCode code) {
|
||||
throw new WebCodeException(code);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the error code to the client with the HTTP status.
|
||||
* @param code
|
||||
* @param status
|
||||
*/
|
||||
public static void throwErrorCode(ErrorCode code, Response.Status status) {
|
||||
throw new WebCodeException(code, status);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the HTTP status to the client as error.
|
||||
* @param status
|
||||
* @param message
|
||||
*/
|
||||
public static void throwHTTPErrorStatus(Response.Status status, String message) {
|
||||
if (status.getStatusCode() < 400)
|
||||
throw new IllegalArgumentException("Error status must be >= 400.");
|
||||
throw new WebApplicationException(message, status.getStatusCode());
|
||||
}
|
||||
}
|
|
@ -0,0 +1,132 @@
|
|||
package org.gcube.common.gxrest.response.outbound;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.net.URI;
|
||||
import javax.ws.rs.core.MediaType;
|
||||
import javax.ws.rs.core.Response;
|
||||
import javax.ws.rs.core.Response.ResponseBuilder;
|
||||
|
||||
import org.gcube.common.gxrest.response.entity.EntityTag;
|
||||
|
||||
/**
|
||||
* An outbound success response message for applications.
|
||||
*
|
||||
* @author Manuele Simi (ISTI CNR)
|
||||
*
|
||||
*/
|
||||
public class GXOutboundSuccessResponse {
|
||||
|
||||
private ResponseBuilder delegate;
|
||||
|
||||
private GXOutboundSuccessResponse() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds a new response with the OK HTTP status.
|
||||
*
|
||||
* @return the updated response
|
||||
*/
|
||||
public static GXOutboundSuccessResponse newOKResponse() {
|
||||
GXOutboundSuccessResponse response = new GXOutboundSuccessResponse();
|
||||
response.delegate = Response.ok();
|
||||
response.delegate.tag(EntityTag.gxSuccess);
|
||||
return response;
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds a new response with the CREATE HTTP status.
|
||||
*
|
||||
* @return the updated response
|
||||
*/
|
||||
public static GXOutboundSuccessResponse newCREATEResponse(URI location) {
|
||||
GXOutboundSuccessResponse response = new GXOutboundSuccessResponse();
|
||||
response.delegate = Response.created(location);
|
||||
response.delegate.tag(EntityTag.gxSuccess);
|
||||
return response;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the object as response's content.
|
||||
* Any Java type instance for a response entity, that is supported by the
|
||||
* runtime can be passed.
|
||||
*
|
||||
* @param o the content
|
||||
* @return the updated response
|
||||
* @throws IOException
|
||||
*/
|
||||
public GXOutboundSuccessResponse withContent(Object o) throws IOException {
|
||||
this.delegate.entity(o);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads from the stream the content to set in the response.
|
||||
*
|
||||
* @param is the stream
|
||||
* @return the updated response
|
||||
* @throws IOException
|
||||
*/
|
||||
public GXOutboundSuccessResponse withContent(InputStream is) throws IOException {
|
||||
this.delegate.entity(is);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the message as the response's content.
|
||||
*
|
||||
* @param message
|
||||
* @return the updated response
|
||||
*/
|
||||
public GXOutboundSuccessResponse withContent(String message) {
|
||||
this.delegate.entity(message);
|
||||
this.delegate.type(MediaType.TEXT_PLAIN);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a type to the response message.
|
||||
*
|
||||
* @param type
|
||||
* @return the updated response
|
||||
*/
|
||||
public GXOutboundSuccessResponse ofType(MediaType type) {
|
||||
this.delegate.type(type);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a type to the response message.
|
||||
*
|
||||
* @param type
|
||||
* @return the updated response
|
||||
*/
|
||||
public GXOutboundSuccessResponse ofType(String type) {
|
||||
this.delegate.type(type);
|
||||
return this;
|
||||
}
|
||||
/**
|
||||
* Add an arbitrary header.
|
||||
*
|
||||
* @param name the name of the header
|
||||
* @param value the value of the header, the header will be serialized
|
||||
* using a {@link javax.ws.rs.ext.RuntimeDelegate.HeaderDelegate} if
|
||||
* one is available via {@link javax.ws.rs.ext.RuntimeDelegate#createHeaderDelegate(java.lang.Class)}
|
||||
* for the class of {@code value} or using its {@code toString} method
|
||||
* if a header delegate is not available. If {@code value} is {@code null}
|
||||
* then all current headers of the same name will be removed.
|
||||
* @return the updated response.
|
||||
*/
|
||||
public GXOutboundSuccessResponse withHeader(String name, Object value) {
|
||||
this.delegate.header(name, value);
|
||||
return this;
|
||||
}
|
||||
/**
|
||||
* Builds the response to return.
|
||||
*
|
||||
* @return the response
|
||||
*/
|
||||
public Response build() {
|
||||
return this.delegate.build();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,29 @@
|
|||
|
||||
package org.gcube.common.gxrest.response.outbound;
|
||||
|
||||
/**
|
||||
* A local exception wrapping an {@link ErrorCode}.
|
||||
*
|
||||
* @author Manuele Simi (ISTI CNR)
|
||||
*
|
||||
*/
|
||||
public class LocalCodeException extends Exception implements ErrorCode {
|
||||
|
||||
private static final long serialVersionUID = 1872093579811881630L;
|
||||
private final int id;
|
||||
private final String message;
|
||||
|
||||
public LocalCodeException(ErrorCode code) {
|
||||
super();
|
||||
this.id = code.getId();
|
||||
this.message = code.getMessage();
|
||||
}
|
||||
|
||||
public int getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public String getMessage() {
|
||||
return message;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,34 @@
|
|||
package org.gcube.common.gxrest.response.outbound;
|
||||
|
||||
import javax.ws.rs.WebApplicationException;
|
||||
import javax.ws.rs.core.Response;
|
||||
|
||||
import org.gcube.common.gxrest.response.entity.CodeEntity;
|
||||
import org.gcube.common.gxrest.response.entity.EntityTag;
|
||||
import org.gcube.common.gxrest.response.entity.SerializableErrorEntity;
|
||||
|
||||
/**
|
||||
* Exception with error code returned by a resource method.
|
||||
*
|
||||
* @author Manuele Simi (ISTI CNR)
|
||||
*
|
||||
*/
|
||||
final class WebCodeException extends WebApplicationException {
|
||||
|
||||
private static final long serialVersionUID = 333945715086602250L;
|
||||
|
||||
protected WebCodeException() {
|
||||
super(Response.status(Response.Status.NOT_ACCEPTABLE).build());
|
||||
}
|
||||
|
||||
protected WebCodeException(ErrorCode code, Response.Status status) {
|
||||
super(Response.status(status).entity(new CodeEntity(new SerializableErrorEntity(code))).tag(EntityTag.gxError)
|
||||
.build());
|
||||
}
|
||||
|
||||
protected WebCodeException(ErrorCode code) {
|
||||
super(Response.status(Response.Status.NOT_ACCEPTABLE)
|
||||
.entity(new CodeEntity(new SerializableErrorEntity(code))).tag(EntityTag.gxError).build());
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,64 @@
|
|||
package org.gcube.common.gxrest.response.outbound;
|
||||
|
||||
import javax.ws.rs.WebApplicationException;
|
||||
import javax.ws.rs.core.Response;
|
||||
|
||||
import org.gcube.common.gxrest.response.entity.CodeEntity;
|
||||
import org.gcube.common.gxrest.response.entity.EntityTag;
|
||||
import org.gcube.common.gxrest.response.entity.SerializableErrorEntity;
|
||||
|
||||
/**
|
||||
* An exception returned to the Rest client.
|
||||
*
|
||||
* @author Manuele Simi (ISTI CNR)
|
||||
*
|
||||
*/
|
||||
final class WebStreamException extends WebApplicationException {
|
||||
|
||||
private static final long serialVersionUID = 822443082773903217L;
|
||||
|
||||
/**
|
||||
* Returns the exception.
|
||||
*
|
||||
* @param exception
|
||||
* @param keepLines
|
||||
* @param status
|
||||
* the HTTP status to associate to the response.
|
||||
*/
|
||||
protected <E extends Exception> WebStreamException(E exception, int keepLines, Response.Status status) {
|
||||
super(exception.getCause(), Response.status(status)
|
||||
.entity(new CodeEntity(new SerializableErrorEntity(exception, keepLines))).tag(EntityTag.gxError).build());
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the exception.
|
||||
*
|
||||
* @param exception
|
||||
* @param status
|
||||
* the HTTP status to associate to the response.
|
||||
*/
|
||||
protected <E extends Exception> WebStreamException(E exception, int keepLines) {
|
||||
this(exception, keepLines, Response.Status.NOT_ACCEPTABLE);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the exception.
|
||||
*
|
||||
* @param exception
|
||||
*/
|
||||
protected <E extends Exception> WebStreamException(E exception) {
|
||||
this(exception, 0, Response.Status.NOT_ACCEPTABLE);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the exception.
|
||||
*
|
||||
* @param exception
|
||||
* @param status
|
||||
* the HTTP status to associate to the response.
|
||||
*/
|
||||
protected <E extends Exception> WebStreamException(E exception, Response.Status status) {
|
||||
this(exception, 0, status);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,8 @@
|
|||
/**
|
||||
* Outbound responses for web applications.
|
||||
* These responses are returned by the resource methods of the web application.
|
||||
*
|
||||
* @author Manuele Simi (ISTI-CNR)
|
||||
*
|
||||
*/
|
||||
package org.gcube.common.gxrest.response.outbound;
|
|
@ -0,0 +1,240 @@
|
|||
package org.gcube.common.gxrest.request;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.util.Map;
|
||||
import java.util.Properties;
|
||||
import java.util.WeakHashMap;
|
||||
|
||||
import org.gcube.common.authorization.client.Constants;
|
||||
import org.gcube.common.authorization.client.exceptions.ObjectNotFound;
|
||||
import org.gcube.common.authorization.library.AuthorizationEntry;
|
||||
import org.gcube.common.authorization.library.provider.SecurityTokenProvider;
|
||||
import org.gcube.common.gxrest.response.inbound.GXInboundResponse;
|
||||
import org.junit.AfterClass;
|
||||
import org.junit.Before;
|
||||
import org.junit.BeforeClass;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.junit.runners.BlockJUnit4ClassRunner;
|
||||
|
||||
import com.fasterxml.jackson.databind.JsonMappingException;
|
||||
|
||||
/**
|
||||
* Test cases for {@link GXHTTPStringRequest}
|
||||
*
|
||||
* @author Manuele Simi (ISTI-CNR)
|
||||
*
|
||||
*/
|
||||
@RunWith(BlockJUnit4ClassRunner.class)
|
||||
public class GXHTTPStringRequestTest {
|
||||
|
||||
private GXHTTPStringRequest request;
|
||||
|
||||
public static String DEFAULT_TEST_SCOPE = "";
|
||||
|
||||
static String DEFAULT_RM_URL = "";
|
||||
|
||||
static String DEFAULT_RR_URL = "";
|
||||
|
||||
|
||||
private static boolean skipTest = false;
|
||||
|
||||
static {
|
||||
Properties properties = new Properties();
|
||||
try (InputStream input = GXHTTPStringRequestTest.class.getClassLoader().getResourceAsStream("token.props")) {
|
||||
// load the properties file
|
||||
properties.load(input);
|
||||
DEFAULT_TEST_SCOPE = properties.getProperty("DEFAULT_SCOPE_TOKEN");
|
||||
if (DEFAULT_TEST_SCOPE.isEmpty())
|
||||
skipTest = true;
|
||||
DEFAULT_RM_URL = properties.getProperty("RM_URL");
|
||||
DEFAULT_RR_URL = properties.getProperty("RR_URL");
|
||||
} catch (IOException | NullPointerException e) {
|
||||
skipTest = true;
|
||||
}
|
||||
}
|
||||
|
||||
@BeforeClass
|
||||
public static void beforeClass() throws Exception {
|
||||
setContext(DEFAULT_TEST_SCOPE);
|
||||
}
|
||||
|
||||
public static void setContext(String token) throws ObjectNotFound, Exception {
|
||||
if (DEFAULT_TEST_SCOPE.isEmpty()) {
|
||||
skipTest = true;
|
||||
return;
|
||||
}
|
||||
SecurityTokenProvider.instance.set(token);
|
||||
}
|
||||
|
||||
public static String getCurrentScope(String token) throws ObjectNotFound, Exception {
|
||||
AuthorizationEntry authorizationEntry = Constants.authorizationService().get(token);
|
||||
String context = authorizationEntry.getContext();
|
||||
return context;
|
||||
}
|
||||
|
||||
@AfterClass
|
||||
public static void afterClass() throws Exception {
|
||||
SecurityTokenProvider.instance.reset();
|
||||
}
|
||||
|
||||
/**
|
||||
* Test method for {@link org.gcube.common.gxrest.request.GXHTTPStringRequest#newRequest(java.lang.String)}.
|
||||
*/
|
||||
@Before
|
||||
public void testNewRequest() {
|
||||
request = GXHTTPStringRequest.newRequest(DEFAULT_RM_URL).from("GXRequestTest");
|
||||
}
|
||||
|
||||
/**
|
||||
* Test method for {@link org.gcube.common.gxrest.request.GXHTTPStringRequest#post()}.
|
||||
*/
|
||||
@Test
|
||||
public void testPost() {
|
||||
if (skipTest)
|
||||
return;
|
||||
request.clear();
|
||||
String context ="{\"@class\":\"Context\",\"header\":{\"@class\":\"Header\",\"uuid\":\"6f86dc81-2f59-486b-8aa9-3ab5486313c4\",\"creator\":null,\"modifiedBy\":\"gxRestTest\",\"creationTime\":null,\"lastUpdateTime\":null},\"name\":\"gxTest\",\"parent\":null,\"children\":[]}";
|
||||
Map<String,String> queryParams = new WeakHashMap<>();
|
||||
queryParams.put("rrURL", DEFAULT_RR_URL);
|
||||
try {
|
||||
GXInboundResponse response = request.path("gxrest")
|
||||
.header("Another header", "GXHTTPRequestTest")
|
||||
.queryParams(queryParams).post(context);
|
||||
assertTrue("Unexpected returned code.", response.hasCREATEDCode());
|
||||
if (response.hasException()) {
|
||||
try {
|
||||
throw response.getException();
|
||||
} catch (ClassNotFoundException e) {
|
||||
//that's OK, we can tolerate this
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
throw e;
|
||||
}
|
||||
} else {
|
||||
System.out.println("Returned string " + response.getStreamedContentAsString());
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
fail("Failed to send a POST request");
|
||||
}
|
||||
}
|
||||
|
||||
@Test(expected=com.fasterxml.jackson.databind.JsonMappingException.class)
|
||||
public void testPostNoBody() throws Exception {
|
||||
if (skipTest)
|
||||
throw new JsonMappingException("");
|
||||
request.clear();
|
||||
Map<String,String> queryParams = new WeakHashMap<>();
|
||||
queryParams.put("rrURL", DEFAULT_RR_URL);
|
||||
try {
|
||||
GXInboundResponse response = request.path("gxrest")
|
||||
.header("Another header", "GXHTTPRequestTest")
|
||||
.queryParams(queryParams).post();
|
||||
assertTrue("Unexpected returned code.", response.hasNOT_ACCEPTABLECode());
|
||||
assertTrue("Unexpected GX status", response.hasGXError());
|
||||
if (response.hasGXError()) {
|
||||
try {
|
||||
throw response.getException();
|
||||
} catch (ClassNotFoundException e) {
|
||||
//that's OK, we can tolerate this
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
throw e;
|
||||
}
|
||||
} else {
|
||||
System.out.println("Returned string " + response.getStreamedContentAsString());
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
throw e;
|
||||
//fail("Failed to send a POST request");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Test method for {@link org.gcube.common.gxrest.request.GXHTTPStringRequest#get()}.
|
||||
*/
|
||||
@Test
|
||||
public void testGet() {
|
||||
request.clear();
|
||||
}
|
||||
|
||||
/**
|
||||
* Test method for {@link org.gcube.common.gxrest.request.GXHTTPStringRequest#put()}.
|
||||
*/
|
||||
@Test
|
||||
public void testPut() {
|
||||
if (skipTest)
|
||||
return;
|
||||
request.clear();
|
||||
Map<String,String> queryParams = new WeakHashMap<>();
|
||||
queryParams.put("rrURL", DEFAULT_RR_URL);
|
||||
String context ="{\"@class\":\"Context\",\"header\":{\"@class\":\"Header\",\"uuid\":\"6f86dc81-2f59-486b-8aa9-3ab5486313c4\",\"creator\":null,\"modifiedBy\":\"gxRestTest\",\"creationTime\":null,\"lastUpdateTime\":null},\"name\":\"gxTest\",\"parent\":null,\"children\":[]}";
|
||||
try {
|
||||
GXInboundResponse response = request.path("gxrest")
|
||||
.header("Another header", "GXHTTPRequestTest")
|
||||
.path("5f86dc81-2f59-486b-8aa9-3ab5486313c4").queryParams(queryParams).put(context);
|
||||
assertTrue("Unexpected returned code.", response.hasCREATEDCode());
|
||||
if (response.hasException()) {
|
||||
try {
|
||||
throw response.getException();
|
||||
} catch (ClassNotFoundException e) {
|
||||
//that's OK, we can tolerate this
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
throw e;
|
||||
}
|
||||
} else {
|
||||
System.out.println("Returned string " + response.getStreamedContentAsString());
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
fail("Failed to send a DELETE request");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Test method for {@link org.gcube.common.gxrest.request.GXHTTPStringRequest#delete()}.
|
||||
*/
|
||||
@Test
|
||||
public void testDelete() {
|
||||
if (skipTest)
|
||||
return;
|
||||
request.clear();
|
||||
Map<String,String> queryParams = new WeakHashMap<>();
|
||||
queryParams.put("rrURL", DEFAULT_RR_URL);
|
||||
try {
|
||||
GXInboundResponse response = request.path("gxrest")
|
||||
.header("Another header", "GXHTTPRequestTest")
|
||||
.path("5f86dc81-2f59-486b-8aa9-3ab5486313c4").queryParams(queryParams).delete();
|
||||
assertTrue("Unexpected returned code.", response.hasBAD_REQUESTCode());
|
||||
if (response.hasException()) {
|
||||
try {
|
||||
throw response.getException();
|
||||
} catch (ClassNotFoundException e) {
|
||||
//that's OK, we can tolerate this
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
fail("Failed to send a DELETE request");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Test method for {@link org.gcube.common.gxrest.request.GXHTTPStringRequest#head()}.
|
||||
*/
|
||||
@Test
|
||||
public void testHead() {
|
||||
request.clear();
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,178 @@
|
|||
package org.gcube.common.gxrest.request;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.util.Map;
|
||||
import java.util.Properties;
|
||||
import java.util.WeakHashMap;
|
||||
|
||||
import javax.ws.rs.client.Entity;
|
||||
import javax.ws.rs.core.MediaType;
|
||||
|
||||
import org.gcube.common.authorization.client.Constants;
|
||||
import org.gcube.common.authorization.client.exceptions.ObjectNotFound;
|
||||
import org.gcube.common.authorization.library.AuthorizationEntry;
|
||||
import org.gcube.common.authorization.library.provider.SecurityTokenProvider;
|
||||
import org.gcube.common.gxrest.response.inbound.GXInboundResponse;
|
||||
import org.junit.AfterClass;
|
||||
import org.junit.Before;
|
||||
import org.junit.BeforeClass;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.junit.runners.BlockJUnit4ClassRunner;
|
||||
|
||||
/**
|
||||
* Test cases for {@link GXWebTargetAdapterRequest}
|
||||
*
|
||||
* @author Manuele Simi (ISTI-CNR)
|
||||
*
|
||||
*/
|
||||
@RunWith(BlockJUnit4ClassRunner.class)
|
||||
public class GXWebTargetAdapterRequestTest {
|
||||
|
||||
private GXWebTargetAdapterRequest request;
|
||||
|
||||
public static String DEFAULT_TEST_SCOPE = "";
|
||||
|
||||
static String DEFAULT_RM_URL = "";
|
||||
|
||||
static String DEFAULT_RR_URL = "";
|
||||
|
||||
private static boolean skipTest = false;
|
||||
|
||||
static {
|
||||
Properties properties = new Properties();
|
||||
try (InputStream input = GXWebTargetAdapterRequest.class.getClassLoader().getResourceAsStream("token.props")) {
|
||||
// load the properties file
|
||||
properties.load(input);
|
||||
DEFAULT_TEST_SCOPE = properties.getProperty("DEFAULT_SCOPE_TOKEN");
|
||||
if (DEFAULT_TEST_SCOPE.isEmpty())
|
||||
skipTest = true;
|
||||
DEFAULT_RM_URL = properties.getProperty("RM_URL");
|
||||
DEFAULT_RR_URL = properties.getProperty("RR_URL");
|
||||
} catch (IOException | NullPointerException e) {
|
||||
skipTest = true;
|
||||
}
|
||||
}
|
||||
@BeforeClass
|
||||
public static void beforeClass() throws Exception {
|
||||
if (!skipTest)
|
||||
setContext(DEFAULT_TEST_SCOPE);
|
||||
}
|
||||
|
||||
public static void setContext(String token) throws ObjectNotFound, Exception {
|
||||
if (skipTest || DEFAULT_TEST_SCOPE.isEmpty()) {
|
||||
skipTest = true;
|
||||
return;
|
||||
} else {
|
||||
SecurityTokenProvider.instance.set(token);
|
||||
}
|
||||
}
|
||||
|
||||
public static String getCurrentScope(String token) throws ObjectNotFound, Exception {
|
||||
AuthorizationEntry authorizationEntry = Constants.authorizationService().get(token);
|
||||
String context = authorizationEntry.getContext();
|
||||
return context;
|
||||
}
|
||||
|
||||
@AfterClass
|
||||
public static void afterClass() throws Exception {
|
||||
SecurityTokenProvider.instance.reset();
|
||||
}
|
||||
|
||||
/**
|
||||
* Test method for {@link org.gcube.common.gxrest.request.GXHTTPStringRequest#newRequest(java.lang.String)}.
|
||||
*/
|
||||
@Before
|
||||
public void testNewRequest() {
|
||||
request = GXWebTargetAdapterRequest.newRequest(DEFAULT_RM_URL).from("GXRequestTest");
|
||||
}
|
||||
|
||||
/**
|
||||
* Test method for {@link org.gcube.common.gxrest.request.GXWebTargetAdapterRequest#put()}.
|
||||
*/
|
||||
@Test
|
||||
public void testPut() {
|
||||
if (skipTest)
|
||||
return;
|
||||
//fail("Not yet implemented");
|
||||
}
|
||||
|
||||
/**
|
||||
* Test method for {@link org.gcube.common.gxrest.request.GXWebTargetAdapterRequest#delete()}.
|
||||
*/
|
||||
@Test
|
||||
public void testDelete() {
|
||||
if (skipTest)
|
||||
return;
|
||||
//fail("Not yet implemented");
|
||||
}
|
||||
|
||||
/**
|
||||
* Test method for {@link org.gcube.common.gxrest.request.GXWebTargetAdapterRequest#post()}.
|
||||
*/
|
||||
@Test
|
||||
public void testPost() {
|
||||
if (skipTest)
|
||||
return;
|
||||
String context ="{\"@class\":\"Context\",\"header\":{\"@class\":\"Header\",\"uuid\":\"6f86dc81-2f59-486b-8aa9-3ab5486313c4\",\"creator\":null,\"modifiedBy\":\"gxRestTest\",\"creationTime\":null,\"lastUpdateTime\":null},\"name\":\"gxTest\",\"parent\":null,\"children\":[]}";
|
||||
Map<String,Object[]> queryParams = new WeakHashMap<>();
|
||||
queryParams.put("rrURL", new String[]{DEFAULT_RR_URL});
|
||||
try {
|
||||
GXInboundResponse response = request.path("gxrest")
|
||||
.header("User-Agent", this.getClass().getSimpleName())
|
||||
.header("Another header", "another value")
|
||||
.queryParams(queryParams).post(Entity.entity(context, MediaType.APPLICATION_JSON + ";charset=UTF-8"));
|
||||
assertTrue("Unexpected returned code.", response.hasCREATEDCode());
|
||||
if (response.hasGXError()) {
|
||||
if (response.hasException()) {
|
||||
try {
|
||||
throw response.getException();
|
||||
} catch (ClassNotFoundException e) {
|
||||
//that's OK, we can tolerate this
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (response.hasCREATEDCode()) {
|
||||
System.out.println("Resource successfully created!");
|
||||
System.out.println("Returned message: " + response.getStreamedContentAsString());
|
||||
} else {
|
||||
System.out.println("Resource creation failed. Returned status:" + response.getHTTPCode());
|
||||
//if you want to use the original responser
|
||||
response.getSource();
|
||||
//then consume the response
|
||||
}
|
||||
}
|
||||
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
fail("Failed to send a POST request");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Test method for {@link org.gcube.common.gxrest.request.GXWebTargetAdapterRequest#head()}.
|
||||
*/
|
||||
@Test
|
||||
public void testHead() {
|
||||
if (skipTest)
|
||||
return;
|
||||
//fail("Not yet implemented");
|
||||
}
|
||||
|
||||
/**
|
||||
* Test method for {@link org.gcube.common.gxrest.request.GXWebTargetAdapterRequest#get()}.
|
||||
*/
|
||||
@Test
|
||||
public void testGet() {
|
||||
if (skipTest)
|
||||
return;
|
||||
//fail("Not yet implemented");
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,20 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE xml>
|
||||
<configuration>
|
||||
|
||||
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
|
||||
<encoder>
|
||||
<pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{0}: %msg%n</pattern>
|
||||
</encoder>
|
||||
</appender>
|
||||
|
||||
|
||||
<logger name="org.gcube" level="INFO" />
|
||||
<logger name="org.gcube.common.gxrest" level="TRACE" />
|
||||
|
||||
|
||||
<root level="WARN">
|
||||
<appender-ref ref="STDOUT" />
|
||||
</root>
|
||||
|
||||
</configuration>
|
|
@ -0,0 +1 @@
|
|||
gxREST
|
|
@ -0,0 +1,14 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="CompilerConfiguration">
|
||||
<annotationProcessing>
|
||||
<profile name="Maven default annotation processors profile" enabled="true">
|
||||
<sourceOutputDir name="target/generated-sources/annotations" />
|
||||
<sourceTestOutputDir name="target/generated-test-sources/test-annotations" />
|
||||
<outputRelativeToContentRoot value="true" />
|
||||
<module name="gxHTTP" />
|
||||
<module name="gxJRS" />
|
||||
</profile>
|
||||
</annotationProcessing>
|
||||
</component>
|
||||
</project>
|
|
@ -0,0 +1,8 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="Encoding">
|
||||
<file url="file://$PROJECT_DIR$/.." charset="UTF-8" />
|
||||
<file url="file://$PROJECT_DIR$/../gxHTTP" charset="UTF-8" />
|
||||
<file url="file://$PROJECT_DIR$/../gxJRS" charset="UTF-8" />
|
||||
</component>
|
||||
</project>
|
|
@ -0,0 +1,35 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="ExternalStorageConfigurationManager" enabled="true" />
|
||||
<component name="MavenProjectsManager">
|
||||
<option name="originalFiles">
|
||||
<list>
|
||||
<option value="$PROJECT_DIR$/../pom.xml" />
|
||||
</list>
|
||||
</option>
|
||||
</component>
|
||||
<component name="ProjectRootManager" version="2" languageLevel="JDK_1_8" project-jdk-name="1.8" project-jdk-type="JavaSDK">
|
||||
<output url="file://$PROJECT_DIR$/out" />
|
||||
</component>
|
||||
<component name="SvnBranchConfigurationManager">
|
||||
<option name="myConfigurationMap">
|
||||
<map>
|
||||
<entry key="$PROJECT_DIR$/..">
|
||||
<value>
|
||||
<SvnBranchConfiguration>
|
||||
<option name="branchUrls">
|
||||
<list>
|
||||
<option value="https://svn.d4science.research-infrastructures.eu/gcube/branches" />
|
||||
<option value="https://svn.d4science.research-infrastructures.eu/gcube/misc" />
|
||||
<option value="https://svn.d4science.research-infrastructures.eu/gcube/private" />
|
||||
<option value="https://svn.d4science.research-infrastructures.eu/gcube/tags" />
|
||||
</list>
|
||||
</option>
|
||||
<option name="trunkUrl" value="https://svn.d4science.research-infrastructures.eu/gcube/trunk" />
|
||||
</SvnBranchConfiguration>
|
||||
</value>
|
||||
</entry>
|
||||
</map>
|
||||
</option>
|
||||
</component>
|
||||
</project>
|
|
@ -0,0 +1,6 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="VcsDirectoryMappings">
|
||||
<mapping directory="$PROJECT_DIR$/.." vcs="svn" />
|
||||
</component>
|
||||
</project>
|
|
@ -0,0 +1,69 @@
|
|||
<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>
|
||||
<parent>
|
||||
<groupId>org.gcube.tools</groupId>
|
||||
<artifactId>maven-parent</artifactId>
|
||||
<version>1.0.0</version>
|
||||
</parent>
|
||||
|
||||
<groupId>org.gcube.common</groupId>
|
||||
<artifactId>gxREST</artifactId>
|
||||
<version>1.1.2-SNAPSHOT</version>
|
||||
<packaging>pom</packaging>
|
||||
<name>gCube eXtensions to REST</name>
|
||||
<description>gCube eXtensions to REST</description>
|
||||
|
||||
<modules>
|
||||
<module>gxHTTP</module>
|
||||
<module>gxJRS</module>
|
||||
</modules>
|
||||
|
||||
<properties>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
<serviceClass>Common</serviceClass>
|
||||
<jersey.version>2.25.1</jersey.version>
|
||||
<jaxrs.version>2.0.1</jaxrs.version>
|
||||
</properties>
|
||||
|
||||
<scm>
|
||||
<connection>scm:https://svn.d4science.research-infrastructures.eu/gcube/trunk/common/${project.artifactId}</connection>
|
||||
<developerConnection>scm:https://svn.d4science.research-infrastructures.eu/gcube/trunk/common/${project.artifactId}</developerConnection>
|
||||
<url>https://svn.d4science.research-infrastructures.eu/gcube/trunk/common/${project.artifactId}</url>
|
||||
</scm>
|
||||
|
||||
|
||||
<dependencyManagement>
|
||||
<dependencies>
|
||||
<!-- https://mvnrepository.com/artifact/org.glassfish.jersey/jersey-bom -->
|
||||
<dependency>
|
||||
<groupId>org.glassfish.jersey</groupId>
|
||||
<artifactId>jersey-bom</artifactId>
|
||||
<version>${jersey.version}</version>
|
||||
<type>pom</type>
|
||||
<scope>import</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.gcube.distribution</groupId>
|
||||
<artifactId>gcube-bom</artifactId>
|
||||
<version>LATEST</version>
|
||||
<type>pom</type>
|
||||
<scope>import</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.gcube.information-system</groupId>
|
||||
<artifactId>information-system-bom</artifactId>
|
||||
<version>LATEST</version>
|
||||
<type>pom</type>
|
||||
<scope>import</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</dependencyManagement>
|
||||
|
||||
|
||||
<dependencies>
|
||||
|
||||
</dependencies>
|
||||
|
||||
</project>
|
Loading…
Reference in New Issue