addons/promote/common/src/main/java/org/commonjava/indy/promote/validate/PromotionValidator.java
@Measure
    public ValidationRequest validate( PromoteRequest request, ValidationResult result, String baseUrl )
            throws PromotionValidationException, IndyWorkflowException
    {
        ValidationRuleSet set = validationsManager.getRuleSetMatching( request.getTargetKey() );

        ArtifactStore source;
        try
        {
            source = storeDataMgr.getArtifactStore( request.getSource() );
        }
        catch ( IndyDataException e )
        {
            throw new PromotionValidationException(
                    String.format( "Failed to retrieve source ArtifactStore: %s for validation", request.getSource() ),
                    e );
        }

        if ( set != null )
        {

            logger.debug( "Running validation rule-set for promotion: {}", set.getName() );

            result.setRuleSet( set.getName() );
            MDC.put( PROMOTION_VALIDATION_RULE_SET, set.getName() );

            List<String> ruleNames = set.getRuleNames();
            if ( ruleNames != null && !ruleNames.isEmpty() )
            {
                final ArtifactStore store = getRequestStore( request, baseUrl );
                final ValidationRequest req = new ValidationRequest( request, set, validationTools, store );
                try
                {
                    DrainingExecutorCompletionService<Exception> svc =
                            new DrainingExecutorCompletionService<>( validateService );

                    detectOverloadVoid(()->{
                        for ( String ruleRef : ruleNames )
                        {
                            svc.submit( () -> {
                                MDC.put( PROMOTION_VALIDATION_RULE, ruleRef );
                                Exception err = null;
                                try
                                {
                                    executeValidationRule( ruleRef, req, result, request );
                                }
                                catch ( Exception e )
                                {
                                    err = e;
                                }
                                finally
                                {
                                    MDC.remove( PROMOTION_VALIDATION_RULE );
                                }

                                return err;
                            } );
                        }
                    });

                    List<String> errors = new ArrayList<>();
                    svc.drain( err->{
                        if ( err != null )
                        {
                            logger.error( "Promotion validation failure", err );
                            errors.add( err.getMessage() );
                        }
                    } );

                    if ( !errors.isEmpty() )
                    {
                        throw new PromotionValidationException( format( "Failed to do promotion validation: \n\n%s", join( errors, "\n" ) ) );
                    }
                }
                catch ( InterruptedException e )
                {
                    throw new PromotionValidationException( "Failed to do promotion validation: validation execution has been interrupted ", e );
                }
                catch ( ExecutionException e )
                {
                    throw new PromotionValidationException( "Failed to execute promotion validations", e );
                }
                finally
                {
                    if ( needTempRepo( request ) )
                    {
                        try
                        {
                            final String changeSum = format( "Removes the temp remote repo [%s] after promote operation.", store );
                            storeDataMgr.deleteArtifactStore( store.getKey(),
                                                              new ChangeSummary( ChangeSummary.SYSTEM_USER,
                                                                                 changeSum ),
                                                              new EventMetadata().set( ContentManager.SUPPRESS_EVENTS,
                                                                                       true ) );

                            Transfer root = downloadManager.getStoreRootDirectory( store );
                            if ( root.exists() )
                            {
                                root.delete( false );
                            }

                            logger.debug( "Promotion temporary repo {} has been deleted for {}", store.getKey(),
                                         request.getSource() );
                        }
                        catch ( IndyDataException | IOException e )
                        {
                            logger.warn( "Temporary promotion validation repository was NOT removed correctly.", e );
                        }
                    }
                }
                return req;
            }
            else
            {
                logger.info( "No validation rules are defined for: {}", request.getTargetKey() );
                return new ValidationRequest( request, set, validationTools, source );
            }
        }
        else
        {
            logger.info( "No validation rule-sets are defined for: {}", request.getTargetKey() );
            return new ValidationRequest( request, set, validationTools, source );
        }
    }
