001package 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 021import org.apache.archiva.admin.model.RepositoryAdminException; 022import org.apache.archiva.admin.model.beans.NetworkProxy; 023import org.apache.archiva.admin.model.beans.RemoteRepository; 024import org.apache.archiva.admin.model.networkproxy.NetworkProxyAdmin; 025import org.apache.archiva.admin.model.proxyconnector.ProxyConnectorAdmin; 026import org.apache.archiva.admin.model.remote.RemoteRepositoryAdmin; 027import org.apache.archiva.common.ArchivaException; 028import org.apache.archiva.common.plexusbridge.MavenIndexerUtils; 029import org.apache.archiva.common.plexusbridge.PlexusSisuBridge; 030import org.apache.archiva.common.plexusbridge.PlexusSisuBridgeException; 031import org.apache.archiva.configuration.ArchivaConfiguration; 032import org.apache.archiva.configuration.ConfigurationEvent; 033import org.apache.archiva.configuration.ConfigurationListener; 034import org.apache.archiva.proxy.common.WagonFactory; 035import org.apache.commons.lang.StringUtils; 036import org.apache.maven.index.NexusIndexer; 037import org.apache.maven.index.context.IndexingContext; 038import org.apache.maven.index.context.UnsupportedExistingLuceneIndexException; 039import org.apache.maven.index.packer.IndexPacker; 040import org.apache.maven.index.updater.IndexUpdater; 041import org.slf4j.Logger; 042import org.slf4j.LoggerFactory; 043import org.springframework.scheduling.TaskScheduler; 044import org.springframework.scheduling.support.CronTrigger; 045import org.springframework.stereotype.Service; 046 047import javax.annotation.PostConstruct; 048import javax.annotation.PreDestroy; 049import javax.inject.Inject; 050import javax.inject.Named; 051import java.io.IOException; 052import java.util.Date; 053import java.util.List; 054import java.util.concurrent.CopyOnWriteArrayList; 055 056/** 057 * @author Olivier Lamy 058 * @since 1.4-M1 059 */ 060@Service ("downloadRemoteIndexScheduler#default") 061public 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 @Override 153 public void configurationEvent( ConfigurationEvent event ) 154 { 155 // TODO remove jobs and add again 156 } 157 158 159 @Override 160 public void scheduleDownloadRemote( String repositoryId, boolean now, boolean fullDownload ) 161 throws DownloadRemoteIndexException 162 { 163 try 164 { 165 RemoteRepository remoteRepository = remoteRepositoryAdmin.getRemoteRepository( repositoryId ); 166 if ( remoteRepository == null ) 167 { 168 log.warn( "ignore scheduleDownloadRemote for repo with id {} as not exists", repositoryId ); 169 return; 170 } 171 NetworkProxy networkProxy = null; 172 if ( StringUtils.isNotBlank( remoteRepository.getRemoteDownloadNetworkProxyId() ) ) 173 { 174 networkProxy = networkProxyAdmin.getNetworkProxy( remoteRepository.getRemoteDownloadNetworkProxyId() ); 175 if ( networkProxy == null ) 176 { 177 log.warn( 178 "your remote repository is configured to download remote index trought a proxy we cannot find id:{}", 179 remoteRepository.getRemoteDownloadNetworkProxyId() ); 180 } 181 } 182 183 DownloadRemoteIndexTaskRequest downloadRemoteIndexTaskRequest = 184 new DownloadRemoteIndexTaskRequest().setRemoteRepository( remoteRepository ).setNetworkProxy( 185 networkProxy ).setFullDownload( fullDownload ).setWagonFactory( 186 wagonFactory ).setRemoteRepositoryAdmin( remoteRepositoryAdmin ).setIndexUpdater( 187 indexUpdater ).setIndexPacker( this.indexPacker ); 188 189 if ( now ) 190 { 191 log.info( "schedule download remote index for repository {}", remoteRepository.getId() ); 192 // do it now 193 taskScheduler.schedule( 194 new DownloadRemoteIndexTask( downloadRemoteIndexTaskRequest, this.runningRemoteDownloadIds ), 195 new Date() ); 196 } 197 else 198 { 199 log.info( "schedule download remote index for repository {} with cron expression {}", 200 remoteRepository.getId(), remoteRepository.getCronExpression() ); 201 try 202 { 203 CronTrigger cronTrigger = new CronTrigger( remoteRepository.getCronExpression() ); 204 taskScheduler.schedule( 205 new DownloadRemoteIndexTask( downloadRemoteIndexTaskRequest, this.runningRemoteDownloadIds ), 206 cronTrigger ); 207 } 208 catch ( IllegalArgumentException e ) 209 { 210 log.warn( "Unable to schedule remote index download: {}", e.getLocalizedMessage() ); 211 } 212 213 if ( remoteRepository.isDownloadRemoteIndexOnStartup() ) 214 { 215 log.info( 216 "remote repository {} configured with downloadRemoteIndexOnStartup schedule now a download", 217 remoteRepository.getId() ); 218 taskScheduler.schedule( 219 new DownloadRemoteIndexTask( downloadRemoteIndexTaskRequest, this.runningRemoteDownloadIds ), 220 new Date() ); 221 } 222 } 223 224 } 225 catch ( RepositoryAdminException e ) 226 { 227 log.error( e.getMessage(), e ); 228 throw new DownloadRemoteIndexException( e.getMessage(), e ); 229 } 230 } 231 232 public TaskScheduler getTaskScheduler() 233 { 234 return taskScheduler; 235 } 236 237 public void setTaskScheduler( TaskScheduler taskScheduler ) 238 { 239 this.taskScheduler = taskScheduler; 240 } 241 242 @Override 243 public List<String> getRunningRemoteDownloadIds() 244 { 245 return runningRemoteDownloadIds; 246 } 247}