Search in sources :

Example 1 with ResolvedComponentVersion

use of software.amazon.awssdk.services.greengrassv2data.model.ResolvedComponentVersion in project aws-greengrass-nucleus by aws-greengrass.

the class ComponentManagerTest method GIVEN_requirement_is_from_local_group_and_has_no_local_version_WHEN_resolve_version_THEN_use_cloud_version.

@Test
void GIVEN_requirement_is_from_local_group_and_has_no_local_version_WHEN_resolve_version_THEN_use_cloud_version() throws Exception {
    ComponentIdentifier componentA_1_0_0 = new ComponentIdentifier(componentA, v1_0_0);
    ComponentMetadata componentA_1_0_0_md = new ComponentMetadata(componentA_1_0_0, Collections.emptyMap());
    // no local version
    when(componentStore.findBestMatchAvailableComponent(eq(componentA), any())).thenReturn(Optional.empty());
    // has cloud version
    com.amazon.aws.iot.greengrass.component.common.ComponentRecipe recipe = com.amazon.aws.iot.greengrass.component.common.ComponentRecipe.builder().componentName(componentA).componentVersion(v1_0_0).componentType(ComponentType.GENERIC).recipeFormatVersion(RecipeFormatVersion.JAN_25_2020).build();
    ResolvedComponentVersion resolvedComponentVersion = ResolvedComponentVersion.builder().componentName(componentA).componentVersion(v1_0_0.getValue()).recipe(SdkBytes.fromByteArray(MAPPER.writeValueAsBytes(recipe))).arn(TEST_ARN).build();
    when(componentManagementServiceHelper.resolveComponentVersion(anyString(), any(), any())).thenReturn(resolvedComponentVersion);
    // mock return metadata from the id
    when(componentStore.getPackageMetadata(any())).thenReturn(componentA_1_0_0_md);
    // WHEN
    ComponentMetadata componentMetadata = componentManager.resolveComponentVersion(componentA, Collections.singletonMap(DeploymentDocumentConverter.LOCAL_DEPLOYMENT_GROUP_NAME, Requirement.buildNPM("^1.0")));
    // THEN
    assertThat(componentMetadata, is(componentA_1_0_0_md));
    verify(componentStore).findBestMatchAvailableComponent(componentA, Requirement.buildNPM("^1.0"));
    verify(componentManagementServiceHelper).resolveComponentVersion(componentA, null, Collections.singletonMap(DeploymentDocumentConverter.LOCAL_DEPLOYMENT_GROUP_NAME, Requirement.buildNPM("^1.0")));
    verify(componentStore).getPackageMetadata(componentA_1_0_0);
    verify(componentStore).saveComponentRecipe(recipe);
    verify(componentStore).saveRecipeMetadata(componentA_1_0_0, new RecipeMetadata(TEST_ARN));
}
Also used : ResolvedComponentVersion(software.amazon.awssdk.services.greengrassv2data.model.ResolvedComponentVersion) RecipeMetadata(com.aws.greengrass.componentmanager.models.RecipeMetadata) ComponentIdentifier(com.aws.greengrass.componentmanager.models.ComponentIdentifier) ComponentMetadata(com.aws.greengrass.componentmanager.models.ComponentMetadata) Test(org.junit.jupiter.api.Test)

Example 2 with ResolvedComponentVersion

use of software.amazon.awssdk.services.greengrassv2data.model.ResolvedComponentVersion in project aws-greengrass-nucleus by aws-greengrass.

the class ComponentManagerTest method GIVEN_component_is_local_active_WHEN_cloud_returns_a_recipe_THEN_use_cloud_recipe.

