001 package 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 022 import org.apache.archiva.common.ArchivaException; 023 import org.apache.archiva.common.plexusbridge.PlexusSisuBridge; 024 import org.apache.archiva.common.plexusbridge.PlexusSisuBridgeException; 025 import org.apache.archiva.redback.components.scheduler.DefaultScheduler; 026 import org.apache.archiva.scheduler.repository.DefaultRepositoryArchivaTaskScheduler; 027 import org.apache.maven.index.NexusIndexer; 028 import org.apache.maven.index.context.IndexingContext; 029 import org.apache.archiva.redback.components.taskqueue.Task; 030 import org.apache.archiva.redback.components.taskqueue.execution.ThreadedTaskQueueExecutor; 031 import org.quartz.SchedulerException; 032 import org.springframework.web.context.WebApplicationContext; 033 import org.springframework.web.context.support.WebApplicationContextUtils; 034 035 import javax.servlet.ServletContextEvent; 036 import javax.servlet.ServletContextListener; 037 import java.lang.reflect.Field; 038 import java.util.Properties; 039 import java.util.concurrent.ExecutorService; 040 041 /** 042 * ArchivaStartup - the startup of all archiva features in a deterministic order. 043 * 044 * 045 */ 046 public class ArchivaStartup 047 implements ServletContextListener 048 { 049 private ThreadedTaskQueueExecutor tqeDbScanning; 050 051 private ThreadedTaskQueueExecutor tqeRepoScanning; 052 053 private ThreadedTaskQueueExecutor tqeIndexing; 054 055 private DefaultRepositoryArchivaTaskScheduler repositoryTaskScheduler; 056 057 private PlexusSisuBridge plexusSisuBridge; 058 059 private NexusIndexer nexusIndexer; 060 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 public void contextDestroyed( ServletContextEvent contextEvent ) 100 { 101 WebApplicationContext applicationContext = 102 WebApplicationContextUtils.getRequiredWebApplicationContext( contextEvent.getServletContext() ); 103 104 // TODO check this stop 105 106 /* 107 if ( applicationContext != null && applicationContext instanceof ClassPathXmlApplicationContext ) 108 { 109 ( (ClassPathXmlApplicationContext) applicationContext ).close(); 110 } */ 111 112 if ( applicationContext != null ) //&& applicationContext instanceof PlexusWebApplicationContext ) 113 { 114 // stop task queue executors 115 stopTaskQueueExecutor( tqeDbScanning ); 116 stopTaskQueueExecutor( tqeRepoScanning ); 117 stopTaskQueueExecutor( tqeIndexing ); 118 119 // stop the DefaultArchivaTaskScheduler and its scheduler 120 if ( repositoryTaskScheduler != null ) 121 { 122 try 123 { 124 repositoryTaskScheduler.stop(); 125 } 126 catch ( SchedulerException e ) 127 { 128 e.printStackTrace(); 129 } 130 131 try 132 { 133 // shutdown the scheduler, otherwise Quartz scheduler and Threads still exists 134 Field schedulerField = repositoryTaskScheduler.getClass().getDeclaredField( "scheduler" ); 135 schedulerField.setAccessible( true ); 136 137 DefaultScheduler scheduler = (DefaultScheduler) schedulerField.get( repositoryTaskScheduler ); 138 scheduler.stop(); 139 } 140 catch ( Exception e ) 141 { 142 e.printStackTrace(); 143 } 144 } 145 146 // close the application context 147 //applicationContext.close(); 148 // TODO fix close call 149 //applicationContext. 150 } 151 152 // closing correctly indexer to close correctly lock and file 153 for ( IndexingContext indexingContext : nexusIndexer.getIndexingContexts().values() ) 154 { 155 try 156 { 157 indexingContext.close( false ); 158 } 159 catch ( Exception e ) 160 { 161 contextEvent.getServletContext().log( "skip error closing indexingContext " + e.getMessage() ); 162 } 163 } 164 165 } 166 167 private void stopTaskQueueExecutor( ThreadedTaskQueueExecutor taskQueueExecutor ) 168 { 169 if ( taskQueueExecutor != null ) 170 { 171 Task currentTask = taskQueueExecutor.getCurrentTask(); 172 if ( currentTask != null ) 173 { 174 taskQueueExecutor.cancelTask( currentTask ); 175 } 176 177 try 178 { 179 taskQueueExecutor.stop(); 180 ExecutorService service = getExecutorServiceForTTQE( taskQueueExecutor ); 181 if ( service != null ) 182 { 183 service.shutdown(); 184 } 185 } 186 catch ( Exception e ) 187 { 188 e.printStackTrace(); 189 } 190 } 191 } 192 193 private ExecutorService getExecutorServiceForTTQE( ThreadedTaskQueueExecutor ttqe ) 194 { 195 ExecutorService service = null; 196 try 197 { 198 Field executorServiceField = ttqe.getClass().getDeclaredField( "executorService" ); 199 executorServiceField.setAccessible( true ); 200 service = (ExecutorService) executorServiceField.get( ttqe ); 201 } 202 catch ( Exception e ) 203 { 204 e.printStackTrace(); 205 } 206 return service; 207 } 208 }