This project has retired. For details please refer to its Attic page.
Source code
001package org.apache.archiva.web.startup;
002
003/*
004 * Licensed to the Apache Software Foundation (ASF) under one
005 * or more contributor license agreements.  See the NOTICE file
006 * distributed with this work for additional information
007 * regarding copyright ownership.  The ASF licenses this file
008 * to you under the Apache License, Version 2.0 (the
009 * "License"); you may not use this file except in compliance
010 * with the License.  You may obtain a copy of the License at
011 *
012 *  http://www.apache.org/licenses/LICENSE-2.0
013 *
014 * Unless required by applicable law or agreed to in writing,
015 * software distributed under the License is distributed on an
016 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
017 * KIND, either express or implied.  See the License for the
018 * specific language governing permissions and limitations
019 * under the License.
020 */
021
022import org.apache.archiva.common.ArchivaException;
023import org.apache.archiva.common.plexusbridge.PlexusSisuBridge;
024import org.apache.archiva.common.plexusbridge.PlexusSisuBridgeException;
025import org.apache.archiva.redback.components.scheduler.DefaultScheduler;
026import org.apache.archiva.scheduler.repository.DefaultRepositoryArchivaTaskScheduler;
027import org.apache.maven.index.NexusIndexer;
028import org.apache.maven.index.context.IndexingContext;
029import org.apache.archiva.redback.components.taskqueue.Task;
030import org.apache.archiva.redback.components.taskqueue.execution.ThreadedTaskQueueExecutor;
031import org.quartz.SchedulerException;
032import org.springframework.web.context.WebApplicationContext;
033import org.springframework.web.context.support.WebApplicationContextUtils;
034
035import javax.servlet.ServletContext;
036import javax.servlet.ServletContextEvent;
037import javax.servlet.ServletContextListener;
038import java.lang.reflect.Field;
039import java.util.Properties;
040import java.util.concurrent.ExecutorService;
041
042/**
043 * ArchivaStartup - the startup of all archiva features in a deterministic order.
044 */
045public class ArchivaStartup
046    implements ServletContextListener
047{
048    private ThreadedTaskQueueExecutor tqeDbScanning;
049
050    private ThreadedTaskQueueExecutor tqeRepoScanning;
051
052    private ThreadedTaskQueueExecutor tqeIndexing;
053
054    private DefaultRepositoryArchivaTaskScheduler repositoryTaskScheduler;
055
056    private PlexusSisuBridge plexusSisuBridge;
057
058    private NexusIndexer nexusIndexer;
059
060    @Override
061    public void contextInitialized( ServletContextEvent contextEvent )
062    {
063        WebApplicationContext wac =
064            WebApplicationContextUtils.getRequiredWebApplicationContext( contextEvent.getServletContext() );
065
066        SecuritySynchronization securitySync = wac.getBean( SecuritySynchronization.class );
067
068        repositoryTaskScheduler =
069            wac.getBean( "archivaTaskScheduler#repository", DefaultRepositoryArchivaTaskScheduler.class );
070
071        Properties archivaRuntimeProperties = wac.getBean( "archivaRuntimeProperties", Properties.class );
072
073        tqeRepoScanning = wac.getBean( "taskQueueExecutor#repository-scanning", ThreadedTaskQueueExecutor.class );
074
075        tqeIndexing = wac.getBean( "taskQueueExecutor#indexing", ThreadedTaskQueueExecutor.class );
076
077        plexusSisuBridge = wac.getBean( PlexusSisuBridge.class );
078
079        try
080        {
081            nexusIndexer = plexusSisuBridge.lookup( NexusIndexer.class );
082        }
083        catch ( PlexusSisuBridgeException e )
084        {
085            throw new RuntimeException( "Unable to get NexusIndexer: " + e.getMessage(), e );
086        }
087        try
088        {
089            securitySync.startup();
090            repositoryTaskScheduler.startup();
091            Banner.display( (String) archivaRuntimeProperties.get( "archiva.version" ) );
092        }
093        catch ( ArchivaException e )
094        {
095            throw new RuntimeException( "Unable to properly startup archiva: " + e.getMessage(), e );
096        }
097    }
098
099    @Override
100    public void contextDestroyed( ServletContextEvent contextEvent )
101    {
102        WebApplicationContext applicationContext =
103            WebApplicationContextUtils.getRequiredWebApplicationContext( contextEvent.getServletContext() );
104
105        // we log using servlet mechanism as due to some possible problem with slf4j when container shutdown
106        // so servletContext.log
107        ServletContext servletContext = contextEvent.getServletContext();
108
109        // TODO check this stop
110
111        /*
112        if ( applicationContext != null && applicationContext instanceof ClassPathXmlApplicationContext )
113        {
114            ( (ClassPathXmlApplicationContext) applicationContext ).close();
115        } */
116
117        if ( applicationContext != null ) //&& applicationContext instanceof PlexusWebApplicationContext )
118        {
119            // stop task queue executors
120            stopTaskQueueExecutor( tqeDbScanning, servletContext );
121            stopTaskQueueExecutor( tqeRepoScanning, servletContext );
122            stopTaskQueueExecutor( tqeIndexing, servletContext );
123
124            // stop the DefaultArchivaTaskScheduler and its scheduler
125            if ( repositoryTaskScheduler != null )
126            {
127                try
128                {
129                    repositoryTaskScheduler.stop();
130                }
131                catch ( SchedulerException e )
132                {
133                    servletContext.log( e.getMessage(), e );
134                }
135
136                try
137                {
138                    // shutdown the scheduler, otherwise Quartz scheduler and Threads still exists
139                    Field schedulerField = repositoryTaskScheduler.getClass().getDeclaredField( "scheduler" );
140                    schedulerField.setAccessible( true );
141
142                    DefaultScheduler scheduler = (DefaultScheduler) schedulerField.get( repositoryTaskScheduler );
143                    scheduler.stop();
144                }
145                catch ( Exception e )
146                {
147                    servletContext.log( e.getMessage(), e );
148                }
149            }
150
151            // close the application context
152            //applicationContext.close();
153            // TODO fix close call
154            //applicationContext.
155        }
156
157        // closing correctly indexer to close correctly lock and file
158        for ( IndexingContext indexingContext : nexusIndexer.getIndexingContexts().values() )
159        {
160            try
161            {
162                indexingContext.close( false );
163            }
164            catch ( Exception e )
165            {
166                servletContext.log( "skip error closing indexingContext " + e.getMessage(), e );
167            }
168        }
169
170    }
171
172    private void stopTaskQueueExecutor( ThreadedTaskQueueExecutor taskQueueExecutor, ServletContext servletContext )
173    {
174        if ( taskQueueExecutor != null )
175        {
176            Task currentTask = taskQueueExecutor.getCurrentTask();
177            if ( currentTask != null )
178            {
179                taskQueueExecutor.cancelTask( currentTask );
180            }
181
182            try
183            {
184                taskQueueExecutor.stop();
185                ExecutorService service = getExecutorServiceForTTQE( taskQueueExecutor, servletContext );
186                if ( service != null )
187                {
188                    service.shutdown();
189                }
190            }
191            catch ( Exception e )
192            {
193                servletContext.log( e.getMessage(), e );
194            }
195        }
196    }
197
198    private ExecutorService getExecutorServiceForTTQE( ThreadedTaskQueueExecutor ttqe, ServletContext servletContext )
199    {
200        ExecutorService service = null;
201        try
202        {
203            Field executorServiceField = ttqe.getClass().getDeclaredField( "executorService" );
204            executorServiceField.setAccessible( true );
205            service = (ExecutorService) executorServiceField.get( ttqe );
206        }
207        catch ( Exception e )
208        {
209            servletContext.log( e.getMessage(), e );
210        }
211        return service;
212    }
213}