diff options
author | Bjørn Christian Seime <bjorncs@verizonmedia.com> | 2019-10-11 17:09:53 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2019-10-11 17:09:53 +0200 |
commit | 82241ec5eb67ac74b0909c264060f4f519006227 (patch) | |
tree | 52b3610c00dab080df1bf693cdf8340bbd95a923 | |
parent | 27d03fe0b6a1c31d9e89e91af623b7311902afa9 (diff) | |
parent | d31f043b3cca1a97dc5fb8b81b85c485667c28cf (diff) |
Merge pull request #10964 from vespa-engine/bjorncs/cleanup
Remove dead code
23 files changed, 3 insertions, 1618 deletions
diff --git a/clustercontroller-apputil/pom.xml b/clustercontroller-apputil/pom.xml index 20c0c0df8d2..c8190c1a1ac 100644 --- a/clustercontroller-apputil/pom.xml +++ b/clustercontroller-apputil/pom.xml @@ -18,10 +18,6 @@ <scope>test</scope> </dependency> <dependency> - <groupId>org.apache.httpcomponents</groupId> - <artifactId>httpclient</artifactId> - </dependency> - <dependency> <groupId>com.yahoo.vespa</groupId> <artifactId>annotations</artifactId> <version>${project.version}</version> diff --git a/clustercontroller-apputil/src/main/java/com/yahoo/vespa/clustercontroller/apputil/communication/http/ApacheAsyncHttpClient.java b/clustercontroller-apputil/src/main/java/com/yahoo/vespa/clustercontroller/apputil/communication/http/ApacheAsyncHttpClient.java deleted file mode 100644 index 11d746ef3ce..00000000000 --- a/clustercontroller-apputil/src/main/java/com/yahoo/vespa/clustercontroller/apputil/communication/http/ApacheAsyncHttpClient.java +++ /dev/null @@ -1,183 +0,0 @@ -// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. -package com.yahoo.vespa.clustercontroller.apputil.communication.http; - -import com.yahoo.vespa.clustercontroller.utils.communication.async.AsyncOperation; -import com.yahoo.vespa.clustercontroller.utils.communication.async.AsyncOperationImpl; -import com.yahoo.vespa.clustercontroller.utils.communication.http.AsyncHttpClient; -import com.yahoo.vespa.clustercontroller.utils.communication.http.HttpRequest; -import com.yahoo.vespa.clustercontroller.utils.communication.http.HttpResult; -import com.yahoo.vespa.clustercontroller.utils.communication.http.SyncHttpClient; - -import java.util.*; -import java.util.concurrent.Executor; -import java.util.logging.Logger; - -/** - * There are some stuff to work around with the apache client. - * - Whether to use a proxy or not is global, not per request. - * - Timeout is not handled per request (and is not a request timeout but seems like a "something happening on TCP" timeout. - * - It is not thread safe. - * - * This class gets around these issues by creating one instance per unique setting, and ensuring only one request use a given instance at a time. - */ -public class ApacheAsyncHttpClient implements AsyncHttpClient<HttpResult> { - - private static final Logger log = Logger.getLogger(ApacheAsyncHttpClient.class.getName()); - - public interface SyncHttpClientFactory { - SyncHttpClient createInstance(String proxyHost, int proxyPort, long timeoutMs); - } - - public static class Settings { - String proxyHost; - int proxyPort; - long timeout; - - Settings(HttpRequest request) { - timeout = request.getTimeoutMillis(); - if (request.getPath() != null - && !request.getPath().isEmpty() - && request.getPath().charAt(0) != '/') - { - proxyHost = request.getHost(); - proxyPort = request.getPort(); - int colo = request.getPath().indexOf(':'); - int slash = request.getPath().indexOf('/', colo); - if (colo < 0 && slash < 0) { - throw new IllegalStateException("Http path '" + request.getPath() + "' looks invalid. " - + "Cannot extract proxy server data. Is it a regular request that " - + "should start with a slash?"); - } - if (colo < 0) { - request.setPort(80); - request.setHost(request.getPath().substring(0, slash)); - } else { - request.setHost(request.getPath().substring(0, colo)); - request.setPort(Integer.valueOf(request.getPath().substring(colo + 1, slash))); - } - request.setPath(request.getPath().substring(slash)); - } - } - - @Override - public boolean equals(Object other) { - Settings o = (Settings) other; - if (timeout != o.timeout || proxyPort != o.proxyPort - || (proxyHost == null ^ o.proxyHost == null) - || (proxyHost != null && !proxyHost.equals(o.proxyHost))) - { - return false; - } - return true; - } - - @Override - public int hashCode() { - return (proxyHost == null ? 0 : proxyHost.hashCode()) ^ proxyPort ^ Long.valueOf(timeout).hashCode(); - } - } - private final Executor executor; - private final SyncHttpClientFactory clientFactory; - private boolean closed = false; - private final int maxInstanceCacheSize; // Maximum number of currently unused instances. - private final Map<Settings, LinkedList<SyncHttpClient>> apacheInstances = new LinkedHashMap<Settings, LinkedList<SyncHttpClient>>() { - protected @Override boolean removeEldestEntry(Map.Entry<Settings,LinkedList<SyncHttpClient>> eldest) { - return getUnusedCacheSize() > maxInstanceCacheSize; - } - }; - - public ApacheAsyncHttpClient(Executor executor) { - this(executor, new SyncHttpClientFactory() { - @Override - public SyncHttpClient createInstance(String proxyHost, int proxyPort, long timeoutMs) { - return new ApacheHttpInstance(proxyHost, proxyPort, timeoutMs); - } - }); - } - - public ApacheAsyncHttpClient(Executor executor, SyncHttpClientFactory clientFactory) { - this.executor = executor; - this.clientFactory = clientFactory; - maxInstanceCacheSize = 16; - log.fine("Starting apache com.yahoo.vespa.clustercontroller.utils.communication.async HTTP client"); - } - - private SyncHttpClient getFittingInstance(Settings settings) { - synchronized (apacheInstances) { - if (closed) throw new IllegalStateException("Http client has been closed for business."); - LinkedList<SyncHttpClient> fittingInstances = apacheInstances.get(settings); - if (fittingInstances == null) { - fittingInstances = new LinkedList<>(); - apacheInstances.put(settings, fittingInstances); - } - if (fittingInstances.isEmpty()) { - return clientFactory.createInstance(settings.proxyHost, settings.proxyPort, settings.timeout); - } else { - return fittingInstances.removeFirst(); - } - } - } - private void insertInstance(Settings settings, SyncHttpClient instance) { - synchronized (apacheInstances) { - LinkedList<SyncHttpClient> fittingInstances = apacheInstances.get(settings); - if (closed || fittingInstances == null) { - instance.close(); - return; - } - fittingInstances.addLast(instance); - } - } - private int getUnusedCacheSize() { - int size = 0; - synchronized (apacheInstances) { - for (LinkedList<SyncHttpClient> list : apacheInstances.values()) { - size += list.size(); - } - } - return size; - } - - @Override - public AsyncOperation<HttpResult> execute(HttpRequest r) { - final HttpRequest request = r.clone(); // Gonna modify it to extract proxy information - final Settings settings = new Settings(request); - final SyncHttpClient instance = getFittingInstance(settings); - final AsyncOperationImpl<HttpResult> op = new AsyncOperationImpl<>(r.toString(), r.toString(true)); - executor.execute(new Runnable() { - @Override - public void run() { - HttpResult result; - Exception failure = null; - try{ - result = instance.execute(request); - } catch (Exception e) { - result = new HttpResult().setHttpCode(500, "Apache client failed to execute request."); - failure = e; - } - insertInstance(settings, instance); - // Must insert back instance before tagging operation complete to ensure a following - // call can reuse same instance - if (failure != null) { - op.setFailure(failure, result); - } else { - op.setResult(result); - } - } - }); - return op; - } - - @Override - public void close() { - synchronized (apacheInstances) { - closed = true; - for (LinkedList<SyncHttpClient> list : apacheInstances.values()) { - for (SyncHttpClient instance : list) { - instance.close(); - } - } - apacheInstances.clear(); - } - } - -} diff --git a/clustercontroller-apputil/src/main/java/com/yahoo/vespa/clustercontroller/apputil/communication/http/ApacheHttpInstance.java b/clustercontroller-apputil/src/main/java/com/yahoo/vespa/clustercontroller/apputil/communication/http/ApacheHttpInstance.java deleted file mode 100644 index 3eafd2ae1d5..00000000000 --- a/clustercontroller-apputil/src/main/java/com/yahoo/vespa/clustercontroller/apputil/communication/http/ApacheHttpInstance.java +++ /dev/null @@ -1,133 +0,0 @@ -// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. -package com.yahoo.vespa.clustercontroller.apputil.communication.http; - -import com.yahoo.vespa.clustercontroller.utils.communication.http.HttpRequest; -import com.yahoo.vespa.clustercontroller.utils.communication.http.HttpResult; -import com.yahoo.vespa.clustercontroller.utils.communication.http.SyncHttpClient; -import org.apache.http.Header; -import org.apache.http.HttpEntity; -import org.apache.http.HttpHost; -import org.apache.http.HttpResponse; -import org.apache.http.client.methods.HttpDelete; -import org.apache.http.client.methods.HttpGet; -import org.apache.http.client.methods.HttpPost; -import org.apache.http.client.methods.HttpPut; -import org.apache.http.entity.StringEntity; -import org.apache.http.util.EntityUtils; - -import java.io.PrintWriter; -import java.io.StringWriter; -import java.util.logging.Logger; - -// NOTE: these are all deprecated: -import org.apache.http.conn.params.ConnRoutePNames; -import org.apache.http.impl.client.DefaultHttpClient; -import org.apache.http.params.BasicHttpParams; -import org.apache.http.params.HttpConnectionParams; -import org.apache.http.params.HttpParams; - -/** - * Synchronous http client using Apache commons. - */ -public class ApacheHttpInstance implements SyncHttpClient { - - private static final Logger log = Logger.getLogger(ApacheHttpInstance.class.getName()); - DefaultHttpClient client; - - public ApacheHttpInstance(String proxyHost, int proxyPort, long timeoutMs) { - if (timeoutMs > Integer.MAX_VALUE) throw new IllegalArgumentException("Cannot handle timeout not contained in an integer"); - HttpParams httpParams = new BasicHttpParams(); - HttpConnectionParams.setConnectionTimeout(httpParams, (int) timeoutMs); - HttpConnectionParams.setSoTimeout(httpParams, (int) timeoutMs); - - if (proxyHost != null && !proxyHost.isEmpty()) { - httpParams.setParameter(ConnRoutePNames.DEFAULT_PROXY, new HttpHost(proxyHost, proxyPort, "http")); - } - - client = new DefaultHttpClient(httpParams); - } - - /** This function is not threadsafe. */ - public HttpResult execute(HttpRequest r) { - HttpRequest.HttpOp op = r.getHttpOperation(); - if (op == null) { - if (r.getPostContent() != null) { - log.fine("Request " + r + " has no HTTP function specified. Assuming POST as post content is set."); - op = HttpRequest.HttpOp.POST; - } else { - log.fine("Request " + r + " has no HTTP function specified. Assuming GET as post content is set."); - op = HttpRequest.HttpOp.GET; - } - } - if (r.getPostContent() != null - && !(op.equals(HttpRequest.HttpOp.POST) || op.equals(HttpRequest.HttpOp.PUT))) - { - throw new IllegalStateException("A " + op + " operation can't have content"); - } - try { - HttpHost target = new HttpHost(r.getHost(), r.getPort(), "http"); - org.apache.http.HttpRequest req = null; - - String path = r.getPath(); - int uriOption = 0; - for (HttpRequest.KeyValuePair option : r.getUrlOptions()) { - path += (++uriOption == 1 ? '?' : '&'); - path += option.getKey() + '=' + option.getValue(); - } - - switch (op) { - case POST: - HttpPost post = new HttpPost(path); - if (r.getPostContent() != null) { - post.setEntity(new StringEntity(r.getPostContent().toString())); - } - req = post; - break; - case GET: - req = new HttpGet(path); - break; - case PUT: - HttpPut put = new HttpPut(path); - put.setEntity(new StringEntity(r.getPostContent().toString())); - req = put; - break; - case DELETE: - req = new HttpDelete(path); - break; - } - - for (HttpRequest.KeyValuePair header : r.getHeaders()) { - req.addHeader(header.getKey(), header.getValue()); - } - - HttpResponse rsp = client.execute(target, req); - HttpEntity entity = rsp.getEntity(); - - HttpResult result = new HttpResult(); - result.setHttpCode(rsp.getStatusLine().getStatusCode(), rsp.getStatusLine().getReasonPhrase()); - - if (entity != null) { - result.setContent(EntityUtils.toString(entity)); - } - for (Header header : rsp.getAllHeaders()) { - result.addHeader(header.getName(), header.getValue()); - } - - return result; - } catch (Exception e) { - HttpResult result = new HttpResult(); - - StringWriter writer = new StringWriter(); - e.printStackTrace(new PrintWriter(writer)); - writer.flush(); - - result.setHttpCode(500, "Got exception " + writer.toString() + " when sending message."); - return result; - } - } - - public void close() { - client.getConnectionManager().shutdown(); - } - -} diff --git a/clustercontroller-apputil/src/test/java/com/yahoo/vespa/clustercontroller/apputil/communication/http/ApacheAsyncHttpClientTest.java b/clustercontroller-apputil/src/test/java/com/yahoo/vespa/clustercontroller/apputil/communication/http/ApacheAsyncHttpClientTest.java deleted file mode 100644 index c3909e50f0e..00000000000 --- a/clustercontroller-apputil/src/test/java/com/yahoo/vespa/clustercontroller/apputil/communication/http/ApacheAsyncHttpClientTest.java +++ /dev/null @@ -1,239 +0,0 @@ -// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. -package com.yahoo.vespa.clustercontroller.apputil.communication.http; - -import com.yahoo.vespa.clustercontroller.utils.communication.async.AsyncOperation; -import com.yahoo.vespa.clustercontroller.utils.communication.async.AsyncUtils; -import com.yahoo.vespa.clustercontroller.utils.communication.http.*; - -import java.util.LinkedList; -import java.util.concurrent.ArrayBlockingQueue; -import java.util.concurrent.Executor; -import java.util.concurrent.ThreadPoolExecutor; -import java.util.concurrent.TimeUnit; - -import org.junit.After; -import org.junit.Before; -import org.junit.Test; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertTrue; - -public class ApacheAsyncHttpClientTest { - - public static class Server { - public class Request { - HttpRequest request; - Object result; - String proxyHost; - int proxyPort; - long timeoutMs; - - public Request(HttpRequest r, String proxyHost, int proxyPort, long timeoutMs) { - request = r; - this.proxyHost = proxyHost; - this.proxyPort = proxyPort; - this.timeoutMs = timeoutMs; - } - - public void answer(Object result) { - synchronized (requests) { - this.result = result; - requests.notifyAll(); - } - } - } - public final LinkedList<Request> requests = new LinkedList<>(); - - public Request createRequest(HttpRequest r, String proxyHost, int proxyPort, long timeoutMs) { - return new Request(r, proxyHost, proxyPort, timeoutMs); - } - - public Request waitForRequest() { - synchronized (requests) { - while (true) { - if (!requests.isEmpty()) { - return requests.removeFirst(); - } - try{ requests.wait(); } catch (InterruptedException e) {} - } - } - } - } - - private Server server = new Server(); - private int clientCount = 0; - - public class Client implements SyncHttpClient { - String proxyHost; - int proxyPort; - long timeoutMs; - private boolean running = true; - - public Client(String proxyHost, int proxyPort, long timeoutMs) { - this.proxyHost = proxyHost; - this.proxyPort = proxyPort; - this.timeoutMs = timeoutMs; - } - - @Override - public HttpResult execute(HttpRequest r) { - synchronized (server.requests) { - Server.Request pair = server.createRequest(r, proxyHost, proxyPort, timeoutMs); - server.requests.addLast(pair); - server.requests.notifyAll(); - while (running) { - try{ server.requests.wait(); } catch (InterruptedException e) {} - if (pair.result != null) { - if (pair.result instanceof HttpResult) { - return (HttpResult) pair.result; - } else { - throw new RuntimeException((Exception) pair.result); - } - } else { - } - } - } - return new HttpResult().setHttpCode(500, "Shutting down"); - } - - @Override - public void close() { - synchronized (server.requests) { - running = false; - server.requests.notifyAll(); - } - } - } - - public class ClientFactory implements ApacheAsyncHttpClient.SyncHttpClientFactory { - @Override - public SyncHttpClient createInstance(String proxyHost, int proxyPort, long timeoutMs) { - ++clientCount; - return new Client(proxyHost, proxyPort, timeoutMs); - } - } - - private Executor executor; - - @Before - public void setUp() { - executor = new ThreadPoolExecutor(10, 100, 100, TimeUnit.SECONDS, new ArrayBlockingQueue<Runnable>(1000)); - } - - @Test - public void testOneInstancePerUniqueSettings() { - HttpResult result = new HttpResult().setHttpCode(201, "This worked out good"); - ApacheAsyncHttpClient client = new ApacheAsyncHttpClient(executor, new ClientFactory()); - ProxyAsyncHttpClient<HttpResult> proxyClient = new ProxyAsyncHttpClient<>(client, "proxy", 8080); - - // A first request - HttpRequest req = new HttpRequest().setHost("www.yahoo.com").setPath("/foo").setTimeout(400); - AsyncOperation<HttpResult> op = proxyClient.execute(req); - Server.Request r = server.waitForRequest(); - assertEquals(r.request.toString(true), "proxy", r.proxyHost); - assertEquals(r.request.toString(true), 8080, r.proxyPort); - assertEquals(r.request.toString(true), 80, r.request.getPort()); - assertEquals(r.request.toString(true), "www.yahoo.com", r.request.getHost()); - assertEquals(400, r.request.getTimeoutMillis()); - r.answer(result); - AsyncUtils.waitFor(op); - assertTrue(op.isDone()); - assertTrue(op.isSuccess()); - assertEquals(result, op.getResult()); - assertEquals(1, clientCount); - - // A second request should reuse first instance - op = proxyClient.execute(req.clone()); - r = server.waitForRequest(); - r.answer(result); - AsyncUtils.waitFor(op); - assertEquals(1, clientCount); - - // Altering timeout create a new one - op = proxyClient.execute(req.clone().setTimeout(800)); - r = server.waitForRequest(); - assertEquals(800, r.request.getTimeoutMillis()); - r.answer(result); - AsyncUtils.waitFor(op); - assertEquals(2, clientCount); - - // And altering proxy will create a new one - ProxyAsyncHttpClient<HttpResult> proxyClient2 = new ProxyAsyncHttpClient<>(client, "proxy2", 8080); - op = proxyClient2.execute(req.clone()); - r = server.waitForRequest(); - assertEquals(r.request.toString(true), "proxy2", r.proxyHost); - r.answer(result); - AsyncUtils.waitFor(op); - assertEquals(3, clientCount); - - // And the old ones are still cached, even if port now is specified - op = proxyClient.execute(req.clone().setPort(80)); - r = server.waitForRequest(); - assertEquals(r.request.toString(true), "proxy", r.proxyHost); - assertEquals(r.request.toString(true), 8080, r.proxyPort); - assertEquals(r.request.toString(true), 80, r.request.getPort()); - assertEquals(r.request.toString(true), "www.yahoo.com", r.request.getHost()); - assertEquals(400, r.request.getTimeoutMillis()); - r.answer(result); - AsyncUtils.waitFor(op); - assertEquals(3, clientCount); - - client.close(); - } - - @Test - public void testFailingRequest() { - ApacheAsyncHttpClient client = new ApacheAsyncHttpClient(executor, new ClientFactory()); - HttpRequest req = new HttpRequest(); - AsyncOperation<HttpResult> op = client.execute(req); - Server.Request r = server.waitForRequest(); - r.answer(new IllegalStateException("Failed to run")); - AsyncUtils.waitFor(op); - assertEquals(false, op.isSuccess()); - assertTrue(op.getCause().getMessage(), op.getCause().getMessage().contains("Failed to run")); - } - - @Test - public void testClose() { - ApacheAsyncHttpClient client = new ApacheAsyncHttpClient(executor, new ClientFactory()); - HttpRequest req = new HttpRequest(); - AsyncOperation<HttpResult> op = client.execute(req); - Server.Request r = server.waitForRequest(); - client.close(); - r.answer(new HttpResult()); - AsyncUtils.waitFor(op); - assertEquals(true, op.isSuccess()); - - try{ - client.execute(req); - assertTrue(false); - } catch (IllegalStateException e) { - assertTrue(e.getMessage(), e.getMessage().contains("Http client has been closed")); - } - } - - @Test - public void testInvalidProxyRequest() { - ApacheAsyncHttpClient client = new ApacheAsyncHttpClient(executor, new ClientFactory()); - HttpRequest req = new HttpRequest().setPath("foo"); - try{ - client.execute(req); - assertTrue(false); - } catch (IllegalStateException e) { - assertTrue(e.getMessage(), e.getMessage().contains("looks invalid")); - } - } - - @Test - public void testNothingButGetCoverage() { - // There is never any hash conflict for equals to be false in actual use - HttpRequest r = new HttpRequest(); - new ApacheAsyncHttpClient.Settings(r.clone().setTimeout(15)) - .equals(new ApacheAsyncHttpClient.Settings(r)); - // Only actual container is meant to use this constructor - ApacheAsyncHttpClient client = new ApacheAsyncHttpClient(executor); - client.execute(new HttpRequest()); - client.close(); - } - -} diff --git a/clustercontroller-utils/src/main/java/com/yahoo/vespa/clustercontroller/utils/communication/http/AsyncHttpClientWithBase.java b/clustercontroller-utils/src/main/java/com/yahoo/vespa/clustercontroller/utils/communication/http/AsyncHttpClientWithBase.java deleted file mode 100644 index d824303df57..00000000000 --- a/clustercontroller-utils/src/main/java/com/yahoo/vespa/clustercontroller/utils/communication/http/AsyncHttpClientWithBase.java +++ /dev/null @@ -1,39 +0,0 @@ -// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. -package com.yahoo.vespa.clustercontroller.utils.communication.http; - -import com.yahoo.vespa.clustercontroller.utils.communication.async.AsyncOperation; - -public class AsyncHttpClientWithBase<V extends HttpResult> implements AsyncHttpClient<V> { - - protected final AsyncHttpClient<V> client; - private HttpRequest baseRequest = new HttpRequest(); - - public AsyncHttpClientWithBase(AsyncHttpClient<V> client) { - if (client == null) throw new IllegalArgumentException("HTTP client must be set."); - this.client = client; - } - - /** - * If all your http requests have common features you want to set once, you can provide those values in a base - * request. For instance, if you specify a host and a port using this function, all your requests will use that - * host and port unless specified in the request you execute. - */ - public void setHttpRequestBase(HttpRequest r) { - this.baseRequest = (r == null ? new HttpRequest() : r.clone()); - } - - public HttpRequest getHttpRequestBase() { - return baseRequest; - } - - @Override - public AsyncOperation<V> execute(HttpRequest r) { - return client.execute(baseRequest.merge(r)); - } - - @Override - public void close() { - client.close(); - } - -} diff --git a/clustercontroller-utils/src/main/java/com/yahoo/vespa/clustercontroller/utils/communication/http/JsonAsyncHttpClient.java b/clustercontroller-utils/src/main/java/com/yahoo/vespa/clustercontroller/utils/communication/http/JsonAsyncHttpClient.java deleted file mode 100644 index dac4decc1ee..00000000000 --- a/clustercontroller-utils/src/main/java/com/yahoo/vespa/clustercontroller/utils/communication/http/JsonAsyncHttpClient.java +++ /dev/null @@ -1,59 +0,0 @@ -// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. -package com.yahoo.vespa.clustercontroller.utils.communication.http; - -import com.yahoo.vespa.clustercontroller.utils.communication.async.AsyncOperation; -import com.yahoo.vespa.clustercontroller.utils.communication.async.RedirectedAsyncOperation; -import org.codehaus.jettison.json.JSONException; -import org.codehaus.jettison.json.JSONObject; - -/** - * Wrapped for the HTTP client, converting requests to/from JSON. - */ -public class JsonAsyncHttpClient implements AsyncHttpClient<JsonHttpResult> { - - private AsyncHttpClient<HttpResult> client; - private boolean verifyRequestContentAsJson = true; - private boolean addJsonContentType = true; - - public JsonAsyncHttpClient(AsyncHttpClient<HttpResult> client) { - this.client = client; - } - - public JsonAsyncHttpClient verifyRequestContentAsJson(boolean doIt) { - verifyRequestContentAsJson = doIt; - return this; - } - - public JsonAsyncHttpClient addJsonContentType(boolean doIt) { - addJsonContentType = doIt; - return this; - } - - public AsyncOperation<JsonHttpResult> execute(HttpRequest r) { - if (verifyRequestContentAsJson) { - if (r.getPostContent() != null && !(r.getPostContent() instanceof JSONObject)) { - try{ - r = r.clone().setPostContent(new JSONObject(r.getPostContent().toString())); - } catch (JSONException e) { - throw new IllegalArgumentException(e); - } - } - } - if (addJsonContentType && r.getPostContent() != null) { - r = r.clone().addHttpHeader("Content-Type", "application/json"); - } - final AsyncOperation<HttpResult> op = client.execute(r); - return new RedirectedAsyncOperation<HttpResult, JsonHttpResult>(op) { - @Override - public JsonHttpResult getResult() { - return (op.getResult() == null ? null : new JsonHttpResult(op.getResult())); - } - }; - } - - @Override - public void close() { - client.close(); - } - -} diff --git a/clustercontroller-utils/src/main/java/com/yahoo/vespa/clustercontroller/utils/communication/http/LoggingAsyncHttpClient.java b/clustercontroller-utils/src/main/java/com/yahoo/vespa/clustercontroller/utils/communication/http/LoggingAsyncHttpClient.java deleted file mode 100644 index 2d967223f9e..00000000000 --- a/clustercontroller-utils/src/main/java/com/yahoo/vespa/clustercontroller/utils/communication/http/LoggingAsyncHttpClient.java +++ /dev/null @@ -1,43 +0,0 @@ -// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. -package com.yahoo.vespa.clustercontroller.utils.communication.http; - -import com.yahoo.vespa.clustercontroller.utils.communication.async.AsyncOperation; -import com.yahoo.vespa.clustercontroller.utils.communication.async.PipedAsyncOperation; - -import java.io.PrintWriter; -import java.io.StringWriter; -import java.util.logging.Level; -import java.util.logging.Logger; - -public class LoggingAsyncHttpClient<T extends HttpResult> extends AsyncHttpClientWithBase<T> { - - private static final Logger log = Logger.getLogger(LoggingAsyncHttpClient.class.getName()); - private int requestCounter = 0; - - public LoggingAsyncHttpClient(AsyncHttpClient<T> client) { - super(client); - log.info("Logging HTTP requests if fine logging level is added"); - } - - public AsyncOperation<T> execute(HttpRequest r) { - final int requestCount = ++requestCounter; - log.fine("Issuing HTTP request " + requestCount + ": " + r.toString(true)); - final AsyncOperation<T> op = client.execute(r); - return new PipedAsyncOperation<T, T>(op) { - @Override - public T convertResult(T result) { - if (log.isLoggable(Level.FINE)) { - if (op.isSuccess()) { - log.fine("HTTP request " + requestCount + " completed: " + result.toString(true)); - } else { - StringWriter sw = new StringWriter(); - op.getCause().printStackTrace(new PrintWriter(sw)); - log.fine("HTTP request " + requestCount + " failed: " + sw); - } - } - return result; - } - }; - } - -} diff --git a/clustercontroller-utils/src/main/java/com/yahoo/vespa/clustercontroller/utils/communication/http/ProxyAsyncHttpClient.java b/clustercontroller-utils/src/main/java/com/yahoo/vespa/clustercontroller/utils/communication/http/ProxyAsyncHttpClient.java deleted file mode 100644 index 3d6658ae366..00000000000 --- a/clustercontroller-utils/src/main/java/com/yahoo/vespa/clustercontroller/utils/communication/http/ProxyAsyncHttpClient.java +++ /dev/null @@ -1,30 +0,0 @@ -// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. -package com.yahoo.vespa.clustercontroller.utils.communication.http; - -import com.yahoo.vespa.clustercontroller.utils.communication.async.AsyncOperation; - -public class ProxyAsyncHttpClient<V extends HttpResult> extends AsyncHttpClientWithBase<V> { - - private final String proxyHost; - private final int proxyPort; - - public ProxyAsyncHttpClient(AsyncHttpClient<V> client, String proxyHost, int proxyPort) { - super(client); - this.proxyHost = proxyHost; - this.proxyPort = proxyPort; - } - - @Override - public AsyncOperation<V> execute(HttpRequest r) { - r = getHttpRequestBase().merge(r); - if (r.getHost() == null || r.getPath() == null) { - throw new IllegalStateException("Host and path must be set prior to being able to proxy an HTTP request"); - } - StringBuilder path = new StringBuilder().append(r.getHost()); - if (r.getPort() != 0) path.append(':').append(r.getPort()); - if (r.getPath().isEmpty() || r.getPath().charAt(0) != '/') path.append('/'); - path.append(r.getPath()); - return client.execute(r.setHost(proxyHost).setPort(proxyPort).setPath(path.toString())); - } - -} diff --git a/clustercontroller-utils/src/main/java/com/yahoo/vespa/clustercontroller/utils/communication/http/RequestQueue.java b/clustercontroller-utils/src/main/java/com/yahoo/vespa/clustercontroller/utils/communication/http/RequestQueue.java deleted file mode 100644 index 2a3af5724ab..00000000000 --- a/clustercontroller-utils/src/main/java/com/yahoo/vespa/clustercontroller/utils/communication/http/RequestQueue.java +++ /dev/null @@ -1,87 +0,0 @@ -// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. -package com.yahoo.vespa.clustercontroller.utils.communication.http; - -import com.yahoo.vespa.clustercontroller.utils.communication.async.AsyncCallback; -import com.yahoo.vespa.clustercontroller.utils.communication.async.AsyncOperation; - -import java.util.LinkedList; -import java.util.logging.Logger; - -/** - * Utility class to schedule HTTP requests and keeping a maximum amount of them pending at a time. - */ -public class RequestQueue<V extends HttpResult> { - - private static final Logger log = Logger.getLogger(RequestQueue.class.getName()); - private final AsyncHttpClient<V> httpClient; - private final LinkedList<Request<V>> requestQueue = new LinkedList<>(); - private final int maxPendingRequests; - private int pendingRequests = 0; - - public RequestQueue(AsyncHttpClient<V> httpClient, int maxPendingRequests) { - this.httpClient = httpClient; - this.maxPendingRequests = maxPendingRequests; - } - - public boolean empty() { - synchronized (requestQueue) { - return (requestQueue.isEmpty() && pendingRequests == 0); - } - } - - public void waitUntilEmpty() throws InterruptedException { - synchronized (requestQueue) { - while (!empty()) { - requestQueue.wait(); - } - } - } - - public void schedule(HttpRequest request, AsyncCallback<V> callback) { - log.fine("Scheduling " + request + " call"); - synchronized (requestQueue) { - requestQueue.addLast(new Request<>(request, callback)); - sendMore(); - } - } - - private void sendMore() { - while (pendingRequests < maxPendingRequests && !requestQueue.isEmpty()) { - Request<V> call = requestQueue.removeFirst(); - log.fine("Sending " + call.getRequest() + "."); - ++pendingRequests; - AsyncOperation<V> op = httpClient.execute(call.getRequest()); - op.register(call); - } - } - - private class Request<V extends HttpResult> implements AsyncCallback<V> { - private final HttpRequest request; - private final AsyncCallback<V> callback; - - Request(HttpRequest request, AsyncCallback<V> callback) { - this.request = request; - this.callback = callback; - } - - public HttpRequest getRequest() { return request; } - - @Override - public void done(AsyncOperation<V> op) { - if (op.isSuccess()) { - log.fine("Operation " + op.getName() + " completed successfully"); - } else { - log.fine("Operation " + op.getName() + " failed: " + op.getCause()); - } - synchronized (requestQueue) { - --pendingRequests; - } - callback.done(op); - synchronized (requestQueue) { - requestQueue.notifyAll(); - sendMore(); - } - } - } - -} diff --git a/clustercontroller-utils/src/main/java/com/yahoo/vespa/clustercontroller/utils/communication/http/SyncHttpClient.java b/clustercontroller-utils/src/main/java/com/yahoo/vespa/clustercontroller/utils/communication/http/SyncHttpClient.java deleted file mode 100644 index b8890550dc6..00000000000 --- a/clustercontroller-utils/src/main/java/com/yahoo/vespa/clustercontroller/utils/communication/http/SyncHttpClient.java +++ /dev/null @@ -1,11 +0,0 @@ -// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. -package com.yahoo.vespa.clustercontroller.utils.communication.http; - -public interface SyncHttpClient { - - HttpResult execute(HttpRequest r); - - /** Attempt to cancel all pending operations and shut down the client. */ - void close(); - -} diff --git a/clustercontroller-utils/src/main/java/com/yahoo/vespa/clustercontroller/utils/communication/http/TimeoutHandler.java b/clustercontroller-utils/src/main/java/com/yahoo/vespa/clustercontroller/utils/communication/http/TimeoutHandler.java deleted file mode 100644 index eae7e15541b..00000000000 --- a/clustercontroller-utils/src/main/java/com/yahoo/vespa/clustercontroller/utils/communication/http/TimeoutHandler.java +++ /dev/null @@ -1,151 +0,0 @@ -// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. -package com.yahoo.vespa.clustercontroller.utils.communication.http; - -import com.yahoo.vespa.clustercontroller.utils.communication.async.AsyncCallback; -import com.yahoo.vespa.clustercontroller.utils.communication.async.AsyncOperation; -import com.yahoo.vespa.clustercontroller.utils.communication.async.AsyncOperationImpl; -import com.yahoo.vespa.clustercontroller.utils.util.Clock; - -import java.util.*; -import java.util.concurrent.Executor; -import java.util.concurrent.TimeoutException; -import java.util.logging.Logger; - -public class TimeoutHandler<V extends HttpResult> extends AsyncHttpClientWithBase<V> { - - public static class InternalRequest<V extends HttpResult> extends AsyncOperationImpl<V> { - final AsyncOperation<V> operation; - long startTime; - long timeout; - - public InternalRequest(AsyncOperation<V> op, long startTime, long timeout) { - super(op.getName(), op.getDescription()); - this.operation = op; - this.startTime = startTime; - this.timeout = timeout; - op.register(new AsyncCallback<V>() { - @Override - public void done(AsyncOperation<V> op) { - if (!isDone()) { - if (op.isSuccess()) { - setResult(op.getResult()); - } else { - setFailure(op.getCause(), op.getResult()); - } - } - } - }); - } - - public long getTimeoutTime() { return startTime + timeout; } - - public void handleTimeout(long currentTime) { - long timePassed = currentTime - startTime; - this.setFailure(new TimeoutException("Operation timeout. " + timePassed + " ms since operation was issued. Timeout was " + timeout + " ms.")); - operation.cancel(); - } - - @Override - public boolean cancel() { return operation.cancel(); } - @Override - public boolean isCanceled() { return operation.isCanceled(); } - @Override - public Double getProgress() { return (isDone() ? Double.valueOf(1.0) : operation.getProgress()); } - } - - public static class ChangeLogger { - private InternalRequest lastTimeoutLogged = null; - private boolean emptyLogged = true; - - public void logChanges(TreeMap<Long, InternalRequest> requests) { - if (requests.isEmpty()) { - if (!emptyLogged) { - log.finest("No more pending requests currently."); - emptyLogged = true; - } - } else { - emptyLogged = false; - InternalRequest r = requests.firstEntry().getValue(); - if (lastTimeoutLogged == null || !lastTimeoutLogged.equals(r)) { - lastTimeoutLogged = r; - log.finest("Next operation to possibly timeout will do so at " + r.getTimeoutTime()); - } - } - } - } - - private final static Logger log = Logger.getLogger(TimeoutHandler.class.getName()); - private final TreeMap<Long, InternalRequest> requests = new TreeMap<>(); - private final ChangeLogger changeLogger = new ChangeLogger(); - private final Clock clock; - private boolean run = true; - private Runnable timeoutHandler = new Runnable() { - @Override - public void run() { - log.fine("Starting timeout monitor thread"); - while (true) { - performTimeoutHandlerTick(); - synchronized (clock) { - try{ clock.wait(100); } catch (InterruptedException e) {} - if (!run) break; - } - } - log.fine("Stopped timeout monitor thread"); - } - }; - - public TimeoutHandler(Executor executor, Clock clock, AsyncHttpClient<V> client) { - super(client); - this.clock = clock; - executor.execute(timeoutHandler); - } - - @Override - public void close() { - synchronized (clock) { - run = false; - clock.notifyAll(); - } - synchronized (requests) { - for (InternalRequest r : requests.values()) { - r.operation.cancel(); - r.setFailure(new TimeoutException("Timeout handler shutting down. Shutting down all requests monitored.")); - } - requests.clear(); - } - } - - @Override - public AsyncOperation<V> execute(HttpRequest r) { - AsyncOperation<V> op = super.execute(r); - InternalRequest<V> request = new InternalRequest<>(op, clock.getTimeInMillis(), r.getTimeoutMillis()); - synchronized (requests) { - requests.put(request.getTimeoutTime(), request); - } - return request; - } - - void performTimeoutHandlerTick() { - synchronized (requests) { - removeCompletedRequestsFromTimeoutList(); - handleTimeoutsAtTime(clock.getTimeInMillis()); - changeLogger.logChanges(requests); - } - } - - private void removeCompletedRequestsFromTimeoutList() { - while (!requests.isEmpty() && requests.firstEntry().getValue().operation.isDone()) { - requests.remove(requests.firstEntry().getKey()); - log.finest("Removed completed request from operation timeout list."); - } - } - - private void handleTimeoutsAtTime(long currentTime) { - Map<Long, InternalRequest> timeouts = requests.subMap(0l, currentTime + 1); - for (InternalRequest r : timeouts.values()) { - r.handleTimeout(currentTime); - requests.values().remove(r); - } - } - -} diff --git a/clustercontroller-utils/src/main/java/com/yahoo/vespa/clustercontroller/utils/test/FakeClock.java b/clustercontroller-utils/src/main/java/com/yahoo/vespa/clustercontroller/utils/test/FakeClock.java deleted file mode 100644 index 80f06b62675..00000000000 --- a/clustercontroller-utils/src/main/java/com/yahoo/vespa/clustercontroller/utils/test/FakeClock.java +++ /dev/null @@ -1,38 +0,0 @@ -// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. -package com.yahoo.vespa.clustercontroller.utils.test; - -import java.util.logging.Logger; - -/** - * Unit tests want to fast forward time to avoid waiting for time to pass - */ -public class FakeClock extends SettableClock { - - private static final Logger logger = Logger.getLogger(FakeClock.class.getName()); - protected long currentTime = 1; - - @Override - public long getTimeInMillis() { - return currentTime; - } - - @Override - public void adjust(long adjustment) { - synchronized (this) { - logger.fine("Adjusting clock, adding " + adjustment + " ms to it."); - currentTime += adjustment; - notifyAll(); - } - } - - @Override - public void set(long newTime) { - synchronized (this) { - if (newTime < currentTime) { - // throw new IllegalArgumentException("Clock attempted to be set to go backwards"); - } - currentTime = newTime; - } - } - -} diff --git a/clustercontroller-utils/src/main/java/com/yahoo/vespa/clustercontroller/utils/test/SettableClock.java b/clustercontroller-utils/src/main/java/com/yahoo/vespa/clustercontroller/utils/test/SettableClock.java deleted file mode 100644 index 12b398709f0..00000000000 --- a/clustercontroller-utils/src/main/java/com/yahoo/vespa/clustercontroller/utils/test/SettableClock.java +++ /dev/null @@ -1,11 +0,0 @@ -// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. -package com.yahoo.vespa.clustercontroller.utils.test; - -import com.yahoo.vespa.clustercontroller.utils.util.Clock; - -public abstract class SettableClock extends Clock { - - public abstract void set(long newTime); - public abstract void adjust(long adjustment); - -} diff --git a/clustercontroller-utils/src/test/java/com/yahoo/vespa/clustercontroller/utils/communication/http/AsyncHttpClientWithBaseTest.java b/clustercontroller-utils/src/test/java/com/yahoo/vespa/clustercontroller/utils/communication/http/AsyncHttpClientWithBaseTest.java deleted file mode 100644 index 0175eab84c2..00000000000 --- a/clustercontroller-utils/src/test/java/com/yahoo/vespa/clustercontroller/utils/communication/http/AsyncHttpClientWithBaseTest.java +++ /dev/null @@ -1,56 +0,0 @@ -// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. -package com.yahoo.vespa.clustercontroller.utils.communication.http; - -import com.yahoo.vespa.clustercontroller.utils.communication.async.AsyncOperation; -import com.yahoo.vespa.clustercontroller.utils.communication.async.AsyncOperationImpl; -import org.junit.Test; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotSame; -import static org.junit.Assert.fail; - -public class AsyncHttpClientWithBaseTest { - - @Test - public void testOverride() { - class HttpClient implements AsyncHttpClient<HttpResult> { - HttpRequest lastRequest; - @Override - public AsyncOperation<HttpResult> execute(HttpRequest r) { - lastRequest = r; - return new AsyncOperationImpl<>("test"); - } - @Override - public void close() { - } - } - - HttpClient client = new HttpClient(); - AsyncHttpClientWithBase<HttpResult> base = new AsyncHttpClientWithBase<>(client); - // No override by default - HttpRequest r = new HttpRequest().setPath("/foo").setHost("bar").setPort(50); - base.execute(r); - assertEquals(client.lastRequest, r); - // Base request always set - base.setHttpRequestBase(null); - base.execute(r); - assertEquals(client.lastRequest, r); - // Set an override - base.setHttpRequestBase(new HttpRequest().setHttpOperation(HttpRequest.HttpOp.DELETE)); - base.execute(r); - assertNotSame(client.lastRequest, r); - assertEquals(HttpRequest.HttpOp.DELETE, client.lastRequest.getHttpOperation()); - - base.close(); - } - - @Test - public void testClientMustBeSet() { - try{ - new AsyncHttpClientWithBase<>(null); - fail(); - } catch (IllegalArgumentException e) { - } - } - -} diff --git a/clustercontroller-utils/src/test/java/com/yahoo/vespa/clustercontroller/utils/communication/http/DummyAsyncHttpClient.java b/clustercontroller-utils/src/test/java/com/yahoo/vespa/clustercontroller/utils/communication/http/DummyAsyncHttpClient.java deleted file mode 100644 index 7070fb8570e..00000000000 --- a/clustercontroller-utils/src/test/java/com/yahoo/vespa/clustercontroller/utils/communication/http/DummyAsyncHttpClient.java +++ /dev/null @@ -1,26 +0,0 @@ -// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. -package com.yahoo.vespa.clustercontroller.utils.communication.http; - -import com.yahoo.vespa.clustercontroller.utils.communication.async.AsyncOperation; -import com.yahoo.vespa.clustercontroller.utils.communication.async.AsyncOperationImpl; - -public class DummyAsyncHttpClient implements AsyncHttpClient<HttpResult> { - HttpResult result; - HttpRequest lastRequest; - - public DummyAsyncHttpClient(HttpResult result) { - this.result = result; - } - - @Override - public AsyncOperation<HttpResult> execute(HttpRequest r) { - lastRequest = r; - AsyncOperationImpl<HttpResult> op = new AsyncOperationImpl<>(r.toString()); - op.setResult(result); - return op; - } - - @Override - public void close() { - } -} diff --git a/clustercontroller-utils/src/test/java/com/yahoo/vespa/clustercontroller/utils/communication/http/JsonAsyncHttpClientTest.java b/clustercontroller-utils/src/test/java/com/yahoo/vespa/clustercontroller/utils/communication/http/JsonAsyncHttpClientTest.java deleted file mode 100644 index 3d3cd517020..00000000000 --- a/clustercontroller-utils/src/test/java/com/yahoo/vespa/clustercontroller/utils/communication/http/JsonAsyncHttpClientTest.java +++ /dev/null @@ -1,119 +0,0 @@ -// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. -package com.yahoo.vespa.clustercontroller.utils.communication.http; - -import com.yahoo.vespa.clustercontroller.utils.communication.async.AsyncOperation; -import com.yahoo.vespa.clustercontroller.utils.communication.async.AsyncOperationImpl; -import org.codehaus.jettison.json.JSONObject; -import org.junit.Test; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNull; -import static org.junit.Assert.assertTrue; - -public class JsonAsyncHttpClientTest { - - @Test - public void testJSONInJSONOut() throws Exception { - DummyAsyncHttpClient dummy = new DummyAsyncHttpClient( - new HttpResult().setContent(new JSONObject().put("bar", 42))); - JsonAsyncHttpClient client = new JsonAsyncHttpClient(dummy); - client.addJsonContentType(true); - client.verifyRequestContentAsJson(true); - - HttpRequest r = new HttpRequest(); - r.setPostContent(new JSONObject().put("foo", 34)); - - AsyncOperation<JsonHttpResult> result = client.execute(r); - - assertEquals(new JSONObject().put("bar", 42).toString(), result.getResult().getJson().toString()); - assertTrue(result.isSuccess()); - - result.toString(); - client.close(); - } - - @Test - public void testStringInJSONOut() throws Exception { - DummyAsyncHttpClient dummy = new DummyAsyncHttpClient( - new HttpResult().setContent(new JSONObject().put("bar", 42).toString())); - JsonAsyncHttpClient client = new JsonAsyncHttpClient(dummy); - - HttpRequest r = new HttpRequest(); - r.setPostContent(new JSONObject().put("foo", 34).toString()); - - AsyncOperation<JsonHttpResult> result = client.execute(r); - - assertEquals(new JSONObject().put("bar", 42).toString(), result.getResult().getJson().toString()); - } - - @Test - public void testIllegalJsonIn() throws Exception { - DummyAsyncHttpClient dummy = new DummyAsyncHttpClient( - new HttpResult().setContent(new JSONObject().put("bar", 42))); - JsonAsyncHttpClient client = new JsonAsyncHttpClient(dummy); - - try { - HttpRequest r = new HttpRequest(); - r.setPostContent("my illegal json"); - - client.execute(r); - assertTrue(false); - } catch (Exception e) { - - } - } - - @Test - public void testIllegalJSONOut() throws Exception { - DummyAsyncHttpClient dummy = new DummyAsyncHttpClient( - new HttpResult().setContent("my illegal json")); - JsonAsyncHttpClient client = new JsonAsyncHttpClient(dummy); - - HttpRequest r = new HttpRequest(); - r.setPostContent(new JSONObject().put("foo", 34).toString()); - - AsyncOperation<JsonHttpResult> result = client.execute(r); - - assertEquals("{\"error\":\"Invalid JSON in output: A JSONObject text must begin with '{' at character 1 of my illegal json\",\"output\":\"my illegal json\"}", result.getResult().getJson().toString()); - } - - @Test - public void testEmptyReply() { - class Client implements AsyncHttpClient<HttpResult> { - AsyncOperationImpl<HttpResult> lastOp; - @Override - public AsyncOperation<HttpResult> execute(HttpRequest r) { - return lastOp = new AsyncOperationImpl<>(r.toString()); - } - @Override - public void close() { - } - }; - Client client = new Client(); - JsonAsyncHttpClient jsonClient = new JsonAsyncHttpClient(client); - AsyncOperation<JsonHttpResult> op = jsonClient.execute(new HttpRequest()); - client.lastOp.setResult(null); - assertNull(op.getResult()); - } - - @Test - public void testNotVerifyingJson() throws Exception { - DummyAsyncHttpClient dummy = new DummyAsyncHttpClient( - new HttpResult().setContent(new JSONObject().put("bar", 42))); - JsonAsyncHttpClient client = new JsonAsyncHttpClient(dummy); - client.addJsonContentType(true); - client.verifyRequestContentAsJson(false); - - HttpRequest r = new HttpRequest(); - r.setPostContent(new JSONObject().put("foo", 34)); - - AsyncOperation<JsonHttpResult> result = client.execute(r); - - assertEquals(new JSONObject().put("bar", 42).toString(), result.getResult().getJson().toString()); - assertTrue(result.isSuccess()); - - result.toString(); - client.close(); - } - -} diff --git a/clustercontroller-utils/src/test/java/com/yahoo/vespa/clustercontroller/utils/communication/http/LoggingAsyncHttpClientTest.java b/clustercontroller-utils/src/test/java/com/yahoo/vespa/clustercontroller/utils/communication/http/LoggingAsyncHttpClientTest.java deleted file mode 100644 index 37841f7ca29..00000000000 --- a/clustercontroller-utils/src/test/java/com/yahoo/vespa/clustercontroller/utils/communication/http/LoggingAsyncHttpClientTest.java +++ /dev/null @@ -1,55 +0,0 @@ -// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. -package com.yahoo.vespa.clustercontroller.utils.communication.http; - -import com.yahoo.vespa.clustercontroller.utils.communication.async.AsyncOperation; -import com.yahoo.vespa.clustercontroller.utils.communication.async.AsyncOperationImpl; -import org.junit.Test; - -import java.util.logging.Level; -import java.util.logging.Logger; - -import static org.junit.Assert.assertEquals; - -public class LoggingAsyncHttpClientTest { - - class HttpClient implements AsyncHttpClient<HttpResult> { - AsyncOperationImpl<HttpResult> lastOp; - @Override - public AsyncOperation<HttpResult> execute(HttpRequest r) { - return lastOp = new AsyncOperationImpl<>("test"); - } - @Override - public void close() { - } - } - - @Test - public void testWithoutDebugLog() { - doRequests(); - } - - @Test - public void testWithDebugLog() { - Logger log = Logger.getLogger(LoggingAsyncHttpClient.class.getName()); - log.setLevel(Level.FINE); - doRequests(); - } - - private void doRequests() { - { - HttpClient client = new HttpClient(); - LoggingAsyncHttpClient<HttpResult> loggingClient = new LoggingAsyncHttpClient<>(client); - AsyncOperation<HttpResult> op = loggingClient.execute(new HttpRequest()); - client.lastOp.setResult(new HttpResult().setContent("foo")); - assertEquals("foo", op.getResult().getContent()); - } - { - HttpClient client = new HttpClient(); - LoggingAsyncHttpClient<HttpResult> loggingClient = new LoggingAsyncHttpClient<>(client); - AsyncOperation<HttpResult> op = loggingClient.execute(new HttpRequest()); - client.lastOp.setFailure(new Exception("foo")); - assertEquals("foo", op.getCause().getMessage()); - } - } - -} diff --git a/clustercontroller-utils/src/test/java/com/yahoo/vespa/clustercontroller/utils/communication/http/ProxyAsyncHttpClientTest.java b/clustercontroller-utils/src/test/java/com/yahoo/vespa/clustercontroller/utils/communication/http/ProxyAsyncHttpClientTest.java deleted file mode 100644 index 062fd4aaa32..00000000000 --- a/clustercontroller-utils/src/test/java/com/yahoo/vespa/clustercontroller/utils/communication/http/ProxyAsyncHttpClientTest.java +++ /dev/null @@ -1,49 +0,0 @@ -// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. -package com.yahoo.vespa.clustercontroller.utils.communication.http; - -import org.codehaus.jettison.json.JSONObject; -import org.junit.Test; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertTrue; - -public class ProxyAsyncHttpClientTest { - - @Test - public void testSimple() throws Exception { - // Can't really test much here, but verifies that the code runs. - DummyAsyncHttpClient dummy = new DummyAsyncHttpClient( - new HttpResult().setContent(new JSONObject().put("bar", 42))); - ProxyAsyncHttpClient client = new ProxyAsyncHttpClient<>(dummy, "myproxyhost", 1234); - - HttpRequest r = new HttpRequest(); - r.setPath("/foo"); - r.setHost("myhost"); - r.setPort(4567); - - r.setPostContent(new JSONObject().put("foo", 34)); - - client.execute(r); - - assertEquals(new HttpRequest().setPath("/myhost:4567/foo") - .setHost("myproxyhost") - .setPort(1234) - .setPostContent(new JSONObject().put("foo", 34)), - dummy.lastRequest); - } - - @Test - public void testNoAndEmptyPath() throws Exception { - DummyAsyncHttpClient dummy = new DummyAsyncHttpClient( - new HttpResult().setContent(new JSONObject().put("bar", 42))); - ProxyAsyncHttpClient client = new ProxyAsyncHttpClient<>(dummy, "myproxyhost", 1234); - try{ - client.execute(new HttpRequest()); - assertTrue(false); - } catch (IllegalStateException e) { - assertTrue(e.getMessage().contains("Host and path must be set prior")); - } - client.execute(new HttpRequest().setHost("local").setPath("")); - } - -} diff --git a/clustercontroller-utils/src/test/java/com/yahoo/vespa/clustercontroller/utils/communication/http/RequestQueueTest.java b/clustercontroller-utils/src/test/java/com/yahoo/vespa/clustercontroller/utils/communication/http/RequestQueueTest.java deleted file mode 100644 index 230920df53f..00000000000 --- a/clustercontroller-utils/src/test/java/com/yahoo/vespa/clustercontroller/utils/communication/http/RequestQueueTest.java +++ /dev/null @@ -1,114 +0,0 @@ -// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. -package com.yahoo.vespa.clustercontroller.utils.communication.http; - -import com.yahoo.vespa.clustercontroller.utils.communication.async.AsyncCallback; -import com.yahoo.vespa.clustercontroller.utils.communication.async.AsyncOperation; -import com.yahoo.vespa.clustercontroller.utils.communication.async.AsyncOperationImpl; -import org.junit.Test; - -import java.util.LinkedList; - -import static org.junit.Assert.assertEquals; - -public class RequestQueueTest { - - public static class Request { - public final HttpRequest request; - public final AsyncOperationImpl<HttpResult> result; - - public Request(HttpRequest r, AsyncOperationImpl<HttpResult> rr) { - this.request = r; - this.result = rr; - } - } - - public class TestClient implements AsyncHttpClient<HttpResult> { - LinkedList<Request> requests = new LinkedList<>(); - @Override - public AsyncOperation<HttpResult> execute(HttpRequest r) { - Request p = new Request(r, new AsyncOperationImpl<HttpResult>(r.toString())); - synchronized (requests) { - requests.addLast(p); - } - return p.result; - } - @Override - public void close() {} - }; - - @Test - public void testNormalUsage() { - TestClient client = new TestClient(); - RequestQueue<HttpResult> queue = new RequestQueue<>(client, 4); - final LinkedList<HttpResult> results = new LinkedList<>(); - for (int i=0; i<10; ++i) { - queue.schedule(new HttpRequest().setPath("/" + i), new AsyncCallback<HttpResult>() { - @Override - public void done(AsyncOperation<HttpResult> op) { - if (op.isSuccess()) { - results.add(op.getResult()); - } else { - results.add(new HttpResult().setHttpCode(500, op.getCause().getMessage())); - } - } - }); - } - assertEquals(4, client.requests.size()); - for (int i=0; i<3; ++i) { - Request p = client.requests.removeFirst(); - p.result.setResult(new HttpResult()); - assertEquals(true, results.getLast().isSuccess()); - } - assertEquals(4, client.requests.size()); - for (int i=0; i<7; ++i) { - Request p = client.requests.removeFirst(); - p.result.setFailure(new Exception("Fail")); - assertEquals(false, results.getLast().isSuccess()); - } - assertEquals(0, client.requests.size()); - assertEquals(true, queue.empty()); - assertEquals(10, results.size()); - } - - public class Waiter implements Runnable { - boolean waiting = false; - boolean completed = false; - RequestQueue<HttpResult> queue; - Waiter(RequestQueue<HttpResult> queue) { - this.queue = queue; - } - public void run() { - try{ - waiting = true; - queue.waitUntilEmpty(); - } catch (InterruptedException e) { throw new Error(e); } - completed = true; - } - } - - @Test - public void testWaitUntilEmpty() throws Exception { - TestClient client = new TestClient(); - RequestQueue<HttpResult> queue = new RequestQueue<>(client, 4); - final LinkedList<HttpResult> result = new LinkedList<>(); - queue.schedule(new HttpRequest().setPath("/foo"), new AsyncCallback<HttpResult>() { - @Override - public void done(AsyncOperation<HttpResult> op) { - result.add(op.getResult()); - } - }); - Waiter waiter = new Waiter(queue); - Thread thread = new Thread(waiter); - thread.start(); - while (!waiter.waiting) { - Thread.sleep(1); - } - assertEquals(0, result.size()); - client.requests.getFirst().result.setResult(new HttpResult()); - while (!waiter.completed) { - Thread.sleep(1); - } - assertEquals(1, result.size()); - } - -} diff --git a/clustercontroller-utils/src/test/java/com/yahoo/vespa/clustercontroller/utils/communication/http/TimeoutHandlerTest.java b/clustercontroller-utils/src/test/java/com/yahoo/vespa/clustercontroller/utils/communication/http/TimeoutHandlerTest.java deleted file mode 100644 index 72a2a4eab8a..00000000000 --- a/clustercontroller-utils/src/test/java/com/yahoo/vespa/clustercontroller/utils/communication/http/TimeoutHandlerTest.java +++ /dev/null @@ -1,127 +0,0 @@ -// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. -package com.yahoo.vespa.clustercontroller.utils.communication.http; - -import com.yahoo.vespa.clustercontroller.utils.communication.async.AsyncOperation; -import com.yahoo.vespa.clustercontroller.utils.communication.async.AsyncOperationImpl; -import com.yahoo.vespa.clustercontroller.utils.communication.async.AsyncUtils; -import com.yahoo.vespa.clustercontroller.utils.test.FakeClock; -import org.junit.After; -import org.junit.Before; -import org.junit.Test; - -import java.util.concurrent.ArrayBlockingQueue; -import java.util.concurrent.ThreadPoolExecutor; -import java.util.concurrent.TimeUnit; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertTrue; - -public class TimeoutHandlerTest { - - public class TestClient implements AsyncHttpClient<HttpResult> { - AsyncOperationImpl<HttpResult> lastOp; - @Override - public AsyncOperation<HttpResult> execute(HttpRequest r) { - return lastOp = new AsyncOperationImpl<>("test"); - } - @Override - public void close() {} - }; - - private ThreadPoolExecutor executor; - private TestClient client; - private FakeClock clock; - private TimeoutHandler<HttpResult> handler; - - @Before - public void setUp() { - executor = new ThreadPoolExecutor(10, 100, 100, TimeUnit.SECONDS, new ArrayBlockingQueue<Runnable>(1000)); - clock = new FakeClock(); - client = new TestClient(); - handler = new TimeoutHandler<>(executor, clock, client); - } - - @After - public void tearDown() { - handler.close(); - executor.shutdown(); - } - - @Test - public void testTimeout() { - AsyncOperation<HttpResult> op = handler.execute(new HttpRequest().setTimeout(1000)); - assertFalse(op.isDone()); - clock.adjust(999); - // Give it a bit of time for timeout handler to have a chance of timout out prematurely - try{ Thread.sleep(1); } catch (InterruptedException e) {} - assertFalse(op.isDone()); - clock.adjust(1); - AsyncUtils.waitFor(op); - assertTrue(op.isDone()); - assertFalse(op.isSuccess()); - assertTrue(op.getCause().getMessage(), op.getCause().getMessage().contains("Operation timeout")); - // After timeout, finishing the original request no longer matter - client.lastOp.setResult(new HttpResult()); - assertFalse(op.isSuccess()); - assertTrue(op.getCause().getMessage(), op.getCause().getMessage().contains("Operation timeout")); - } - - @Test - public void testNoTimeout() { - AsyncOperation<HttpResult> op = handler.execute(new HttpRequest().setTimeout(1000)); - clock.adjust(999); - assertFalse(op.isDone()); - client.lastOp.setResult(new HttpResult().setContent("foo")); - AsyncUtils.waitFor(op); - assertTrue(op.isDone()); - assertTrue(op.isSuccess()); - assertEquals("foo", op.getResult().getContent()); - } - - @Test - public void testNoTimeoutFailing() { - AsyncOperation<HttpResult> op = handler.execute(new HttpRequest().setTimeout(1000)); - clock.adjust(999); - assertFalse(op.isDone()); - client.lastOp.setFailure(new Exception("foo")); - AsyncUtils.waitFor(op); - assertTrue(op.isDone()); - assertFalse(op.isSuccess()); - assertEquals("foo", op.getCause().getMessage()); - } - - @Test - public void testProvokeCompletedOpPurgeInTimeoutList() { - AsyncOperation<HttpResult> op1 = handler.execute(new HttpRequest().setTimeout(1000)); - AsyncOperationImpl<HttpResult> op1Internal = client.lastOp; - clock.adjust(300); - AsyncOperation<HttpResult> op2 = handler.execute(new HttpRequest().setTimeout(1000)); - clock.adjust(300); - op1Internal.setResult(new HttpResult().setContent("foo")); - AsyncUtils.waitFor(op1); - clock.adjust(800); - AsyncUtils.waitFor(op2); - assertEquals(true, op1.isDone()); - assertEquals(true, op2.isDone()); - assertEquals(true, op1.isSuccess()); - assertEquals(false, op2.isSuccess()); - } - - @Test - public void testNothingButGetCoverage() { - AsyncOperation<HttpResult> op = handler.execute(new HttpRequest().setTimeout(1000)); - op.getProgress(); - op.cancel(); - assertFalse(op.isCanceled()); // Cancel not currently supported - client.lastOp.setResult(new HttpResult().setContent("foo")); - AsyncUtils.waitFor(op); - op.getProgress(); - op = handler.execute(new HttpRequest().setTimeout(1000)); - handler.performTimeoutHandlerTick(); - handler.performTimeoutHandlerTick(); - client.lastOp.setResult(new HttpResult().setContent("foo")); - AsyncUtils.waitFor(op); - } - -} diff --git a/clustercontroller-utils/src/main/java/com/yahoo/vespa/clustercontroller/utils/communication/http/AsyncHttpClient.java b/clustercontroller-utils/src/test/java/com/yahoo/vespa/clustercontroller/utils/test/AsyncHttpClient.java index 6af3e4de759..29f86842b34 100644 --- a/clustercontroller-utils/src/main/java/com/yahoo/vespa/clustercontroller/utils/communication/http/AsyncHttpClient.java +++ b/clustercontroller-utils/src/test/java/com/yahoo/vespa/clustercontroller/utils/test/AsyncHttpClient.java @@ -1,7 +1,9 @@ // Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. -package com.yahoo.vespa.clustercontroller.utils.communication.http; +package com.yahoo.vespa.clustercontroller.utils.test; import com.yahoo.vespa.clustercontroller.utils.communication.async.AsyncOperation; +import com.yahoo.vespa.clustercontroller.utils.communication.http.HttpRequest; +import com.yahoo.vespa.clustercontroller.utils.communication.http.HttpResult; /** * Abstraction of an asynchronous HTTP client, such that applications don't need to depend directly on an HTTP client. diff --git a/clustercontroller-utils/src/test/java/com/yahoo/vespa/clustercontroller/utils/test/FakeClockTest.java b/clustercontroller-utils/src/test/java/com/yahoo/vespa/clustercontroller/utils/test/FakeClockTest.java deleted file mode 100644 index 47edd7ac55c..00000000000 --- a/clustercontroller-utils/src/test/java/com/yahoo/vespa/clustercontroller/utils/test/FakeClockTest.java +++ /dev/null @@ -1,42 +0,0 @@ -// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. -package com.yahoo.vespa.clustercontroller.utils.test; - -import org.junit.Test; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertTrue; - -public class FakeClockTest { - - @Test - public void testSimple() { - FakeClock clock = new FakeClock(); - // Should not start at 0, as that is common not initialized yet value - assertTrue(clock.getTimeInMillis() > 0); - long start = clock.getTimeInMillis(); - - clock.adjust(5); - assertEquals(start + 5, clock.getTimeInMillis()); - - clock.set(start + 10); - assertEquals(start + 10, clock.getTimeInMillis()); - - clock.adjust(5); - assertEquals(start + 15, clock.getTimeInMillis()); - } - - // TODO: This should probably throw exceptions.. However, that doesn't seem to be current behavior. - // I suspect some tests misuse the clock to reset things to run another test. Should probably be fixed. - @Test - public void testTurnTimeBack() { - FakeClock clock = new FakeClock(); - clock.set(1000); - - clock.set(500); - assertEquals(500, clock.getTimeInMillis()); - - clock.adjust(-100); - assertEquals(400, clock.getTimeInMillis()); - } - -} diff --git a/clustercontroller-utils/src/main/java/com/yahoo/vespa/clustercontroller/utils/test/TestTransport.java b/clustercontroller-utils/src/test/java/com/yahoo/vespa/clustercontroller/utils/test/TestTransport.java index 87ecd127e44..d2e76cd77f9 100644 --- a/clustercontroller-utils/src/main/java/com/yahoo/vespa/clustercontroller/utils/test/TestTransport.java +++ b/clustercontroller-utils/src/test/java/com/yahoo/vespa/clustercontroller/utils/test/TestTransport.java @@ -3,7 +3,6 @@ package com.yahoo.vespa.clustercontroller.utils.test; import com.yahoo.vespa.clustercontroller.utils.communication.async.AsyncOperation; import com.yahoo.vespa.clustercontroller.utils.communication.async.AsyncOperationImpl; -import com.yahoo.vespa.clustercontroller.utils.communication.http.AsyncHttpClient; import com.yahoo.vespa.clustercontroller.utils.communication.http.HttpRequest; import com.yahoo.vespa.clustercontroller.utils.communication.http.HttpRequestHandler; import com.yahoo.vespa.clustercontroller.utils.communication.http.HttpResult; |