Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ class ArtifactRefAvailability implements ValidationRule {
String validate(ValidationRequest request) {
def verifyStoreKeys = request.getTools().getValidationStoreKeys(request, true);

def errors = new ArrayList()
def errors = Collections.synchronizedList(new ArrayList());
def tools = request.getTools()
def dc = new ModelProcessorConfig().setIncludeBuildSection(false).setIncludeManagedDependencies(false)

Expand Down Expand Up @@ -62,17 +62,15 @@ class ArtifactRefAvailability implements ValidationRule {
}
})

synchronized (errors) {
if (!found) {
errors.add(String.format("%s is invalid: %s is not available via: %s",
it, path, StringUtils.join(verifyStoreKeys, ", ")))
}
if (!found) {
errors.add(String.format("%s is invalid: %s is not available via: %s",
it, path, StringUtils.join(verifyStoreKeys, ", ")))
}

if (!foundPom) {
errors.add(String.format("%s is invalid: %s is not available via: %s", it,
tools.toArtifactPath(target.asPomArtifact()),
StringUtils.join(verifyStoreKeys, ", ")))
}
if (!foundPom) {
errors.add(String.format("%s is invalid: %s is not available via: %s", it,
tools.toArtifactPath(target.asPomArtifact()),
StringUtils.join(verifyStoreKeys, ", ")))
}
}
})
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,17 +10,15 @@ class NoPreExistingPaths implements ValidationRule {
String validate(ValidationRequest request) throws PromotionValidationException {
def verifyStoreKeys = request.getTools().getValidationStoreKeys(request, false);

def errors = new ArrayList()
def errors = Collections.synchronizedList(new ArrayList());
def tools = request.getTools()

tools.paralleledEach(request.getSourcePaths(), { it ->
def aref = tools.getArtifact(it);
if (aref != null) {
tools.paralleledEach(verifyStoreKeys, { verifyStoreKey ->
if (tools.exists(verifyStoreKey, it)) {
synchronized (errors) {
errors.add(String.format("%s is already available in: %s", it, verifyStoreKey))
}
errors.add(String.format("%s is already available in: %s", it, verifyStoreKey))
}
})
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ class NoSnapshots implements ValidationRule {
String validate(ValidationRequest request) {
def verifyStoreKeys = request.getTools().getValidationStoreKeys(request, true)

def errors = new ArrayList()
def errors = Collections.synchronizedList(new ArrayList());
def tools = request.getTools()
def dc = new ModelProcessorConfig().setIncludeBuildSection(true).setIncludeManagedPlugins(true).setIncludeManagedDependencies(true)

Expand All @@ -20,9 +20,7 @@ class NoSnapshots implements ValidationRule {
def ref = tools.getArtifact(it)
if (ref != null) {
if (!ref.getVersionSpec().isRelease()) {
synchronized (errors) {
errors.add(String.format("%s is a variable/snapshot version.", it))
}
errors.add(String.format("%s is a variable/snapshot version.", it))
}
}

Expand All @@ -31,9 +29,7 @@ class NoSnapshots implements ValidationRule {
tools.paralleledEach(relationships, { rel ->
def target = rel.getTarget()
if (!target.getVersionSpec().isRelease()) {
synchronized (errors) {
errors.add(String.format("%s uses a variable/snapshot version in: %s", target, it))
}
errors.add(String.format("%s uses a variable/snapshot version in: %s", target, it))
}
})
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ class NoVersionRanges implements ValidationRule {
String validate(ValidationRequest request) {
def verifyStoreKeys = request.getTools().getValidationStoreKeys(request, true)

def errors = new ArrayList()
def errors = Collections.synchronizedList(new ArrayList());
def tools = request.getTools()
def dc = new ModelProcessorConfig().setIncludeBuildSection(true).setIncludeManagedPlugins(true).setIncludeManagedDependencies(true)

Expand All @@ -21,9 +21,7 @@ class NoVersionRanges implements ValidationRule {
tools.paralleledEach(relationships, { rel ->
def target = rel.getTarget()
if (!target.getVersionSpec().isSingle()) {
synchronized(errors) {
errors.add(String.format( "%s uses a compound version in: %s", target, it))
}
errors.add(String.format("%s uses a compound version in: %s", target, it))
}
})
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import org.slf4j.LoggerFactory
class ParsablePom implements ValidationRule {

String validate(ValidationRequest request) {
def errors = new ArrayList()
def errors = Collections.synchronizedList(new ArrayList());
def tools = request.getTools()
def logger = LoggerFactory.getLogger(ValidationRule.class)
logger.info("Parsing POMs in:\n {}.", request.getSourcePaths().join("\n "))
Expand All @@ -20,9 +20,7 @@ class ParsablePom implements ValidationRule {
def pom = tools.readLocalPom(it, request)
}
catch (Exception e) {
synchronized(errors) {
errors.add(String.format("%s: Failed to parse POM. Error was: %s", it, e))
}
errors.add(String.format("%s: Failed to parse POM. Error was: %s", it, e))
}
}
})
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ class ProjectArtifacts implements ValidationRule {

String validate(ValidationRequest request) throws Exception {
def classifierAndTypeSet = request.getValidationParameter("classifierAndTypeSet")
def errors = new ArrayList()
def errors = Collections.synchronizedList(new ArrayList());

if (classifierAndTypeSet != null) {
def ctStrings = classifierAndTypeSet.split("\\s*,\\s*")
Expand Down Expand Up @@ -57,9 +57,7 @@ class ProjectArtifacts implements ValidationRule {
tcs.each { tc ->
logger.trace("Checking if TC: {} is in: {} for: {}", tc, entry.value, entry.key)
if (!entry.value.contains(tc)) {
synchronized(errors) {
errors.add(String.format("%s: missing artifact with type/classifier: %s", entry.key, tc))
}
errors.add(String.format("%s: missing artifact with type/classifier: %s", entry.key, tc))
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ class ProjectVersionPattern implements ValidationRule {

String validate(ValidationRequest request) throws Exception {
def versionPattern = request.getValidationParameter("versionPattern")
def errors = new ArrayList()
def errors = Collections.synchronizedList(new ArrayList());

if (versionPattern != null) {
def tools = request.getTools()
Expand All @@ -18,10 +18,8 @@ class ProjectVersionPattern implements ValidationRule {
if (ref != null) {
def vs = ref.getVersionString()
if (!vs.matches(versionPattern)) {
synchronized (errors) {
errors.add(String.format("%s does not match version pattern: '%s' (version was: '%s')",
it, versionPattern, vs))
}
errors.add(String.format("%s does not match version pattern: '%s' (version was: '%s')",
it, versionPattern, vs))
}
}
})
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -79,12 +79,14 @@
*/
public class PromotionValidationTools
{
final Logger logger = LoggerFactory.getLogger( this.getClass() );

public static final String AVAILABLE_IN_STORES = "availableInStores";

@Deprecated
public static final String AVAILABLE_IN_STORE_KEY = "availableInStoreKey";

private static final int DEFAULT_RULE_PARALLEL_WAIT_TIME_MINS = 10;
private static final int DEFAULT_RULE_PARALLEL_WAIT_TIME_MINS = 30;

@Inject
private ContentManager contentManager;
Expand Down Expand Up @@ -561,7 +563,7 @@ public <K, V> void paralleledEach( Map<K, V> map, Closure closure )

private <T> void runParallelAndWait( Collection<T> runCollection, Closure closure, Logger logger )
{
Set<T> todo = new HashSet<>( runCollection);
Set<T> todo = new HashSet<>( runCollection );
final CountDownLatch latch = new CountDownLatch( todo.size() );
todo.forEach( e -> ruleParallelExecutor.execute( () -> {
try
Expand All @@ -577,7 +579,12 @@ private <T> void runParallelAndWait( Collection<T> runCollection, Closure closur

try
{
latch.await( DEFAULT_RULE_PARALLEL_WAIT_TIME_MINS, TimeUnit.MINUTES );
// true if the count reached zero and false if timeout
boolean finished = latch.await( DEFAULT_RULE_PARALLEL_WAIT_TIME_MINS, TimeUnit.MINUTES );
if ( !finished )
{
throw new RuntimeException( "Parallel execution timeout" );
}
}
catch ( InterruptedException e )
{
Expand All @@ -586,4 +593,22 @@ private <T> void runParallelAndWait( Collection<T> runCollection, Closure closur
}
}

public <T> void forEach( Collection<T> collection, Closure closure )
{
logger.trace( "Exe on collection {} with closure {}", collection, closure );
collection.forEach( e -> closure.call( e ) );
}

public <T> void forEach( T[] array, Closure closure )
{
logger.trace( "Exe on array {} with closure {}", array, closure );
Arrays.asList( array ).forEach( e -> closure.call( e ) );
}

public <K, V> void forEach( Map<K, V> map, Closure closure )
{
Set<Map.Entry<K, V>> entries = map.entrySet();
logger.trace( "Exe on map {} with closure {}", entries, closure );
entries.forEach( e -> closure.call( e ) );
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
package org.commonjava.indy.promote.validate;

import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang3.ClassUtils;
import org.commonjava.cdi.util.weft.DrainingExecutorCompletionService;
import org.commonjava.cdi.util.weft.ExecutorConfig;
import org.commonjava.cdi.util.weft.WeftExecutorService;
Expand All @@ -27,6 +28,7 @@
import org.commonjava.indy.data.IndyDataException;
import org.commonjava.indy.data.StoreDataManager;
import org.commonjava.indy.measure.annotation.Measure;
import org.commonjava.indy.metrics.IndyMetricsManager;
import org.commonjava.indy.model.core.ArtifactStore;
import org.commonjava.indy.model.core.RemoteRepository;
import org.commonjava.indy.promote.conf.PromoteConfig;
Expand All @@ -51,7 +53,9 @@
import java.util.List;
import java.util.Set;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.atomic.AtomicReference;

import static com.codahale.metrics.MetricRegistry.name;
import static java.lang.String.format;
import static org.apache.commons.lang.StringUtils.join;
import static org.commonjava.indy.core.ctl.PoolUtils.detectOverloadVoid;
Expand All @@ -78,6 +82,9 @@ public class PromotionValidator
@Inject
private PromoteConfig config;

@Inject
private IndyMetricsManager metricsManager;

@Inject
@WeftManaged
@ExecutorConfig( named = "promote-validation-rules-runner", threads = 20, priority = 5, loadSensitive = ExecutorConfig.BooleanLiteral.TRUE, maxLoadFactor = 400 )
Expand All @@ -90,13 +97,15 @@ protected PromotionValidator()
}

public PromotionValidator( PromoteValidationsManager validationsManager, PromotionValidationTools validationTools,
StoreDataManager storeDataMgr, DownloadManager downloadManager, WeftExecutorService validateService )
StoreDataManager storeDataMgr, DownloadManager downloadManager,
WeftExecutorService validateService, IndyMetricsManager metricsManager )
{
this.validationsManager = validationsManager;
this.validationTools = validationTools;
this.storeDataMgr = storeDataMgr;
this.downloadManager = downloadManager;
this.validateService = validateService;
this.metricsManager = metricsManager;
}

/**
Expand Down Expand Up @@ -228,7 +237,7 @@ public ValidationRequest validate( PromoteRequest request, ValidationResult resu
}
}

@Measure
//@Measure <-- this does not work. Internal calls can never be intercepted.
private void executeValidationRule( final String ruleRef, final ValidationRequest req,
final ValidationResult result, final PromoteRequest request )
throws PromotionValidationException
Expand All @@ -239,32 +248,68 @@ private void executeValidationRule( final String ruleRef, final ValidationReques
ValidationRuleMapping rule = validationsManager.getRuleMappingNamed( ruleName );
if ( rule != null )
{
try
logger.debug( "Running promotion validation rule: {}", rule.getName() );
String error = null;
if ( metricsManager != null )
{
logger.debug( "Running promotion validation rule: {}", rule.getName() );
String error = rule.getRule().validate( req );
if ( StringUtils.isNotEmpty( error ) )
{
logger.debug( "{} failed", rule.getName() );
result.addValidatorError( rule.getName(), error );
}
else
AtomicReference<Exception> ex = new AtomicReference<>();
error = metricsManager.wrapWithStandardMetrics( () -> {
try
{
return rule.getRule().validate( req );
}
catch ( Exception e )
{
ex.set( e );
return null;
}
}, () -> getMetricName( rule.getName() ) );

if ( ex.get() != null )
{
logger.debug( "{} succeeded", rule.getName() );
throwException( ex.get(), rule, request );
}
}
catch ( Exception e )
else
{
if ( e instanceof PromotionValidationException )
try
{
error = rule.getRule().validate( req );
}
catch ( Exception e )
{
throw (PromotionValidationException) e;
throwException( e, rule, request );
}
}

throw new PromotionValidationException(
"Failed to run validation rule: {} for request: {}. Reason: {}", e,
rule.getName(), request, e );
if ( StringUtils.isNotEmpty( error ) )
{
logger.debug( "{} failed", rule.getName() );
result.addValidatorError( rule.getName(), error );
}
else
{
logger.debug( "{} succeeded", rule.getName() );
}
}
}

private void throwException( Exception e, ValidationRuleMapping rule, PromoteRequest request )
throws PromotionValidationException
{
if ( e instanceof PromotionValidationException )
{
throw (PromotionValidationException) e;
}

throw new PromotionValidationException( "Failed to run validation rule: {} for request: {}. Reason: {}", e,
rule.getName(), request, e );
}

private String getMetricName( String ruleName )
{
String cls = ClassUtils.getAbbreviatedName( getClass().getName(), 1 );
return name( cls, "rule", ruleName );
}

private boolean needTempRepo( PromoteRequest promoteRequest )
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -178,7 +178,7 @@ public void setup()
galleyParts.getMavenMetadataReader(),
modelProcessor, galleyParts.getTypeMapper(),
galleyParts.getTransferManager(),
contentDigester ), storeManager, downloadManager, validateService );
contentDigester ), storeManager, downloadManager, validateService, null );

PromoteConfig config = new PromoteConfig();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,11 @@ public Object operation( InvocationContext context ) throws Exception
measure = method.getDeclaringClass().getAnnotation( Measure.class );
}

if ( measure == null )
{
return context.proceed();
}

String defaultName = getDefaultName( context.getMethod().getDeclaringClass(), context.getMethod().getName() );
logger.trace( "Gathering metrics for: {} using context: {}", defaultName, context.getContextData() );

Expand Down