http://git-wip-us.apache.org/repos/asf/aurora/blob/356eeac9/commons/src/main/java/org/apache/aurora/common/net/http/GuiceServletConfig.java ---------------------------------------------------------------------- diff --git a/commons/src/main/java/org/apache/aurora/common/net/http/GuiceServletConfig.java b/commons/src/main/java/org/apache/aurora/common/net/http/GuiceServletConfig.java deleted file mode 100644 index e4fa8aa..0000000 --- a/commons/src/main/java/org/apache/aurora/common/net/http/GuiceServletConfig.java +++ /dev/null @@ -1,41 +0,0 @@ -/** - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.apache.aurora.common.net.http; - -import com.google.common.base.Preconditions; -import com.google.inject.Inject; -import com.google.inject.Injector; -import com.google.inject.servlet.GuiceServletContextListener; - -import javax.servlet.ServletContextEvent; -import java.util.logging.Logger; - -/** - * A wrapper around the GuiceServletContextListener that has access to the injector. - * - * @author Florian Leibert - */ -public class GuiceServletConfig extends GuiceServletContextListener { - private final Injector injector; - - @Inject - public GuiceServletConfig(Injector injector) { - this.injector = Preconditions.checkNotNull(injector); - } - - @Override - protected Injector getInjector() { - return injector; - } -}
http://git-wip-us.apache.org/repos/asf/aurora/blob/356eeac9/commons/src/main/java/org/apache/aurora/common/net/http/HttpServerDispatch.java ---------------------------------------------------------------------- diff --git a/commons/src/main/java/org/apache/aurora/common/net/http/HttpServerDispatch.java b/commons/src/main/java/org/apache/aurora/common/net/http/HttpServerDispatch.java deleted file mode 100644 index 3208267..0000000 --- a/commons/src/main/java/org/apache/aurora/common/net/http/HttpServerDispatch.java +++ /dev/null @@ -1,123 +0,0 @@ -/** - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.apache.aurora.common.net.http; - -import java.util.Map; - -import javax.annotation.Nullable; -import javax.servlet.Filter; -import javax.servlet.ServletContextAttributeListener; -import javax.servlet.ServletContextListener; -import javax.servlet.ServletRequestAttributeListener; -import javax.servlet.ServletRequestListener; -import javax.servlet.http.HttpServlet; - -/** - * A HTTP server dispatcher. Supports registering handlers for different - * URI paths, which will be called when a request is received. - * - * @author Florian Leibert - */ -public interface HttpServerDispatch { - - /** - * Opens the HTTP server on the given port. - * - * @param port The port to listen on. - * @return {@code true} if the server started successfully on the port, {@code false} otherwise. - */ - boolean listen(int port); - - /** - * Opens the HTTP server on random port within the given range. - * - * @param minPort The minimum port number to listen on. - * @param maxPort The maximum port number to listen on. - * @return {@code true} if the server started successfully on the port, {@code false} otherwise. - */ - boolean listen(int minPort, int maxPort); - - /** - * @return true if the underlying HttpServer is started, false otherwise. - */ - boolean isStarted(); - - /** - * @return the port the underlying HttpServer is listening on, which requires - * the underlying HttpServer to be started and listening. - */ - int getPort(); - - /** - * Stops the HTTP server. - */ - void stop(); - - /** - * Adds an arbitrary endpoint to the root servlet. - * This can be used to include convenience links, or references to endpoints served by - * a different servlet container under this HTTP server. - * - * @param path The URI path of the endpoint. - */ - void registerIndexLink(String path); - - /** - * Registers a URI handler, replacing the existing handler if it exists. - * - * @param path The URI path that the handler should be called for. - * @param handler The handler to call. - * @param initParams An optional map of servlet init parameter names and their values. - * @param silent Whether to display the registered handler in the root "/" response. - * Useful for handlers that you want to avoid accidental clicks on. - */ - void registerHandler(String path, HttpServlet handler, - @Nullable Map<String, String> initParams, boolean silent); - - /** - * Registers a servlet filter. - * - * @param filterClass Filter class to register. - * @param pathSpec Path spec that the filter should be activated on. - */ - void registerFilter(Class<? extends Filter> filterClass, String pathSpec); - - /** - * Registers a context listener. - * - * @param servletContextListener Listener to register. - */ - void registerListener(ServletContextListener servletContextListener); - - /** - * Registers a context attribute listener. - * - * @param servletContextAttributeListener Listener to register. - */ - void registerListener(ServletContextAttributeListener servletContextAttributeListener); - - /** - * Registers a request listener. - * - * @param servletRequestListener Listener to register. - */ - void registerListener(ServletRequestListener servletRequestListener); - - /** - * Registers a request attribute listener. - * - * @param servletRequestAttributeListener Listener to register. - */ - void registerListener(ServletRequestAttributeListener servletRequestAttributeListener); -} http://git-wip-us.apache.org/repos/asf/aurora/blob/356eeac9/commons/src/main/java/org/apache/aurora/common/net/http/JettyHttpServerDispatch.java ---------------------------------------------------------------------- diff --git a/commons/src/main/java/org/apache/aurora/common/net/http/JettyHttpServerDispatch.java b/commons/src/main/java/org/apache/aurora/common/net/http/JettyHttpServerDispatch.java deleted file mode 100644 index a3fa57e..0000000 --- a/commons/src/main/java/org/apache/aurora/common/net/http/JettyHttpServerDispatch.java +++ /dev/null @@ -1,283 +0,0 @@ -/** - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.apache.aurora.common.net.http; - -import java.io.IOException; -import java.util.EventListener; -import java.util.List; -import java.util.Map; -import java.util.Random; -import java.util.Set; -import java.util.logging.Level; -import java.util.logging.Logger; - -import javax.annotation.Nullable; -import javax.servlet.Filter; -import javax.servlet.ServletContextAttributeListener; -import javax.servlet.ServletContextListener; -import javax.servlet.ServletRequestAttributeListener; -import javax.servlet.ServletRequestListener; -import javax.servlet.http.HttpServlet; -import javax.servlet.http.HttpServletRequest; - -import com.google.common.base.Optional; -import com.google.common.base.Preconditions; -import com.google.common.collect.Lists; -import com.google.common.collect.Ordering; -import com.google.common.collect.Sets; -import com.google.inject.Inject; - -import org.apache.aurora.common.net.http.handlers.TextResponseHandler; -import org.mortbay.jetty.AbstractConnector; -import org.mortbay.jetty.Connector; -import org.mortbay.jetty.Handler; -import org.mortbay.jetty.RequestLog; -import org.mortbay.jetty.Server; -import org.mortbay.jetty.handler.RequestLogHandler; -import org.mortbay.jetty.nio.SelectChannelConnector; -import org.mortbay.jetty.servlet.Context; -import org.mortbay.jetty.servlet.ServletHolder; - -import org.apache.aurora.common.base.MorePreconditions; - -/** - * A simple multi-threaded HTTP server dispatcher. Supports registering handlers for different - * URI paths, which will be called when a request is received. - * - * @author William Farner - */ -public class JettyHttpServerDispatch implements HttpServerDispatch { - private static final Logger LOG = Logger.getLogger(JettyHttpServerDispatch.class.getName()); - - // Registered endpoints. Used only for display. - private final Set<String> registeredEndpoints = Sets.newHashSet(); - - private final Optional<RequestLog> requestLog; - private Server server; - private Context context; - private int port; - - /** - * Creates an HTTP server. - */ - public JettyHttpServerDispatch() { - this.requestLog = Optional.absent(); - } - - /** - * Creates an HTTP server which will be configured to log requests to the provided request log. - * - * @param requestLog HTTP request log. - */ - @Inject - public JettyHttpServerDispatch(RequestLog requestLog) { - this.requestLog = Optional.of(requestLog); - } - - /** - * Opens the HTTP server on the given port. - * - * @param port The port to listen on. - * @return {@code true} if the server started successfully on the port, {@code false} otherwise. - */ - public boolean listen(int port) { - return listen(port, port); - } - - @Override - public synchronized boolean listen(int minPort, int maxPort) { - boolean state = !isStarted(); - Preconditions.checkState(state, - "HttpServerDispatch has already been started on port: %d", port); - - Connector connector = openConnector(minPort, maxPort); - if (connector == null) return false; // Couldn't open a server port. - port = connector.getLocalPort(); - - server = new Server(); - server.addConnector(connector); - context = new Context(server, "/", Context.NO_SESSIONS); - if (requestLog.isPresent()) { - RequestLogHandler logHandler = new RequestLogHandler(); - logHandler.setRequestLog(requestLog.get()); - context.addHandler(logHandler); - } - - context.addServlet(new ServletHolder(new RootHandler()), "/"); - - try { - server.start(); - LOG.info("HTTP server is listening on port " + port); - return true; - } catch (Exception e) { - LOG.log(Level.SEVERE, "HTTP server failed to start on port " + connector.getLocalPort(), e); - return false; - } - } - - @Override - public synchronized boolean isStarted() { - return (server != null) && server.isStarted(); - } - - @Override - public synchronized int getPort() { - Preconditions.checkState(isStarted(), "HttpServer must be started before port can be determined"); - return port; - } - - /** - * Opens a new Connector which is a Jetty specific way of handling the - * lifecycle and configuration of the Jetty server. The connector will - * open a Socket on an available port between minPort and maxPort. - * A subclass can override this method to modify connector configurations - * such as queue-size or header-buffer-size. - * @param minPort the minimum port number to bind to. - * @param maxPort the maximum port number to bind to. - * @return - */ - protected Connector openConnector(int minPort, int maxPort) { - if (minPort != 0 || maxPort != 0) { - Preconditions.checkState(minPort > 0, "Invalid port range."); - Preconditions.checkState(maxPort > 0, "Invalid port range."); - Preconditions.checkState(minPort <= maxPort, "Invalid port range."); - } - int attempts = 0; - int port; - - int maxAttempts = minPort == maxPort ? 1 : 5; - while (++attempts <= maxAttempts) { - if (minPort == maxPort) { - port = minPort; - } else { - port = minPort + new Random().nextInt(maxPort - minPort); - } - LOG.info("Attempting to listen on port " + port); - - try { - // TODO(John Sirois): consider making Connector impl parametrizable - AbstractConnector connector = new SelectChannelConnector(); - connector.setPort(port); - // Create the server with a maximum TCP backlog of 50, meaning that when the request queue - // exceeds 50, subsequent connections may be rejected. - connector.setAcceptQueueSize(50); - connector.open(); - return connector; - } catch (IOException e) { - LOG.log(Level.WARNING, "Failed to create HTTP server on port " + port, e); - } - } - return null; - } - - @Override - public synchronized void stop() { - if (isStarted()) { - try { - server.stop(); - } catch (Exception e) { - LOG.log(Level.SEVERE, "Error stopping HTTPServer on " + port, e); - } - } - } - - @Override - public synchronized void registerHandler( - String path, - HttpServlet handler, - @Nullable Map<String, String> initParams, - boolean silent) { - - Preconditions.checkNotNull(path); - Preconditions.checkNotNull(handler); - Preconditions.checkState(path.length() > 0); - Preconditions.checkState(path.charAt(0) == '/'); - - if (silent) { - registeredEndpoints.remove(path); - } else { - registeredEndpoints.add(path); - } - - ServletHolder servletHolder = new ServletHolder(handler); - if (initParams != null) { - servletHolder.setInitParameters(initParams); - } - getRootContext().addServlet(servletHolder, path.replaceFirst("/?$", "/*")); - } - - @Override - public synchronized void registerFilter(Class<? extends Filter> filterClass, String pathSpec) { - MorePreconditions.checkNotBlank(pathSpec); - Preconditions.checkNotNull(filterClass); - getRootContext().addFilter(filterClass, pathSpec, Handler.REQUEST); - } - - @Override - public synchronized void registerIndexLink(String path) { - MorePreconditions.checkNotBlank(path); - registeredEndpoints.add(path); - } - - @Override - public void registerListener(ServletContextListener servletContextListener) { - registerEventListener(servletContextListener); - } - - @Override - public void registerListener(ServletContextAttributeListener servletContextAttributeListener) { - registerEventListener(servletContextAttributeListener); - } - - @Override - public void registerListener(ServletRequestListener servletRequestListener) { - registerEventListener(servletRequestListener); - } - - @Override - public void registerListener(ServletRequestAttributeListener servletRequestAttributeListener) { - registerEventListener(servletRequestAttributeListener); - } - - private synchronized void registerEventListener(EventListener eventListener) { - Preconditions.checkNotNull(eventListener); - getRootContext().addEventListener(eventListener); - } - - public synchronized Context getRootContext() { - Preconditions.checkState(context != null, "Context is not yet available. " + - "Ensure that listen(...) is called prior to calling this method."); - return context; - } - - /** - * The root handler, which will display the paths at which all handlers are registered. - */ - private class RootHandler extends TextResponseHandler { - public RootHandler() { - super("text/html"); - } - - @Override - public Iterable<String> getLines(HttpServletRequest request) { - List<String> lines = Lists.newArrayList(); - lines.add("<html>"); - for (String handler : Ordering.natural().sortedCopy(registeredEndpoints)) { - lines.add(String.format("<a href='%s'>%s</a><br />", handler, handler)); - } - lines.add("</html>"); - return lines; - } - } -} http://git-wip-us.apache.org/repos/asf/aurora/blob/356eeac9/commons/src/main/java/org/apache/aurora/common/net/http/RequestLogger.java ---------------------------------------------------------------------- diff --git a/commons/src/main/java/org/apache/aurora/common/net/http/RequestLogger.java b/commons/src/main/java/org/apache/aurora/common/net/http/RequestLogger.java deleted file mode 100644 index 8677880..0000000 --- a/commons/src/main/java/org/apache/aurora/common/net/http/RequestLogger.java +++ /dev/null @@ -1,130 +0,0 @@ -/** - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.apache.aurora.common.net.http; - -import java.util.Locale; -import java.util.logging.Level; -import java.util.logging.Logger; - -import com.google.common.annotations.VisibleForTesting; - -import org.mortbay.component.AbstractLifeCycle; -import org.mortbay.jetty.HttpHeaders; -import org.mortbay.jetty.Request; -import org.mortbay.jetty.RequestLog; -import org.mortbay.jetty.Response; -import org.mortbay.util.DateCache; - -import org.apache.aurora.common.util.Clock; - -import static com.google.common.base.Preconditions.checkNotNull; - -/** - * A request logger that borrows formatting code from {@link org.mortbay.jetty.NCSARequestLog}, - * but removes unneeded features (writing to file) and logging to java.util.logging. - */ -public class RequestLogger extends AbstractLifeCycle implements RequestLog { - - private static final Logger LOG = Logger.getLogger(RequestLogger.class.getName()); - - private final Clock clock; - private final LogSink sink; - private final DateCache logDateCache; - - interface LogSink { - boolean isLoggable(Level level); - void log(Level level, String messagge); - } - - RequestLogger() { - this(Clock.SYSTEM_CLOCK, new LogSink() { - @Override - public boolean isLoggable(Level level) { - return LOG.isLoggable(level); - } - - @Override public void log(Level level, String message) { - LOG.log(level, message); - } - }); - } - - @VisibleForTesting - RequestLogger(Clock clock, LogSink sink) { - this.clock = checkNotNull(clock); - this.sink = checkNotNull(sink); - logDateCache = new DateCache("dd/MMM/yyyy:HH:mm:ss Z", Locale.getDefault()); - logDateCache.setTimeZoneID("GMT"); - } - - private String formatEntry(Request request, Response response) { - StringBuilder buf = new StringBuilder(); - - buf.append(request.getServerName()); - buf.append(' '); - - String addr = request.getHeader(HttpHeaders.X_FORWARDED_FOR); - if (addr == null) { - addr = request.getRemoteAddr(); - } - - buf.append(addr); - buf.append(" ["); - buf.append(logDateCache.format(request.getTimeStamp())); - buf.append("] \""); - buf.append(request.getMethod()); - buf.append(' '); - buf.append(request.getUri().toString()); - buf.append(' '); - buf.append(request.getProtocol()); - buf.append("\" "); - buf.append(response.getStatus()); - buf.append(' '); - buf.append(response.getContentCount()); - buf.append(' '); - - String referer = request.getHeader(HttpHeaders.REFERER); - if (referer == null) { - buf.append("\"-\" "); - } else { - buf.append('"'); - buf.append(referer); - buf.append("\" "); - } - - String agent = request.getHeader(HttpHeaders.USER_AGENT); - if (agent == null) { - buf.append("\"-\" "); - } else { - buf.append('"'); - buf.append(agent); - buf.append('"'); - } - - buf.append(' '); - buf.append(clock.nowMillis() - request.getTimeStamp()); - return buf.toString(); - } - - @Override - public void log(Request request, Response response) { - int statusCategory = response.getStatus() / 100; - Level level = ((statusCategory == 2) || (statusCategory == 3)) ? Level.FINE : Level.INFO; - if (!sink.isLoggable(level)) { - return; - } - - sink.log(level, formatEntry(request, response)); - } -} http://git-wip-us.apache.org/repos/asf/aurora/blob/356eeac9/commons/src/main/java/org/apache/aurora/common/net/http/filters/AbstractHttpFilter.java ---------------------------------------------------------------------- diff --git a/commons/src/main/java/org/apache/aurora/common/net/http/filters/AbstractHttpFilter.java b/commons/src/main/java/org/apache/aurora/common/net/http/filters/AbstractHttpFilter.java deleted file mode 100644 index 681a95d..0000000 --- a/commons/src/main/java/org/apache/aurora/common/net/http/filters/AbstractHttpFilter.java +++ /dev/null @@ -1,63 +0,0 @@ -/** - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.apache.aurora.common.net.http.filters; - -import java.io.IOException; - -import javax.servlet.Filter; -import javax.servlet.FilterChain; -import javax.servlet.FilterConfig; -import javax.servlet.ServletException; -import javax.servlet.ServletRequest; -import javax.servlet.ServletResponse; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; - -/** - * A filter that allows subclass to omit implementations of {@link #init(FilterConfig)} and - * {@link #destroy()}. - */ -public abstract class AbstractHttpFilter implements Filter { - - @Override - public void init(FilterConfig filterConfig) throws ServletException { - // No-op by default. - } - - @Override - public final void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) - throws IOException, ServletException { - doFilter((HttpServletRequest) request, (HttpServletResponse) response, chain); - } - - /** - * Convenience method to allow subclasses to avoid type casting that may be necessary when - * implementing {@link #doFilter(ServletRequest, ServletResponse, FilterChain)}. - * - * @param request HTTP request. - * @param response HTTP response. - * @param chain Filter chain. - * @throws IOException If there is an error reading the request or writing the response. - * @throws ServletException If the filter or chain encounters an error handling the request. - */ - public abstract void doFilter( - HttpServletRequest request, - HttpServletResponse response, - FilterChain chain) throws IOException, ServletException; - - @Override - public void destroy() { - // No-op by default. - } -} http://git-wip-us.apache.org/repos/asf/aurora/blob/356eeac9/commons/src/main/java/org/apache/aurora/common/net/http/filters/HttpStatsFilter.java ---------------------------------------------------------------------- diff --git a/commons/src/main/java/org/apache/aurora/common/net/http/filters/HttpStatsFilter.java b/commons/src/main/java/org/apache/aurora/common/net/http/filters/HttpStatsFilter.java deleted file mode 100644 index 493018a..0000000 --- a/commons/src/main/java/org/apache/aurora/common/net/http/filters/HttpStatsFilter.java +++ /dev/null @@ -1,158 +0,0 @@ -/** - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.apache.aurora.common.net.http.filters; - -import java.io.IOException; -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; -import java.lang.reflect.Method; -import java.util.concurrent.atomic.AtomicLong; -import java.util.logging.Logger; - -import javax.servlet.FilterChain; -import javax.servlet.ServletException; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; -import javax.ws.rs.core.Context; - -import com.google.common.annotations.VisibleForTesting; -import com.google.common.base.Preconditions; -import com.google.common.cache.CacheBuilder; -import com.google.common.cache.CacheLoader; -import com.google.common.cache.LoadingCache; -import com.google.inject.Inject; -import com.sun.jersey.api.core.ExtendedUriInfo; -import com.sun.jersey.api.model.AbstractResourceMethod; -import com.sun.jersey.spi.container.ContainerRequest; -import com.sun.jersey.spi.container.ContainerResponse; -import com.sun.jersey.spi.container.ContainerResponseFilter; - -import org.apache.aurora.common.collections.Pair; -import org.apache.aurora.common.stats.SlidingStats; -import org.apache.aurora.common.stats.Stats; -import org.apache.aurora.common.util.Clock; - -/** - * An HTTP filter that exports counts and timing for requests based on response code. - */ -public class HttpStatsFilter extends AbstractHttpFilter implements ContainerResponseFilter { - /** - * Methods tagged with this annotation will be intercepted and stats will be tracked accordingly. - */ - @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.METHOD) - public @interface TrackRequestStats { - /** - * Indicates the identifier to use when tracking requests with this annotation. - */ - String value(); - } - - private static final Logger LOG = Logger.getLogger(HttpStatsFilter.class.getName()); - - @VisibleForTesting - static final String REQUEST_START_TIME = "request_start_time"; - - private final Clock clock; - @Context private ExtendedUriInfo extendedUriInfo; - - @VisibleForTesting - final LoadingCache<Pair<String, Integer>, SlidingStats> requestCounters = - CacheBuilder.newBuilder() - .build(new CacheLoader<Pair<String, Integer>, SlidingStats>() { - @Override - public SlidingStats load(Pair<String, Integer> identifierAndStatus) { - return new SlidingStats("http_" + identifierAndStatus.getFirst() + "_" - + identifierAndStatus.getSecond() + "_responses", "nanos"); - } - }); - - @Context private HttpServletRequest servletRequest; - - @VisibleForTesting - final LoadingCache<Integer, SlidingStats> statusCounters = CacheBuilder.newBuilder() - .build(new CacheLoader<Integer, SlidingStats>() { - @Override - public SlidingStats load(Integer status) { - return new SlidingStats("http_" + status + "_responses", "nanos"); - } - }); - - @VisibleForTesting - final AtomicLong exceptionCount = Stats.exportLong("http_request_exceptions"); - - @Inject - public HttpStatsFilter(Clock clock) { - this.clock = Preconditions.checkNotNull(clock); - } - - private void trackStats(int status) { - long endTime = clock.nowNanos(); - - Object startTimeAttribute = servletRequest.getAttribute(REQUEST_START_TIME); - if (startTimeAttribute == null) { - LOG.fine("No start time attribute was found on the request, this filter should be wired" - + " as both a servlet filter and a container filter."); - return; - } - - long elapsed = endTime - ((Long) startTimeAttribute).longValue(); - statusCounters.getUnchecked(status).accumulate(elapsed); - - AbstractResourceMethod matchedMethod = extendedUriInfo.getMatchedMethod(); - // It's possible for no method to have matched, e.g. in the case of a 404, don't let those - // cases lead to an exception and a 500 response. - if (matchedMethod == null) { - return; - } - - TrackRequestStats trackRequestStats = matchedMethod.getAnnotation(TrackRequestStats.class); - - if (trackRequestStats == null) { - Method method = matchedMethod.getMethod(); - LOG.fine("The method that handled this request (" + method.getDeclaringClass() + "#" - + method.getName() + ") is not annotated with " + TrackRequestStats.class.getSimpleName() - + ". No request stats will recorded."); - return; - } - - requestCounters.getUnchecked(Pair.of(trackRequestStats.value(), status)).accumulate(elapsed); - } - - @Override - public ContainerResponse filter(ContainerRequest request, ContainerResponse response) { - trackStats(response.getStatus()); - - return response; - } - - @Override - public void doFilter(HttpServletRequest request, HttpServletResponse response, FilterChain chain) - throws IOException, ServletException { - - long startTime = clock.nowNanos(); - request.setAttribute(REQUEST_START_TIME, startTime); - - try { - chain.doFilter(request, response); - } catch (IOException e) { - exceptionCount.incrementAndGet(); - throw e; - } catch (ServletException e) { - exceptionCount.incrementAndGet(); - throw e; - } - } -} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/aurora/blob/356eeac9/commons/src/main/java/org/apache/aurora/common/net/http/handlers/ThriftServlet.java ---------------------------------------------------------------------- diff --git a/commons/src/main/java/org/apache/aurora/common/net/http/handlers/ThriftServlet.java b/commons/src/main/java/org/apache/aurora/common/net/http/handlers/ThriftServlet.java deleted file mode 100644 index 540ab69..0000000 --- a/commons/src/main/java/org/apache/aurora/common/net/http/handlers/ThriftServlet.java +++ /dev/null @@ -1,70 +0,0 @@ -/** - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.apache.aurora.common.net.http.handlers; - -import com.google.common.base.Preconditions; -import com.google.inject.Inject; -import com.google.inject.name.Named; -import org.apache.aurora.common.base.Closure; -import org.apache.aurora.common.net.monitoring.TrafficMonitor; -import org.antlr.stringtemplate.StringTemplate; - -import javax.servlet.ServletException; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; -import java.io.IOException; -import java.util.Set; - -/** - * Servlet to display live information about registered thrift clients and servers. - * - * @author William Farner - */ -public class ThriftServlet extends StringTemplateServlet { - - /** - * {@literal @Named} binding key for client monitor. - */ - public static final String THRIFT_CLIENT_MONITORS = - "com.twitter.common.net.http.handlers.ThriftServlet.THRIFT_CLIENT_MONITORS"; - - /** - * {@literal @Named} binding key for server monitor. - */ - public static final String THRIFT_SERVER_MONITORS = - "com.twitter.common.net.http.handlers.ThriftServlet.THRIFT_SERVER_MONITORS"; - - private Set<TrafficMonitor> clientMonitors; - private Set<TrafficMonitor> serverMonitors; - - @Inject - public ThriftServlet( - @Named(ThriftServlet.THRIFT_CLIENT_MONITORS) Set<TrafficMonitor> clientMonitors, - @Named(ThriftServlet.THRIFT_SERVER_MONITORS) Set<TrafficMonitor> serverMonitors) { - super("thrift", true); - this.clientMonitors = Preconditions.checkNotNull(clientMonitors); - this.serverMonitors = Preconditions.checkNotNull(serverMonitors); - } - - @Override - protected void doGet(HttpServletRequest req, HttpServletResponse resp) - throws ServletException, IOException { - writeTemplate(resp, new Closure<StringTemplate>() { - @Override public void execute(StringTemplate template) { - template.setAttribute("clientMonitors", clientMonitors); - template.setAttribute("serverMonitors", serverMonitors); - } - }); - } -} http://git-wip-us.apache.org/repos/asf/aurora/blob/356eeac9/commons/src/main/java/org/apache/aurora/common/net/loadbalancing/LeastConnectedStrategy.java ---------------------------------------------------------------------- diff --git a/commons/src/main/java/org/apache/aurora/common/net/loadbalancing/LeastConnectedStrategy.java b/commons/src/main/java/org/apache/aurora/common/net/loadbalancing/LeastConnectedStrategy.java deleted file mode 100644 index e0beb25..0000000 --- a/commons/src/main/java/org/apache/aurora/common/net/loadbalancing/LeastConnectedStrategy.java +++ /dev/null @@ -1,170 +0,0 @@ -/** - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.apache.aurora.common.net.loadbalancing; - -import java.util.Collection; -import java.util.Map; -import java.util.Set; -import java.util.SortedSet; -import java.util.logging.Logger; - -import com.google.common.base.Preconditions; -import com.google.common.collect.Lists; -import com.google.common.collect.Maps; -import com.google.common.collect.Sets; - -import org.apache.aurora.common.net.pool.ResourceExhaustedException; - -/** - * A load balancer that attempts to direct load towards a backend that has the fewest leased - * connections. - * - * @author William Farner - */ -public class LeastConnectedStrategy<S> extends StaticLoadBalancingStrategy<S> { - private static final Logger LOG = Logger.getLogger(LeastConnectedStrategy.class.getName()); - - // Maps from backends to the number of connections made to them. - private final Map<S, ConnectionStats> connections = Maps.newHashMap(); - - // Manages sorting of connection counts, with a reference back to the backend. - private final SortedSet<ConnectionStats> connectionStats = Sets.newTreeSet(); - - /** - * Encapsulates a set of connection stats that allow connections to be sorted as per the least - * connected strategy. - */ - private class ConnectionStats implements Comparable<ConnectionStats> { - final S connectionKey; - final int connectionId; - int activeCount = 0; // Stores the total number of active connections. - long useCount = 0; // Stores the total number times a connection has been used. - - ConnectionStats(S connectionKey, int connectionId) { - this.connectionKey = connectionKey; - this.connectionId = connectionId; - } - - @Override - public int compareTo(ConnectionStats other) { - // Sort by number of active connections first. - int difference = activeCount - other.activeCount; - if (difference != 0) { - return difference; - } - - // Sub-sort by total number of times a connection has been used (this will ensure that - // all backends are exercised). - long useDifference = useCount - other.useCount; - if (useDifference != 0) { - return Long.signum(useDifference); - } - - // If the above two are equal, break the tie using the connection id. - return connectionId - other.connectionId; - } - - @Override - public boolean equals(Object o) { - // We use ConnectionStats in a sorted container and so we need to have an equals - // implementation consistent with compareTo, ie: - // (x.compareTo(y) == 0) == x.equals(y) - // We accomplish this directly. - - @SuppressWarnings("unchecked") - ConnectionStats other = (ConnectionStats) o; - return compareTo(other) == 0; - } - - @Override - public String toString() { - return String.format("%d-%d", activeCount, useCount); - } - } - - @Override - protected Collection<S> onBackendsOffered(Set<S> backends) { - Map<S, ConnectionStats> newConnections = Maps.newHashMapWithExpectedSize(backends.size()); - Collection<ConnectionStats> newConnectionStats = - Lists.newArrayListWithCapacity(backends.size()); - - // Recreate all connection stats since their ordering may have changed and this is used for - // comparison tie breaks. - int backendId = 0; - for (S backend : backends) { - ConnectionStats stats = new ConnectionStats(backend, backendId++); - - // Retain the activeCount for existing backends to prevent dogpiling existing active servers - ConnectionStats existing = connections.get(backend); - if (existing != null) { - stats.activeCount = existing.activeCount; - } - - newConnections.put(backend, stats); - newConnectionStats.add(stats); - } - - connections.clear(); - connections.putAll(newConnections); - connectionStats.clear(); - connectionStats.addAll(newConnectionStats); - - return connections.keySet(); - } - - @Override - public S nextBackend() throws ResourceExhaustedException { - Preconditions.checkState(connections.size() == connectionStats.size()); - - if (connectionStats.isEmpty()) { - throw new ResourceExhaustedException("No backends."); - } - - return connectionStats.first().connectionKey; - } - - @Override - public void addConnectResult(S backendKey, ConnectionResult result, long connectTimeNanos) { - Preconditions.checkNotNull(backendKey); - Preconditions.checkState(connections.size() == connectionStats.size()); - Preconditions.checkNotNull(result); - - ConnectionStats stats = connections.get(backendKey); - Preconditions.checkNotNull(stats); - - Preconditions.checkState(connectionStats.remove(stats)); - if (result == ConnectionResult.SUCCESS) { - stats.activeCount++; - } - stats.useCount++; - Preconditions.checkState(connectionStats.add(stats)); - } - - @Override - public void connectionReturned(S backendKey) { - Preconditions.checkNotNull(backendKey); - Preconditions.checkState(connections.size() == connectionStats.size()); - - ConnectionStats stats = connections.get(backendKey); - Preconditions.checkNotNull(stats); - - if (stats.activeCount > 0) { - Preconditions.checkState(connectionStats.remove(stats)); - stats.activeCount--; - Preconditions.checkState(connectionStats.add(stats)); - } else { - LOG.warning("connection stats dropped below zero, ignoring"); - } - } -} http://git-wip-us.apache.org/repos/asf/aurora/blob/356eeac9/commons/src/main/java/org/apache/aurora/common/net/loadbalancing/LoadBalancer.java ---------------------------------------------------------------------- diff --git a/commons/src/main/java/org/apache/aurora/common/net/loadbalancing/LoadBalancer.java b/commons/src/main/java/org/apache/aurora/common/net/loadbalancing/LoadBalancer.java deleted file mode 100644 index b15137d..0000000 --- a/commons/src/main/java/org/apache/aurora/common/net/loadbalancing/LoadBalancer.java +++ /dev/null @@ -1,76 +0,0 @@ -/** - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.apache.aurora.common.net.loadbalancing; - -import org.apache.aurora.common.base.Closure; -import org.apache.aurora.common.net.pool.ResourceExhaustedException; -import org.apache.aurora.common.net.loadbalancing.LoadBalancingStrategy.ConnectionResult; - -import java.util.Collection; -import java.util.Set; - -/** - * A load balancer, which will be used to determine which of a set of backends should be connected - * to for service calls. It is expected that the backends themselves can be changed at any time, - * and the load balancer should immediately restrict itself to using only those backends. - * - * It is likely that the load balancer implementation will periodically receive information about - * backends that it technically should no longer know about. An example is calls to - * {@link #requestResult(Object, RequestResult, long)} and {@link #released(Object)} for - * in-flight requests after backends were changed by {@link #offerBackends(Set, Closure)}. - * - * @author William Farner - */ -public interface LoadBalancer<K> extends RequestTracker<K> { - - /** - * Offers a set of backends that the load balancer should choose from to distribute load amongst. - * - * @param offeredBackends Backends to choose from. - * @param onBackendsChosen A callback that should be notified when the offered backends have been - * (re)chosen from. - */ - void offerBackends(Set<K> offeredBackends, Closure<Collection<K>> onBackendsChosen); - - /** - * Gets the next backend that a request should be sent to. - * - * @return Next backend to send a request. - * @throws ResourceExhaustedException If there are no available backends. - */ - K nextBackend() throws ResourceExhaustedException; - - /** - * Signals the load balancer that a connection was made. - * - * @param backend The backend that was connected to. - * @param connectTimeNanos The time spent waiting for the connection to be established. - */ - void connected(K backend, long connectTimeNanos); - - /** - * Signals the load balancer that a connection was attempted, but failed. - * - * @param backend The backend to which connection attempt was made. - * @param result The result of the connection attempt (only FAILED and TIMEOUT are permitted). - */ - void connectFailed(K backend, ConnectionResult result); - - /** - * Signals the load balancer that a connection was released, and is idle. - * - * @param connection Idle connection. - */ - void released(K connection); -} http://git-wip-us.apache.org/repos/asf/aurora/blob/356eeac9/commons/src/main/java/org/apache/aurora/common/net/loadbalancing/LoadBalancerImpl.java ---------------------------------------------------------------------- diff --git a/commons/src/main/java/org/apache/aurora/common/net/loadbalancing/LoadBalancerImpl.java b/commons/src/main/java/org/apache/aurora/common/net/loadbalancing/LoadBalancerImpl.java deleted file mode 100644 index 30e77c9..0000000 --- a/commons/src/main/java/org/apache/aurora/common/net/loadbalancing/LoadBalancerImpl.java +++ /dev/null @@ -1,122 +0,0 @@ -/** - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.apache.aurora.common.net.loadbalancing; - -import java.util.Collection; -import java.util.Set; - -import com.google.common.base.Preconditions; -import com.google.common.collect.ImmutableSet; - -import org.apache.aurora.common.base.Closure; -import org.apache.aurora.common.net.loadbalancing.LoadBalancingStrategy.ConnectionResult; -import org.apache.aurora.common.net.pool.ResourceExhaustedException; - -/** - * Implementation of a load balancer, that uses a pluggable {@link LoadBalancingStrategy} to define - * actual load balancing behavior. This class handles the responsibility of associating connections - * with backends. - * - * Calls to {@link #connected(Object, long)}, - * {@link #requestResult(Object, RequestResult, long)}, and {@link #released(Object)} will not - * be forwarded for unknown backends/connections. - * - * @author William Farner - */ -public class LoadBalancerImpl<K> implements LoadBalancer<K> { - - private final LoadBalancingStrategy<K> strategy; - - private Set<K> offeredBackends = ImmutableSet.of(); - - /** - * Creates a new load balancer that will use the given strategy. - * - * @param strategy Strategy to delegate load balancing work to. - */ - public LoadBalancerImpl(LoadBalancingStrategy<K> strategy) { - this.strategy = Preconditions.checkNotNull(strategy); - } - - @Override - public synchronized void offerBackends(Set<K> offeredBackends, - final Closure<Collection<K>> onBackendsChosen) { - this.offeredBackends = ImmutableSet.copyOf(offeredBackends); - strategy.offerBackends(offeredBackends, new Closure<Collection<K>>() { - @Override public void execute(Collection<K> chosenBackends) { - onBackendsChosen.execute(chosenBackends); - } - }); - } - - @Override - public synchronized K nextBackend() throws ResourceExhaustedException { - return strategy.nextBackend(); - } - - @Override - public synchronized void connected(K backend, long connectTimeNanos) { - Preconditions.checkNotNull(backend); - - if (!hasBackend(backend)) return; - - strategy.addConnectResult(backend, ConnectionResult.SUCCESS, connectTimeNanos); - } - - private boolean hasBackend(K backend) { - return offeredBackends.contains(backend); - } - - @Override - public synchronized void connectFailed(K backend, ConnectionResult result) { - Preconditions.checkNotNull(backend); - Preconditions.checkNotNull(result); - Preconditions.checkArgument(result != ConnectionResult.SUCCESS); - - if (!hasBackend(backend)) return; - - strategy.addConnectResult(backend, result, 0); - } - - @Override - public synchronized void released(K backend) { - Preconditions.checkNotNull(backend); - - if (!hasBackend(backend)) return; - - strategy.connectionReturned(backend); - } - - @Override - public synchronized void requestResult(K backend, RequestResult result, long requestTimeNanos) { - Preconditions.checkNotNull(backend); - Preconditions.checkNotNull(result); - - if (!hasBackend(backend)) return; - - strategy.addRequestResult(backend, result, requestTimeNanos); - } - - /** - * Convenience method to create a new load balancer. - * - * @param strategy Strategy to use. - * @param <K> Backend type. - * @return A new load balancer. - */ - public static <K> LoadBalancerImpl<K> - create(LoadBalancingStrategy<K> strategy) { - return new LoadBalancerImpl<K>(strategy); - } -} http://git-wip-us.apache.org/repos/asf/aurora/blob/356eeac9/commons/src/main/java/org/apache/aurora/common/net/loadbalancing/LoadBalancingStrategy.java ---------------------------------------------------------------------- diff --git a/commons/src/main/java/org/apache/aurora/common/net/loadbalancing/LoadBalancingStrategy.java b/commons/src/main/java/org/apache/aurora/common/net/loadbalancing/LoadBalancingStrategy.java deleted file mode 100644 index 7f33416..0000000 --- a/commons/src/main/java/org/apache/aurora/common/net/loadbalancing/LoadBalancingStrategy.java +++ /dev/null @@ -1,79 +0,0 @@ -/** - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.apache.aurora.common.net.loadbalancing; - -import org.apache.aurora.common.base.Closure; -import org.apache.aurora.common.net.pool.ResourceExhaustedException; - -import java.util.Collection; -import java.util.Set; - -/** - * A strategy for balancing request load among backends. - * - * Strategies should be externally synchronized, and therefore do not have to worry about reentrant - * access. - * - * @author William Farner - */ -public interface LoadBalancingStrategy<K> { - - /** - * Offers a set of backends that the load balancer should choose from to distribute load amongst. - * - * @param offeredBackends Backends to choose from. - * @param onBackendsChosen A callback that should be notified when the offered backends have been - * (re)chosen from. - */ - public void offerBackends(Set<K> offeredBackends, Closure<Collection<K>> onBackendsChosen); - - /** - * Gets the next backend that a request should be sent to. - * - * @return Next backend to send a request. - * @throws ResourceExhaustedException If there are no available backends. - */ - public K nextBackend() throws ResourceExhaustedException; - - /** - * Offers information about a connection result. - * - * @param key Backend key. - * @param result Connection result. - * @param connectTimeNanos Time spent waiting for connection to be established. - */ - public void addConnectResult(K key, ConnectionResult result, long connectTimeNanos); - - /** - * Offers information about a connection that was returned. - * - * @param key Backend key. - */ - public void connectionReturned(K key); - - /** - * Offers information about a request result. - * - * @param key Backend key. - * @param result Request result. - * @param requestTimeNanos Time spent waiting for a connection to be established. - */ - public void addRequestResult(K key, RequestTracker.RequestResult result, long requestTimeNanos); - - enum ConnectionResult { - FAILED, - TIMEOUT, - SUCCESS - } -} http://git-wip-us.apache.org/repos/asf/aurora/blob/356eeac9/commons/src/main/java/org/apache/aurora/common/net/loadbalancing/MarkDeadStrategy.java ---------------------------------------------------------------------- diff --git a/commons/src/main/java/org/apache/aurora/common/net/loadbalancing/MarkDeadStrategy.java b/commons/src/main/java/org/apache/aurora/common/net/loadbalancing/MarkDeadStrategy.java deleted file mode 100644 index 05a4056..0000000 --- a/commons/src/main/java/org/apache/aurora/common/net/loadbalancing/MarkDeadStrategy.java +++ /dev/null @@ -1,220 +0,0 @@ -/** - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.apache.aurora.common.net.loadbalancing; - -import com.google.common.base.Function; -import com.google.common.base.Preconditions; -import com.google.common.base.Predicate; -import com.google.common.base.Predicates; -import com.google.common.collect.Iterables; -import com.google.common.collect.Maps; -import com.google.common.collect.Sets; -import org.apache.aurora.common.base.Closure; -import org.apache.aurora.common.net.pool.ResourceExhaustedException; -import org.apache.aurora.common.net.loadbalancing.RequestTracker.RequestResult; -import org.apache.aurora.common.util.BackoffDecider; - -import java.util.Collection; -import java.util.Map; -import java.util.Set; -import java.util.logging.Logger; - -/** - * A load balancer that serves as a layer above another load balancer to mark hosts as dead, and - * prevent them from being visible to the wrapped load balancer. - * If all backends become marked as dead, they will all be unmarked. - * - * @author William Farner - */ -public class MarkDeadStrategy<S> implements LoadBalancingStrategy<S> { - private static final Logger LOG = Logger.getLogger(MarkDeadStrategy.class.getName()); - - private final LoadBalancingStrategy<S> wrappedStrategy; - private final Map<S, BackoffDecider> targets = Maps.newHashMap(); - private final Function<S, BackoffDecider> backoffFactory; - protected final Predicate<S> hostChecker; - - private Set<S> liveBackends = null; - private Closure<Collection<S>> onBackendsChosen = null; - - // Flipped when we are in "forced live" mode, where all backends are considered dead and we - // send them all traffic as a last-ditch effort. - private boolean forcedLive = false; - - /** - * Creates a mark dead strategy with a wrapped strategy, backoff decider factory - * and a predicate host checker. Use this constructor if you want to pass in the - * your own implementation of the host checker. - * - * @param wrappedStrategy one of the implementations of the load balancing strategy. - * @param backoffFactory backoff decider factory per host. - * @param hostChecker predicate that returns {@code true} if the host is alive, otherwise returns {@code false}. - */ - public MarkDeadStrategy(LoadBalancingStrategy<S> wrappedStrategy, - Function<S, BackoffDecider> backoffFactory, Predicate<S> hostChecker) { - this.wrappedStrategy = Preconditions.checkNotNull(wrappedStrategy); - this.backoffFactory = Preconditions.checkNotNull(backoffFactory); - this.hostChecker = Preconditions.checkNotNull(hostChecker); - } - - /** - * Constructor that uses a default predicate host checker that always returns true. - * This is the default constructor that all consumers of MarkDeadStrategy currently use. - * - * @param wrappedStrategy one of the implementations of the load balancing strategy. - * @param backoffFactory backoff decider factory per host. - */ - public MarkDeadStrategy(LoadBalancingStrategy<S> wrappedStrategy, - Function<S, BackoffDecider> backoffFactory) { - this(wrappedStrategy, backoffFactory, Predicates.<S>alwaysTrue()); - } - - @Override - public void offerBackends(Set<S> offeredBackends, Closure<Collection<S>> onBackendsChosen) { - this.onBackendsChosen = onBackendsChosen; - targets.keySet().retainAll(offeredBackends); - for (S backend : offeredBackends) { - if (!targets.containsKey(backend)) { - targets.put(backend, backoffFactory.apply(backend)); - } - } - - adjustBackends(); - } - - @Override - public void addConnectResult(S backendKey, ConnectionResult result, long connectTimeNanos) { - Preconditions.checkNotNull(backendKey); - Preconditions.checkNotNull(result); - - BackoffDecider decider = targets.get(backendKey); - Preconditions.checkNotNull(decider); - - addResult(decider, result); - if (shouldNotifyFor(backendKey)) { - wrappedStrategy.addConnectResult(backendKey, result, connectTimeNanos); - } - } - - @Override - public void connectionReturned(S backendKey) { - Preconditions.checkNotNull(backendKey); - - if (shouldNotifyFor(backendKey)) { - wrappedStrategy.connectionReturned(backendKey); - } - } - - @Override - public void addRequestResult(S requestKey, RequestResult result, - long requestTimeNanos) { - Preconditions.checkNotNull(requestKey); - Preconditions.checkNotNull(result); - - BackoffDecider decider = targets.get(requestKey); - Preconditions.checkNotNull(decider); - - addResult(decider, result); - if (shouldNotifyFor(requestKey)) { - wrappedStrategy.addRequestResult(requestKey, result, requestTimeNanos); - } - } - - private void addResult(BackoffDecider decider, ConnectionResult result) { - switch (result) { - case FAILED: - case TIMEOUT: - addResult(decider, false); - break; - case SUCCESS: - addResult(decider, true); - break; - default: - throw new UnsupportedOperationException("Unhandled result type " + result); - } - } - - private void addResult(BackoffDecider decider, RequestTracker.RequestResult result) { - switch (result) { - case FAILED: - case TIMEOUT: - addResult(decider, false); - break; - case SUCCESS: - addResult(decider, true); - break; - default: - throw new UnsupportedOperationException("Unhandled result type " + result); - } - } - - private void addResult(BackoffDecider decider, boolean success) { - if (success) { - decider.addSuccess(); - } else { - decider.addFailure(); - } - - // Check if any of the backends have moved into or out of dead state. - for (Map.Entry<S, BackoffDecider> entry : targets.entrySet()) { - boolean dead = entry.getValue().shouldBackOff(); - boolean markedDead = !liveBackends.contains(entry.getKey()); - - // only check the servers that were marked dead before and see if we can - // connect to them, otherwise set dead to true. - if (markedDead && !dead) { - boolean alive = hostChecker.apply(entry.getKey()); - if (!alive) { - entry.getValue().transitionToBackOff(0, true); - } - dead = !alive; - } - - if (dead && !markedDead && forcedLive) { - // Do nothing here. Since we have forced all backends to be live, we don't want to - // continually advertise the backend list to the wrapped strategy. - } else if (dead != markedDead || !dead && forcedLive) { - adjustBackends(); - break; - } - } - } - - private boolean shouldNotifyFor(S backend) { - return liveBackends.contains(backend); - } - - private final Predicate<S> deadTargetFilter = new Predicate<S>() { - @Override public boolean apply(S backend) { - return !targets.get(backend).shouldBackOff(); - } - }; - - private void adjustBackends() { - liveBackends = Sets.newHashSet(Iterables.filter(targets.keySet(), deadTargetFilter)); - if (liveBackends.isEmpty()) { - liveBackends = targets.keySet(); - forcedLive = true; - } else { - forcedLive = false; - } - LOG.info("Observed backend state change, changing live backends to " + liveBackends); - wrappedStrategy.offerBackends(liveBackends, onBackendsChosen); - } - - @Override - public S nextBackend() throws ResourceExhaustedException { - return wrappedStrategy.nextBackend(); - } -} http://git-wip-us.apache.org/repos/asf/aurora/blob/356eeac9/commons/src/main/java/org/apache/aurora/common/net/loadbalancing/MarkDeadStrategyWithHostCheck.java ---------------------------------------------------------------------- diff --git a/commons/src/main/java/org/apache/aurora/common/net/loadbalancing/MarkDeadStrategyWithHostCheck.java b/commons/src/main/java/org/apache/aurora/common/net/loadbalancing/MarkDeadStrategyWithHostCheck.java deleted file mode 100644 index 8170167..0000000 --- a/commons/src/main/java/org/apache/aurora/common/net/loadbalancing/MarkDeadStrategyWithHostCheck.java +++ /dev/null @@ -1,98 +0,0 @@ -/** - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.apache.aurora.common.net.loadbalancing; - -import java.util.Map; - -import com.google.common.base.Function; -import com.google.common.base.Predicate; -import com.google.common.collect.Maps; - -import org.apache.aurora.common.util.BackoffDecider; - -/** - * A load balancing strategy that extends the functionality of the mark dead strategy by - * integrating a hostChecker that allows hosts to transition out of a dead state - * if the most recent connection to the host was successful. - * - * @param <S> typically socket address of a backend host. - * @author Krishna Gade - */ -public class MarkDeadStrategyWithHostCheck<S> extends MarkDeadStrategy<S> { - - /** - * LiveHostChecker implements Filter to determine whether a host is alive based on the - * result of the most recent connection attempt to that host. It keeps a map of - * backend -> last connection result, which gets updated every time someone tries to - * add to connection result. - */ - protected static class LiveHostChecker<S> implements Predicate<S> { - private final Map<S, ConnectionResult> lastConnectionResult = Maps.newHashMap(); - - /** - * Adds the connection result of this backend to the last connection result map. - * - * @param backend typically the socket address of the backend. - * @param result result of what happened when the client tried to connect to this backend. - */ - public void addConnectResult(S backend, ConnectionResult result) { - lastConnectionResult.put(backend, result); - } - - /** - * Checks if the last connection result for this backend and returns {@code true} if it - * was {@link LoadBalancingStrategy.ConnectionResult#SUCCESS} otherwise returns {@code false}. - * - * @param backend typically the socket address of the backend. - */ - @Override public boolean apply(S backend) { - ConnectionResult result = lastConnectionResult.get(backend); - return result != null && result == ConnectionResult.SUCCESS; - } - } - - // Reference to the host checker we pass to the super class. - // We keep it here to avoid casting on every access to it. - protected final LiveHostChecker<S> liveHostChecker; - - /** - * Creates a mark dead strategy with the given wrapped strategy and backoff decider factory. - * It uses a hostChecker {@link Predicate} that allows hosts to transition out - * of a dead state if the most recent connection to the host was successful. - * - * @param wrappedStrategy one of the implementations of the load balancing strategy. - * @param backoffFactory backoff decider factory per host. - */ - public MarkDeadStrategyWithHostCheck(LoadBalancingStrategy<S> wrappedStrategy, - Function<S, BackoffDecider> backoffFactory) { - super(wrappedStrategy, backoffFactory, new LiveHostChecker<S>()); - // Casting to LiveHostChecker is safe here as that's the only predicate that we pass to super. - this.liveHostChecker = ((LiveHostChecker<S>) hostChecker); - } - - - /** - * Overrides the base class implementation by adding this connection result to the - * host checker. - * - * @param backendKey typically the socket address of the backend. - * @param result result of what happened when the client tried to connect to this backend. - * @param connectTimeNanos time took to connect to the backend in nano seconds. - */ - @Override - public void addConnectResult(S backendKey, ConnectionResult result, long connectTimeNanos) { - liveHostChecker.addConnectResult(backendKey, result); - super.addConnectResult(backendKey, result, connectTimeNanos); - } -} http://git-wip-us.apache.org/repos/asf/aurora/blob/356eeac9/commons/src/main/java/org/apache/aurora/common/net/loadbalancing/RandomStrategy.java ---------------------------------------------------------------------- diff --git a/commons/src/main/java/org/apache/aurora/common/net/loadbalancing/RandomStrategy.java b/commons/src/main/java/org/apache/aurora/common/net/loadbalancing/RandomStrategy.java deleted file mode 100644 index a8da980..0000000 --- a/commons/src/main/java/org/apache/aurora/common/net/loadbalancing/RandomStrategy.java +++ /dev/null @@ -1,57 +0,0 @@ -/** - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.apache.aurora.common.net.loadbalancing; - -import com.google.common.annotations.VisibleForTesting; -import com.google.common.base.Preconditions; -import com.google.common.collect.ImmutableList; -import com.google.common.collect.Lists; -import org.apache.aurora.common.net.pool.ResourceExhaustedException; - -import java.util.Collection; -import java.util.List; -import java.util.Random; -import java.util.Set; - -/** - * A load balancer that selects a random backend each time a request is made.. - * - * @author William Farner - */ -public class RandomStrategy<S> extends StaticLoadBalancingStrategy<S> { - - private List<S> targets = Lists.newArrayList(); - private final Random random; - - public RandomStrategy() { - this(new Random()); - } - - @VisibleForTesting - RandomStrategy(Random random) { - this.random = Preconditions.checkNotNull(random); - } - - @Override - protected Collection<S> onBackendsOffered(Set<S> targets) { - this.targets = ImmutableList.copyOf(targets); - return this.targets; - } - - @Override - public S nextBackend() throws ResourceExhaustedException { - if (targets.isEmpty()) throw new ResourceExhaustedException("No backends."); - return targets.get(random.nextInt(targets.size())); - } -} http://git-wip-us.apache.org/repos/asf/aurora/blob/356eeac9/commons/src/main/java/org/apache/aurora/common/net/loadbalancing/RequestTracker.java ---------------------------------------------------------------------- diff --git a/commons/src/main/java/org/apache/aurora/common/net/loadbalancing/RequestTracker.java b/commons/src/main/java/org/apache/aurora/common/net/loadbalancing/RequestTracker.java deleted file mode 100644 index 745e2f8..0000000 --- a/commons/src/main/java/org/apache/aurora/common/net/loadbalancing/RequestTracker.java +++ /dev/null @@ -1,37 +0,0 @@ -/** - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.apache.aurora.common.net.loadbalancing; - -/** - * Tracks requests made to a backend service. - * - * @author William Farner - */ -public interface RequestTracker<T> { - - /** - * Informs the tracker of a completed request. - * - * @param key Key to identify the owner of the request. - * @param result Result of the request. - * @param requestTimeNanos Time duration spent waiting for the request to complete. - */ - void requestResult(T key, RequestResult result, long requestTimeNanos); - - enum RequestResult { - FAILED, - TIMEOUT, - SUCCESS - } -} http://git-wip-us.apache.org/repos/asf/aurora/blob/356eeac9/commons/src/main/java/org/apache/aurora/common/net/loadbalancing/RoundRobinStrategy.java ---------------------------------------------------------------------- diff --git a/commons/src/main/java/org/apache/aurora/common/net/loadbalancing/RoundRobinStrategy.java b/commons/src/main/java/org/apache/aurora/common/net/loadbalancing/RoundRobinStrategy.java deleted file mode 100644 index 5678331..0000000 --- a/commons/src/main/java/org/apache/aurora/common/net/loadbalancing/RoundRobinStrategy.java +++ /dev/null @@ -1,49 +0,0 @@ -/** - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.apache.aurora.common.net.loadbalancing; - -import com.google.common.collect.Iterators; -import com.google.common.collect.Lists; -import org.apache.aurora.common.net.pool.ResourceExhaustedException; - -import java.util.Collection; -import java.util.Collections; -import java.util.Iterator; -import java.util.List; -import java.util.Set; - -/** - * A load balancer that distributes load by randomizing the list of available backends, and then - * rotating through them evenly. - * - * @author William Farner - */ -public class RoundRobinStrategy<S> extends StaticLoadBalancingStrategy<S> { - - private Iterator<S> iterator = Iterators.emptyIterator(); - - @Override - protected Collection<S> onBackendsOffered(Set<S> targets) { - List<S> newTargets = Lists.newArrayList(targets); - Collections.shuffle(newTargets); - iterator = Iterators.cycle(newTargets); - return newTargets; - } - - @Override - public S nextBackend() throws ResourceExhaustedException { - if (!iterator.hasNext()) throw new ResourceExhaustedException("No backends available!"); - return iterator.next(); - } -} http://git-wip-us.apache.org/repos/asf/aurora/blob/356eeac9/commons/src/main/java/org/apache/aurora/common/net/loadbalancing/StaticLoadBalancingStrategy.java ---------------------------------------------------------------------- diff --git a/commons/src/main/java/org/apache/aurora/common/net/loadbalancing/StaticLoadBalancingStrategy.java b/commons/src/main/java/org/apache/aurora/common/net/loadbalancing/StaticLoadBalancingStrategy.java deleted file mode 100644 index b333b44..0000000 --- a/commons/src/main/java/org/apache/aurora/common/net/loadbalancing/StaticLoadBalancingStrategy.java +++ /dev/null @@ -1,61 +0,0 @@ -/** - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.apache.aurora.common.net.loadbalancing; - -import org.apache.aurora.common.base.Closure; -import org.apache.aurora.common.net.loadbalancing.RequestTracker.RequestResult; - -import java.util.Collection; -import java.util.Set; - -/** - * A baseclass for LoadBalancingStrategies that use a static set of backends they are - * {@link #offerBackends(java.util.Set, Closure) offered}. Also acts as an - * adapter, providing no-op implementations of all other LoadBalancingStrategy methods that only - * need be overridden as required by subclass features. - * - * @author John Sirois - */ -abstract class StaticLoadBalancingStrategy<K> implements LoadBalancingStrategy<K> { - - @Override - public final void offerBackends(Set<K> offeredBackends, Closure<Collection<K>> onBackendsChosen) { - onBackendsChosen.execute(onBackendsOffered(offeredBackends)); - } - - /** - * Subclasses must override and return a collection of the backends actually chosen for use until - * the next offer round. - * - * @param offeredBackends The backends offered in a {@link - * #offerBackends(java.util.Set, Closure)} event. - * @return The collection of backends that will be used until the next offer event. - */ - protected abstract Collection<K> onBackendsOffered(Set<K> offeredBackends); - - @Override - public void addConnectResult(K backendKey, ConnectionResult result, long connectTimeNanos) { - // No-op. - } - - @Override - public void connectionReturned(K backendKey) { - // No-op. - } - - @Override - public void addRequestResult(K requestKey, RequestResult result, long requestTimeNanos) { - // No-op. - } -} http://git-wip-us.apache.org/repos/asf/aurora/blob/356eeac9/commons/src/main/java/org/apache/aurora/common/net/loadbalancing/SubsetStrategy.java ---------------------------------------------------------------------- diff --git a/commons/src/main/java/org/apache/aurora/common/net/loadbalancing/SubsetStrategy.java b/commons/src/main/java/org/apache/aurora/common/net/loadbalancing/SubsetStrategy.java deleted file mode 100644 index 0b852cf..0000000 --- a/commons/src/main/java/org/apache/aurora/common/net/loadbalancing/SubsetStrategy.java +++ /dev/null @@ -1,89 +0,0 @@ -/** - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.apache.aurora.common.net.loadbalancing; - -import com.google.common.base.Preconditions; -import com.google.common.collect.ImmutableSet; -import com.google.common.collect.Lists; -import com.google.common.collect.Sets; -import org.apache.aurora.common.base.Closure; -import org.apache.aurora.common.net.pool.ResourceExhaustedException; -import org.apache.aurora.common.net.loadbalancing.RequestTracker.RequestResult; - -import java.util.Collection; -import java.util.Collections; -import java.util.List; -import java.util.Set; - -/** - * A load balancer that maintains a fixed upper bound on the number of backends that will be made - * available for a wrapped load balancer. - * - * TODO(William Farner): May want to consider periodically swapping subsets. - * - * TODO(William Farner): May want to catch ResourceExhaustedExceptions from wrapped strategy and adjust - * subset if possible. - * - * @author William Farner - */ -public class SubsetStrategy<S> implements LoadBalancingStrategy<S> { - private final LoadBalancingStrategy<S> wrapped; - private final int maxBackends; - - private Set<S> backendSubset = Sets.newHashSet(); - - public SubsetStrategy(int maxBackends, LoadBalancingStrategy<S> wrapped) { - Preconditions.checkArgument(maxBackends > 0); - this.maxBackends = maxBackends; - this.wrapped = Preconditions.checkNotNull(wrapped); - } - - @Override - public void offerBackends(Set<S> offeredBackends, Closure<Collection<S>> onBackendsChosen) { - List<S> allTargets = Lists.newArrayList(offeredBackends); - Collections.shuffle(allTargets); - backendSubset = ImmutableSet.copyOf( - allTargets.subList(0, Math.min(maxBackends, allTargets.size()))); - wrapped.offerBackends(backendSubset, onBackendsChosen); - } - - @Override - public void addConnectResult(S backendKey, ConnectionResult result, - long connectTimeNanos) { - if (backendSubset.contains(backendKey)) { - wrapped.addConnectResult(backendKey, result, connectTimeNanos); - } - } - - @Override - public void connectionReturned(S backendKey) { - if (backendSubset.contains(backendKey)) { - wrapped.connectionReturned(backendKey); - } - } - - @Override - public void addRequestResult(S requestKey, RequestResult result, long requestTimeNanos) { - Preconditions.checkNotNull(requestKey); - - if (backendSubset.contains(requestKey)) { - wrapped.addRequestResult(requestKey, result, requestTimeNanos); - } - } - - @Override - public S nextBackend() throws ResourceExhaustedException { - return wrapped.nextBackend(); - } -} http://git-wip-us.apache.org/repos/asf/aurora/blob/356eeac9/commons/src/main/java/org/apache/aurora/common/net/loadbalancing/TrafficMonitorAdapter.java ---------------------------------------------------------------------- diff --git a/commons/src/main/java/org/apache/aurora/common/net/loadbalancing/TrafficMonitorAdapter.java b/commons/src/main/java/org/apache/aurora/common/net/loadbalancing/TrafficMonitorAdapter.java deleted file mode 100644 index e0c5c35..0000000 --- a/commons/src/main/java/org/apache/aurora/common/net/loadbalancing/TrafficMonitorAdapter.java +++ /dev/null @@ -1,68 +0,0 @@ -/** - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.apache.aurora.common.net.loadbalancing; - -import com.google.common.base.Preconditions; -import org.apache.aurora.common.base.Closure; -import org.apache.aurora.common.net.monitoring.TrafficMonitor; -import org.apache.aurora.common.net.pool.ResourceExhaustedException; - -import java.util.Collection; -import java.util.Set; - -/** - * @author William Farner - */ -public class TrafficMonitorAdapter<K> implements LoadBalancingStrategy<K> { - private final LoadBalancingStrategy<K> strategy; - private final TrafficMonitor<K> monitor; - - public TrafficMonitorAdapter(LoadBalancingStrategy<K> strategy, TrafficMonitor<K> monitor) { - this.strategy = Preconditions.checkNotNull(strategy); - this.monitor = Preconditions.checkNotNull(monitor); - } - - public static <K> TrafficMonitorAdapter<K> create(LoadBalancingStrategy<K> strategy, - TrafficMonitor<K> monitor) { - return new TrafficMonitorAdapter<K>(strategy, monitor); - } - - @Override - public void offerBackends(Set<K> offeredBackends, Closure<Collection<K>> onBackendsChosen) { - strategy.offerBackends(offeredBackends, onBackendsChosen); - } - - @Override - public K nextBackend() throws ResourceExhaustedException { - return strategy.nextBackend(); - } - - @Override - public void addConnectResult(K key, ConnectionResult result, long connectTimeNanos) { - strategy.addConnectResult(key, result, connectTimeNanos); - if (result == ConnectionResult.SUCCESS) monitor.connected(key); - } - - @Override - public void connectionReturned(K key) { - strategy.connectionReturned(key); - monitor.released(key); - } - - @Override - public void addRequestResult(K key, RequestTracker.RequestResult result, long requestTimeNanos) { - strategy.addRequestResult(key, result, requestTimeNanos); - monitor.requestResult(key, result, requestTimeNanos); - } -} http://git-wip-us.apache.org/repos/asf/aurora/blob/356eeac9/commons/src/main/java/org/apache/aurora/common/net/monitoring/ConnectionMonitor.java ---------------------------------------------------------------------- diff --git a/commons/src/main/java/org/apache/aurora/common/net/monitoring/ConnectionMonitor.java b/commons/src/main/java/org/apache/aurora/common/net/monitoring/ConnectionMonitor.java deleted file mode 100644 index 4d32a71..0000000 --- a/commons/src/main/java/org/apache/aurora/common/net/monitoring/ConnectionMonitor.java +++ /dev/null @@ -1,36 +0,0 @@ -/** - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.apache.aurora.common.net.monitoring; - -/** - * Monitors active connections between two hosts.. - * - * @author William Farner - */ -public interface ConnectionMonitor<K> { - - /** - * Instructs the monitor that a connection was established. - * - * @param connectionKey Key for the host that a connection was established with. - */ - public void connected(K connectionKey); - - /** - * Informs the monitor that a connection was released. - * - * @param connectionKey Key for the host that a connection was released for. - */ - public void released(K connectionKey); -}
