Search in sources :

Example 1 with NoAvailableComponentVersionException

use of com.aws.greengrass.componentmanager.exceptions.NoAvailableComponentVersionException in project aws-greengrass-nucleus by aws-greengrass.

the class ComponentManager method negotiateVersionWithCloud.

@SuppressWarnings({ "PMD.AvoidCatchingGenericException", "PMD.AvoidRethrowingException", "PMD.NullAssignment", "PMD.AvoidInstanceofChecksInCatchClause", "PMD.PreserveStackTrace" })
private ComponentIdentifier negotiateVersionWithCloud(String componentName, Map<String, Requirement> versionRequirements, ComponentIdentifier localCandidate) throws PackagingException, InterruptedException {
    ResolvedComponentVersion resolvedComponentVersion;
    if (localCandidate == null) {
        try {
            resolvedComponentVersion = RetryUtils.runWithRetry(clientExceptionRetryConfig, () -> componentServiceHelper.resolveComponentVersion(componentName, null, versionRequirements), "resolve-component-version", logger);
        } catch (InterruptedException e) {
            throw e;
        } catch (Exception e) {
            // Don't bother logging the full stacktrace when it is NoAvailableComponentVersionException since we
            // know the reason for that error
            logger.atError().setCause(e instanceof NoAvailableComponentVersionException ? null : e).kv(COMPONENT_NAME, componentName).kv("versionRequirement", versionRequirements).log("Failed to negotiate version with cloud and no local version to fall back to");
            // know what the cause is.
            if (e instanceof NoAvailableComponentVersionException) {
                throw new NoAvailableComponentVersionException("No local or cloud component version satisfies the requirements.", componentName, versionRequirements);
            } else {
                throw new NoAvailableComponentVersionException("No local or cloud component version satisfies the requirements.", componentName, versionRequirements, e);
            }
        }
    } else {
        try {
            resolvedComponentVersion = componentServiceHelper.resolveComponentVersion(componentName, localCandidate.getVersion(), versionRequirements);
        } catch (Exception e) {
            // Don't bother logging the full stacktrace when it is NoAvailableComponentVersionException since we
            // know the reason for that error
            logger.atInfo().setCause(e instanceof NoAvailableComponentVersionException ? null : e).kv(COMPONENT_NAME, componentName).kv("versionRequirement", versionRequirements).kv("localVersion", localCandidate).log("Failed to negotiate version with cloud and fall back to use the local version");
            return localCandidate;
        }
    }
    ComponentIdentifier resolvedComponentId = new ComponentIdentifier(resolvedComponentVersion.componentName(), new Semver(resolvedComponentVersion.componentVersion()));
    String downloadedRecipeContent = StandardCharsets.UTF_8.decode(resolvedComponentVersion.recipe().asByteBuffer()).toString();
    com.amazon.aws.iot.greengrass.component.common.ComponentRecipe cloudResolvedRecipe = // cloud sends JSON
    RecipeLoader.parseRecipe(downloadedRecipeContent, RecipeLoader.RecipeFormat.JSON);
    // Persist the recipe
    String savedRecipeContent = componentStore.saveComponentRecipe(cloudResolvedRecipe);
    // Since plugin runs in the same JVM as Nucleus does, we need to calculate the digest for its recipe and
    // persist it, so that we can use it to detect and prevent a tampered plugin (recipe) gets loaded
    storeRecipeDigestInConfigStoreForPlugin(cloudResolvedRecipe, savedRecipeContent);
    // Save the arn to the recipe meta data file
    componentStore.saveRecipeMetadata(resolvedComponentId, new RecipeMetadata(resolvedComponentVersion.arn()));
    return resolvedComponentId;
}
Also used : NoAvailableComponentVersionException(com.aws.greengrass.componentmanager.exceptions.NoAvailableComponentVersionException) ComponentIdentifier(com.aws.greengrass.componentmanager.models.ComponentIdentifier) Semver(com.vdurmont.semver4j.Semver) PackageLoadingException(com.aws.greengrass.componentmanager.exceptions.PackageLoadingException) NoAvailableComponentVersionException(com.aws.greengrass.componentmanager.exceptions.NoAvailableComponentVersionException) InvalidArtifactUriException(com.aws.greengrass.componentmanager.exceptions.InvalidArtifactUriException) SizeLimitException(com.aws.greengrass.componentmanager.exceptions.SizeLimitException) SemverException(com.vdurmont.semver4j.SemverException) SdkClientException(software.amazon.awssdk.core.exception.SdkClientException) NoSuchAlgorithmException(java.security.NoSuchAlgorithmException) PackageDownloadException(com.aws.greengrass.componentmanager.exceptions.PackageDownloadException) PackagingException(com.aws.greengrass.componentmanager.exceptions.PackagingException) ServiceLoadException(com.aws.greengrass.lifecyclemanager.exceptions.ServiceLoadException) MissingRequiredComponentsException(com.aws.greengrass.componentmanager.exceptions.MissingRequiredComponentsException) IOException(java.io.IOException) ResolvedComponentVersion(software.amazon.awssdk.services.greengrassv2data.model.ResolvedComponentVersion) RecipeMetadata(com.aws.greengrass.componentmanager.models.RecipeMetadata)

