forked from gCubeSystem/gx-rest
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