Search in sources :

Example 1 with ValidateEventRegistrationException

use of com.aws.greengrass.builtin.services.configstore.exceptions.ValidateEventRegistrationException in project aws-greengrass-nucleus by aws-greengrass.

the class ConfigStoreIPCEventStreamAgent method validateConfiguration.

/**
 * Trigger a validate event to service/component, typically used during deployments.
 *
 * @param componentName service/component to send validate event to
 * @param deploymentId  deployment id which is being validated
 * @param configuration new component configuration to validate
 * @param reportFuture  future to track validation report in response to the event
 * @return true if the service has registered a validator, false if not
 * @throws ValidateEventRegistrationException throws when triggering requested validation event failed
 */
@SuppressWarnings("PMD.AvoidCatchingGenericException")
public boolean validateConfiguration(String componentName, String deploymentId, Map<String, Object> configuration, CompletableFuture<ConfigurationValidityReport> reportFuture) throws ValidateEventRegistrationException {
    for (Map.Entry<String, BiConsumer<String, Map<String, Object>>> e : configValidationListeners.entrySet()) {
        if (e.getKey().equals(componentName)) {
            Pair componentToDeploymentId = new Pair<>(componentName, deploymentId);
            try {
                configValidationReportFutures.put(componentToDeploymentId, reportFuture);
                e.getValue().accept(deploymentId, configuration);
                return true;
            } catch (Exception ex) {
                // TODO: [P41211196]: Retries, timeouts & and better exception handling in sending server event to
                // components
                configValidationReportFutures.remove(componentToDeploymentId);
                throw new ValidateEventRegistrationException(ex);
            }
        }
    }
    return false;
}
Also used : ValidateEventRegistrationException(com.aws.greengrass.builtin.services.configstore.exceptions.ValidateEventRegistrationException) Map(java.util.Map) ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap) HashMap(java.util.HashMap) BiConsumer(java.util.function.BiConsumer) ValidateEventRegistrationException(com.aws.greengrass.builtin.services.configstore.exceptions.ValidateEventRegistrationException) Pair(com.aws.greengrass.util.Pair)

Example 2 with ValidateEventRegistrationException

use of com.aws.greengrass.builtin.services.configstore.exceptions.ValidateEventRegistrationException in project aws-greengrass-nucleus by aws-greengrass.

the class DynamicComponentConfigurationValidator method validateOverIpc.

private boolean validateOverIpc(Deployment deployment, Set<ComponentToValidate> componentsToValidate, CompletableFuture<DeploymentResult> deploymentResultFuture) {
    String deploymentId = deployment.getId();
    Integer timeoutSec = deployment.getDeploymentDocumentObj().getConfigurationValidationPolicy().timeoutInSeconds();
    Long timeoutMs = Duration.ofSeconds(DEFAULT_TIMEOUT_SECOND).toMillis();
    if (timeoutSec != null) {
        timeoutMs = Duration.ofSeconds(timeoutSec).toMillis();
    }
    try {
        String failureMsg = null;
        boolean validationRequested = false;
        boolean valid = true;
        for (ComponentToValidate componentToValidate : componentsToValidate) {
            try {
                if (configStoreIPCEventStreamAgent.validateConfiguration(componentToValidate.componentName, deploymentId, componentToValidate.configuration, componentToValidate.response)) {
                    validationRequested = true;
                }
            // Do nothing if service has not subscribed for validation
            } catch (ValidateEventRegistrationException e) {
                validationRequested = false;
                failureMsg = "Error requesting validation from component " + componentToValidate.componentName;
                valid = false;
                break;
            }
        }
        if (validationRequested) {
            try {
                CompletableFuture.allOf(componentsToValidate.stream().map(ComponentToValidate::getResponse).collect(Collectors.toSet()).toArray(new CompletableFuture[0])).get(timeoutMs, TimeUnit.MILLISECONDS);
                failureMsg = "Components reported that their to-be-deployed configuration is invalid";
                for (ComponentToValidate componentToValidate : componentsToValidate) {
                    // The aggregate future above has a timeout so at this point we will always have a report
                    // already received from all components otherwise the aggregate future would have failed,
                    // so we will no longer be blocked on any of the response futures
                    ConfigurationValidityReport report = componentToValidate.response.join();
                    if (ConfigurationValidityStatus.REJECTED.equals(report.getStatus())) {
                        failureMsg = String.format("%s { name = %s, message = %s }", failureMsg, componentToValidate.componentName, report.getMessage());
                        logger.atError().kv("component", componentToValidate.componentName).kv("message", report.getMessage()).log("Component reported that its to-be-deployed configuration is invalid");
                        valid = false;
                    }
                }
            } catch (InterruptedException | ExecutionException | TimeoutException | CancellationException | CompletionException e) {
                failureMsg = "Error while waiting for validation report for one or more components:" + e.getMessage();
                logger.atError().setCause(e).log(failureMsg);
                valid = false;
            }
        }
        if (!valid) {
            deploymentResultFuture.complete(new DeploymentResult(DeploymentResult.DeploymentStatus.FAILED_NO_STATE_CHANGE, new ComponentConfigurationValidationException(failureMsg)));
        }
        return valid;
    } finally {
        componentsToValidate.forEach(c -> {
            configStoreIPCEventStreamAgent.discardValidationReportTracker(deploymentId, c.componentName, c.response);
            c.response.cancel(true);
        });
    }
}
Also used : DeploymentResult(com.aws.greengrass.deployment.model.DeploymentResult) ValidateEventRegistrationException(com.aws.greengrass.builtin.services.configstore.exceptions.ValidateEventRegistrationException) ComponentConfigurationValidationException(com.aws.greengrass.deployment.exceptions.ComponentConfigurationValidationException) CancellationException(java.util.concurrent.CancellationException) CompletionException(java.util.concurrent.CompletionException) ExecutionException(java.util.concurrent.ExecutionException) ConfigurationValidityReport(software.amazon.awssdk.aws.greengrass.model.ConfigurationValidityReport) TimeoutException(java.util.concurrent.TimeoutException)

Aggregations

ValidateEventRegistrationException (com.aws.greengrass.builtin.services.configstore.exceptions.ValidateEventRegistrationException)2 ComponentConfigurationValidationException (com.aws.greengrass.deployment.exceptions.ComponentConfigurationValidationException)1 DeploymentResult (com.aws.greengrass.deployment.model.DeploymentResult)1 Pair (com.aws.greengrass.util.Pair)1 HashMap (java.util.HashMap)1 Map (java.util.Map)1 CancellationException (java.util.concurrent.CancellationException)1 CompletionException (java.util.concurrent.CompletionException)1 ConcurrentHashMap (java.util.concurrent.ConcurrentHashMap)1 ExecutionException (java.util.concurrent.ExecutionException)1 TimeoutException (java.util.concurrent.TimeoutException)1 BiConsumer (java.util.function.BiConsumer)1 ConfigurationValidityReport (software.amazon.awssdk.aws.greengrass.model.ConfigurationValidityReport)1