Example 2 with NoAvailableComponentVersionException

use of com.aws.greengrass.componentmanager.exceptions.NoAvailableComponentVersionException in project aws-greengrass-nucleus by aws-greengrass.

the class ComponentManager method resolveComponentVersion.

ComponentMetadata resolveComponentVersion(String componentName, Map<String, Requirement> versionRequirements) throws InterruptedException, PackagingException {
    logger.atDebug().setEventType("resolve-component-version-start").kv(COMPONENT_STR, componentName).kv("versionRequirements", versionRequirements).log("Resolving component version starts");
    // Find best local candidate
    Optional<ComponentIdentifier> localCandidateOptional = findBestCandidateLocally(componentName, versionRequirements);
    if (localCandidateOptional.isPresent()) {
        logger.atInfo().kv("LocalCandidateId", localCandidateOptional.get()).log("Found the best local candidate that satisfies the requirement.");
    } else {
        logger.atInfo().log("Can't find a local candidate that satisfies the requirement.");
    }
    ComponentIdentifier resolvedComponentId;
    if (versionRequirements.containsKey(DeploymentDocumentConverter.LOCAL_DEPLOYMENT_GROUP_NAME) && localCandidateOptional.isPresent()) {
        // If local group has a requirement and a satisfying local version presents, use it and don't negotiate with
        // cloud.
        logger.atInfo().log("Local group has a requirement and found satisfying local candidate. Using the local" + " candidate as the resolved version without negotiating with cloud.");
        resolvedComponentId = localCandidateOptional.get();
    } else {
        // Otherwise try to negotiate with cloud
        if (deviceConfiguration.isDeviceConfiguredToTalkToCloud()) {
            logger.atDebug().setEventType("negotiate-version-with-cloud-start").log("Negotiating version with cloud");
            resolvedComponentId = negotiateVersionWithCloud(componentName, versionRequirements, localCandidateOptional.orElse(null));
            logger.atDebug().setEventType("negotiate-version-with-cloud-end").log("Negotiated version with cloud");
        } else {
            // Device running offline. Use the local candidate if present, otherwise fails
            if (localCandidateOptional.isPresent()) {
                logger.atInfo().log("Device is running offline and found satisfying local candidate. Using the " + "local candidate as the resolved version without negotiating with cloud.");
                resolvedComponentId = localCandidateOptional.get();
            } else {
                throw new NoAvailableComponentVersionException("Device is configured to run offline and no local component version satisfies the " + "requirements.", componentName, versionRequirements);
            }
        }
    }
    logger.atInfo().setEventType("resolve-component-version-end").kv("ResolvedComponent", resolvedComponentId).log("Resolved component version.");
    return getComponentMetadata(resolvedComponentId);
}
Also used : NoAvailableComponentVersionException(com.aws.greengrass.componentmanager.exceptions.NoAvailableComponentVersionException) ComponentIdentifier(com.aws.greengrass.componentmanager.models.ComponentIdentifier)

Example 3 with NoAvailableComponentVersionException

use of com.aws.greengrass.componentmanager.exceptions.NoAvailableComponentVersionException in project aws-greengrass-nucleus by aws-greengrass.

the class ComponentServiceHelper method resolveComponentVersion.

/**
 * Resolve a component version with greengrass cloud service. The dependency resolution algorithm goes through the
 * dependencies node by node, so one component got resolve a time.
 *
 * @param componentName             component name to be resolve
 * @param localCandidateVersion     component local candidate version if available
 * @param versionRequirements       component dependents version requirement map
 * @return resolved component version and recipe
 * @throws NoAvailableComponentVersionException if no applicable version available in cloud service
 */
