package com.bazaarvoice.ostrich.examples.dictionary.service; import com.bazaarvoice.ostrich.ServiceEndPoint; import com.bazaarvoice.ostrich.ServiceEndPointBuilder; import com.bazaarvoice.ostrich.registry.zookeeper.ZooKeeperServiceRegistry; import com.fasterxml.jackson.databind.ObjectMapper; import com.google.common.collect.ImmutableMap; import io.dropwizard.Application; import io.dropwizard.Configuration; import io.dropwizard.jetty.ConnectorFactory; import io.dropwizard.jetty.HttpConnectorFactory; import io.dropwizard.lifecycle.Managed; import io.dropwizard.server.DefaultServerFactory; import io.dropwizard.server.ServerFactory; import io.dropwizard.setup.Bootstrap; import io.dropwizard.setup.Environment; import org.apache.curator.framework.CuratorFramework; import javax.ws.rs.core.Response; import javax.ws.rs.core.UriBuilder; import java.net.InetAddress; import java.net.URI; import java.util.List; import java.util.Map; /** * A Dropwizard+Jersey-based client of a simple dictionary service. */ public class DictionaryService extends Application<DictionaryConfiguration> { public static Response.Status STATUS_OVERRIDE = Response.Status.OK; @Override public void initialize(Bootstrap<DictionaryConfiguration> bootstrap) { } @Override public void run(DictionaryConfiguration config, final Environment env) throws Exception { // Load the subset of the dictionary handled by this server. WordList wordList = new WordList(config.getWordFile(), config.getWordRange()); env.jersey().register(new DictionaryResource(wordList, config.getWordRange())); env.jersey().register(ToggleHealthResource.class); env.jersey().register(new IllegalArgumentExceptionMapper()); env.healthChecks().register("dictionary", new DictionaryHealthCheck()); InetAddress localhost = InetAddress.getLocalHost(); String host = localhost.getHostName(); String ip = localhost.getHostAddress(); int port = getHttpPort(config); int adminPort = getAdminHttpPort(config); // The client reads the URLs out of the payload to figure out how to connect to this server. URI serviceUri = UriBuilder.fromResource(DictionaryResource.class).scheme("http").host(ip).port(port).build(); URI adminUri = UriBuilder.fromPath("").scheme("http").host(ip).port(adminPort).build(); Map<String, ?> payload = ImmutableMap.of( "url", serviceUri, "adminUrl", adminUri, "partition", config.getWordRange()); final ServiceEndPoint endPoint = new ServiceEndPointBuilder() .withServiceName(env.getName()) .withId(host + ":" + port) .withPayload(getJson(env).writeValueAsString(payload)) .build(); final CuratorFramework curator = config.getZooKeeperConfiguration().newManagedCurator(env.lifecycle()); env.lifecycle().manage(new Managed() { ZooKeeperServiceRegistry registry = new ZooKeeperServiceRegistry(curator, env.metrics()); @Override public void start() throws Exception { registry.register(endPoint); } @Override public void stop() throws Exception { registry.unregister(endPoint); } }); } private ObjectMapper getJson(Environment env) { return env.getObjectMapper(); } private int getHttpPort(Configuration config) { ServerFactory serverFactory = config.getServerFactory(); if (!(serverFactory instanceof DefaultServerFactory)) { throw new IllegalStateException("Server factory is not an instance of DefaultServerFactory"); } List<ConnectorFactory> connectors = ((DefaultServerFactory) serverFactory).getApplicationConnectors(); for (ConnectorFactory connector : connectors) { if (connector instanceof HttpConnectorFactory) { return ((HttpConnectorFactory) connector).getPort(); } } throw new IllegalStateException("Unable to determine HTTP port"); } private int getAdminHttpPort(Configuration config) { ServerFactory serverFactory = config.getServerFactory(); if (!(serverFactory instanceof DefaultServerFactory)) { throw new IllegalStateException("Server factory is not an instance of DefaultServerFactory"); } List<ConnectorFactory> connectors = ((DefaultServerFactory) serverFactory).getAdminConnectors(); for (ConnectorFactory connector : connectors) { if (connector instanceof HttpConnectorFactory) { return ((HttpConnectorFactory) connector).getPort(); } } throw new IllegalStateException("Unable to determine admin HTTP port"); } public static void main(String[] args) throws Exception { new DictionaryService().run(args); } }