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.checksum.*; 023import org.apache.archiva.configuration.ArchivaConfiguration; 024import org.apache.archiva.configuration.FileTypes; 025import org.apache.archiva.consumers.AbstractMonitoredConsumer; 026import org.apache.archiva.consumers.ConsumerException; 027import org.apache.archiva.consumers.KnownRepositoryContentConsumer; 028import org.apache.archiva.repository.ManagedRepository; 029import org.slf4j.Logger; 030import org.slf4j.LoggerFactory; 031import org.springframework.context.annotation.Scope; 032import org.springframework.stereotype.Service; 033 034import javax.annotation.PostConstruct; 035import javax.inject.Inject; 036import java.io.IOException; 037import java.nio.file.Files; 038import java.nio.file.Path; 039import java.nio.file.Paths; 040import java.util.ArrayList; 041import java.util.Date; 042import java.util.List; 043 044/** 045 * ArtifactMissingChecksumsConsumer - Create missing and/or fix invalid checksums for the artifact. 046 */ 047@Service( "knownRepositoryContentConsumer#create-missing-checksums" ) 048@Scope( "prototype" ) 049public class ArtifactMissingChecksumsConsumer 050 extends AbstractMonitoredConsumer 051 implements KnownRepositoryContentConsumer 052 // it's prototype bean so we assume configuration won't change during a run 053 //, RegistryListener 054{ 055 056 private Logger log = LoggerFactory.getLogger( ArtifactMissingChecksumsConsumer.class ); 057 058 private String id = "create-missing-checksums"; 059 060 private String description = "Create Missing and/or Fix Invalid Checksum files."; 061 062 private ArchivaConfiguration configuration; 063 064 private FileTypes filetypes; 065 066 private static final String TYPE_CHECKSUM_NOT_FILE = "checksum-bad-not-file"; 067 068 private static final String TYPE_CHECKSUM_CANNOT_CALC = "checksum-calc-failure"; 069 070 private static final String TYPE_CHECKSUM_CANNOT_CREATE = "checksum-create-failure"; 071 072 private Path repositoryDir; 073 074 private List<String> includes = new ArrayList<>( 0 ); 075 private List<ChecksumAlgorithm> algorithms; 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 = Paths.get( 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 Path artifactPath = repositoryDir.resolve(path); 143 ChecksummedFile csFile = new ChecksummedFile(artifactPath); 144 UpdateStatusList result = csFile.fixChecksums(algorithms); 145 if (result.getTotalStatus()== UpdateStatus.ERROR) { 146 log.warn( "Error accessing file {}. ", path ); 147 triggerConsumerWarning( TYPE_CHECKSUM_NOT_FILE, 148 "Error accessing file " + path + "." ); 149 } else { 150 result.getStatusList().stream().forEach(st -> 151 triggerInfo(path, st)); 152 } 153 } 154 155 private void triggerInfo(String path, UpdateStatus status) { 156 switch (status.getValue()) { 157 case UpdateStatus.ERROR: 158 log.error( "Cannot create checksum for file {} :", path, status.getError() ); 159 triggerConsumerError( TYPE_CHECKSUM_CANNOT_CREATE, "Cannot create checksum for file " + path + 160 ": " + status.getError().getMessage( ) ); 161 break; 162 case UpdateStatus.CREATED: 163 log.info( "Created missing checksum file {}", path ); 164 triggerConsumerInfo( "Created missing checksum file " + path ); 165 break; 166 case UpdateStatus.UPDATED: 167 log.info( "Fixed checksum file {}", path ); 168 triggerConsumerInfo( "Fixed checksum file " + path ); 169 break; 170 171 } 172 } 173 174 @Override 175 public void processFile( String path, boolean executeOnEntireRepo ) 176 throws ConsumerException 177 { 178 processFile( path ); 179 } 180 181 182 /* 183 @Override 184 public void afterConfigurationChange( Registry registry, String propertyName, Object propertyValue ) 185 { 186 if ( ConfigurationNames.isRepositoryScanning( propertyName ) ) 187 { 188 initIncludes(); 189 } 190 } 191 192 193 @Override 194 public void beforeConfigurationChange( Registry registry, String propertyName, Object propertyValue ) 195 { 196 // do nothing 197 } 198 199 */ 200 201 private void initIncludes( ) 202 { 203 includes = new ArrayList<>( filetypes.getFileTypePatterns( FileTypes.ARTIFACTS ) ); 204 205 } 206 207 @PostConstruct 208 public void initialize( ) 209 { 210 //configuration.addChangeListener( this ); 211 212 initIncludes( ); 213 algorithms = ChecksumUtil.getAlgorithms(configuration.getConfiguration().getArchivaRuntimeConfiguration().getChecksumTypes()); 214 } 215}