Package org.sonatype.nexus.extender

Source Code of org.sonatype.nexus.extender.NexusContextListener

/*
* Sonatype Nexus (TM) Open Source Version
* Copyright (c) 2007-2014 Sonatype, Inc.
* All rights reserved. Includes the third-party code listed at http://links.sonatype.com/products/nexus/oss/attributions.
*
* This program and the accompanying materials are made available under the terms of the Eclipse Public License Version 1.0,
* which accompanies this distribution and is available at http://www.eclipse.org/legal/epl-v10.html.
*
* Sonatype Nexus (TM) Professional Version is available from Sonatype, Inc. "Sonatype" and "Sonatype Nexus" are trademarks
* of Sonatype, Inc. Apache Maven is a trademark of the Apache Software Foundation. M2eclipse is a trademark of the
* Eclipse Foundation. All other trademarks are the property of their respective owners.
*/
package org.sonatype.nexus.extender;

import java.util.Arrays;
import java.util.Dictionary;
import java.util.EnumSet;
import java.util.HashSet;
import java.util.Hashtable;
import java.util.Map;
import java.util.Set;

import javax.servlet.Filter;
import javax.servlet.ServletContext;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;

import org.sonatype.nexus.NxApplication;
import org.sonatype.nexus.log.LogManager;
import org.sonatype.nexus.web.NexusGuiceFilter;
import org.sonatype.nexus.web.NexusServletModule;

import com.codahale.metrics.SharedMetricRegistries;
import com.google.common.base.Throwables;
import com.google.inject.Guice;
import com.google.inject.Injector;
import com.google.inject.Key;
import com.google.inject.servlet.GuiceServletContextListener;
import org.apache.karaf.features.Feature;
import org.apache.karaf.features.FeaturesService;
import org.apache.karaf.features.FeaturesService.Option;
import org.eclipse.sisu.inject.BeanLocator;
import org.eclipse.sisu.wire.WireModule;
import org.osgi.framework.BundleContext;
import org.osgi.framework.FrameworkEvent;
import org.osgi.framework.FrameworkListener;
import org.osgi.framework.ServiceRegistration;
import org.osgi.framework.startlevel.FrameworkStartLevel;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import static com.google.common.base.Preconditions.checkState;
import static java.util.Collections.singletonMap;
import static org.apache.karaf.features.FeaturesService.Option.ContinueBatchOnFailure;
import static org.apache.karaf.features.FeaturesService.Option.NoAutoRefreshBundles;
import static org.apache.karaf.features.FeaturesService.Option.NoCleanIfFailure;

/**
* {@link ServletContextListener} that bootstraps the core Nexus application.
*
* @since 3.0
*/
public class NexusContextListener
    extends GuiceServletContextListener
    implements FrameworkListener
{
  private static final int NEXUS_PLUGIN_START_LEVEL = 200;

  private static final Logger log = LoggerFactory.getLogger(NexusContextListener.class);

  private final NexusBundleExtender extender;

  private BundleContext bundleContext;

  private ServletContext servletContext;

  private FeaturesService featuresService;

  private Injector injector;

  private LogManager logManager;

  private NxApplication application;

  private ServiceRegistration<Filter> registration;

  public NexusContextListener(final NexusBundleExtender extender) {
    this.extender = extender;
  }

  @Override
  public void contextInitialized(final ServletContextEvent event) {
    SharedMetricRegistries.getOrCreate("nexus");

    bundleContext = extender.getBundleContext();

    servletContext = event.getServletContext();
    Map<?, ?> variables = (Map<?, ?>) servletContext.getAttribute("nexus.properties");
    if (variables == null) {
      variables = System.getProperties();
    }

    featuresService = bundleContext.getService(bundleContext.getServiceReference(FeaturesService.class));

    injector = Guice.createInjector(new WireModule(new NexusServletModule(servletContext, variables)));
    log.debug("Injector: {}", injector);

    super.contextInitialized(event);

    extender.doStart(); // start tracking nexus bundles

    try {
      logManager = lookup(LogManager.class);
      log.debug("Log manager: {}", logManager);
      logManager.configure();

      application = lookup(NxApplication.class);
      log.debug("Application: {}", application);

      FrameworkStartLevel fsl = bundleContext.getBundle(0).adapt(FrameworkStartLevel.class);

      // assign higher start level to hold back plugin activation
      fsl.setInitialBundleStartLevel(NEXUS_PLUGIN_START_LEVEL);

      installNexusFeatures();

      // raise framework start level to activate plugins
      fsl.setStartLevel(NEXUS_PLUGIN_START_LEVEL, this);
    }
    catch (final Exception e) {
      log.error("Failed to lookup application", e);
      Throwables.propagate(e);
    }
  }

  public void frameworkEvent(final FrameworkEvent event) {
    if (event.getType() == FrameworkEvent.STARTLEVEL_CHANGED) {
      // any local Nexus plugins have now been activated

      try {
        application.start();
      }
      catch (final Exception e) {
        log.error("Failed to start application", e);
        Throwables.propagate(e);
      }

      // register our dynamic filter with the surrounding bootstrap code
      final Filter filter = injector.getInstance(NexusGuiceFilter.class);
      final Dictionary<String, ?> properties = new Hashtable<>(singletonMap("name", "nexus"));
      registration = bundleContext.registerService(Filter.class, filter, properties);
    }
  }

  @Override
  public void contextDestroyed(final ServletContextEvent event) {

    // remove our dynamic filter
    if (registration != null) {
      registration.unregister();
      registration = null;
    }

    if (application != null) {
      try {
        application.stop();
      }
      catch (final Exception e) {
        log.error("Failed to stop application", e);
      }
      application = null;
    }

    if (logManager != null) {
      logManager.shutdown();
      logManager = null;
    }

    extender.doStop(); // stop tracking bundles

    if (servletContext != null) {
      super.contextDestroyed(new ServletContextEvent(servletContext));
      servletContext = null;
    }

    injector = null;

    SharedMetricRegistries.remove("nexus");
  }

  @Override
  protected Injector getInjector() {
    checkState(injector != null, "Missing injector reference");
    return injector;
  }

  private <T> T lookup(final Class<T> clazz) {
    return injector.getInstance(BeanLocator.class).locate(Key.get(clazz)).iterator().next().getValue();
  }

  private void installNexusFeatures() throws Exception {
    Set<Feature> features = new HashSet<>();

    // for now scan the system for candidate features
    for (Feature feature : featuresService.listFeatures()) {
      String name = feature.getName();
      if (name.startsWith("nexus") && name.endsWith("plugin")) {
        log.info("Adding {}", name);
        features.add(feature);
      }
    }

    log.info("Installing chosen features...");

    // install features using batch mode; skip features already in the cache
    features.removeAll(Arrays.asList(featuresService.listInstalledFeatures()));
    if (features.size() > 0) {
      EnumSet<Option> options = EnumSet.of(ContinueBatchOnFailure, NoCleanIfFailure, NoAutoRefreshBundles);
      featuresService.installFeatures(features, options);
    }

    log.info("Installed {} features", features.size());
  }
}
TOP

Related Classes of org.sonatype.nexus.extender.NexusContextListener

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.