package org.apache.maven.archiva.web.startup; /* * 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.BufferedOutputStream; import java.io.BufferedWriter; import java.io.File; import java.io.FileWriter; import java.io.IOException; import java.io.PrintWriter; import java.lang.management.ManagementFactory; import java.lang.management.ThreadMXBean; import java.lang.reflect.Field; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.util.Iterator; import java.util.List; import java.util.Map; import javax.servlet.ServletContextEvent; import javax.servlet.ServletContextListener; import org.apache.archiva.web.xmlrpc.api.AdministrationService; import org.apache.maven.archiva.common.ArchivaException; import org.apache.maven.archiva.scheduled.ArchivaTaskScheduler; import org.apache.maven.archiva.scheduled.DefaultArchivaTaskScheduler; import org.codehaus.plexus.PlexusConstants; import org.codehaus.plexus.PlexusContainer; import org.codehaus.plexus.component.repository.exception.ComponentLookupException; import org.codehaus.plexus.personality.plexus.lifecycle.phase.StoppingException; import org.codehaus.plexus.scheduler.DefaultScheduler; import org.codehaus.plexus.spring.PlexusComponentFactoryBean; import org.codehaus.plexus.spring.PlexusLifecycleBeanPostProcessor; import org.codehaus.plexus.spring.PlexusToSpringUtils; import org.codehaus.plexus.spring.PlexusWebApplicationContext; import org.codehaus.plexus.spring.SpringPlexusConfiguration; import org.codehaus.plexus.taskqueue.DefaultTaskQueue; import org.codehaus.plexus.taskqueue.Task; import org.codehaus.plexus.taskqueue.execution.TaskQueueExecutor; import org.codehaus.plexus.taskqueue.execution.ThreadedTaskQueueExecutor; import org.springframework.beans.factory.support.DefaultListableBeanFactory; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; import org.springframework.web.context.WebApplicationContext; import org.springframework.web.context.support.WebApplicationContextUtils; import edu.emory.mathcs.backport.java.util.concurrent.ExecutorService; /** * ArchivaStartup - the startup of all archiva features in a deterministic order. * * @version $Id: ArchivaStartup.java 755318 2009-03-17 16:53:49Z brett $ */ public class ArchivaStartup implements ServletContextListener { private String taskSchedulerId = null; private String tqeDbId = null; private String tqeRepId = null; public void contextInitialized(ServletContextEvent contextEvent) { WebApplicationContext wac = WebApplicationContextUtils.getRequiredWebApplicationContext(contextEvent.getServletContext()); SecuritySynchronization securitySync = (SecuritySynchronization) wac.getBean(PlexusToSpringUtils.buildSpringId(SecuritySynchronization.class)); ResolverFactoryInit resolverFactory = (ResolverFactoryInit) wac.getBean(PlexusToSpringUtils.buildSpringId(ResolverFactoryInit.class)); // ArchivaTaskScheduler taskScheduler = (ArchivaTaskScheduler) wac.getBean(PlexusToSpringUtils.buildSpringId(ArchivaTaskScheduler.class)); taskSchedulerId = PlexusToSpringUtils.buildSpringId(ArchivaTaskScheduler.class); tqeDbId = PlexusToSpringUtils.buildSpringId(TaskQueueExecutor.class, "database-update"); tqeRepId = PlexusToSpringUtils.buildSpringId(TaskQueueExecutor.class, "repository-scanning"); System.out.println("TaskScheduler ID="+taskSchedulerId); System.out.println("TaskQueueExecutor(database-update) ID=" + tqeDbId); System.out.println("TaskQueueExecutor(repository-scanning) ID=" + tqeRepId); ArchivaTaskScheduler taskScheduler = (ArchivaTaskScheduler) wac.getBean(taskSchedulerId); Object tqeDb = wac.getBean(tqeDbId); Object tqeRep = wac.getBean(tqeRepId); try { securitySync.startup(); resolverFactory.startup(); taskScheduler.startup(); Banner.display(); } catch ( ArchivaException e ) { throw new RuntimeException( "Unable to properly startup archiva: " + e.getMessage(), e ); } } public void contextDestroyed(ServletContextEvent contextEvent) { // Comment: Piece of code makes no sense as method argument is of type // PlexusWebApplicationContext ApplicationContext applicationContext = WebApplicationContextUtils .getRequiredWebApplicationContext(contextEvent .getServletContext()); if (applicationContext != null && applicationContext instanceof ClassPathXmlApplicationContext) { ((ClassPathXmlApplicationContext) applicationContext).close(); } // Comment: Code that shut down the scheduler and the // ApplicationContexts. // Maybe there is a better approach, using the application-configs. // But I'm not familiar with the system, so it's just an idea! System.out.println("Running test - shutdown code ......."); if (applicationContext != null && applicationContext instanceof PlexusWebApplicationContext) { // Get the taskScheduler ArchivaTaskScheduler taskScheduler = (ArchivaTaskScheduler) applicationContext .getBean(taskSchedulerId); // Get TaskQueueExecutor#database-update ThreadedTaskQueueExecutor tqeDb = (ThreadedTaskQueueExecutor) applicationContext .getBean(tqeDbId); // Get TaskQueueExecutor#repository-scanning ThreadedTaskQueueExecutor tqeRep = (ThreadedTaskQueueExecutor) applicationContext .getBean(tqeRepId); // Get the beanFactory Object factory = ((PlexusWebApplicationContext) applicationContext) .getBeanFactory(); DefaultListableBeanFactory beanFactory = (DefaultListableBeanFactory) factory; // Get current Task of TaskQueueExecutor#database-update Task currentTask = tqeDb.getCurrentTask(); if (currentTask != null) { tqeDb.cancelTask(currentTask); } // Stop it and shutdown the executerService try { tqeDb.stop(); ExecutorService service = getExecutorServiceForTTQE(tqeDb); if (service != null) { service.shutdown(); } service.shutdown(); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } // Get current Task of TaskQueueExecutor#repository-scanning currentTask = tqeRep.getCurrentTask(); if (currentTask != null) { tqeRep.cancelTask(currentTask); } // Stop it and shutdown the executerService try { tqeRep.stop(); ExecutorService service = getExecutorServiceForTTQE(tqeRep); if (service != null) { service.shutdown(); } } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } // Stop the DefaultArchivaTaskScheduler and its scheduler if (taskScheduler != null && taskScheduler instanceof DefaultArchivaTaskScheduler) { try { ((DefaultArchivaTaskScheduler) taskScheduler).stop(); } catch (StoppingException e) { // TODO Auto-generated catch block e.printStackTrace(); } } try { // Shutdown the scheduler, otherwise Quartz scheduler and Threads still exists Field schedulerField = DefaultArchivaTaskScheduler.class .getDeclaredField("scheduler"); schedulerField.setAccessible(true); // org.codehaus.plexus.scheduler.DefaultScheduler; DefaultScheduler scheduler = (DefaultScheduler) schedulerField .get(taskScheduler); scheduler.getScheduler().shutdown(false); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } // Close the application context ((PlexusWebApplicationContext) applicationContext).close(); System.out.println("End test - shutdown code ......."); } } private static ExecutorService getExecutorServiceForTTQE(ThreadedTaskQueueExecutor ttqe) { ExecutorService service = null; try { Field executorService = ThreadedTaskQueueExecutor.class.getDeclaredField("executorService"); executorService.setAccessible(true); service = (ExecutorService) executorService.get(ttqe); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } return service; } }