Difference between revisions of "GxRest/GxJRS/Requests"
Manuele.simi (Talk | contribs) (→GXWebTargetAdapterRequest) |
Manuele.simi (Talk | contribs) (→Using HTTPS) |
||
(48 intermediate revisions by the same user not shown) | |||
Line 1: | Line 1: | ||
− | |||
− | |||
= Types of Requests = | = Types of Requests = | ||
+ | As of version 1.1.2, there are three types of requests in [[GxRest/GxJRS|gxJRS]], all implementing the <code>GXHTTP</code> [[GxHTTP/Requests#Request_interface|request interface]]. | ||
+ | |||
+ | Each request method returns a GXInboundResponse instance that can be consumed as explained [[GxRest/GxJRS/Responses|here]]. | ||
+ | |||
+ | = GXHTTPStringRequest = | ||
+ | This type of request is entirely based on plain HTTP. It does not require any other software than the standard Java <code>java.net</code> and <code>java.io</code> packages to work. | ||
+ | |||
+ | The following snippet shows how to send a Post request to create a new resource in a collection of resources named ''context'' (the name depends on your service implementation): | ||
+ | <source lang="Java"> | ||
+ | import org.gcube.common.gxrest.response.inbound.GXInboundResponse; | ||
+ | import org.gcube.common.gxrest.request.GXHTTPRequest; | ||
+ | |||
+ | GXHTTPRequest request = GXHTTPRequest.newRequest("http://host:port/service/").from("GXRequestTest"); | ||
+ | |||
+ | //prepare some parameters | ||
+ | String context ="json serialization (not shown)"; | ||
+ | Map<String,String> queryParams = new WeakHashMap<>(); | ||
+ | String DEFAULT_RR_URL = "url of resource registry to contact"; | ||
+ | queryParams.put("rrURL", DEFAULT_RR_URL); | ||
+ | |||
+ | try { | ||
+ | GXInboundResponse response = request.path("context") | ||
+ | .queryParams(queryParams).withBody(context).post(); | ||
+ | } catch (Exception e) { | ||
+ | e.printStackTrace(); | ||
+ | System.err.println("Failed to send a POST request"); | ||
+ | } | ||
+ | </source> | ||
− | = | + | = GXHTTPStreamRequest = |
= GXWebTargetAdapterRequest = | = GXWebTargetAdapterRequest = | ||
Line 22: | Line 48: | ||
String context ="json serialization (not shown)"; | String context ="json serialization (not shown)"; | ||
Map<String,String> queryParams = new WeakHashMap<>(); | Map<String,String> queryParams = new WeakHashMap<>(); | ||
− | |||
String DEFAULT_RR_URL = "url of resource registry to contact"; | String DEFAULT_RR_URL = "url of resource registry to contact"; | ||
+ | queryParams.put("rrURL", DEFAULT_RR_URL); | ||
+ | |||
− | //send the request | + | //send the request to the context resource's collection |
− | GXInboundResponse response = request.path(" | + | GXInboundResponse response = request.path("context") |
.queryParams(queryParams).withEntity(Entity.entity(context, MediaType.APPLICATION_JSON)).post(); | .queryParams(queryParams).withEntity(Entity.entity(context, MediaType.APPLICATION_JSON)).post(); | ||
</source> | </source> | ||
− | == | + | == Using HTTPS == |
− | + | To send a request with HTTPS, the only difference is in the creation of the request: | |
− | + | ||
− | + | ||
<source lang="Java"> | <source lang="Java"> | ||
GXWebTargetAdapterRequest request = | GXWebTargetAdapterRequest request = | ||
− | GXWebTargetAdapterRequest. | + | GXWebTargetAdapterRequest.newHTTPSRequest("http://host:port/service/").from("GXRequestTest"); |
− | + | ||
</source> | </source> | ||
+ | Calling ''newHTTPSRequest()'' makes sure that the request will contact the service via HTTPS. | ||
== Registering JAX-RS components == | == Registering JAX-RS components == | ||
Line 64: | Line 90: | ||
A Feature is a special type of JAX-RS configuration meta-provider. Once a feature is registered, its ''configure()'' method is invoked during JAX-RS runtime configuration and bootstrapping phase allowing the feature to further configure the runtime context in which it has been registered. | A Feature is a special type of JAX-RS configuration meta-provider. Once a feature is registered, its ''configure()'' method is invoked during JAX-RS runtime configuration and bootstrapping phase allowing the feature to further configure the runtime context in which it has been registered. | ||
− | == | + | == How to integrate with the FeatherWeight Stack == |
− | + | If <code>common-jaxrs-client</code> is used to discover and call a remote service, gxRest can be integrated with the call. | |
+ | |||
+ | This example shows how to extend the <code>org.gcube.common.clients.Plugin</code> and resolve the request in the delegate: | ||
<source lang="Java"> | <source lang="Java"> | ||
− | import javax.ws.rs. | + | import javax.ws.rs.client.WebTarget; |
− | import org.gcube.common. | + | import javax.xml.transform.dom.DOMResult; |
+ | import javax.xml.ws.EndpointReference; | ||
+ | import org.gcube.common.clients.Plugin; | ||
+ | import org.gcube.common.calls.jaxrs.GcubeService; | ||
+ | import org.gcube.common.calls.jaxrs.TargetFactory; | ||
+ | import org.gcube.common.clients.config.ProxyConfig; | ||
+ | import org.gcube.common.clients.delegates.ProxyDelegate; | ||
+ | import org.gcube.common.gxrest.request.GXWebTargetAdapterRequest; | ||
− | + | import org.w3c.dom.Node; | |
− | + | public class MyPlugin extends Plugin<GXWebTargetAdapterRequest,MyClient> { | |
− | + | ||
− | + | public MyPlugin() { | |
− | + | super("species-products-discovery/gcube/service"); | |
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
} | } | ||
− | + | ||
− | + | @Override | |
− | + | public Exception convert(Exception e, ProxyConfig<?, ?> arg1) { | |
− | + | return e; | |
− | } | + | } |
− | + | ||
− | + | @Override | |
− | + | public MyPlugin newProxy(ProxyDelegate<GXWebTargetAdapterRequest> delegate) { | |
− | // | + | return new MyClient(delegate); |
+ | } | ||
+ | |||
+ | @Override | ||
+ | public GXWebTargetAdapterRequest resolve(EndpointReference epr, ProxyConfig<?, ?> config) | ||
+ | throws Exception { | ||
+ | DOMResult result = new DOMResult(); | ||
+ | epr.writeTo(result); | ||
+ | Node node =result.getNode(); | ||
+ | Node child=node.getFirstChild(); | ||
+ | String address = child.getTextContent(); | ||
+ | GXWebTargetAdapterRequest request = GXWebTargetAdapterRequest.newRequest(address); | ||
+ | //set additional path parts or parameters here | ||
+ | return request; | ||
+ | |||
} | } | ||
} | } | ||
+ | </source> | ||
+ | |||
+ | And here it is an example how to extend the Call class and delegate the call: | ||
+ | |||
+ | <source lang="Java"> | ||
+ | import org.gcube.common.clients.Call; | ||
+ | import org.gcube.common.clients.delegates.ProxyDelegate; | ||
+ | import org.gcube.common.gxrest.response.inbound.GXInboundResponse; | ||
+ | import org.gcube.common.gxrest.request.GXWebTargetAdapterRequest; | ||
+ | |||
+ | public class MyClient { | ||
+ | |||
+ | private final ProxyDelegate<GXWebTargetAdapterRequest> delegate; | ||
+ | |||
+ | public MyClient(ProxyDelegate<GXWebTargetAdapterRequest> config){ | ||
+ | this.delegate = config; | ||
+ | } | ||
+ | |||
+ | |||
+ | public void myCallMethod(final String id) | ||
+ | throws UnsupportedPluginException, UnsupportedCapabilityException, InvalidIdentifierException { | ||
+ | |||
+ | Call<GXWebTargetAdapterRequest, MultiLocatorResponse> call = new Call<GXWebTargetAdapterRequest, MultiLocatorResponse>() { | ||
+ | @Override | ||
+ | public MultiLocatorResponse call(GXWebTargetAdapterRequest manager) throws Exception { | ||
+ | GXInboundResponse response = manager.path(“children”).path(id).get(); | ||
+ | if (response.hasGXError()) { | ||
+ | //manage the error (TODO: show how to fetch and throw exceptions | ||
+ | } | ||
+ | //MultiLocatorResponse is the expected content of the response in the form of a serialized Json | ||
+ | return response.tryConvertStreamedContentFromJson(MultiLocatorResponse.class); | ||
+ | } | ||
+ | }; | ||
+ | |||
+ | //invoke the call instance | ||
+ | try { | ||
+ | MultiLocatorResponse results = delegate.make(call); | ||
+ | // consume the results | ||
+ | |||
+ | }catch(Exception e) { | ||
+ | //handle the error | ||
+ | } | ||
+ | } | ||
+ | } | ||
+ | |||
+ | </source> | ||
+ | |||
+ | = Overriding the security context = | ||
+ | By default, the security token available in the current thread is attached to the request. | ||
+ | |||
+ | However, if there is the need to force a specific token to be used, this can be done by invoking the ''setSecurityToken()'' method on the request object: | ||
+ | <source lang="Java"> | ||
+ | GXWebTargetAdapterRequest request = | ||
+ | GXWebTargetAdapterRequest.newRequest("http://host:port/service/").from("GXRequestTest"); | ||
+ | request.setSecurityToken("my token"); | ||
</source> | </source> |
Latest revision as of 01:58, 3 April 2019
Contents
Types of Requests
As of version 1.1.2, there are three types of requests in gxJRS, all implementing the GXHTTP
request interface.
Each request method returns a GXInboundResponse instance that can be consumed as explained here.
GXHTTPStringRequest
This type of request is entirely based on plain HTTP. It does not require any other software than the standard Java java.net
and java.io
packages to work.
The following snippet shows how to send a Post request to create a new resource in a collection of resources named context (the name depends on your service implementation):
import org.gcube.common.gxrest.response.inbound.GXInboundResponse; import org.gcube.common.gxrest.request.GXHTTPRequest; GXHTTPRequest request = GXHTTPRequest.newRequest("http://host:port/service/").from("GXRequestTest"); //prepare some parameters String context ="json serialization (not shown)"; Map<String,String> queryParams = new WeakHashMap<>(); String DEFAULT_RR_URL = "url of resource registry to contact"; queryParams.put("rrURL", DEFAULT_RR_URL); try { GXInboundResponse response = request.path("context") .queryParams(queryParams).withBody(context).post(); } catch (Exception e) { e.printStackTrace(); System.err.println("Failed to send a POST request"); }
GXHTTPStreamRequest
GXWebTargetAdapterRequest
This type of request is also generic but it relies on a JAX-RS runtime implementation. It dynamically loads the first WebTarget available on the classpath and uses it for modeling and sending the request. The reference implementation for JAX-RS is named Jersey, but it is not included in Java SE. If you want to use this request you must explicitly add a JAR-RS implementation to your classpath.
This is basic example that sends a Post request to create a new resource:
import org.gcube.common.gxrest.response.inbound.GXInboundResponse; import org.gcube.common.gxrest.request.GXWebTargetAdapterRequest; import javax.ws.rs.client.Entity; import javax.ws.rs.core.MediaType; //... GXWebTargetAdapterRequest request = GXWebTargetAdapterRequest.newRequest("http://host:port/service/").from("GXRequestTest"); //prepare some parameters String context ="json serialization (not shown)"; Map<String,String> queryParams = new WeakHashMap<>(); String DEFAULT_RR_URL = "url of resource registry to contact"; queryParams.put("rrURL", DEFAULT_RR_URL); //send the request to the context resource's collection GXInboundResponse response = request.path("context") .queryParams(queryParams).withEntity(Entity.entity(context, MediaType.APPLICATION_JSON)).post();
Using HTTPS
To send a request with HTTPS, the only difference is in the creation of the request:
GXWebTargetAdapterRequest request = GXWebTargetAdapterRequest.newHTTPSRequest("http://host:port/service/").from("GXRequestTest");
Calling newHTTPSRequest() makes sure that the request will contact the service via HTTPS.
Registering JAX-RS components
The following example shows how to register an instance of a custom JAX-RS component (a feature in this case) to be instantiated and used in the scope of the request:
import javax.ws.rs.core.Feature; public class MyFeature implements Feature { @Override public boolean configure(FeatureContext context) { boolean enabled = false; //decides if the feature is enabled... return enabled; } } GXWebTargetAdapterRequest request = GXWebTargetAdapterRequest.newRequest("http://host:port/service/").from("GXRequestTest"); request.register(MyFeature.class)
A Feature is a special type of JAX-RS configuration meta-provider. Once a feature is registered, its configure() method is invoked during JAX-RS runtime configuration and bootstrapping phase allowing the feature to further configure the runtime context in which it has been registered.
How to integrate with the FeatherWeight Stack
If common-jaxrs-client
is used to discover and call a remote service, gxRest can be integrated with the call.
This example shows how to extend the org.gcube.common.clients.Plugin
and resolve the request in the delegate:
import javax.ws.rs.client.WebTarget; import javax.xml.transform.dom.DOMResult; import javax.xml.ws.EndpointReference; import org.gcube.common.clients.Plugin; import org.gcube.common.calls.jaxrs.GcubeService; import org.gcube.common.calls.jaxrs.TargetFactory; import org.gcube.common.clients.config.ProxyConfig; import org.gcube.common.clients.delegates.ProxyDelegate; import org.gcube.common.gxrest.request.GXWebTargetAdapterRequest; import org.w3c.dom.Node; public class MyPlugin extends Plugin<GXWebTargetAdapterRequest,MyClient> { public MyPlugin() { super("species-products-discovery/gcube/service"); } @Override public Exception convert(Exception e, ProxyConfig<?, ?> arg1) { return e; } @Override public MyPlugin newProxy(ProxyDelegate<GXWebTargetAdapterRequest> delegate) { return new MyClient(delegate); } @Override public GXWebTargetAdapterRequest resolve(EndpointReference epr, ProxyConfig<?, ?> config) throws Exception { DOMResult result = new DOMResult(); epr.writeTo(result); Node node =result.getNode(); Node child=node.getFirstChild(); String address = child.getTextContent(); GXWebTargetAdapterRequest request = GXWebTargetAdapterRequest.newRequest(address); //set additional path parts or parameters here return request; } }
And here it is an example how to extend the Call class and delegate the call:
import org.gcube.common.clients.Call; import org.gcube.common.clients.delegates.ProxyDelegate; import org.gcube.common.gxrest.response.inbound.GXInboundResponse; import org.gcube.common.gxrest.request.GXWebTargetAdapterRequest; public class MyClient { private final ProxyDelegate<GXWebTargetAdapterRequest> delegate; public MyClient(ProxyDelegate<GXWebTargetAdapterRequest> config){ this.delegate = config; } public void myCallMethod(final String id) throws UnsupportedPluginException, UnsupportedCapabilityException, InvalidIdentifierException { Call<GXWebTargetAdapterRequest, MultiLocatorResponse> call = new Call<GXWebTargetAdapterRequest, MultiLocatorResponse>() { @Override public MultiLocatorResponse call(GXWebTargetAdapterRequest manager) throws Exception { GXInboundResponse response = manager.path(“children”).path(id).get(); if (response.hasGXError()) { //manage the error (TODO: show how to fetch and throw exceptions } //MultiLocatorResponse is the expected content of the response in the form of a serialized Json return response.tryConvertStreamedContentFromJson(MultiLocatorResponse.class); } }; //invoke the call instance try { MultiLocatorResponse results = delegate.make(call); // consume the results }catch(Exception e) { //handle the error } } }
Overriding the security context
By default, the security token available in the current thread is attached to the request.
However, if there is the need to force a specific token to be used, this can be done by invoking the setSecurityToken() method on the request object:
GXWebTargetAdapterRequest request = GXWebTargetAdapterRequest.newRequest("http://host:port/service/").from("GXRequestTest"); request.setSecurityToken("my token");