@SuppressWarnings("PMD.PreserveStackTrace")
ResolvedComponentVersion resolveComponentVersion(String componentName, Semver localCandidateVersion, Map<String, Requirement> versionRequirements) throws NoAvailableComponentVersionException {
    ComponentPlatform platform = ComponentPlatform.builder().attributes(platformResolver.getCurrentPlatform()).build();
    Map<String, String> versionRequirementsInString = versionRequirements.entrySet().stream().collect(Collectors.toMap(Map.Entry::getKey, e -> e.getValue().toString()));
    ComponentCandidate candidate = ComponentCandidate.builder().componentName(componentName).componentVersion(localCandidateVersion == null ? null : localCandidateVersion.getValue()).versionRequirements(versionRequirementsInString).build();
    ResolveComponentCandidatesRequest request = ResolveComponentCandidatesRequest.builder().platform(platform).componentCandidates(Collections.singletonList(candidate)).build();
    ResolveComponentCandidatesResponse result;
    try {
        result = clientFactory.getGreengrassV2DataClient().resolveComponentCandidates(request);
    } catch (ResourceNotFoundException e) {
        logger.atDebug().kv("componentName", componentName).kv("versionRequirements", versionRequirements).log("No applicable version found in cloud registry", e);
        throw new NoAvailableComponentVersionException("No cloud component version satisfies the requirements.", componentName, versionRequirements);
    }
    Validate.isTrue(result.resolvedComponentVersions() != null && result.resolvedComponentVersions().size() == 1, "Component service returns invalid response. It should have one resolved component version");
    return result.resolvedComponentVersions().get(0);
}
Also used : ComponentPlatform(software.amazon.awssdk.services.greengrassv2data.model.ComponentPlatform) ResolvedComponentVersion(software.amazon.awssdk.services.greengrassv2data.model.ResolvedComponentVersion) NoAvailableComponentVersionException(com.aws.greengrass.componentmanager.exceptions.NoAvailableComponentVersionException) GreengrassServiceClientFactory(com.aws.greengrass.util.GreengrassServiceClientFactory) Collectors(java.util.stream.Collectors) Inject(javax.inject.Inject) Requirement(com.vdurmont.semver4j.Requirement) Validate(org.apache.commons.lang3.Validate) Semver(com.vdurmont.semver4j.Semver) ResolveComponentCandidatesResponse(software.amazon.awssdk.services.greengrassv2data.model.ResolveComponentCandidatesResponse) Map(java.util.Map) ResourceNotFoundException(software.amazon.awssdk.services.greengrassv2data.model.ResourceNotFoundException) LogManager(com.aws.greengrass.logging.impl.LogManager) Collections(java.util.Collections) PlatformResolver(com.aws.greengrass.config.PlatformResolver) Logger(com.aws.greengrass.logging.api.Logger) ComponentCandidate(software.amazon.awssdk.services.greengrassv2data.model.ComponentCandidate) ResolveComponentCandidatesRequest(software.amazon.awssdk.services.greengrassv2data.model.ResolveComponentCandidatesRequest) ComponentPlatform(software.amazon.awssdk.services.greengrassv2data.model.ComponentPlatform) ResolveComponentCandidatesResponse(software.amazon.awssdk.services.greengrassv2data.model.ResolveComponentCandidatesResponse) NoAvailableComponentVersionException(com.aws.greengrass.componentmanager.exceptions.NoAvailableComponentVersionException) ComponentCandidate(software.amazon.awssdk.services.greengrassv2data.model.ComponentCandidate) ResourceNotFoundException(software.amazon.awssdk.services.greengrassv2data.model.ResourceNotFoundException) Map(java.util.Map) ResolveComponentCandidatesRequest(software.amazon.awssdk.services.greengrassv2data.model.ResolveComponentCandidatesRequest)

Aggregations

NoAvailableComponentVersionException (com.aws.greengrass.componentmanager.exceptions.NoAvailableComponentVersionException)3 ComponentIdentifier (com.aws.greengrass.componentmanager.models.ComponentIdentifier)2 Semver (com.vdurmont.semver4j.Semver)2 ResolvedComponentVersion (software.amazon.awssdk.services.greengrassv2data.model.ResolvedComponentVersion)2 InvalidArtifactUriException (com.aws.greengrass.componentmanager.exceptions.InvalidArtifactUriException)1 MissingRequiredComponentsException (com.aws.greengrass.componentmanager.exceptions.MissingRequiredComponentsException)1 PackageDownloadException (com.aws.greengrass.componentmanager.exceptions.PackageDownloadException)1 PackageLoadingException (com.aws.greengrass.componentmanager.exceptions.PackageLoadingException)1 PackagingException (com.aws.greengrass.componentmanager.exceptions.PackagingException)1 SizeLimitException (com.aws.greengrass.componentmanager.exceptions.SizeLimitException)1 RecipeMetadata (com.aws.greengrass.componentmanager.models.RecipeMetadata)1 PlatformResolver (com.aws.greengrass.config.PlatformResolver)1 ServiceLoadException (com.aws.greengrass.lifecyclemanager.exceptions.ServiceLoadException)1 Logger (com.aws.greengrass.logging.api.Logger)1 LogManager (com.aws.greengrass.logging.impl.LogManager)1 GreengrassServiceClientFactory (com.aws.greengrass.util.GreengrassServiceClientFactory)1 Requirement (com.vdurmont.semver4j.Requirement)1 SemverException (com.vdurmont.semver4j.SemverException)1 IOException (java.io.IOException)1 NoSuchAlgorithmException (java.security.NoSuchAlgorithmException)1