use of com.aws.greengrass.componentmanager.models.ComponentRequirementIdentifier in project aws-greengrass-nucleus by aws-greengrass.
the class DependencyResolverTest method GIVEN_other_group_have_same_dependency_WHEN_deploy_current_group_THEN_resolve_dependency_version.
@Test
void GIVEN_other_group_have_same_dependency_WHEN_deploy_current_group_THEN_resolve_dependency_version() throws Exception {
/*
* group1 group2
* (1.0.0)/ \(1.1.0) / (2.0.0)
* A B2 X
* (1.0.0)/ / /
* B1 /(<=1.2.0) / (>=1.0.0)
* (>=1.1.0)\ / /
* C1
*/
// prepare A
Map<String, String> dependenciesA_1_x = new HashMap<>();
dependenciesA_1_x.put(componentB1, "1.0.0");
ComponentMetadata componentA_1_0_0 = new ComponentMetadata(new ComponentIdentifier(componentA, v1_0_0), dependenciesA_1_x);
when(componentManager.resolveComponentVersion(eq(componentA), any())).thenReturn(componentA_1_0_0);
// prepare B1
Map<String, String> dependenciesB1_1_x = new HashMap<>();
dependenciesB1_1_x.put(componentC1, ">=1.1.0");
ComponentMetadata componentB1_1_0_0 = new ComponentMetadata(new ComponentIdentifier(componentB1, v1_0_0), dependenciesB1_1_x);
when(componentManager.resolveComponentVersion(eq(componentB1), any())).thenReturn(componentB1_1_0_0);
// prepare B2
Map<String, String> dependenciesB2_1_x = new HashMap<>();
dependenciesB2_1_x.put(componentC1, "<=1.2.0");
ComponentMetadata componentB2_1_1_0 = new ComponentMetadata(new ComponentIdentifier(componentB2, v1_1_0), dependenciesB2_1_x);
when(componentManager.resolveComponentVersion(eq(componentB2), any())).thenReturn(componentB2_1_1_0);
// prepare C1
ComponentMetadata componentC_1_2_0 = new ComponentMetadata(new ComponentIdentifier(componentC1, v1_2_0), Collections.emptyMap());
when(componentManager.resolveComponentVersion(eq(componentC1), any())).thenReturn(componentC_1_2_0);
ComponentMetadata componentC_1_1_0 = new ComponentMetadata(new ComponentIdentifier(componentC1, v1_1_0), Collections.emptyMap());
when(componentManager.getActiveAndSatisfiedComponentMetadata(eq(componentC1), any())).thenReturn(componentC_1_1_0);
// prepare X
Map<String, String> dependenciesX_2_x = new HashMap<>();
dependenciesX_2_x.put(componentC1, ">=1.0.0");
ComponentMetadata componentX_2_0_0 = new ComponentMetadata(new ComponentIdentifier(componentX, v2_0_0), dependenciesX_2_x);
when(componentManager.getActiveAndSatisfiedComponentMetadata(eq(componentX), any())).thenReturn(componentX_2_0_0);
// top-level package order: A, B2
DeploymentDocument doc = new DeploymentDocument("mockId", "mockJob1", Arrays.asList(new DeploymentPackageConfiguration(componentA, true, v1_0_0.getValue()), new DeploymentPackageConfiguration(componentB2, true, v1_1_0.getValue())), Collections.emptyList(), "mockGroup1", 1L, FailureHandlingPolicy.DO_NOTHING, componentUpdatePolicy, configurationValidationPolicy);
Map<String, Set<ComponentRequirementIdentifier>> otherGroupRootPackages = new HashMap<>();
Set<ComponentRequirementIdentifier> rootPackages = new HashSet<>();
rootPackages.add(new ComponentRequirementIdentifier(componentX, Requirement.buildNPM("2.0.0")));
otherGroupRootPackages.put("mockGroup2", rootPackages);
context.runOnPublishQueueAndWait(() -> System.out.println("Waiting for queue to finish updating the config"));
List<ComponentIdentifier> result = dependencyResolver.resolveDependencies(doc, otherGroupRootPackages);
assertThat(result.size(), is(5));
assertThat(result, containsInAnyOrder(new ComponentIdentifier(componentA, v1_0_0), new ComponentIdentifier(componentB1, v1_0_0), new ComponentIdentifier(componentB2, v1_1_0), new ComponentIdentifier(componentC1, v1_2_0), new ComponentIdentifier(componentX, v2_0_0)));
ArgumentCaptor<String> componentNameCaptor = ArgumentCaptor.forClass(String.class);
ArgumentCaptor<Map<String, Requirement>> versionRequirementsCaptor = ArgumentCaptor.forClass(Map.class);
verify(componentManager, times(5)).resolveComponentVersion(componentNameCaptor.capture(), versionRequirementsCaptor.capture());
List<String> componentNameList = componentNameCaptor.getAllValues();
assertThat(componentNameList, contains("A", "B1", "C1", "B2", "C1"));
List<Map<String, Requirement>> versionRequirementsList = versionRequirementsCaptor.getAllValues();
assertThat(versionRequirementsList.size(), is(5));
Map<String, Requirement> versionRequirements = versionRequirementsList.get(2);
assertThat(versionRequirements.size(), is(2));
assertThat(versionRequirements, IsMapContaining.hasEntry("B1", Requirement.buildNPM(">=1.1.0")));
assertThat(versionRequirements, IsMapContaining.hasEntry("X", Requirement.buildNPM(">=1.0.0")));
versionRequirements = versionRequirementsList.get(4);
assertThat(versionRequirements.size(), is(3));
assertThat(versionRequirements, IsMapContaining.hasEntry("X", Requirement.buildNPM(">=1.0.0")));
assertThat(versionRequirements, IsMapContaining.hasEntry("B1", Requirement.buildNPM(">=1.1.0")));
assertThat(versionRequirements, IsMapContaining.hasEntry("B2", Requirement.buildNPM("<=1.2.0")));
}
use of com.aws.greengrass.componentmanager.models.ComponentRequirementIdentifier in project aws-greengrass-nucleus by aws-greengrass.
the class DefaultDeploymentTask method getNonTargetGroupToRootPackagesMap.
@SuppressWarnings("PMD.AvoidCatchingGenericException")
private Map<String, Set<ComponentRequirementIdentifier>> getNonTargetGroupToRootPackagesMap(DeploymentDocument deploymentDocument) throws DeploymentTaskFailureException, InterruptedException {
// Don't block local deployments due to device being offline by using finite retries for getting the
// hierarchy and fall back to hierarchy stored previously in worst case. For cloud deployment, use infinite
// retries by default similar/to all other cloud interactions.
boolean isLocalDeployment = Deployment.DeploymentType.LOCAL.equals(deployment.getDeploymentType());
// SDK already retries with RetryMode.STANDARD. For local deployment we don't retry on top of that
int retryCount = isLocalDeployment ? 1 : INFINITE_RETRY_COUNT;
Optional<Set<String>> groupsForDeviceOpt;
try {
groupsForDeviceOpt = thingGroupHelper.listThingGroupsForDevice(retryCount);
} catch (GreengrassV2DataException e) {
if (e.statusCode() == HttpStatusCode.FORBIDDEN) {
// Getting group hierarchy requires permission to call the ListThingGroupsForCoreDevice API which
// may not be configured on existing IoT Thing policy in use for current device, log a warning in
// that case and move on.
logger.atWarn().setCause(e).log("Failed to get thing group hierarchy. Deployment will proceed. " + "To automatically clean up unused components, please add " + "greengrass:ListThingGroupsForCoreDevice permission to your IoT Thing policy.");
groupsForDeviceOpt = getPersistedMembershipInfo();
} else {
throw new DeploymentTaskFailureException("Error fetching thing group information", e);
}
} catch (Exception e) {
if (isLocalDeployment && ThingGroupHelper.DEVICE_OFFLINE_INDICATIVE_EXCEPTIONS.contains(e.getClass())) {
logger.atWarn().setCause(e).log("Failed to get thing group hierarchy, local deployment will proceed");
groupsForDeviceOpt = getPersistedMembershipInfo();
} else {
throw new DeploymentTaskFailureException("Error fetching thing group information", e);
}
}
Set<String> groupsForDevice = groupsForDeviceOpt.isPresent() ? groupsForDeviceOpt.get() : Collections.emptySet();
Map<String, Set<ComponentRequirementIdentifier>> nonTargetGroupsToRootPackagesMap = new HashMap<>();
Topics groupsToRootPackages = deploymentServiceConfig.lookupTopics(DeploymentService.GROUP_TO_ROOT_COMPONENTS_TOPICS);
groupsToRootPackages.iterator().forEachRemaining(node -> {
Topics groupTopics = (Topics) node;
// skip root packages if device does not belong to that group anymore
if (!groupTopics.getName().equals(deploymentDocument.getGroupName()) && (groupTopics.getName().startsWith(DEVICE_DEPLOYMENT_GROUP_NAME_PREFIX) || groupTopics.getName().equals(LOCAL_DEPLOYMENT_GROUP_NAME) || groupsForDevice.contains(groupTopics.getName()))) {
groupTopics.forEach(pkgNode -> {
Topics pkgTopics = (Topics) pkgNode;
Requirement versionReq = Requirement.buildNPM(Coerce.toString(pkgTopics.lookup(GROUP_TO_ROOT_COMPONENTS_VERSION_KEY)));
nonTargetGroupsToRootPackagesMap.putIfAbsent(groupTopics.getName(), new HashSet<>());
nonTargetGroupsToRootPackagesMap.get(groupTopics.getName()).add(new ComponentRequirementIdentifier(pkgTopics.getName(), versionReq));
});
}
});
deploymentServiceConfig.lookupTopics(DeploymentService.GROUP_MEMBERSHIP_TOPICS).remove();
Topics groupMembership = deploymentServiceConfig.lookupTopics(DeploymentService.GROUP_MEMBERSHIP_TOPICS);
groupsForDevice.forEach(groupMembership::createLeafChild);
return nonTargetGroupsToRootPackagesMap;
}
Aggregations