blob: bc528dff1e318f8881837549ad4e45034500aeac [file] [log] [blame]
package org.apache.helix.rest.server;
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you 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.
*/
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
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.apache.helix.HelixException;
import org.apache.helix.rest.common.HelixRestNamespace;
import org.apache.helix.rest.server.auditlog.AuditLogger;
import org.apache.helix.rest.server.auditlog.auditloggers.FileBasedAuditLogger;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.yaml.snakeyaml.Yaml;
public class HelixRestMain {
private static Logger LOG = LoggerFactory.getLogger(HelixRestServer.class);
private static final String HELP = "help";
private static final String ZKSERVERADDRESS = "zkSvr";
private static final String NAMESPACE_MANIFEST_FILE = "namespace-manifest-file";
private static final String PORT = "port";
private static final int DEFAULT_PORT = 8100;
private static final String URI_PREFIX = "/admin/v2";
private static void printUsage(Options cliOptions) {
HelpFormatter helpFormatter = new HelpFormatter();
helpFormatter.printHelp("java " + HelixRestServer.class.getName(), cliOptions);
}
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 helixRestNamespaceOption = OptionBuilder.withLongOpt(NAMESPACE_MANIFEST_FILE)
.withDescription("A yaml file describing helix namespace")
.create();
helixRestNamespaceOption.setArgs(1);
helixRestNamespaceOption.setRequired(false);
helixRestNamespaceOption.setArgName("NamespaceManifestFile(Optional)");
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);
options.addOption(helixRestNamespaceOption);
return options;
}
private 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) {
LOG.error("RestAdminApplication: failed to parse command-line options: " + pe.toString());
printUsage(cliOptions);
System.exit(1);
}
int port = DEFAULT_PORT;
String zkAddr;
List<HelixRestNamespace> namespaces = new ArrayList<>();
if (cmd.hasOption(HELP)) {
printUsage(cliOptions);
return;
} else {
if (cmd.hasOption(PORT)) {
port = Integer.parseInt(cmd.getOptionValue(PORT));
}
zkAddr = String.valueOf(cmd.getOptionValue(ZKSERVERADDRESS));
namespaces.add(new HelixRestNamespace(zkAddr));
if (cmd.hasOption(NAMESPACE_MANIFEST_FILE)) {
constructNamespaceFromConfigFile(String.valueOf(cmd.getOptionValue(NAMESPACE_MANIFEST_FILE)), namespaces);
}
}
final HelixRestServer restServer = new HelixRestServer(namespaces, port, URI_PREFIX,
Arrays.<AuditLogger>asList(new FileBasedAuditLogger()));
try {
restServer.start();
restServer.join();
} catch (HelixException ex) {
LOG.error("Failed to start Helix rest server, " + ex);
} finally {
restServer.shutdown();
}
}
private static void constructNamespaceFromConfigFile(String filePath, List<HelixRestNamespace> namespaces)
throws IOException {
Yaml yaml = new Yaml();
@SuppressWarnings("unchecked")
ArrayList<Map<String, String>> configs =
(ArrayList<Map<String, String>>) yaml.load(new FileInputStream(new File(filePath)));
for (Map<String, String> config : configs) {
// Currently we don't support adding default namespace through yaml manifest so all
// namespaces created here will not be default
// TODO: support specifying default namespace from config file
namespaces.add(new HelixRestNamespace(
config.get(HelixRestNamespace.HelixRestNamespaceProperty.NAME.name()),
HelixRestNamespace.HelixMetadataStoreType.valueOf(
config.get(HelixRestNamespace.HelixRestNamespaceProperty.METADATA_STORE_TYPE.name())),
config.get(HelixRestNamespace.HelixRestNamespaceProperty.METADATA_STORE_ADDRESS.name()),
false, Boolean.parseBoolean(
config.get(HelixRestNamespace.HelixRestNamespaceProperty.MULTI_ZK_ENABLED.name())),
config.get(HelixRestNamespace.HelixRestNamespaceProperty.MSDS_ENDPOINT.name())));
}
}
/**
* @param args
* @throws Exception
*/
public static void main(String[] args) throws Exception {
processCommandLineArgs(args);
}
}