diff options
Diffstat (limited to 'clustercontroller-utils/src/main/java/com/yahoo/vespa/clustercontroller')
11 files changed, 0 insertions, 672 deletions
diff --git a/clustercontroller-utils/src/main/java/com/yahoo/vespa/clustercontroller/utils/communication/http/AsyncHttpClient.java b/clustercontroller-utils/src/main/java/com/yahoo/vespa/clustercontroller/utils/communication/http/AsyncHttpClient.java deleted file mode 100644 index 6af3e4de759..00000000000 --- a/clustercontroller-utils/src/main/java/com/yahoo/vespa/clustercontroller/utils/communication/http/AsyncHttpClient.java +++ /dev/null @@ -1,16 +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; - -/** - * Abstraction of an asynchronous HTTP client, such that applications don't need to depend directly on an HTTP client. - */ -public interface AsyncHttpClient<V extends HttpResult> { - - AsyncOperation<V> 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/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/main/java/com/yahoo/vespa/clustercontroller/utils/test/TestTransport.java b/clustercontroller-utils/src/main/java/com/yahoo/vespa/clustercontroller/utils/test/TestTransport.java deleted file mode 100644 index 87ecd127e44..00000000000 --- a/clustercontroller-utils/src/main/java/com/yahoo/vespa/clustercontroller/utils/test/TestTransport.java +++ /dev/null @@ -1,187 +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.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; - -import java.io.PrintWriter; -import java.io.StringWriter; -import java.util.HashMap; -import java.util.LinkedList; -import java.util.List; -import java.util.Map; -import java.util.logging.Level; -import java.util.logging.Logger; -/** - * This class is a utility for unit tests.. You can register HttpRequestHandler instances in it, and then - * you can extract an AsyncHttpClient<HttpResult> instance from it, which you can use to talk to the - * registered servers. Thus you can do end to end testing of components talking over HTTP without actually - * going through HTTP if you are using the HTTP abstraction layer in communication.http package. - */ -public class TestTransport { - - private static final Logger log = Logger.getLogger(TestTransport.class.getName()); - private static class Handler { - HttpRequestHandler handler; - String pathPrefix; - Handler(HttpRequestHandler h, String prefix) { this.handler = h; this.pathPrefix = prefix; } - } - private static class Socket { - public final String hostname; - public final int port; - - Socket(String hostname, int port) { - this.hostname = hostname; - this.port = port; - } - @Override - public boolean equals(Object o) { - if (!(o instanceof Socket)) return false; - Socket other = (Socket) o; - return (hostname.equals(other.hostname) && port == other.port); - } - @Override - public int hashCode() { - return hostname.hashCode() * port; - } - } - private static class Request { - public final HttpRequest request; - public final AsyncOperationImpl<HttpResult> result; - - Request(HttpRequest r, AsyncOperationImpl<HttpResult> rr) { - this.request = r; - this.result = rr; - } - } - private final Map<Socket, List<Handler>> handlers = new HashMap<>(); - private final LinkedList<Request> requests = new LinkedList<>(); - private final AsyncHttpClient<HttpResult> client = new AsyncHttpClient<HttpResult>() { - @Override - public AsyncOperation<HttpResult> execute(HttpRequest r) { - log.fine("Queueing request " + r); - if (r.getHttpOperation() == null) { - r = r.clone(); - r.setHttpOperation(r.getPostContent() == null ? HttpRequest.HttpOp.GET : HttpRequest.HttpOp.POST); - } - r.verifyComplete(); - AsyncOperationImpl<HttpResult> op = new AsyncOperationImpl<>(r.toString()); - synchronized (requests) { - requests.addLast(new Request(r, op)); - } - return op; - } - @Override - public void close() { TestTransport.this.close(); } - }; - private boolean running = true; - private final Thread workerThread = new Thread() { - @Override - public void run() { - while (running) { - synchronized (requests) { - if (requests.isEmpty()) { - try { - requests.wait(100); - } catch (InterruptedException e) { return; } - } else { - Request request = requests.removeFirst(); - HttpRequest r = request.request; - log.fine("Processing request " + r); - HttpRequestHandler handler = getHandler(r); - if (handler == null) { - if (log.isLoggable(Level.FINE)) { - log.fine("Failed to find target for request " + r.toString(true)); - log.fine("Existing handlers:"); - for (Socket socket : handlers.keySet()) { - log.fine(" Socket " + socket.hostname + ":" + socket.port); - for (Handler h : handlers.get(socket)) { - log.fine(" " + h.pathPrefix); - } - } - } - request.result.setResult(new HttpResult().setHttpCode( - 404, "No such server socket with suitable path prefix found open")); - } else { - try{ - request.result.setResult(handler.handleRequest(r)); - } catch (Exception e) { - HttpResult result = new HttpResult().setHttpCode(500, e.getMessage()); - StringWriter sw = new StringWriter(); - e.printStackTrace(new PrintWriter(sw)); - result.setContent(sw.toString()); - request.result.setResult(result); - } - } - //log.fine("Request " + r.toString(true) + " created result " + request.getSecond().getResult().toString(true)); - } - } - } - } - }; - - public TestTransport() { - workerThread.start(); - } - - public void close() { - if (!running) return; - running = false; - synchronized (requests) { requests.notifyAll(); } - try { - workerThread.join(); - } catch (InterruptedException e) {} - } - - /** Get an HTTP client that talks to this test transport layer. */ - public AsyncHttpClient<HttpResult> getClient() { return client; } - - private HttpRequestHandler getHandler(HttpRequest r) { - Socket socket = new Socket(r.getHost(), r.getPort()); - synchronized (this) { - List<Handler> handlerList = handlers.get(socket); - if (handlerList == null) { - log.fine("No socket match"); - return null; - } - log.fine("Socket found"); - for (Handler h : handlers.get(socket)) { - if (r.getPath().length() >= h.pathPrefix.length() && r.getPath().substring(0, h.pathPrefix.length()).equals(h.pathPrefix)) { - return h.handler; - } - } - log.fine("No path prefix match"); - } - return null; - } - - public void addServer(HttpRequestHandler server, String hostname, int port, String pathPrefix) { - Socket socket = new Socket(hostname, port); - synchronized (this) { - List<Handler> shandlers = handlers.get(socket); - if (shandlers == null) { - shandlers = new LinkedList<>(); - handlers.put(socket, shandlers); - } - shandlers.add(new Handler(server, pathPrefix)); - } - } - - public void removeServer(HttpRequestHandler server, String hostname, int port, String pathPrefix) { - Socket socket = new Socket(hostname, port); - synchronized (this) { - List<Handler> shandlers = handlers.get(socket); - if (shandlers == null) return; - for (Handler h : shandlers) { - if (h.handler == server && h.pathPrefix.equals(pathPrefix)) { - shandlers.remove(h); - } - } - } - } - -} |