001 package org.apache.archiva.scheduler.indexing; 002 /* 003 * Licensed to the Apache Software Foundation (ASF) under one 004 * or more contributor license agreements. See the NOTICE file 005 * distributed with this work for additional information 006 * regarding copyright ownership. The ASF licenses this file 007 * to you under the Apache License, Version 2.0 (the 008 * "License"); you may not use this file except in compliance 009 * with the License. You may obtain a copy of the License at 010 * 011 * http://www.apache.org/licenses/LICENSE-2.0 012 * 013 * Unless required by applicable law or agreed to in writing, 014 * software distributed under the License is distributed on an 015 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 016 * KIND, either express or implied. See the License for the 017 * specific language governing permissions and limitations 018 * under the License. 019 */ 020 021 import org.apache.archiva.admin.model.RepositoryAdminException; 022 import org.apache.archiva.admin.model.beans.NetworkProxy; 023 import org.apache.archiva.admin.model.beans.RemoteRepository; 024 import org.apache.archiva.admin.model.networkproxy.NetworkProxyAdmin; 025 import org.apache.archiva.admin.model.proxyconnector.ProxyConnectorAdmin; 026 import org.apache.archiva.admin.model.remote.RemoteRepositoryAdmin; 027 import org.apache.archiva.common.ArchivaException; 028 import org.apache.archiva.common.plexusbridge.MavenIndexerUtils; 029 import org.apache.archiva.common.plexusbridge.PlexusSisuBridge; 030 import org.apache.archiva.common.plexusbridge.PlexusSisuBridgeException; 031 import org.apache.archiva.configuration.ArchivaConfiguration; 032 import org.apache.archiva.configuration.ConfigurationEvent; 033 import org.apache.archiva.configuration.ConfigurationListener; 034 import org.apache.archiva.proxy.common.WagonFactory; 035 import org.apache.commons.lang.StringUtils; 036 import org.apache.maven.index.NexusIndexer; 037 import org.apache.maven.index.context.IndexingContext; 038 import org.apache.maven.index.context.UnsupportedExistingLuceneIndexException; 039 import org.apache.maven.index.packer.IndexPacker; 040 import org.apache.maven.index.updater.IndexUpdater; 041 import org.slf4j.Logger; 042 import org.slf4j.LoggerFactory; 043 import org.springframework.scheduling.TaskScheduler; 044 import org.springframework.scheduling.support.CronTrigger; 045 import org.springframework.stereotype.Service; 046 047 import javax.annotation.PostConstruct; 048 import javax.annotation.PreDestroy; 049 import javax.inject.Inject; 050 import javax.inject.Named; 051 import java.io.IOException; 052 import java.util.Date; 053 import java.util.List; 054 import java.util.concurrent.CopyOnWriteArrayList; 055 056 /** 057 * @author Olivier Lamy 058 * @since 1.4-M1 059 */ 060 @Service ("downloadRemoteIndexScheduler#default") 061 public class DefaultDownloadRemoteIndexScheduler 062 implements ConfigurationListener, DownloadRemoteIndexScheduler 063 { 064 065 private Logger log = LoggerFactory.getLogger( getClass() ); 066 067 @Inject 068 @Named (value = "taskScheduler#indexDownloadRemote") 069 private TaskScheduler taskScheduler; 070 071 @Inject 072 private ArchivaConfiguration archivaConfiguration; 073 074 @Inject 075 private WagonFactory wagonFactory; 076 077 @Inject 078 private RemoteRepositoryAdmin remoteRepositoryAdmin; 079 080 @Inject 081 private ProxyConnectorAdmin proxyConnectorAdmin; 082 083 @Inject 084 private NetworkProxyAdmin networkProxyAdmin; 085 086 @Inject 087 private PlexusSisuBridge plexusSisuBridge; 088 089 @Inject 090 private MavenIndexerUtils mavenIndexerUtils; 091 092 private NexusIndexer nexusIndexer; 093 094 private IndexUpdater indexUpdater; 095 096 private IndexPacker indexPacker; 097 098 // store ids about currently running remote download : updated in DownloadRemoteIndexTask 099 private List<String> runningRemoteDownloadIds = new CopyOnWriteArrayList<String>(); 100 101 @PostConstruct 102 public void startup() 103 throws ArchivaException, RepositoryAdminException, PlexusSisuBridgeException, IOException, 104 UnsupportedExistingLuceneIndexException, DownloadRemoteIndexException 105 { 106 archivaConfiguration.addListener( this ); 107 // TODO add indexContexts even if null 108 109 nexusIndexer = plexusSisuBridge.lookup( NexusIndexer.class ); 110 111 indexUpdater = plexusSisuBridge.lookup( IndexUpdater.class ); 112 113 this.indexPacker = plexusSisuBridge.lookup( IndexPacker.class ); 114 115 for ( RemoteRepository remoteRepository : remoteRepositoryAdmin.getRemoteRepositories() ) 116 { 117 String contextKey = "remote-" + remoteRepository.getId(); 118 IndexingContext context = nexusIndexer.getIndexingContexts().get( contextKey ); 119 if ( context == null ) 120 { 121 continue; 122 } 123 124 // TODO record jobs from configuration 125 if ( remoteRepository.isDownloadRemoteIndex() && StringUtils.isNotEmpty( 126 remoteRepository.getCronExpression() ) ) 127 { 128 boolean fullDownload = context.getIndexDirectoryFile().list().length == 0; 129 scheduleDownloadRemote( remoteRepository.getId(), false, fullDownload ); 130 } 131 } 132 133 134 } 135 136 @PreDestroy 137 public void shutdown() 138 throws RepositoryAdminException, IOException 139 { 140 for ( RemoteRepository remoteRepository : remoteRepositoryAdmin.getRemoteRepositories() ) 141 { 142 String contextKey = "remote-" + remoteRepository.getId(); 143 IndexingContext context = nexusIndexer.getIndexingContexts().get( contextKey ); 144 if ( context == null ) 145 { 146 continue; 147 } 148 nexusIndexer.removeIndexingContext( context, false ); 149 } 150 } 151 152 public void configurationEvent( ConfigurationEvent event ) 153 { 154 // TODO remove jobs and add again 155 } 156 157 158 public void scheduleDownloadRemote( String repositoryId, boolean now, boolean fullDownload ) 159 throws DownloadRemoteIndexException 160 { 161 try 162 { 163 RemoteRepository remoteRepository = remoteRepositoryAdmin.getRemoteRepository( repositoryId ); 164 if ( remoteRepository == null ) 165 { 166 log.warn( "ignore scheduleDownloadRemote for repo with id {} as not exists", repositoryId ); 167 return; 168 } 169 NetworkProxy networkProxy = null; 170 if ( StringUtils.isNotBlank( remoteRepository.getRemoteDownloadNetworkProxyId() ) ) 171 { 172 networkProxy = networkProxyAdmin.getNetworkProxy( remoteRepository.getRemoteDownloadNetworkProxyId() ); 173 if ( networkProxy == null ) 174 { 175 log.warn( 176 "your remote repository is configured to download remote index trought a proxy we cannot find id:{}", 177 remoteRepository.getRemoteDownloadNetworkProxyId() ); 178 } 179 } 180 181 DownloadRemoteIndexTaskRequest downloadRemoteIndexTaskRequest = 182 new DownloadRemoteIndexTaskRequest().setRemoteRepository( remoteRepository ).setNetworkProxy( 183 networkProxy ).setFullDownload( fullDownload ).setWagonFactory( 184 wagonFactory ).setRemoteRepositoryAdmin( remoteRepositoryAdmin ).setIndexUpdater( 185 indexUpdater ).setIndexPacker( this.indexPacker ); 186 187 if ( now ) 188 { 189 log.info( "schedule download remote index for repository {}", remoteRepository.getId() ); 190 // do it now 191 taskScheduler.schedule( 192 new DownloadRemoteIndexTask( downloadRemoteIndexTaskRequest, this.runningRemoteDownloadIds ), 193 new Date() ); 194 } 195 else 196 { 197 log.info( "schedule download remote index for repository {} with cron expression {}", 198 remoteRepository.getId(), remoteRepository.getCronExpression() ); 199 try 200 { 201 CronTrigger cronTrigger = new CronTrigger( remoteRepository.getCronExpression() ); 202 taskScheduler.schedule( 203 new DownloadRemoteIndexTask( downloadRemoteIndexTaskRequest, this.runningRemoteDownloadIds ), 204 cronTrigger ); 205 } 206 catch ( IllegalArgumentException e ) 207 { 208 log.warn( "Unable to schedule remote index download: " + e.getLocalizedMessage() ); 209 } 210 211 if ( remoteRepository.isDownloadRemoteIndexOnStartup() ) 212 { 213 log.info( 214 "remote repository {} configured with downloadRemoteIndexOnStartup schedule now a download", 215 remoteRepository.getId() ); 216 taskScheduler.schedule( 217 new DownloadRemoteIndexTask( downloadRemoteIndexTaskRequest, this.runningRemoteDownloadIds ), 218 new Date() ); 219 } 220 } 221 222 } 223 catch ( RepositoryAdminException e ) 224 { 225 log.error( e.getMessage(), e ); 226 throw new DownloadRemoteIndexException( e.getMessage(), e ); 227 } 228 } 229 230 public TaskScheduler getTaskScheduler() 231 { 232 return taskScheduler; 233 } 234 235 public void setTaskScheduler( TaskScheduler taskScheduler ) 236 { 237 this.taskScheduler = taskScheduler; 238 } 239 }