001package org.apache.archiva.scheduler.indexing.maven; 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.proxy.ProxyRegistry; 022import org.apache.archiva.proxy.model.NetworkProxy; 023import org.apache.archiva.scheduler.indexing.DownloadRemoteIndexException; 024import org.apache.archiva.scheduler.indexing.DownloadRemoteIndexScheduler; 025import org.apache.archiva.admin.model.RepositoryAdminException; 026import org.apache.archiva.configuration.ArchivaConfiguration; 027import org.apache.archiva.configuration.ConfigurationEvent; 028import org.apache.archiva.configuration.ConfigurationListener; 029import org.apache.archiva.indexer.UnsupportedBaseContextException; 030import org.apache.archiva.proxy.maven.WagonFactory; 031import org.apache.archiva.repository.RepositoryRegistry; 032import org.apache.archiva.repository.features.RemoteIndexFeature; 033import org.apache.commons.lang3.StringUtils; 034import org.apache.maven.index.context.IndexingContext; 035import org.apache.maven.index.packer.IndexPacker; 036import org.apache.maven.index.updater.IndexUpdater; 037import org.slf4j.Logger; 038import org.slf4j.LoggerFactory; 039import org.springframework.scheduling.TaskScheduler; 040import org.springframework.scheduling.support.CronTrigger; 041import org.springframework.stereotype.Service; 042 043import javax.annotation.PostConstruct; 044import javax.inject.Inject; 045import javax.inject.Named; 046import java.util.Date; 047import java.util.List; 048import java.util.concurrent.CopyOnWriteArrayList; 049 050/** 051 * @author Olivier Lamy 052 * @since 1.4-M1 053 */ 054@Service( "downloadRemoteIndexScheduler#default" ) 055public class DefaultDownloadRemoteIndexScheduler 056 implements ConfigurationListener, DownloadRemoteIndexScheduler 057{ 058 059 private Logger log = LoggerFactory.getLogger( getClass() ); 060 061 @Inject 062 @Named( value = "taskScheduler#indexDownloadRemote" ) 063 private TaskScheduler taskScheduler; 064 065 @Inject 066 RepositoryRegistry repositoryRegistry; 067 068 @Inject 069 private ArchivaConfiguration archivaConfiguration; 070 071 @Inject 072 private WagonFactory wagonFactory; 073 074 @Inject 075 private IndexUpdater indexUpdater; 076 077 @Inject 078 private IndexPacker indexPacker; 079 080 @Inject 081 private ProxyRegistry proxyRegistry; 082 083 // store ids about currently running remote download : updated in DownloadRemoteIndexTask 084 private List<String> runningRemoteDownloadIds = new CopyOnWriteArrayList<String>(); 085 086 @PostConstruct 087 public void startup() 088 throws 089 DownloadRemoteIndexException, UnsupportedBaseContextException { 090 archivaConfiguration.addListener( this ); 091 // TODO add indexContexts even if null 092 093 for ( org.apache.archiva.repository.RemoteRepository remoteRepository : repositoryRegistry.getRemoteRepositories() ) 094 { 095 String contextKey = "remote-" + remoteRepository.getId(); 096 IndexingContext context = remoteRepository.getIndexingContext().getBaseContext(IndexingContext.class); 097 if ( context == null ) 098 { 099 continue; 100 } 101 RemoteIndexFeature rif = remoteRepository.getFeature(RemoteIndexFeature.class).get(); 102 103 104 // TODO record jobs from configuration 105 if ( rif.isDownloadRemoteIndex() && StringUtils.isNotEmpty( 106 remoteRepository.getSchedulingDefinition() ) ) 107 { 108 boolean fullDownload = context.getIndexDirectoryFile().list().length == 0; 109 scheduleDownloadRemote( remoteRepository.getId(), false, fullDownload ); 110 } 111 } 112 113 114 } 115 116 @Override 117 public void configurationEvent( ConfigurationEvent event ) 118 { 119 // TODO remove jobs and add again 120 } 121 122 123 @Override 124 public void scheduleDownloadRemote( String repositoryId, boolean now, boolean fullDownload ) 125 throws DownloadRemoteIndexException 126 { 127 org.apache.archiva.repository.RemoteRepository remoteRepo = repositoryRegistry.getRemoteRepository(repositoryId); 128 129 if ( remoteRepo == null ) 130 { 131 log.warn( "ignore scheduleDownloadRemote for repo with id {} as not exists", repositoryId ); 132 return; 133 } 134 if (!remoteRepo.supportsFeature(RemoteIndexFeature.class)) { 135 log.warn("ignore scheduleDownloadRemote for repo with id {}. Does not support remote index.", repositoryId); 136 return; 137 } 138 RemoteIndexFeature rif = remoteRepo.getFeature(RemoteIndexFeature.class).get(); 139 NetworkProxy networkProxy = null; 140 if ( StringUtils.isNotBlank( rif.getProxyId() ) ) 141 { 142 networkProxy = proxyRegistry.getNetworkProxy( rif.getProxyId() ); 143 if ( networkProxy == null ) 144 { 145 log.warn( 146 "your remote repository is configured to download remote index trought a proxy we cannot find id:{}", 147 rif.getProxyId() ); 148 } 149 } 150 151 DownloadRemoteIndexTaskRequest downloadRemoteIndexTaskRequest = new DownloadRemoteIndexTaskRequest() // 152 .setRemoteRepository( remoteRepo ) // 153 .setNetworkProxy( networkProxy ) // 154 .setFullDownload( fullDownload ) // 155 .setWagonFactory( wagonFactory ) // 156 .setIndexUpdater( indexUpdater ) // 157 .setIndexPacker( this.indexPacker ); 158 159 if ( now ) 160 { 161 log.info( "schedule download remote index for repository {}", remoteRepo.getId() ); 162 // do it now 163 taskScheduler.schedule( 164 new DownloadRemoteIndexTask( downloadRemoteIndexTaskRequest, this.runningRemoteDownloadIds ), 165 new Date() ); 166 } 167 else 168 { 169 log.info( "schedule download remote index for repository {} with cron expression {}", 170 remoteRepo.getId(), remoteRepo.getSchedulingDefinition()); 171 try 172 { 173 CronTrigger cronTrigger = new CronTrigger( remoteRepo.getSchedulingDefinition()); 174 taskScheduler.schedule( 175 new DownloadRemoteIndexTask( downloadRemoteIndexTaskRequest, this.runningRemoteDownloadIds ), 176 cronTrigger ); 177 } 178 catch ( IllegalArgumentException e ) 179 { 180 log.warn( "Unable to schedule remote index download: {}", e.getLocalizedMessage() ); 181 } 182 183 if ( rif.isDownloadRemoteIndexOnStartup() ) 184 { 185 log.info( 186 "remote repository {} configured with downloadRemoteIndexOnStartup schedule now a download", 187 remoteRepo.getId() ); 188 taskScheduler.schedule( 189 new DownloadRemoteIndexTask( downloadRemoteIndexTaskRequest, this.runningRemoteDownloadIds ), 190 new Date() ); 191 } 192 } 193 194 } 195 196 public TaskScheduler getTaskScheduler() 197 { 198 return taskScheduler; 199 } 200 201 public void setTaskScheduler( TaskScheduler taskScheduler ) 202 { 203 this.taskScheduler = taskScheduler; 204 } 205 206 @Override 207 public List<String> getRunningRemoteDownloadIds() 208 { 209 return runningRemoteDownloadIds; 210 } 211}