use of com.aws.greengrass.deployment.DeploymentStatusKeeper.DEPLOYMENT_STATUS_KEY_NAME in project aws-greengrass-nucleus by aws-greengrass.
the class MultiGroupDeploymentTest method GIVEN_device_belongs_to_two_groups_WHEN_device_is_removed_from_one_group_THEN_next_deployment_removes_corresponding_component.
@Test
void GIVEN_device_belongs_to_two_groups_WHEN_device_is_removed_from_one_group_THEN_next_deployment_removes_corresponding_component() throws Exception {
CountDownLatch firstGroupCDL = new CountDownLatch(1);
CountDownLatch secondGroupCDL = new CountDownLatch(1);
DeploymentStatusKeeper deploymentStatusKeeper = kernel.getContext().get(DeploymentStatusKeeper.class);
deploymentStatusKeeper.registerDeploymentStatusConsumer(Deployment.DeploymentType.IOT_JOBS, (status) -> {
if (status.get(DEPLOYMENT_ID_KEY_NAME).equals("firstGroup") && status.get(DEPLOYMENT_STATUS_KEY_NAME).equals("SUCCEEDED")) {
firstGroupCDL.countDown();
}
if (status.get(DEPLOYMENT_ID_KEY_NAME).equals("secondGroup") && status.get(DEPLOYMENT_STATUS_KEY_NAME).equals("SUCCEEDED")) {
secondGroupCDL.countDown();
}
return true;
}, "dummyValue");
when(thingGroupHelper.listThingGroupsForDevice(anyInt())).thenReturn(Optional.of(new HashSet<>(Arrays.asList("firstGroup", "secondGroup"))));
submitSampleJobDocument(DeploymentServiceIntegrationTest.class.getResource("FleetConfigWithRedSignalService.json").toURI(), "firstGroup", Deployment.DeploymentType.IOT_JOBS);
assertTrue(firstGroupCDL.await(10, TimeUnit.SECONDS));
when(thingGroupHelper.listThingGroupsForDevice(anyInt())).thenReturn(Optional.of(new HashSet<>(Arrays.asList("secondGroup"))));
submitSampleJobDocument(DeploymentServiceIntegrationTest.class.getResource("FleetConfigWithSomeService.json").toURI(), "secondGroup", Deployment.DeploymentType.IOT_JOBS);
assertTrue(secondGroupCDL.await(10, TimeUnit.SECONDS));
Topics groupToRootTopic = kernel.getConfig().lookupTopics(SERVICES_NAMESPACE_TOPIC, DEPLOYMENT_SERVICE_TOPICS, GROUP_TO_ROOT_COMPONENTS_TOPICS);
List<String> groupNames = new ArrayList<>();
groupToRootTopic.forEach(node -> groupNames.add(node.getName()));
assertTrue(groupNames.containsAll(Arrays.asList("secondGroup")), "Device should belong to firstGroup and secondGroup");
Map<GreengrassService, DependencyType> dependenciesAfter = kernel.getMain().getDependencies();
List<String> serviceNames = dependenciesAfter.keySet().stream().map(service -> service.getName()).collect(Collectors.toList());
assertTrue(serviceNames.containsAll(Arrays.asList("SomeService")));
Topics componentsToGroupTopic = kernel.getConfig().lookupTopics(SERVICES_NAMESPACE_TOPIC, DEPLOYMENT_SERVICE_TOPICS, COMPONENTS_TO_GROUPS_TOPICS);
assertNotNull(componentsToGroupTopic.find("SomeService", "secondGroup"));
}
use of com.aws.greengrass.deployment.DeploymentStatusKeeper.DEPLOYMENT_STATUS_KEY_NAME in project aws-greengrass-nucleus by aws-greengrass.
the class MqttReconnectTest method GIVEN_new_deployment_while_device_online_WHEN_mqtt_disconnects_and_reconnects_THEN_job_executes_successfully.
// GG_NEEDS_REVIEW: TODO: Fix flaky test https://sim.amazon.com/issues/P40525318
@Disabled
@Timeout(value = 10, unit = TimeUnit.MINUTES)
@Test
void GIVEN_new_deployment_while_device_online_WHEN_mqtt_disconnects_and_reconnects_THEN_job_executes_successfully(ExtensionContext context) throws Exception {
ignoreExceptionUltimateCauseOfType(context, MqttException.class);
ignoreExceptionUltimateCauseOfType(context, TimeoutException.class);
ignoreExceptionWithMessage(context, "No valid versions were found for this package based on provided requirement");
CountDownLatch jobInProgress = new CountDownLatch(1);
CountDownLatch jobCompleted = new CountDownLatch(1);
CountDownLatch connectionInterrupted = new CountDownLatch(1);
// Create Job
CreateDeploymentRequest createDeploymentRequest = CreateDeploymentRequest.builder().components(Utils.immutableMap("CustomerApp", ComponentDeploymentSpecification.builder().componentVersion("1.0.0").build())).build();
CreateDeploymentResponse result = draftAndCreateDeployment(createDeploymentRequest);
String jobId = result.iotJobId();
// Subscribe to persisted deployment status
Topics deploymentServiceTopics = kernel.getConfig().lookupTopics(SERVICES_NAMESPACE_TOPIC, DEPLOYMENT_SERVICE_TOPICS);
Topics processedDeployments = deploymentServiceTopics.lookupTopics(RUNTIME_STORE_NAMESPACE_TOPIC, PROCESSED_DEPLOYMENTS_TOPICS);
processedDeployments.subscribe((whatHappened, newValue) -> {
if (!(newValue instanceof Topic)) {
return;
}
if (newValue.childOf(DEPLOYMENT_STATUS_KEY_NAME)) {
newValue = newValue.parent;
} else {
return;
}
Map<String, Object> deploymentDetails = ((Topics) newValue).toPOJO();
if (!deploymentDetails.get(DEPLOYMENT_ID_KEY_NAME).toString().equals(jobId)) {
return;
}
String status = deploymentDetails.get(DEPLOYMENT_STATUS_KEY_NAME).toString();
if (JobStatus.IN_PROGRESS.toString().equals(status)) {
jobInProgress.countDown();
} else if (jobInProgress.getCount() <= 0 && JobStatus.SUCCEEDED.toString().equals(status)) {
jobCompleted.countDown();
}
});
kernel.launch();
assertTrue(jobInProgress.await(2, TimeUnit.MINUTES));
NetworkUtils networkUtils = NetworkUtils.getByPlatform();
Consumer<GreengrassLogMessage> logListener = m -> {
String message = m.getMessage();
if (UPDATE_DEPLOYMENT_STATUS_MQTT_ERROR_LOG.equals(message) && m.getCause().getCause() instanceof MqttException || UPDATE_DEPLOYMENT_STATUS_TIMEOUT_ERROR_LOG.equals(message)) {
connectionInterrupted.countDown();
}
};
try {
Slf4jLogAdapter.addGlobalListener(logListener);
networkUtils.disconnectMqtt();
// Wait for the deployment to finish offline
assertTrue(jobCompleted.await(5, TimeUnit.MINUTES));
assertTrue(connectionInterrupted.await(2, TimeUnit.MINUTES));
} finally {
networkUtils.recoverMqtt();
Slf4jLogAdapter.removeGlobalListener(logListener);
}
// Wait for DNS Cache to expire
Thread.sleep(DNS_CACHE_TTL.plus(Duration.ofSeconds(1)).toMillis());
// Wait for the IoT job to be updated and marked as successful
// The reason for making the timeout as 7 min is because it has been observed that if the update job status was
// invoked just before the connection recovers it can block the call for total timeout of 5 mins,
// without successfully updating the status of the job in cloud. After this timeout expires the status will
// be updated again as part of the onConnectionResumed callback. Additional 2 mins are for this status
// to get updated
IotJobsUtils.waitForJobExecutionStatusToSatisfy(iotClient, jobId, thingInfo.getThingName(), Duration.ofMinutes(7), s -> s.equals(JobExecutionStatus.SUCCEEDED));
}
use of com.aws.greengrass.deployment.DeploymentStatusKeeper.DEPLOYMENT_STATUS_KEY_NAME in project aws-greengrass-nucleus by aws-greengrass.
the class DeploymentServiceIntegrationTest method GIVEN_cloud_deployment_has_required_capabilities_WHEN_receives_deployment_THEN_fail_with_proper_detailed_status.
@Test
void GIVEN_cloud_deployment_has_required_capabilities_WHEN_receives_deployment_THEN_fail_with_proper_detailed_status() throws Exception {
CountDownLatch cdlDeployRedSignal = new CountDownLatch(1);
Consumer<GreengrassLogMessage> listener = m -> {
if (m.getMessage() != null) {
if (m.getMessage().contains("Current deployment finished") && m.getContexts().get("DeploymentId").equals("deployRedSignal")) {
cdlDeployRedSignal.countDown();
}
}
};
CountDownLatch deploymentCDL = new CountDownLatch(1);
DeploymentStatusKeeper deploymentStatusKeeper = kernel.getContext().get(DeploymentStatusKeeper.class);
deploymentStatusKeeper.registerDeploymentStatusConsumer(DeploymentType.SHADOW, (status) -> {
if (status.get(DEPLOYMENT_ID_KEY_NAME).equals("deployRedSignal") && status.get(DEPLOYMENT_STATUS_KEY_NAME).equals("FAILED")) {
deploymentCDL.countDown();
assertThat(((Map) status.get(DEPLOYMENT_STATUS_DETAILS_KEY_NAME)).get(DEPLOYMENT_FAILURE_CAUSE_KEY), equalTo("The current nucleus version doesn't support one or more capabilities that are required by " + "this deployment: ANOTHER_CAPABILITY"));
}
return true;
}, "dummy");
try (AutoCloseable l = TestUtils.createCloseableLogListener(listener)) {
submitSampleJobDocument(DeploymentServiceIntegrationTest.class.getResource("FleetConfigWithRequiredCapability.json").toURI(), "deployRedSignal", DeploymentType.SHADOW);
assertTrue(cdlDeployRedSignal.await(30, TimeUnit.SECONDS));
assertTrue(deploymentCDL.await(10, TimeUnit.SECONDS));
}
}
use of com.aws.greengrass.deployment.DeploymentStatusKeeper.DEPLOYMENT_STATUS_KEY_NAME in project aws-greengrass-nucleus by aws-greengrass.
the class MultiGroupDeploymentTest method GIVEN_device_belongs_to_two_groups_WHEN_device_receives_deployments_to_both_groups_THEN_no_components_removed.
@Test
void GIVEN_device_belongs_to_two_groups_WHEN_device_receives_deployments_to_both_groups_THEN_no_components_removed() throws Exception {
CountDownLatch firstGroupCDL = new CountDownLatch(1);
CountDownLatch secondGroupCDL = new CountDownLatch(1);
DeploymentStatusKeeper deploymentStatusKeeper = kernel.getContext().get(DeploymentStatusKeeper.class);
deploymentStatusKeeper.registerDeploymentStatusConsumer(Deployment.DeploymentType.IOT_JOBS, (status) -> {
if (status.get(DEPLOYMENT_ID_KEY_NAME).equals("firstGroup") && status.get(DEPLOYMENT_STATUS_KEY_NAME).equals("SUCCEEDED")) {
firstGroupCDL.countDown();
}
if (status.get(DEPLOYMENT_ID_KEY_NAME).equals("secondGroup") && status.get(DEPLOYMENT_STATUS_KEY_NAME).equals("SUCCEEDED")) {
secondGroupCDL.countDown();
}
return true;
}, "dummyValue");
when(thingGroupHelper.listThingGroupsForDevice(anyInt())).thenReturn(Optional.of(new HashSet<>(Arrays.asList("firstGroup", "secondGroup"))));
submitSampleJobDocument(DeploymentServiceIntegrationTest.class.getResource("FleetConfigWithRedSignalService.json").toURI(), "firstGroup", Deployment.DeploymentType.IOT_JOBS);
assertTrue(firstGroupCDL.await(10, TimeUnit.SECONDS));
submitSampleJobDocument(DeploymentServiceIntegrationTest.class.getResource("FleetConfigWithSomeService.json").toURI(), "secondGroup", Deployment.DeploymentType.IOT_JOBS);
assertTrue(secondGroupCDL.await(10, TimeUnit.SECONDS));
Topics groupToRootTopic = kernel.getConfig().lookupTopics(SERVICES_NAMESPACE_TOPIC, DEPLOYMENT_SERVICE_TOPICS, GROUP_TO_ROOT_COMPONENTS_TOPICS);
List<String> groupNames = new ArrayList<>();
groupToRootTopic.forEach(node -> groupNames.add(node.getName()));
assertTrue(groupNames.containsAll(Arrays.asList("firstGroup", "secondGroup")), "Device should belong to firstGroup and secondGroup");
Map<GreengrassService, DependencyType> dependenciesAfter = kernel.getMain().getDependencies();
List<String> serviceNames = dependenciesAfter.keySet().stream().map(service -> service.getName()).collect(Collectors.toList());
assertTrue(serviceNames.containsAll(Arrays.asList("SomeService", "RedSignal")));
Topics componentsToGroupTopic = kernel.getConfig().lookupTopics(SERVICES_NAMESPACE_TOPIC, DEPLOYMENT_SERVICE_TOPICS, COMPONENTS_TO_GROUPS_TOPICS);
assertNotNull(componentsToGroupTopic.find("SomeService", "secondGroup"));
assertNotNull(componentsToGroupTopic.find("RedSignal", "firstGroup"));
}
use of com.aws.greengrass.deployment.DeploymentStatusKeeper.DEPLOYMENT_STATUS_KEY_NAME in project aws-greengrass-nucleus by aws-greengrass.
the class MultiGroupDeploymentTest method GIVEN_two_groups_with_common_root_component_WHEN_device_is_removed_from_one_group_THEN_common_component_not_removed.
@Test
void GIVEN_two_groups_with_common_root_component_WHEN_device_is_removed_from_one_group_THEN_common_component_not_removed() throws Exception {
CountDownLatch firstGroupCDL = new CountDownLatch(1);
CountDownLatch secondGroupCDL = new CountDownLatch(1);
CountDownLatch thirdGroupCDL = new CountDownLatch(1);
DeploymentStatusKeeper deploymentStatusKeeper = kernel.getContext().get(DeploymentStatusKeeper.class);
deploymentStatusKeeper.registerDeploymentStatusConsumer(Deployment.DeploymentType.IOT_JOBS, (status) -> {
if (status.get(DEPLOYMENT_ID_KEY_NAME).equals("firstGroup") && status.get(DEPLOYMENT_STATUS_KEY_NAME).equals("SUCCEEDED")) {
firstGroupCDL.countDown();
}
if (status.get(DEPLOYMENT_ID_KEY_NAME).equals("secondGroup") && status.get(DEPLOYMENT_STATUS_KEY_NAME).equals("SUCCEEDED")) {
secondGroupCDL.countDown();
}
if (status.get(DEPLOYMENT_ID_KEY_NAME).equals("thirdGroup") && status.get(DEPLOYMENT_STATUS_KEY_NAME).equals("SUCCEEDED")) {
thirdGroupCDL.countDown();
}
return true;
}, "dummyValue");
// deployment to firstGroup adds red signal and yellow signal
when(thingGroupHelper.listThingGroupsForDevice(anyInt())).thenReturn(Optional.of(new HashSet<>(Arrays.asList("firstGroup", "secondGroup", "thirdGroup"))));
submitSampleJobDocument(DeploymentServiceIntegrationTest.class.getResource("FleetConfigWithRedAndYellowService.json").toURI(), "firstGroup", Deployment.DeploymentType.IOT_JOBS);
assertTrue(firstGroupCDL.await(10, TimeUnit.SECONDS));
// deployment to secondGroup adds red signal
submitSampleJobDocument(DeploymentServiceIntegrationTest.class.getResource("FleetConfigWithRedSignalService.json").toURI(), "secondGroup", Deployment.DeploymentType.IOT_JOBS);
assertTrue(secondGroupCDL.await(10, TimeUnit.SECONDS));
// verify group to root components mapping
Topics groupToRootTopic = kernel.getConfig().lookupTopics(SERVICES_NAMESPACE_TOPIC, DEPLOYMENT_SERVICE_TOPICS, GROUP_TO_ROOT_COMPONENTS_TOPICS);
List<String> groupNames = new ArrayList<>();
groupToRootTopic.forEach(node -> groupNames.add(node.getName()));
assertTrue(groupNames.containsAll(Arrays.asList("firstGroup", "secondGroup")));
// verify components to group mapping
Topics componentsToGroupTopic = kernel.getConfig().lookupTopics(SERVICES_NAMESPACE_TOPIC, DEPLOYMENT_SERVICE_TOPICS, COMPONENTS_TO_GROUPS_TOPICS);
assertNotNull(componentsToGroupTopic.find("RedSignal", "secondGroup"));
assertNotNull(componentsToGroupTopic.find("RedSignal", "firstGroup"));
// device gets removed from firstGroup,
when(thingGroupHelper.listThingGroupsForDevice(anyInt())).thenReturn(Optional.of(new HashSet<>(Arrays.asList("secondGroup", "thirdGroup"))));
// next deployment to thirdGroup will clean up root components only associated with firstGroup
submitSampleJobDocument(DeploymentServiceIntegrationTest.class.getResource("FleetConfigWithSomeService.json").toURI(), "thirdGroup", Deployment.DeploymentType.IOT_JOBS);
assertTrue(thirdGroupCDL.await(10, TimeUnit.SECONDS));
// components belonging to only first group are removed, red signal should still be present as its associated with secondGroup
groupToRootTopic = kernel.getConfig().lookupTopics(SERVICES_NAMESPACE_TOPIC, DEPLOYMENT_SERVICE_TOPICS, GROUP_TO_ROOT_COMPONENTS_TOPICS);
List<String> groups = new ArrayList<>();
groupToRootTopic.forEach(node -> groups.add(node.getName()));
assertTrue(groups.containsAll(Arrays.asList("secondGroup", "thirdGroup")), "Device should only belong to secondGroup and thirdGroup");
Map<GreengrassService, DependencyType> dependenciesAfter = kernel.getMain().getDependencies();
List<String> serviceNames = dependenciesAfter.keySet().stream().map(service -> service.getName()).collect(Collectors.toList());
assertTrue(serviceNames.containsAll(Arrays.asList("SomeService", "RedSignal")));
assertFalse(serviceNames.containsAll(Arrays.asList("YellowSignal")));
componentsToGroupTopic = kernel.getConfig().lookupTopics(SERVICES_NAMESPACE_TOPIC, DEPLOYMENT_SERVICE_TOPICS, COMPONENTS_TO_GROUPS_TOPICS);
assertNotNull(componentsToGroupTopic.find("SomeService", "thirdGroup"));
assertNotNull(componentsToGroupTopic.find("RedSignal", "secondGroup"));
// mapping of regSignal to firstGroup is removed
assertNull(componentsToGroupTopic.find("RedSignal", "firstGroup"));
}
Aggregations