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.common.plexusbridge.DigesterUtils; 024import org.apache.archiva.common.plexusbridge.PlexusSisuBridge; 025import org.apache.archiva.common.plexusbridge.PlexusSisuBridgeException; 026import org.apache.archiva.consumers.AbstractMonitoredConsumer; 027import org.apache.archiva.consumers.ConsumerException; 028import org.apache.archiva.consumers.KnownRepositoryContentConsumer; 029import org.codehaus.plexus.digest.ChecksumFile; 030import org.codehaus.plexus.digest.Digester; 031import org.codehaus.plexus.digest.DigesterException; 032import org.slf4j.Logger; 033import org.slf4j.LoggerFactory; 034import org.springframework.context.annotation.Scope; 035import org.springframework.stereotype.Service; 036 037import javax.annotation.PostConstruct; 038import javax.inject.Inject; 039import java.io.File; 040import java.io.FileNotFoundException; 041import java.io.IOException; 042import java.util.ArrayList; 043import java.util.Date; 044import java.util.List; 045 046/** 047 * ValidateChecksumConsumer - validate the provided checksum against the file it represents. 048 */ 049@Service( "knownRepositoryContentConsumer#validate-checksums" ) 050@Scope( "prototype" ) 051public class ValidateChecksumConsumer 052 extends AbstractMonitoredConsumer 053 implements KnownRepositoryContentConsumer 054{ 055 private Logger log = LoggerFactory.getLogger( ValidateChecksumConsumer.class ); 056 057 private static final String NOT_VALID_CHECKSUM = "checksum-not-valid"; 058 059 private static final String CHECKSUM_NOT_FOUND = "checksum-not-found"; 060 061 private static final String CHECKSUM_DIGESTER_FAILURE = "checksum-digester-failure"; 062 063 private static final String CHECKSUM_IO_ERROR = "checksum-io-error"; 064 065 private String id = "validate-checksums"; 066 067 private String description = "Validate checksums against file."; 068 069 private ChecksumFile checksum; 070 071 private List<Digester> allDigesters; 072 073 @Inject 074 private PlexusSisuBridge plexusSisuBridge; 075 076 @Inject 077 private DigesterUtils digesterUtils; 078 079 private File repositoryDir; 080 081 private List<String> includes; 082 083 @Override 084 public String getId( ) 085 { 086 return this.id; 087 } 088 089 @Override 090 public String getDescription( ) 091 { 092 return this.description; 093 } 094 095 @Override 096 public void beginScan( ManagedRepository repository, Date whenGathered ) 097 throws ConsumerException 098 { 099 this.repositoryDir = new File( repository.getLocation( ) ); 100 } 101 102 @Override 103 public void beginScan( ManagedRepository repository, Date whenGathered, boolean executeOnEntireRepo ) 104 throws ConsumerException 105 { 106 beginScan( repository, whenGathered ); 107 } 108 109 @Override 110 public void completeScan( ) 111 { 112 /* nothing to do */ 113 } 114 115 @Override 116 public void completeScan( boolean executeOnEntireRepo ) 117 { 118 completeScan( ); 119 } 120 121 @Override 122 public List<String> getExcludes( ) 123 { 124 return null; 125 } 126 127 @Override 128 public List<String> getIncludes( ) 129 { 130 return this.includes; 131 } 132 133 @Override 134 public void processFile( String path ) 135 throws ConsumerException 136 { 137 File checksumFile = new File( this.repositoryDir, path ); 138 try 139 { 140 if ( !checksum.isValidChecksum( checksumFile ) ) 141 { 142 log.warn( "The checksum for {} is invalid.", checksumFile ); 143 triggerConsumerWarning( NOT_VALID_CHECKSUM, "The checksum for " + checksumFile + " is invalid." ); 144 } 145 } 146 catch ( FileNotFoundException e ) 147 { 148 log.error( "File not found during checksum validation: ", e ); 149 triggerConsumerError( CHECKSUM_NOT_FOUND, "File not found during checksum validation: " + e.getMessage( ) ); 150 } 151 catch ( DigesterException e ) 152 { 153 log.error( "Digester failure during checksum validation on {}", checksumFile ); 154 triggerConsumerError( CHECKSUM_DIGESTER_FAILURE, 155 "Digester failure during checksum validation on " + checksumFile ); 156 } 157 catch ( IOException e ) 158 { 159 log.error( "Checksum I/O error during validation on {}", checksumFile ); 160 triggerConsumerError( CHECKSUM_IO_ERROR, "Checksum I/O error during validation on " + checksumFile ); 161 } 162 } 163 164 @Override 165 public void processFile( String path, boolean executeOnEntireReDpo ) 166 throws Exception 167 { 168 processFile( path ); 169 } 170 171 @PostConstruct 172 public void initialize( ) 173 throws PlexusSisuBridgeException 174 { 175 checksum = plexusSisuBridge.lookup( ChecksumFile.class ); 176 List<Digester> allDigesters = new ArrayList<>( digesterUtils.getAllDigesters( ) ); 177 includes = new ArrayList<>( allDigesters.size( ) ); 178 for ( Digester digester : allDigesters ) 179 { 180 includes.add( "**/*" + digester.getFilenameExtension( ) ); 181 } 182 } 183}