@Test
void GIVEN_component_is_local_active_WHEN_cloud_returns_a_recipe_THEN_use_cloud_recipe() throws Exception {
    ComponentIdentifier componentA_1_0_0 = new ComponentIdentifier(componentA, v1_0_0);
    ComponentMetadata componentA_1_0_0_md = new ComponentMetadata(componentA_1_0_0, Collections.emptyMap());
    Topics serviceConfigTopics = mock(Topics.class);
    Topic versionTopic = mock(Topic.class);
    Topics runtimeTopics = mock(Topics.class);
    Topic digestTopic = mock(Topic.class);
    com.amazon.aws.iot.greengrass.component.common.ComponentRecipe newRecipe = com.amazon.aws.iot.greengrass.component.common.ComponentRecipe.builder().componentName("SampleComponent2").componentVersion(new Semver("2.0.0")).componentType(ComponentType.PLUGIN).recipeFormatVersion(RecipeFormatVersion.JAN_25_2020).build();
    GreengrassService mockKernelService = mock(GreengrassService.class);
    when(kernel.findServiceTopic(componentA)).thenReturn(mock(Topics.class));
    when(kernel.locate(componentA)).thenReturn(mockService);
    when(kernel.getMain()).thenReturn(mockKernelService);
    when(mockKernelService.getRuntimeConfig()).thenReturn(runtimeTopics);
    when(runtimeTopics.lookup(any())).thenReturn(digestTopic);
    when(mockService.getServiceConfig()).thenReturn(serviceConfigTopics);
    when(serviceConfigTopics.findLeafChild(VERSION_CONFIG_KEY)).thenReturn(versionTopic);
    when(versionTopic.getOnce()).thenReturn(v1_0_0.getValue());
    ResolvedComponentVersion resolvedComponentVersion = ResolvedComponentVersion.builder().componentName(componentA).componentVersion(v1_0_0.getValue()).recipe(SdkBytes.fromByteArray(MAPPER.writeValueAsBytes(newRecipe))).arn(TEST_ARN).build();
    when(componentManagementServiceHelper.resolveComponentVersion(anyString(), any(), any())).thenReturn(resolvedComponentVersion);
    when(componentStore.getPackageMetadata(any())).thenReturn(componentA_1_0_0_md);
    String recipeString = SerializerFactory.getRecipeSerializer().writeValueAsString(newRecipe);
    when(componentStore.saveComponentRecipe(any())).thenReturn(recipeString);
    ComponentMetadata componentMetadata = componentManager.resolveComponentVersion(componentA, Collections.singletonMap("X", Requirement.buildNPM("^1.0")));
    assertThat(componentMetadata, is(componentA_1_0_0_md));
    verify(componentManagementServiceHelper).resolveComponentVersion(componentA, v1_0_0, Collections.singletonMap("X", Requirement.buildNPM("^1.0")));
    verify(componentStore).saveComponentRecipe(newRecipe);
    verify(componentStore).getPackageMetadata(componentA_1_0_0);
    verify(componentStore).saveRecipeMetadata(componentA_1_0_0, new RecipeMetadata(TEST_ARN));
    verify(digestTopic).withValue(Digest.calculate(recipeString));
}
Also used : Topics(com.aws.greengrass.config.Topics) ComponentIdentifier(com.aws.greengrass.componentmanager.models.ComponentIdentifier) ArgumentMatchers.anyString(org.mockito.ArgumentMatchers.anyString) ComponentMetadata(com.aws.greengrass.componentmanager.models.ComponentMetadata) Semver(com.vdurmont.semver4j.Semver) ResolvedComponentVersion(software.amazon.awssdk.services.greengrassv2data.model.ResolvedComponentVersion) GreengrassService(com.aws.greengrass.lifecyclemanager.GreengrassService) RecipeMetadata(com.aws.greengrass.componentmanager.models.RecipeMetadata) Topic(com.aws.greengrass.config.Topic) Test(org.junit.jupiter.api.Test)

Example 3 with ResolvedComponentVersion

use of software.amazon.awssdk.services.greengrassv2data.model.ResolvedComponentVersion in project aws-greengrass-nucleus by aws-greengrass.

the class ComponentManagerTest method GIVEN_component_no_local_version_WHEN_cloud_service_client_exception_THEN_retry.