@Measure
    public ValidationRequest validate( PromoteRequest request, ValidationResult result, String baseUrl )
            throws PromotionValidationException, IndyWorkflowException
    {
        ValidationRuleSet set = validationsManager.getRuleSetMatching( request.getTargetKey() );

        ArtifactStore source;
        try
        {
            source = storeDataMgr.getArtifactStore( request.getSource() );
        }
        catch ( IndyDataException e )
        {
            throw new PromotionValidationException(
                    String.format( "Failed to retrieve source ArtifactStore: %s for validation", request.getSource() ),
                    e );
        }

        if ( set != null )
        {

            logger.debug( "Running validation rule-set for promotion: {}", set.getName() );

            result.setRuleSet( set.getName() );
            MDC.put( PROMOTION_VALIDATION_RULE_SET, set.getName() );

            List<String> ruleNames = set.getRuleNames();
            if ( ruleNames != null && !ruleNames.isEmpty() )
            {
                final ArtifactStore store = getRequestStore( request, baseUrl );
                final ValidationRequest req = new ValidationRequest( request, set, validationTools, store );
                try
                {
                    DrainingExecutorCompletionService<Exception> svc =
                            new DrainingExecutorCompletionService<>( validateService );

                    detectOverloadVoid(()->{
                        for ( String ruleRef : ruleNames )
                        {
                            svc.submit( () -> {
                                MDC.put( PROMOTION_VALIDATION_RULE, ruleRef );
                                Exception err = null;
                                try
                                {
                                    executeValidationRule( ruleRef, req, result, request );
                                }
                                catch ( Exception e )
                                {
                                    err = e;
                                }
                                finally
                                {
                                    MDC.remove( PROMOTION_VALIDATION_RULE );
                                }

                                return err;
                            } );
                        }
                    });

                    List<String> errors = new ArrayList<>();
                    svc.drain( err->{
                        if ( err != null )
                        {
                            logger.error( "Promotion validation failure", err );
                            errors.add( err.getMessage() );
                        }
                    } );

                    if ( !errors.isEmpty() )
                    {
                        throw new PromotionValidationException( format( "Failed to do promotion validation: \n\n%s", join( errors, "\n" ) ) );
                    }
                }
                catch ( InterruptedException e )
                {
                    throw new PromotionValidationException( "Failed to do promotion validation: validation execution has been interrupted ", e );
                }
                catch ( ExecutionException e )
                {
                    throw new PromotionValidationException( "Failed to execute promotion validations", e );
                }
                finally
                {
                    if ( needTempRepo( request ) )
                    {
                        try
                        {
                            final String changeSum = format( "Removes the temp remote repo [%s] after promote operation.", store );
                            storeDataMgr.deleteArtifactStore( store.getKey(),
                                                              new ChangeSummary( ChangeSummary.SYSTEM_USER,
                                                                                 changeSum ),
                                                              new EventMetadata().set( ContentManager.SUPPRESS_EVENTS,
                                                                                       true ) );

                            Transfer root = downloadManager.getStoreRootDirectory( store );
                            if ( root.exists() )
                            {
                                root.delete( false );
                            }

                            logger.debug( "Promotion temporary repo {} has been deleted for {}", store.getKey(),
                                         request.getSource() );
                        }
                        catch ( IndyDataException | IOException e )
                        {
                            logger.warn( "Temporary promotion validation repository was NOT removed correctly.", e );
                        }
                    }
                }
                return req;
            }
            else
            {
                logger.info( "No validation rules are defined for: {}", request.getTargetKey() );
                return new ValidationRequest( request, set, validationTools, source );
            }
        }
        else
        {
            logger.info( "No validation rule-sets are defined for: {}", request.getTargetKey() );
            return new ValidationRequest( request, set, validationTools, source );
        }
    }
NOTE: As of Indy 1.2.6, ValidationRequest passed back to enable further post-processing, especially of promotion
paths, after promotion takes place. This enables us to avoid re-executing recursive path discovery, for instance.

@param request
@param result
@param baseUrl
@return
@throws PromotionValidationException
@throws IndyWorkflowException