/* * 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. * */ package org.apache.usergrid.chop.runner; import java.io.File; import java.io.IOException; import java.text.SimpleDateFormat; import java.util.Date; import java.util.TimeZone; import javax.servlet.ServletContext; import javax.servlet.ServletContextEvent; import org.apache.usergrid.chop.api.Project; import org.apache.usergrid.chop.api.Runner; import org.apache.usergrid.chop.api.store.amazon.Ec2Metadata; import org.apache.usergrid.chop.spi.RunnerRegistry; import org.safehaus.guicyfig.Env; import org.safehaus.jettyjam.utils.TestMode; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.amazonaws.services.redshift.model.transform.ReservedNodeStaxUnmarshaller; import com.google.inject.Guice; import com.google.inject.Injector; import com.google.inject.servlet.GuiceServletContextListener; import com.netflix.config.ConfigurationManager; /** ... */ @SuppressWarnings( "UnusedDeclaration" ) public class RunnerConfig extends GuiceServletContextListener { private final static Logger LOG = LoggerFactory.getLogger( RunnerConfig.class ); private Injector injector; private Project project; private Runner runner; private ServletFig servletFig; private boolean registered = false; public Project getProject() { return project; } public Runner getRunner() { return runner; } public ServletFig getServletFig() { return servletFig; } @Override protected Injector getInjector() { if ( injector != null ) { return injector; } injector = Guice.createInjector( new Module() ); return injector; } @Override public void contextInitialized( ServletContextEvent servletContextEvent ) { super.contextInitialized( servletContextEvent ); /* * -------------------------------------------------------------------- * Archaius Configuration Settings * -------------------------------------------------------------------- */ Env env = Env.getEnvironment(); if ( env == Env.ALL ) { ConfigurationManager.getDeploymentContext().setDeploymentEnvironment( "CHOP" ); LOG.info( "Setting environment to: CHOP" ); } else if ( env == Env.UNIT ) { LOG.info( "Operating in UNIT environment" ); } try { ConfigurationManager.loadCascadedPropertiesFromResources( "project" ); } catch ( IOException e ) { LOG.error( "Failed to load project properties!", e ); throw new RuntimeException( "Cannot do much without properly loading our configuration.", e ); } /* * -------------------------------------------------------------------- * Environment Based Configuration Property Adjustments * -------------------------------------------------------------------- */ servletFig = injector.getInstance( ServletFig.class ); runner = injector.getInstance( Runner.class ); project = injector.getInstance( Project.class ); ServletContext context = servletContextEvent.getServletContext(); /* * -------------------------------------------------------------------- * Adjust Runner Settings to Environment * -------------------------------------------------------------------- */ if ( env == Env.UNIT || env == Env.INTEG || env == Env.ALL ) { runner.bypass( Runner.HOSTNAME_KEY, "localhost" ); runner.bypass( Runner.IPV4_KEY, "127.0.0.1" ); } else if ( env == Env.CHOP ) { Ec2Metadata.applyBypass( runner ); } StringBuilder sb = new StringBuilder(); sb.append( "https://" ) .append( runner.getHostname() ) .append( ':' ) .append( runner.getServerPort() ) .append( context.getContextPath() ); String baseUrl = sb.toString(); runner.bypass( Runner.URL_KEY, baseUrl ); LOG.info( "Setting url key {} to base url {}", Runner.URL_KEY, baseUrl ); File tempDir = new File( System.getProperties().getProperty( "java.io.tmpdir" ) ); runner.bypass( Runner.RUNNER_TEMP_DIR_KEY, tempDir.getAbsolutePath() ); LOG.info( "Setting runner temp directory key {} to context temp directory {}", Runner.RUNNER_TEMP_DIR_KEY, tempDir.getAbsolutePath() ); /* * -------------------------------------------------------------------- * Adjust ServletFig Settings to Environment * -------------------------------------------------------------------- */ servletFig.bypass( ServletFig.SERVER_INFO_KEY, context.getServerInfo() ); LOG.info( "Setting server info key {} to {}", ServletFig.SERVER_INFO_KEY, context.getServerInfo() ); servletFig.bypass( ServletFig.CONTEXT_PATH, context.getContextPath() ); LOG.info( "Setting server context path key {} to {}", ServletFig.CONTEXT_PATH, context.getContextPath() ); // @todo Is this necessary? servletFig.bypass( ServletFig.CONTEXT_TEMPDIR_KEY, tempDir.getAbsolutePath() ); LOG.info( "Setting runner context temp directory key {} to context temp directory {}", ServletFig.CONTEXT_TEMPDIR_KEY, tempDir.getAbsolutePath() ); /* * -------------------------------------------------------------------- * Start Up The RunnerRegistry and Register * -------------------------------------------------------------------- */ if ( isTestMode() ) { runner.bypass( Runner.HOSTNAME_KEY, "localhost" ); runner.bypass( Runner.IPV4_KEY, "127.0.0.1" ); project.bypass( Project.LOAD_KEY, "bogus-load-key" ); project.bypass( Project.ARTIFACT_ID_KEY, "bogus-artifact-id" ); project.bypass( Project.GROUP_ID_KEY, "org.apache.usergrid.chop" ); project.bypass( Project.CHOP_VERSION_KEY, "bogus-chop-version" ); SimpleDateFormat dateFormat = new SimpleDateFormat( "yyyy.MM.dd.HH.mm.ss" ); dateFormat.setTimeZone( TimeZone.getTimeZone( "UTC" ) ); project.bypass( Project.CREATE_TIMESTAMP_KEY, dateFormat.format( new Date() ) ); project.bypass( Project.GIT_URL_KEY, "http://stash.safehaus.org/projects/CHOP/repos/main/browse" ); project.bypass( Project.GIT_UUID_KEY, "d637a8ce" ); project.bypass( Project.LOAD_TIME_KEY, dateFormat.format( new Date() ) ); project.bypass( Project.PROJECT_VERSION_KEY, "1.0.0-SNAPSHOT" ); } if ( runner.getHostname() != null && project.getLoadKey() != null ) { if ( env != Env.TEST && env != Env.UNIT ) { /* * ------------------------------------------------------------ * Register runner on a different thread since jetty runner * is not started yet and the port is not known * ------------------------------------------------------------ */ Thread registryThread = new Thread( new Runnable() { @Override public void run() { registerRunner(); } } ); registryThread.start(); } else { LOG.warn( "Env = {} so we are not registering this runner.", env ); } } else { LOG.warn( "Runner registry not started, and not registered: insufficient configuration parameters." ); } } private void registerRunner( ) { RunnerAppJettyRunner jettyRunner = RunnerAppJettyRunner.getInstance(); int time = 5000; while ( ! jettyRunner.isStarted( 100 ) ) { time -= 100; if ( time < 0 ) { throw new IllegalStateException( "This runner has not been started yet!" ); } } runner.bypass( Runner.SERVER_PORT_KEY, "" + jettyRunner.getPort() ); runner.bypass( Runner.URL_KEY, "https://" + runner.getHostname() + ":" + runner.getServerPort() ); final RunnerRegistry registry = getInjector().getInstance( RunnerRegistry.class ); registry.register( runner ); registered =true; Runtime.getRuntime().addShutdownHook( new Thread( new Runnable() { @Override public void run() { if ( registered ) { System.err.println( "Premature shutdown, attempting to unregister this runner." ); registry.unregister( runner ); LOG.info( "Unregistering runner on shutdownx: {}", runner.getHostname() ); registered = false; } } } ) ); LOG.info( "Registered runner information in coordinator registry." ); } static TestMode mode = null; public static TestMode getTestMode() { if ( mode == null ) { boolean hasKey = System.getProperties().containsKey( TestMode.TEST_MODE_PROPERTY ); if ( hasKey ) { mode = TestMode.valueOf( System.getProperty( TestMode.TEST_MODE_PROPERTY, TestMode.UNDEFINED.toString() ) ); } } return mode; } public static boolean isTestMode() { return mode != null && ( mode == TestMode.INTEG || mode == TestMode.UNIT ); } @Override public void contextDestroyed( ServletContextEvent servletContextEvent ) { Env env = Env.getEnvironment(); RunnerRegistry registry = getInjector().getInstance( RunnerRegistry.class ); if ( env == Env.CHOP || registered ) { registry.unregister( injector.getInstance( Runner.class ) ); registered = false; LOG.info( "Unregistered runner information in coordinator registry." ); } else { LOG.warn( "Environment is set to {} so we are not un-registering this runner.", env ); } super.contextDestroyed( servletContextEvent ); } }