@Test
void GIVEN_component_no_local_version_WHEN_cloud_service_client_exception_THEN_retry(ExtensionContext context) throws Exception {
    ignoreExceptionOfType(context, SdkClientException.class);
    componentManager.setClientExceptionRetryConfig(RetryUtils.RetryConfig.builder().initialRetryInterval(Duration.ofSeconds(1)).maxRetryInterval(Duration.ofSeconds(1)).maxAttempt(Integer.MAX_VALUE).retryableExceptions(Arrays.asList(SdkClientException.class)).build());
    ComponentIdentifier componentA_1_0_0 = new ComponentIdentifier(componentA, v1_0_0);
    ComponentMetadata componentA_1_0_0_md = new ComponentMetadata(componentA_1_0_0, Collections.emptyMap());
    // no local version
    when(componentStore.findBestMatchAvailableComponent(eq(componentA), any())).thenReturn(Optional.empty());
    // has cloud version
    com.amazon.aws.iot.greengrass.component.common.ComponentRecipe recipe = com.amazon.aws.iot.greengrass.component.common.ComponentRecipe.builder().componentName(componentA).componentVersion(v1_0_0).componentType(ComponentType.GENERIC).recipeFormatVersion(RecipeFormatVersion.JAN_25_2020).build();
    ResolvedComponentVersion resolvedComponentVersion = ResolvedComponentVersion.builder().componentName(componentA).componentVersion(v1_0_0.getValue()).recipe(SdkBytes.fromByteArray(MAPPER.writeValueAsBytes(recipe))).arn(TEST_ARN).build();
    // Retry succeeds
    when(componentManagementServiceHelper.resolveComponentVersion(anyString(), any(), any())).thenThrow(SdkClientException.class).thenReturn(resolvedComponentVersion);
    // mock return metadata from the id
    when(componentStore.getPackageMetadata(any())).thenReturn(componentA_1_0_0_md);
    ComponentMetadata componentMetadata = componentManager.resolveComponentVersion(componentA, Collections.singletonMap("X", Requirement.buildNPM("^1.0")));
    assertThat(componentMetadata, is(componentA_1_0_0_md));
    verify(componentManagementServiceHelper, times(2)).resolveComponentVersion(componentA, null, Collections.singletonMap("X", Requirement.buildNPM("^1.0")));
    verify(componentStore, never()).findComponentRecipeContent(any());
    verify(componentStore).saveComponentRecipe(any());
    verify(componentStore).getPackageMetadata(componentA_1_0_0);
}
Also used : ResolvedComponentVersion(software.amazon.awssdk.services.greengrassv2data.model.ResolvedComponentVersion) SdkClientException(software.amazon.awssdk.core.exception.SdkClientException) ComponentIdentifier(com.aws.greengrass.componentmanager.models.ComponentIdentifier) ComponentMetadata(com.aws.greengrass.componentmanager.models.ComponentMetadata) Test(org.junit.jupiter.api.Test)

Example 4 with ResolvedComponentVersion

use of software.amazon.awssdk.services.greengrassv2data.model.ResolvedComponentVersion in project aws-greengrass-nucleus by aws-greengrass.

the class ComponentServiceHelperTest method GIVEN_component_version_requirements_WHEN_resolve_component_version_THEN_send_service_request.

