001package org.apache.archiva.consumers.core; 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.admin.model.beans.ManagedRepository; 023import org.apache.archiva.checksum.ChecksumAlgorithm; 024import org.apache.archiva.checksum.ChecksummedFile; 025import org.apache.archiva.configuration.ArchivaConfiguration; 026import org.apache.archiva.configuration.FileTypes; 027import org.apache.archiva.consumers.AbstractMonitoredConsumer; 028import org.apache.archiva.consumers.ConsumerException; 029import org.apache.archiva.consumers.KnownRepositoryContentConsumer; 030import org.slf4j.Logger; 031import org.slf4j.LoggerFactory; 032import org.springframework.context.annotation.Scope; 033import org.springframework.stereotype.Service; 034 035import javax.annotation.PostConstruct; 036import javax.inject.Inject; 037import java.io.File; 038import java.io.IOException; 039import java.util.ArrayList; 040import java.util.Date; 041import java.util.List; 042 043/** 044 * ArtifactMissingChecksumsConsumer - Create missing and/or fix invalid checksums for the artifact. 045 */ 046@Service( "knownRepositoryContentConsumer#create-missing-checksums" ) 047@Scope( "prototype" ) 048public class ArtifactMissingChecksumsConsumer 049 extends AbstractMonitoredConsumer 050 implements KnownRepositoryContentConsumer 051 // it's prototype bean so we assume configuration won't change during a run 052 //, RegistryListener 053{ 054 055 private Logger log = LoggerFactory.getLogger( ArtifactMissingChecksumsConsumer.class ); 056 057 private String id = "create-missing-checksums"; 058 059 private String description = "Create Missing and/or Fix Invalid Checksums (.sha1, .md5)"; 060 061 private ArchivaConfiguration configuration; 062 063 private FileTypes filetypes; 064 065 private ChecksummedFile checksum; 066 067 private static final String TYPE_CHECKSUM_NOT_FILE = "checksum-bad-not-file"; 068 069 private static final String TYPE_CHECKSUM_CANNOT_CALC = "checksum-calc-failure"; 070 071 private static final String TYPE_CHECKSUM_CANNOT_CREATE = "checksum-create-failure"; 072 073 private File repositoryDir; 074 075 private List<String> includes = new ArrayList<>( 0 ); 076 077 @Inject 078 public ArtifactMissingChecksumsConsumer( ArchivaConfiguration configuration, FileTypes filetypes ) 079 { 080 this.configuration = configuration; 081 this.filetypes = filetypes; 082 083 //configuration.addChangeListener( this ); 084 085 initIncludes( ); 086 } 087 088 @Override 089 public String getId( ) 090 { 091 return this.id; 092 } 093 094 @Override 095 public String getDescription( ) 096 { 097 return this.description; 098 } 099 100 @Override 101 public void beginScan( ManagedRepository repo, Date whenGathered ) 102 throws ConsumerException 103 { 104 this.repositoryDir = new File( repo.getLocation( ) ); 105 } 106 107 @Override 108 public void beginScan( ManagedRepository repo, Date whenGathered, boolean executeOnEntireRepo ) 109 throws ConsumerException 110 { 111 beginScan( repo, whenGathered ); 112 } 113 114 @Override 115 public void completeScan( ) 116 { 117 /* do nothing */ 118 } 119 120 @Override 121 public void completeScan( boolean executeOnEntireRepo ) 122 { 123 completeScan( ); 124 } 125 126 @Override 127 public List<String> getExcludes( ) 128 { 129 return getDefaultArtifactExclusions( ); 130 } 131 132 @Override 133 public List<String> getIncludes( ) 134 { 135 return includes; 136 } 137 138 @Override 139 public void processFile( String path ) 140 throws ConsumerException 141 { 142 createFixChecksum( path, ChecksumAlgorithm.SHA1 ); 143 createFixChecksum( path, ChecksumAlgorithm.MD5 ); 144 } 145 146 @Override 147 public void processFile( String path, boolean executeOnEntireRepo ) 148 throws ConsumerException 149 { 150 processFile( path ); 151 } 152 153 private void createFixChecksum( String path, ChecksumAlgorithm checksumAlgorithm ) 154 { 155 File artifactFile = new File( this.repositoryDir, path ); 156 File checksumFile = new File( this.repositoryDir, path + "." + checksumAlgorithm.getExt( ) ); 157 158 // Checking for existence 159 if (artifactFile.exists()) 160 { 161 if ( checksumFile.exists( ) ) 162 { 163 checksum = new ChecksummedFile( artifactFile ); 164 try 165 { 166 if ( !checksum.isValidChecksum( checksumAlgorithm ) ) 167 { 168 checksum.fixChecksums( new ChecksumAlgorithm[]{checksumAlgorithm} ); 169 log.info( "Fixed checksum file {}", checksumFile.getAbsolutePath( ) ); 170 triggerConsumerInfo( "Fixed checksum file " + checksumFile.getAbsolutePath( ) ); 171 } 172 } 173 catch ( IOException e ) 174 { 175 log.error( "Cannot calculate checksum for file {} :", checksumFile, e ); 176 triggerConsumerError( TYPE_CHECKSUM_CANNOT_CALC, "Cannot calculate checksum for file " + checksumFile + 177 ": " + e.getMessage( ) ); 178 } 179 } 180 else if ( !checksumFile.exists( ) ) 181 { 182 checksum = new ChecksummedFile( artifactFile ); 183 try 184 { 185 checksum.createChecksum( checksumAlgorithm ); 186 log.info( "Created missing checksum file {}", checksumFile.getAbsolutePath( ) ); 187 triggerConsumerInfo( "Created missing checksum file " + checksumFile.getAbsolutePath( ) ); 188 } 189 catch ( IOException e ) 190 { 191 log.error( "Cannot create {} checksum for file {} :", checksumAlgorithm, artifactFile, e ); 192 triggerConsumerError( TYPE_CHECKSUM_CANNOT_CREATE, "Cannot create checksum for file " + checksumFile + 193 ": " + e.getMessage( ) ); 194 } 195 } 196 else 197 { 198 log.warn( "Checksum file {} is not a file. ", checksumFile.getAbsolutePath( ) ); 199 triggerConsumerWarning( TYPE_CHECKSUM_NOT_FILE, 200 "Checksum file " + checksumFile.getAbsolutePath( ) + " is not a file." ); 201 } 202 } 203 } 204 205 /* 206 @Override 207 public void afterConfigurationChange( Registry registry, String propertyName, Object propertyValue ) 208 { 209 if ( ConfigurationNames.isRepositoryScanning( propertyName ) ) 210 { 211 initIncludes(); 212 } 213 } 214 215 216 @Override 217 public void beforeConfigurationChange( Registry registry, String propertyName, Object propertyValue ) 218 { 219 // do nothing 220 } 221 222 */ 223 224 private void initIncludes( ) 225 { 226 includes = new ArrayList<>( filetypes.getFileTypePatterns( FileTypes.ARTIFACTS ) ); 227 228 } 229 230 @PostConstruct 231 public void initialize( ) 232 { 233 //configuration.addChangeListener( this ); 234 235 initIncludes( ); 236 } 237}