package app; import java.util.ArrayList; import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Map.Entry; import java.util.concurrent.CountDownLatch; import java.util.concurrent.TimeUnit; import java.util.logging.Logger; import javax.ws.rs.HttpMethod; import javax.ws.rs.WebApplicationException; import javax.ws.rs.client.Client; import javax.ws.rs.client.ClientBuilder; import javax.ws.rs.client.Invocation.Builder; import org.gcube.common.authorization.library.provider.AuthorizationProvider; import org.gcube.common.authorization.library.provider.UserInfo; import org.gcube.common.authorization.library.utils.Caller; import org.gcube.smartgears.extensions.HttpExtension.Method; import org.glassfish.jersey.client.ClientConfig; import org.glassfish.jersey.client.ClientResponse; import org.glassfish.jersey.logging.LoggingFeature; import utils.TestUtils; public class Request { private String path=""; private String scope = TestUtils.scope; //private OutBoundHeaders headers = new OutBoundHeaders(); private String method = HttpMethod.GET; private String body = null; private boolean logged = false; Map> headers = new HashMap<>(); public static Request request() { return new Request(); } private Request() { } public Request at(String path) { this.path=path; return this; } public Request logging() { logged=true; return this; } public Request inScope(String scope) { this.scope=scope; return this; } public Request with(String body) { this.body=body; return this; } public Request with(String name, String value) { this.headers.put(name, Collections.singletonList(value)); return this; } public Request using(Method method) { this.method=method.getValue(); return this; } public String path() { return path; } public String body() { return body; } public String method() { return method; } public String scope() { return scope; } ClientResponse make(final int port) { // we make a scoped call in a separate thread, with which we then synchronize for completion. // this helps isolate the caller's thread (Main normally) from the app's thread, // starting with the scope itself. final CountDownLatch latch = new CountDownLatch(1); class Box { volatile WebApplicationException failure; volatile ClientResponse response; } final Box box = new Box(); new Thread() { public void run() { AuthorizationProvider.instance.set(new Caller(new UserInfo("test", new ArrayList()),"DEFAULT")); try { ClientConfig config = new ClientConfig(); Client client = ClientBuilder.newClient(); if (logged) client.register(new LoggingFeature(Logger.getLogger(getClass().getName()))); Builder builder = client.target(address(path,port)).request(); builder.header("gcube-scope", scope); for (Entry> header : headers.entrySet()) for (Object value : header.getValue()) builder.header(header.getKey(), value); if (method.equals(HttpMethod.DELETE)) builder.delete(); else { System.err.println("making request @ "+address(path,port)); ClientResponse response = builder.method(method,ClientResponse.class); //throws an exception if there response has error status if (response.getStatus()>300) throw new WebApplicationException(response.getStatus()); box.response=response; } } catch (WebApplicationException t) { box.failure=t; } latch.countDown(); }; }.start(); try { if (!latch.await(2000, TimeUnit.MILLISECONDS)) throw new RuntimeException("application has not responded in time"); } catch (InterruptedException e) { throw new RuntimeException(e); } if (box.failure !=null) throw box.failure; else return box.response; } private String address(String path, long port) { path = (path.isEmpty() || path.startsWith("/"))?path:"/"+path; return "http://localhost:" + port+ "/" + TestUtils.context_root+path; } }