From a6610a67e3b8b3cb31b138beda9107fad96f661a Mon Sep 17 00:00:00 2001 From: Greg Brandt Date: Sat, 11 Apr 2015 01:09:26 -0700 Subject: [PATCH] helix-ui server can be programmatically started/stopped --- .../ui/HelixUIApplicationConfiguration.java | 8 ++ .../helix/ui/resource/DashboardResource.java | 16 ++- .../ui/util/DropWizardApplicationRunner.java | 104 ++++++++++++++---- 3 files changed, 104 insertions(+), 24 deletions(-) diff --git a/helix-ui/src/main/java/org/apache/helix/ui/HelixUIApplicationConfiguration.java b/helix-ui/src/main/java/org/apache/helix/ui/HelixUIApplicationConfiguration.java index 4daa29891b..6547b470c8 100644 --- a/helix-ui/src/main/java/org/apache/helix/ui/HelixUIApplicationConfiguration.java +++ b/helix-ui/src/main/java/org/apache/helix/ui/HelixUIApplicationConfiguration.java @@ -39,10 +39,18 @@ public ImmutableMap> getViewRendererConfigu return viewRendererConfiguration; } + public void setAdminMode(boolean adminMode) { + this.adminMode = adminMode; + } + public boolean isAdminMode() { return adminMode; } + public void setZkAddresses(Set zkAddresses) { + this.zkAddresses = zkAddresses; + } + public Set getZkAddresses() { return zkAddresses; } diff --git a/helix-ui/src/main/java/org/apache/helix/ui/resource/DashboardResource.java b/helix-ui/src/main/java/org/apache/helix/ui/resource/DashboardResource.java index 450c02e0b5..09915998b5 100644 --- a/helix-ui/src/main/java/org/apache/helix/ui/resource/DashboardResource.java +++ b/helix-ui/src/main/java/org/apache/helix/ui/resource/DashboardResource.java @@ -32,9 +32,11 @@ import javax.ws.rs.*; import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.Response; +import java.net.URI; import java.util.*; -@Path("/dashboard") +@Path("/") @Produces(MediaType.TEXT_HTML) public class DashboardResource { private static final List REBALANCE_MODES = ImmutableList.of( @@ -57,19 +59,25 @@ public DashboardResource(ClientCache clientCache, } @GET + public Response getRoot() { + return Response.seeOther(URI.create("/dashboard")).build(); + } + + @GET + @Path("/dashboard") public LandingView getLandingView() { return new LandingView(); } @GET - @Path("/{zkAddress}") + @Path("/dashboard/{zkAddress}") public ClusterView getClusterView(@PathParam("zkAddress") String zkAddress) throws Exception { clientCache.get(zkAddress); // n.b. will validate return getClusterView(zkAddress, null); } @GET - @Path("/{zkAddress}/{cluster}") + @Path("/dashboard/{zkAddress}/{cluster}") public ClusterView getClusterView( @PathParam("zkAddress") String zkAddress, @PathParam("cluster") String cluster) throws Exception { @@ -114,7 +122,7 @@ public ClusterView getClusterView( } @GET - @Path("/{zkAddress}/{cluster}/{resource}") + @Path("/dashboard/{zkAddress}/{cluster}/{resource}") public ResourceView getResourceView( @PathParam("zkAddress") String zkAddress, @PathParam("cluster") String cluster, diff --git a/helix-ui/src/main/java/org/apache/helix/ui/util/DropWizardApplicationRunner.java b/helix-ui/src/main/java/org/apache/helix/ui/util/DropWizardApplicationRunner.java index 24de1b865f..587d267568 100644 --- a/helix-ui/src/main/java/org/apache/helix/ui/util/DropWizardApplicationRunner.java +++ b/helix-ui/src/main/java/org/apache/helix/ui/util/DropWizardApplicationRunner.java @@ -19,17 +19,22 @@ * under the License. */ +import com.codahale.metrics.MetricRegistry; import io.dropwizard.Application; import io.dropwizard.Configuration; import io.dropwizard.cli.ServerCommand; import io.dropwizard.configuration.ConfigurationFactory; import io.dropwizard.setup.Bootstrap; import io.dropwizard.setup.Environment; +import org.apache.helix.ui.HelixUIApplication; +import org.apache.helix.ui.HelixUIApplicationConfiguration; import org.eclipse.jetty.server.Server; import org.eclipse.jetty.util.component.AbstractLifeCycle; import org.eclipse.jetty.util.component.LifeCycle; import java.io.File; +import java.lang.reflect.Field; +import java.util.List; /** * A utility to run DropWizard (http://dropwizard.io/) applications in-process. @@ -41,11 +46,11 @@ public class DropWizardApplicationRunner { * @param config An application configuration instance (with properties set) * @param applicationClass The {@link io.dropwizard.Application} implementation class * @param The configuration class - * @return A Jetty server + * @return A DropWizard server startable in-process */ @SuppressWarnings("unchecked") public static - Server createServer(T config, Class> applicationClass) throws Exception { + DropWizardServer createServer(T config, Class> applicationClass) throws Exception { // Create application final Application application = applicationClass.getConstructor().newInstance(); @@ -53,41 +58,38 @@ Server createServer(T config, Class> applicationClass) final ServerCommand serverCommand = new ServerCommand(application); final Bootstrap bootstrap = new Bootstrap(application); bootstrap.addCommand(serverCommand); - application.initialize(bootstrap); // Write a temporary config file File tmpConfigFile = new File( - System.getProperty("java.io.tmpdir"), - config.getClass().getCanonicalName() + "_" + System.currentTimeMillis()); + System.getProperty("java.io.tmpdir"), + config.getClass().getCanonicalName() + "_" + System.currentTimeMillis()); tmpConfigFile.deleteOnExit(); bootstrap.getObjectMapper().writeValue(tmpConfigFile, config); // Parse configuration ConfigurationFactory configurationFactory - = bootstrap.getConfigurationFactoryFactory() - .create((Class) config.getClass(), - bootstrap.getValidatorFactory().getValidator(), - bootstrap.getObjectMapper(), - "dw"); + = bootstrap.getConfigurationFactoryFactory() + .create((Class) config.getClass(), + bootstrap.getValidatorFactory().getValidator(), + bootstrap.getObjectMapper(), + "dw"); final T builtConfig = configurationFactory.build( - bootstrap.getConfigurationSourceProvider(), tmpConfigFile.getAbsolutePath()); + bootstrap.getConfigurationSourceProvider(), tmpConfigFile.getAbsolutePath()); // Configure logging builtConfig.getLoggingFactory() - .configure(bootstrap.getMetricRegistry(), - bootstrap.getApplication().getName()); + .configure(bootstrap.getMetricRegistry(), + bootstrap.getApplication().getName()); // Environment final Environment environment = new Environment(bootstrap.getApplication().getName(), - bootstrap.getObjectMapper(), - bootstrap.getValidatorFactory().getValidator(), - bootstrap.getMetricRegistry(), - bootstrap.getClassLoader()); + bootstrap.getObjectMapper(), + bootstrap.getValidatorFactory().getValidator(), + bootstrap.getMetricRegistry(), + bootstrap.getClassLoader()); // Initialize environment builtConfig.getMetricsFactory().configure(environment.lifecycle(), bootstrap.getMetricRegistry()); - bootstrap.run(builtConfig, environment); - application.run(builtConfig, environment); // Server final Server server = builtConfig.getServerFactory().build(environment); @@ -98,7 +100,69 @@ public void lifeCycleStopped(LifeCycle event) { } }); - return server; + return new DropWizardServer(builtConfig, bootstrap, application, environment, server, environment.metrics()); + } + + public static class DropWizardServer { + private final T builtConfig; + private final Bootstrap bootstrap; + private final Application application; + private final Environment environment; + private final Server jettyServer; + private final MetricRegistry metricRegistry; + + DropWizardServer(T builtConfig, + Bootstrap bootstrap, + Application application, + Environment environment, + Server jettyServer, + MetricRegistry metricRegistry) { + this.builtConfig = builtConfig; + this.bootstrap = bootstrap; + this.application = application; + this.environment = environment; + this.jettyServer = jettyServer; + this.metricRegistry = metricRegistry; + } + + public MetricRegistry getMetricRegistry() { + return metricRegistry; + } + + public void start() throws Exception { + application.initialize(bootstrap); + bootstrap.run(builtConfig, environment); + application.run(builtConfig, environment); + toggleManagedObjects(true); + jettyServer.start(); + } + + public void stop() throws Exception { + jettyServer.stop(); + toggleManagedObjects(false); + } + + @SuppressWarnings("unchecked") + private void toggleManagedObjects(boolean start) throws Exception { + Field managedObjectsField = environment.lifecycle().getClass().getDeclaredField("managedObjects"); + managedObjectsField.setAccessible(true); + List managedObjects = (List) managedObjectsField.get(environment.lifecycle()); + for (LifeCycle managedObject : managedObjects) { + if (start) { + managedObject.start(); + } else { + managedObject.stop(); + } + } + } + } + + public static void main(String[] args) throws Exception { + HelixUIApplicationConfiguration config + = new HelixUIApplicationConfiguration(); + DropWizardServer server + = DropWizardApplicationRunner.createServer(config, HelixUIApplication.class); + server.start(); } }