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.ChecksumAlgorithm; 023import org.apache.archiva.checksum.ChecksumReference; 024import org.apache.archiva.checksum.ChecksumValidationException; 025import org.apache.archiva.checksum.ChecksummedFile; 026import org.apache.archiva.consumers.AbstractMonitoredConsumer; 027import org.apache.archiva.consumers.ConsumerException; 028import org.apache.archiva.consumers.KnownRepositoryContentConsumer; 029import org.apache.archiva.repository.ManagedRepository; 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 java.nio.file.Path; 037import java.nio.file.Paths; 038import java.util.ArrayList; 039import java.util.Date; 040import java.util.List; 041import java.util.Set; 042 043import static org.apache.archiva.checksum.ChecksumValidationException.ValidationError.*; 044 045/** 046 * ValidateChecksumConsumer - validate the provided checksum against the file it represents. 047 */ 048@Service( "knownRepositoryContentConsumer#validate-checksums" ) 049@Scope( "prototype" ) 050public class ValidateChecksumConsumer 051 extends AbstractMonitoredConsumer 052 implements KnownRepositoryContentConsumer 053{ 054 private Logger log = LoggerFactory.getLogger( ValidateChecksumConsumer.class ); 055 056 private static final String NOT_VALID_CHECKSUM = "checksum-not-valid"; 057 058 private static final String CHECKSUM_NOT_FOUND = "checksum-not-found"; 059 060 private static final String CHECKSUM_DIGESTER_FAILURE = "checksum-digester-failure"; 061 062 private static final String CHECKSUM_IO_ERROR = "checksum-io-error"; 063 064 private String id = "validate-checksums"; 065 066 private String description = "Validate checksums against file."; 067 068 private Path repositoryDir; 069 070 private List<String> includes; 071 072 @Override 073 public String getId( ) 074 { 075 return this.id; 076 } 077 078 @Override 079 public String getDescription( ) 080 { 081 return this.description; 082 } 083 084 @Override 085 public void beginScan( ManagedRepository repository, Date whenGathered ) 086 throws ConsumerException 087 { 088 this.repositoryDir = Paths.get( repository.getLocation( ) ); 089 } 090 091 @Override 092 public void beginScan( ManagedRepository repository, Date whenGathered, boolean executeOnEntireRepo ) 093 throws ConsumerException 094 { 095 beginScan( repository, whenGathered ); 096 } 097 098 @Override 099 public void completeScan( ) 100 { 101 /* nothing to do */ 102 } 103 104 @Override 105 public void completeScan( boolean executeOnEntireRepo ) 106 { 107 completeScan( ); 108 } 109 110 @Override 111 public List<String> getExcludes( ) 112 { 113 return null; 114 } 115 116 @Override 117 public List<String> getIncludes( ) 118 { 119 return this.includes; 120 } 121 122 @Override 123 public void processFile( String path ) 124 throws ConsumerException 125 { 126 Path checksumFile = this.repositoryDir.resolve( path ); 127 try 128 { 129 ChecksumReference cf = ChecksummedFile.getFromChecksumFile( checksumFile ); 130 if ( !cf.getFile().isValidChecksum( cf.getAlgorithm(), true ) ) 131 { 132 log.warn( "The checksum for {} is invalid.", checksumFile ); 133 triggerConsumerWarning( NOT_VALID_CHECKSUM, "The checksum for " + checksumFile + " is invalid." ); 134 } 135 } 136 catch ( ChecksumValidationException e ) 137 { 138 if (e.getErrorType()==READ_ERROR) { 139 log.error( "Checksum read error during validation on {}", checksumFile ); 140 triggerConsumerError( CHECKSUM_IO_ERROR, "Checksum I/O error during validation on " + checksumFile ); 141 } else if (e.getErrorType()==INVALID_FORMAT || e.getErrorType()==DIGEST_ERROR) { 142 log.error( "Digester failure during checksum validation on {}", checksumFile ); 143 triggerConsumerError( CHECKSUM_DIGESTER_FAILURE, 144 "Digester failure during checksum validation on " + checksumFile ); 145 } else if (e.getErrorType()==FILE_NOT_FOUND) { 146 log.error( "File not found during checksum validation: ", e ); 147 triggerConsumerError( CHECKSUM_NOT_FOUND, "File not found during checksum validation: " + e.getMessage( ) ); 148 } 149 } 150 } 151 152 @Override 153 public void processFile( String path, boolean executeOnEntireReDpo ) 154 throws Exception 155 { 156 processFile( path ); 157 } 158 159 @PostConstruct 160 public void initialize( ) 161 { 162 Set<String> extensions = ChecksumAlgorithm.getAllExtensions(); 163 includes = new ArrayList<>( extensions.size() ); 164 for ( String ext : extensions ) 165 { 166 includes.add( "**/*." + ext ); 167 } 168 } 169}