diff options
author | Jon Bratseth <bratseth@yahoo-inc.com> | 2016-06-15 23:09:44 +0200 |
---|---|---|
committer | Jon Bratseth <bratseth@yahoo-inc.com> | 2016-06-15 23:09:44 +0200 |
commit | 72231250ed81e10d66bfe70701e64fa5fe50f712 (patch) | |
tree | 2728bba1131a6f6e5bdf95afec7d7ff9358dac50 /clustercontroller-standalone/src/main |
Publish
Diffstat (limited to 'clustercontroller-standalone/src/main')
4 files changed, 280 insertions, 0 deletions
diff --git a/clustercontroller-standalone/src/main/java/com/yahoo/vespa/clustercontroller/standalone/ClusterControllerConfigFetcher.java b/clustercontroller-standalone/src/main/java/com/yahoo/vespa/clustercontroller/standalone/ClusterControllerConfigFetcher.java new file mode 100644 index 00000000000..dbe0c167cfb --- /dev/null +++ b/clustercontroller-standalone/src/main/java/com/yahoo/vespa/clustercontroller/standalone/ClusterControllerConfigFetcher.java @@ -0,0 +1,96 @@ +// Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. +/** + * Used to manually fetch config for the stand alone application. + */ +package com.yahoo.vespa.clustercontroller.standalone; + +import com.yahoo.vespa.clustercontroller.apps.clustercontroller.ClusterControllerClusterConfigurer; +import com.yahoo.vespa.clustercontroller.core.FleetControllerOptions; +import com.yahoo.vespa.config.content.FleetcontrollerConfig; +import com.yahoo.vespa.config.content.StorDistributionConfig; +import com.yahoo.cloud.config.SlobroksConfig; +import com.yahoo.config.subscription.ConfigSubscriber; +import com.yahoo.config.subscription.ConfigHandle; +import com.yahoo.cloud.config.ZookeepersConfig; + +import java.util.logging.Logger; + +public class ClusterControllerConfigFetcher { + private static Logger log = Logger.getLogger(ClusterControllerConfigFetcher.class.getName()); + + private final ConfigSubscriber configSubscriber = new ConfigSubscriber(); + private final ConfigHandle<FleetcontrollerConfig> fleetcontrollerConfigHandle; + private final ConfigHandle<SlobroksConfig> slobrokConfigHandle; + private final ConfigHandle<StorDistributionConfig> distributionConfigHandle; + private final ConfigHandle<ZookeepersConfig> zookeeperConfigHandle; + + private FleetControllerOptions options; + + public ClusterControllerConfigFetcher() throws Exception { + String configId = createConfigId(); + log.fine("Using fleetcontroller config id \"" + configId + '"'); + String slobrokConfigId = createSlobrokConfigId(); + log.fine("Using slobrok config id \"" + slobrokConfigId + '"'); + + fleetcontrollerConfigHandle = configSubscriber.subscribe(FleetcontrollerConfig.class, configId); + slobrokConfigHandle = configSubscriber.subscribe(SlobroksConfig.class, slobrokConfigId); + distributionConfigHandle = configSubscriber.subscribe(StorDistributionConfig.class, configId); + zookeeperConfigHandle = configSubscriber.subscribe(ZookeepersConfig.class, configId); + + if (!configReady()) { + throw new IllegalStateException("Initial configuration failed."); + } + options = generateOptions(); + } + + public void close() { + log.fine("Shutting down fleetcontroller config subscription"); + configSubscriber.close(); + } + + private String createConfigId() { + return System.getProperty("config.id"); + } + + private String createSlobrokConfigId() { + return System.getProperty("slobrok.config.id"); + } + + public FleetControllerOptions getOptions() { + return options; + } + + public FleetControllerOptions generateOptions() throws Exception { + ClusterControllerClusterConfigurer configurer = new ClusterControllerClusterConfigurer( + null, + distributionConfigHandle.getConfig(), + fleetcontrollerConfigHandle.getConfig(), + slobrokConfigHandle.getConfig(), + zookeeperConfigHandle.getConfig(), + null); + return configurer.getOptions(); + } + + /** Test to see if the config has been updated, and if so, update the config. */ + public boolean updated(long timeoutMillis) throws Exception { + if (configUpdated(timeoutMillis)) { + log.fine("Updated fleetcontroller config."); + options = generateOptions(); + return true; + } else { + return false; + } + } + + public long getGeneration() { + return configSubscriber.getGeneration(); + } + + boolean configReady() { + return configSubscriber.nextConfig(); + } + + boolean configUpdated(long timeoutMillis) { + return configSubscriber.nextConfig(timeoutMillis); + } +} diff --git a/clustercontroller-standalone/src/main/java/com/yahoo/vespa/clustercontroller/standalone/StandAloneClusterController.java b/clustercontroller-standalone/src/main/java/com/yahoo/vespa/clustercontroller/standalone/StandAloneClusterController.java new file mode 100644 index 00000000000..a07f46ee682 --- /dev/null +++ b/clustercontroller-standalone/src/main/java/com/yahoo/vespa/clustercontroller/standalone/StandAloneClusterController.java @@ -0,0 +1,113 @@ +// Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. +package com.yahoo.vespa.clustercontroller.standalone; + +import com.yahoo.log.LogLevel; +import com.yahoo.log.LogSetup; +import com.yahoo.log.event.Event; +import com.yahoo.vespa.clustercontroller.core.FleetController; + +import java.util.logging.Logger; + +/** + * This is the class containing the main method used to run fleet controller as a stand-alone program. + */ +public class StandAloneClusterController { + private static Logger log = Logger.getLogger(StandAloneClusterController.class.getName()); + + private final ClusterControllerConfigFetcher config; + private FleetController controller; + private boolean started = false, stop = false; + + public static class ShutdownHook extends Thread { + private StandAloneClusterController app; + + public ShutdownHook(StandAloneClusterController app) { + this.app = app; + } + + @Override + public void run() { + try{ + app.stop(); + } catch (Exception e) { + log.log(LogLevel.FATAL, "Failed to stop application '" + app.getName() + "': " + e.getMessage()); + e.printStackTrace(); + return; + } + } + + } + + public static void main(String args[]) throws Exception { + runApplication(new StandAloneClusterController(new ClusterControllerConfigFetcher())); + } + + public static void runApplication(StandAloneClusterController myApp) { + LogSetup.initVespaLogging("fleetcontroller"); + try{ + myApp.start(); + } catch (Exception e) { + log.log(LogLevel.FATAL, "Failed to start application '" + myApp.getName() + "': " + e.getMessage()); + e.printStackTrace(); + return; + } + Runtime.getRuntime().addShutdownHook(new ShutdownHook(myApp)); + try{ + myApp.run(); + } catch (Exception e) { + log.log(LogLevel.FATAL, "Application '" + myApp.getName() + "' runtime failure: " + e.getMessage()); + e.printStackTrace(); + } + } + + public StandAloneClusterController(ClusterControllerConfigFetcher config) { + this.config = config; + } + + public String getName() { + return "Fleetcontroller " + config.getOptions().fleetControllerIndex + + " of cluster " + config.getOptions().clusterName; + } + + public void start() throws Exception { + controller = FleetController.createForStandAlone(config.getOptions()); + Event.started(getName()); + } + + public void run() throws Exception { + synchronized(this) { + started = true; + } + try{ + while (true) { + synchronized (this) { + if (stop) { + notifyAll(); + return; + } + if (config.updated(1)) { + controller.updateOptions(config.getOptions(), config.getGeneration()); + } + try{ wait(1000); } catch (InterruptedException e) {} + } + } + } finally { + started = false; + } + } + + public void stop() throws Exception { + Event.stopping(getName(), "controlled shutdown"); + synchronized (this) { + controller.shutdown(); + stop = true; + notifyAll(); + while (started) { + try{ wait(1000); } catch (InterruptedException e) {} + } + config.close(); + } + log.fine("Fleetcontroller done shutting down"); + } + +} diff --git a/clustercontroller-standalone/src/main/resources/log4j-vespa-fleetcontroller.properties b/clustercontroller-standalone/src/main/resources/log4j-vespa-fleetcontroller.properties new file mode 100644 index 00000000000..e69de29bb2d --- /dev/null +++ b/clustercontroller-standalone/src/main/resources/log4j-vespa-fleetcontroller.properties diff --git a/clustercontroller-standalone/src/main/sh/fleetcontroller-start b/clustercontroller-standalone/src/main/sh/fleetcontroller-start new file mode 100755 index 00000000000..dda006ff7b1 --- /dev/null +++ b/clustercontroller-standalone/src/main/sh/fleetcontroller-start @@ -0,0 +1,71 @@ +#!/bin/sh +# Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. + +# BEGIN environment bootstrap section +# Do not edit between here and END as this section should stay identical in all scripts + +findpath () { + myname=${0} + mypath=${myname%/*} + myname=${myname##*/} + if [ "$mypath" ] && [ -d "$mypath" ]; then + return + fi + mypath=$(pwd) + if [ -f "${mypath}/${myname}" ]; then + return + fi + echo "FATAL: Could not figure out the path where $myname lives from $0" + exit 1 +} + +COMMON_ENV=libexec/vespa/common-env.sh + +source_common_env () { + if [ "$VESPA_HOME" ] && [ -d "$VESPA_HOME" ]; then + # ensure it ends with "/" : + VESPA_HOME=${VESPA_HOME%/}/ + export VESPA_HOME + common_env=$VESPA_HOME/$COMMON_ENV + if [ -f "$common_env" ]; then + . $common_env + return + fi + fi + return 1 +} + +findroot () { + source_common_env && return + if [ "$VESPA_HOME" ]; then + echo "FATAL: bad VESPA_HOME value '$VESPA_HOME'" + exit 1 + fi + if [ "$ROOT" ] && [ -d "$ROOT" ]; then + VESPA_HOME="$ROOT" + source_common_env && return + fi + findpath + while [ "$mypath" ]; do + VESPA_HOME=${mypath} + source_common_env && return + mypath=${mypath%/*} + done + echo "FATAL: missing VESPA_HOME environment variable" + echo "Could not locate $COMMON_ENV anywhere" + exit 1 +} + +findroot + +# END environment bootstrap section + +JAR=lib/jars/clustercontroller-standalone-jar-with-dependencies.jar + +ROOT=$VESPA_HOME +export ROOT +cd $ROOT || { echo "Cannot cd to $ROOT" 1>&2; exit 1; } + +jvmargs="-server -Xms16m -Xmx2048m -Dlog4j.configuration=file:$VESPA_HOME/etc/log4j-vespa-fleetcontroller.properties" +jar="-cp $ROOT/$JAR com.yahoo.vespa.clustercontroller.standalone.StandAloneClusterController" +exec java $jvmargs -Dconfig.id=$VESPA_CONFIG_ID -Dslobrok.config.id="admin/slobrok.0" "$@" $jar |