Java tutorial
/** * Copyright (C) 2012 LinkedIn Inc <opensource@linkedin.com> * * 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 com.linkedin.helix.webapp; import org.apache.commons.cli.CommandLine; import org.apache.commons.cli.CommandLineParser; import org.apache.commons.cli.GnuParser; import org.apache.commons.cli.HelpFormatter; import org.apache.commons.cli.Option; import org.apache.commons.cli.OptionBuilder; import org.apache.commons.cli.Options; import org.apache.commons.cli.ParseException; import org.restlet.Application; import org.restlet.Context; import org.restlet.Restlet; import org.restlet.Router; import org.restlet.data.MediaType; import org.restlet.data.Request; import org.restlet.data.Response; import org.restlet.resource.StringRepresentation; import org.restlet.util.Template; import com.linkedin.helix.webapp.resources.ClusterResource; import com.linkedin.helix.webapp.resources.ClustersResource; import com.linkedin.helix.webapp.resources.ConfigResource; import com.linkedin.helix.webapp.resources.ControllerResource; import com.linkedin.helix.webapp.resources.ControllerStatusUpdateResource; import com.linkedin.helix.webapp.resources.CurrentStateResource; import com.linkedin.helix.webapp.resources.CurrentStatesResource; import com.linkedin.helix.webapp.resources.ErrorResource; import com.linkedin.helix.webapp.resources.ErrorsResource; import com.linkedin.helix.webapp.resources.ExternalViewResource; import com.linkedin.helix.webapp.resources.IdealStateResource; import com.linkedin.helix.webapp.resources.InstanceResource; import com.linkedin.helix.webapp.resources.InstancesResource; import com.linkedin.helix.webapp.resources.ResourceGroupResource; import com.linkedin.helix.webapp.resources.ResourceGroupsResource; import com.linkedin.helix.webapp.resources.SchedulerTasksResource; import com.linkedin.helix.webapp.resources.StateModelResource; import com.linkedin.helix.webapp.resources.StateModelsResource; import com.linkedin.helix.webapp.resources.StatusUpdateResource; import com.linkedin.helix.webapp.resources.StatusUpdatesResource; import com.linkedin.helix.webapp.resources.ZkChildResource; import com.linkedin.helix.webapp.resources.ZkPathResource; public class RestAdminApplication extends Application { public static final String HELP = "help"; public static final String ZKSERVERADDRESS = "zkSvr"; public static final String PORT = "port"; public static final String ZKCLIENT = "zkClient"; public static final int DEFAULT_PORT = 8100; public RestAdminApplication() { super(); } public RestAdminApplication(Context context) { super(context); } @Override public Restlet createRoot() { Router router = new Router(getContext()); router.setDefaultMatchingMode(Template.MODE_EQUALS); router.attach("/clusters", ClustersResource.class); router.attach("/clusters/{clusterName}", ClusterResource.class); router.attach("/clusters/{clusterName}/resourceGroups", ResourceGroupsResource.class); router.attach("/clusters/{clusterName}/resourceGroups/{resourceName}", ResourceGroupResource.class); router.attach("/clusters/{clusterName}/instances", InstancesResource.class); router.attach("/clusters/{clusterName}/instances/{instanceName}", InstanceResource.class); router.attach("/clusters/{clusterName}/instances/{instanceName}/currentState/{resourceName}", CurrentStateResource.class); router.attach("/clusters/{clusterName}/instances/{instanceName}/statusUpdate/{resourceName}", StatusUpdateResource.class); router.attach("/clusters/{clusterName}/instances/{instanceName}/errors/{resourceName}", ErrorResource.class); router.attach("/clusters/{clusterName}/instances/{instanceName}/currentState", CurrentStatesResource.class); router.attach("/clusters/{clusterName}/instances/{instanceName}/statusUpdate", StatusUpdatesResource.class); router.attach("/clusters/{clusterName}/instances/{instanceName}/errors", ErrorsResource.class); router.attach("/clusters/{clusterName}/resourceGroups/{resourceName}/idealState", IdealStateResource.class); router.attach("/clusters/{clusterName}/resourceGroups/{resourceName}/externalView", ExternalViewResource.class); router.attach("/clusters/{clusterName}/StateModelDefs/{modelName}", StateModelResource.class); router.attach("/clusters/{clusterName}/StateModelDefs", StateModelsResource.class); router.attach("/clusters/{clusterName}/SchedulerTasks", SchedulerTasksResource.class); router.attach("/clusters/{clusterName}/Controller", ControllerResource.class); router.attach("/clusters/{clusterName}/Controller/statusUpdates/{MessageType}/{MessageId}", ControllerStatusUpdateResource.class); router.attach("/clusters/{clusterName}/configs", ConfigResource.class); router.attach("/clusters/{clusterName}/configs/{scope}", ConfigResource.class); router.attach("/clusters/{clusterName}/configs/{scope}/{scopeKey1}", ConfigResource.class); router.attach("/clusters/{clusterName}/configs/{scope}/{scopeKey1}/{scopeKey2}", ConfigResource.class); router.attach("/zkPath", ZkPathResource.class).setMatchingMode(Template.MODE_STARTS_WITH); router.attach("/zkChild", ZkChildResource.class).setMatchingMode(Template.MODE_STARTS_WITH); Restlet mainpage = new Restlet() { @Override public void handle(Request request, Response response) { StringBuilder stringBuilder = new StringBuilder(); stringBuilder.append("<html>"); stringBuilder.append("<head><title>Restlet Cluster Management page</title></head>"); stringBuilder.append("<body bgcolor=white>"); stringBuilder.append("<table border=\"0\">"); stringBuilder.append("<tr>"); stringBuilder.append("<td>"); stringBuilder.append("<h1>Rest cluster management interface V1</h1>"); stringBuilder.append("</td>"); stringBuilder.append("</tr>"); stringBuilder.append("</table>"); stringBuilder.append("</body>"); stringBuilder.append("</html>"); response.setEntity(new StringRepresentation(stringBuilder.toString(), MediaType.TEXT_HTML)); } }; router.attach("", mainpage); return router; } public static void printUsage(Options cliOptions) { HelpFormatter helpFormatter = new HelpFormatter(); helpFormatter.printHelp("java " + RestAdminApplication.class.getName(), cliOptions); } @SuppressWarnings("static-access") private static Options constructCommandLineOptions() { Option helpOption = OptionBuilder.withLongOpt(HELP).withDescription("Prints command-line options info") .create(); helpOption.setArgs(0); helpOption.setRequired(false); helpOption.setArgName("print help message"); Option zkServerOption = OptionBuilder.withLongOpt(ZKSERVERADDRESS) .withDescription("Provide zookeeper address").create(); zkServerOption.setArgs(1); zkServerOption.setRequired(true); zkServerOption.setArgName("ZookeeperServerAddress(Required)"); Option portOption = OptionBuilder.withLongOpt(PORT).withDescription("Provide web service port").create(); portOption.setArgs(1); portOption.setRequired(false); portOption.setArgName("web service port, default: " + DEFAULT_PORT); Options options = new Options(); options.addOption(helpOption); options.addOption(zkServerOption); options.addOption(portOption); return options; } public static void processCommandLineArgs(String[] cliArgs) throws Exception { CommandLineParser cliParser = new GnuParser(); Options cliOptions = constructCommandLineOptions(); CommandLine cmd = null; try { cmd = cliParser.parse(cliOptions, cliArgs); } catch (ParseException pe) { System.err.println("RestAdminApplication: failed to parse command-line options: " + pe.toString()); printUsage(cliOptions); System.exit(1); } int port = DEFAULT_PORT; if (cmd.hasOption(HELP)) { printUsage(cliOptions); return; } else if (cmd.hasOption(PORT)) { port = Integer.parseInt(cmd.getOptionValue(PORT)); } HelixAdminWebApp app = new HelixAdminWebApp(cmd.getOptionValue(ZKSERVERADDRESS), port); app.start(); try { Thread.currentThread().join(); } finally { app.stop(); } } /** * @param args * @throws Exception */ public static void main(String[] args) throws Exception { processCommandLineArgs(args); } }