@Test
void GIVEN_component_version_requirements_WHEN_resolve_component_version_THEN_send_service_request() throws Exception {
    Map<String, Requirement> versionRequirements = new HashMap<>();
    versionRequirements.put("X", Requirement.buildNPM("^1.0"));
    versionRequirements.put("Y", Requirement.buildNPM("^1.5"));
    ResolvedComponentVersion componentVersion = ResolvedComponentVersion.builder().componentName(COMPONENT_A).componentVersion(v1_0_0.getValue()).recipe(SdkBytes.fromByteArray("new recipe".getBytes(Charsets.UTF_8))).build();
    ResolveComponentCandidatesResponse result = ResolveComponentCandidatesResponse.builder().resolvedComponentVersions(Collections.singletonList(componentVersion)).build();
    when(client.resolveComponentCandidates(any(ResolveComponentCandidatesRequest.class))).thenReturn(result);
    ResolvedComponentVersion componentVersionReturn = helper.resolveComponentVersion(COMPONENT_A, v1_0_0, versionRequirements);
    assertThat(componentVersionReturn, is(componentVersion));
    ArgumentCaptor<ResolveComponentCandidatesRequest> requestArgumentCaptor = ArgumentCaptor.forClass(ResolveComponentCandidatesRequest.class);
    verify(client).resolveComponentCandidates(requestArgumentCaptor.capture());
    ResolveComponentCandidatesRequest request = requestArgumentCaptor.getValue();
    assertThat(request.platform(), notNullValue());
    assertThat(request.platform().attributes(), notNullValue());
    Map<String, String> attributes = request.platform().attributes();
    assertThat(attributes, hasKey(PlatformResolver.OS_KEY));
    assertThat(attributes, hasKey(PlatformResolver.ARCHITECTURE_KEY));
    assertThat(request.componentCandidates().size(), is(1));
    ComponentCandidate candidate = request.componentCandidates().get(0);
    assertThat(candidate.componentName(), is(COMPONENT_A));
    assertThat(candidate.componentVersion(), is("1.0.0"));
    assertThat(candidate.versionRequirements(), IsMapContaining.hasEntry("X", ">=1.0.0 <2.0.0"));
    assertThat(candidate.versionRequirements(), IsMapContaining.hasEntry("Y", ">=1.5.0 <2.0.0"));
}
Also used : ResolvedComponentVersion(software.amazon.awssdk.services.greengrassv2data.model.ResolvedComponentVersion) Requirement(com.vdurmont.semver4j.Requirement) HashMap(java.util.HashMap) ResolveComponentCandidatesResponse(software.amazon.awssdk.services.greengrassv2data.model.ResolveComponentCandidatesResponse) ComponentCandidate(software.amazon.awssdk.services.greengrassv2data.model.ComponentCandidate) Matchers.containsString(org.hamcrest.Matchers.containsString) ResolveComponentCandidatesRequest(software.amazon.awssdk.services.greengrassv2data.model.ResolveComponentCandidatesRequest) Test(org.junit.jupiter.api.Test)

Example 5 with ResolvedComponentVersion

use of software.amazon.awssdk.services.greengrassv2data.model.ResolvedComponentVersion 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)

Aggregations

ResolvedComponentVersion (software.amazon.awssdk.services.greengrassv2data.model.ResolvedComponentVersion)6 ComponentIdentifier (com.aws.greengrass.componentmanager.models.ComponentIdentifier)4 Test (org.junit.jupiter.api.Test)4 ComponentMetadata (com.aws.greengrass.componentmanager.models.ComponentMetadata)3 RecipeMetadata (com.aws.greengrass.componentmanager.models.RecipeMetadata)3 Semver (com.vdurmont.semver4j.Semver)3 NoAvailableComponentVersionException (com.aws.greengrass.componentmanager.exceptions.NoAvailableComponentVersionException)2 Requirement (com.vdurmont.semver4j.Requirement)2 SdkClientException (software.amazon.awssdk.core.exception.SdkClientException)2 ComponentCandidate (software.amazon.awssdk.services.greengrassv2data.model.ComponentCandidate)2 ResolveComponentCandidatesRequest (software.amazon.awssdk.services.greengrassv2data.model.ResolveComponentCandidatesRequest)2 ResolveComponentCandidatesResponse (software.amazon.awssdk.services.greengrassv2data.model.ResolveComponentCandidatesResponse)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 PlatformResolver (com.aws.greengrass.config.PlatformResolver)1 Topic (com.aws.greengrass.config.Topic)1