use of com.aws.greengrass.deployment.DeploymentService.DEPLOYMENT_SERVICE_TOPICS 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.DeploymentService.DEPLOYMENT_SERVICE_TOPICS in project aws-greengrass-nucleus by aws-greengrass.
the class DeploymentServiceTest method startDeploymentServiceInAnotherThread.
private void startDeploymentServiceInAnotherThread() throws InterruptedException {
CountDownLatch cdl = new CountDownLatch(1);
Consumer<GreengrassLogMessage> listener = m -> {
if (m.getContexts() != null && m.getContexts().containsKey(SERVICE_NAME_KEY) && m.getContexts().get(SERVICE_NAME_KEY).equalsIgnoreCase(DEPLOYMENT_SERVICE_TOPICS)) {
cdl.countDown();
}
};
Slf4jLogAdapter.addGlobalListener(listener);
deploymentServiceThread = new Thread(() -> {
try {
deploymentService.startup();
} catch (InterruptedException ignore) {
}
});
deploymentServiceThread.start();
boolean running = cdl.await(1, TimeUnit.SECONDS);
Slf4jLogAdapter.removeGlobalListener(listener);
assertTrue(running, "Deployment service must be running");
}
use of com.aws.greengrass.deployment.DeploymentService.DEPLOYMENT_SERVICE_TOPICS 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.DeploymentService.DEPLOYMENT_SERVICE_TOPICS in project aws-greengrass-nucleus by aws-greengrass.
the class MultipleGroupsDeploymentE2ETest method GIVEN_deployment_2_multiple_groups_WHEN_device_removed_from_group_THEN_components_removed_on_next_deployment.
@Timeout(value = 10, unit = TimeUnit.MINUTES)
@Test
void GIVEN_deployment_2_multiple_groups_WHEN_device_removed_from_group_THEN_components_removed_on_next_deployment() throws Exception {
CreateDeploymentRequest deploymentToFirstGroup = CreateDeploymentRequest.builder().targetArn(thingGroupArn).components(Utils.immutableMap("CustomerApp", ComponentDeploymentSpecification.builder().componentVersion("1.0.0").build())).build();
CreateDeploymentResponse firstDeploymentResult = draftAndCreateDeployment(deploymentToFirstGroup);
IotJobsUtils.waitForJobExecutionStatusToSatisfy(iotClient, firstDeploymentResult.iotJobId(), thingInfo.getThingName(), Duration.ofMinutes(5), s -> s.equals(JobExecutionStatus.SUCCEEDED));
CreateDeploymentRequest deviceDeployment = CreateDeploymentRequest.builder().targetArn(thingInfo.getThingArn()).components(Utils.immutableMap("SomeService", ComponentDeploymentSpecification.builder().componentVersion("1.0.0").build())).build();
CountDownLatch deviceDeploymentSucceeded = listenToShadowDeploymentUpdates();
draftAndCreateDeployment(deviceDeployment);
deviceDeploymentSucceeded.await(5, TimeUnit.MINUTES);
CreateThingGroupResponse thirdThingGroup = IotJobsUtils.createThingGroupAndAddThing(iotClient, thingInfo);
createdThingGroups.add(thirdThingGroup.thingGroupName());
CreateDeploymentRequest deploymentToThirdGroup = CreateDeploymentRequest.builder().targetArn(thirdThingGroup.thingGroupArn()).components(Utils.immutableMap("YellowSignal", ComponentDeploymentSpecification.builder().componentVersion("1.0.0").build())).build();
CreateDeploymentResponse thirdDeploymentResult = draftAndCreateDeployment(deploymentToThirdGroup);
IotJobsUtils.waitForJobExecutionStatusToSatisfy(iotClient, thirdDeploymentResult.iotJobId(), thingInfo.getThingName(), Duration.ofMinutes(5), s -> s.equals(JobExecutionStatus.SUCCEEDED));
IotJobsUtils.removeFromThingGroup(iotClient, thingInfo, thirdThingGroup.thingGroupArn());
CreateThingGroupResponse fourthThingGroup = IotJobsUtils.createThingGroupAndAddThing(iotClient, thingInfo);
createdThingGroups.add(fourthThingGroup.thingGroupName());
CreateDeploymentRequest deploymentToFourthGroup = CreateDeploymentRequest.builder().targetArn(fourthThingGroup.thingGroupArn()).components(Utils.immutableMap("RedSignal", ComponentDeploymentSpecification.builder().componentVersion("1.0.0").build())).build();
CreateDeploymentResponse fourthDeploymentResult = draftAndCreateDeployment(deploymentToFourthGroup);
IotJobsUtils.waitForJobExecutionStatusToSatisfy(iotClient, fourthDeploymentResult.iotJobId(), thingInfo.getThingName(), Duration.ofMinutes(5), s -> s.equals(JobExecutionStatus.SUCCEEDED));
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(getTestComponentNameInCloud("CustomerApp"), getTestComponentNameInCloud("SomeService"), getTestComponentNameInCloud("RedSignal"))));
assertFalse(serviceNames.containsAll(Arrays.asList(getTestComponentNameInCloud("YellowSignal"))));
Topics groupToRootTopic = kernel.getConfig().lookupTopics(SERVICES_NAMESPACE_TOPIC, DEPLOYMENT_SERVICE_TOPICS, GROUP_TO_ROOT_COMPONENTS_TOPICS);
assertNotNull(groupToRootTopic.findTopics(THING_GROUP_RESOURCE_TYPE_PREFIX + thingGroupName, getTestComponentNameInCloud("CustomerApp")));
assertNotNull(groupToRootTopic.findTopics("thing/" + thingInfo.getThingName(), getTestComponentNameInCloud("SomeService")));
assertNotNull(groupToRootTopic.findTopics(THING_GROUP_RESOURCE_TYPE_PREFIX + fourthThingGroup.thingGroupName(), getTestComponentNameInCloud("RedSignal")));
assertNull(groupToRootTopic.findTopics(THING_GROUP_RESOURCE_TYPE_PREFIX + thirdThingGroup.thingGroupName()));
Topics componentsToGroupTopic = kernel.getConfig().lookupTopics(SERVICES_NAMESPACE_TOPIC, DEPLOYMENT_SERVICE_TOPICS, COMPONENTS_TO_GROUPS_TOPICS);
assertNotNull(componentsToGroupTopic.findTopics(getTestComponentNameInCloud("CustomerApp")));
assertNotNull(componentsToGroupTopic.findTopics(getTestComponentNameInCloud("SomeService")));
assertNotNull(componentsToGroupTopic.findTopics(getTestComponentNameInCloud("RedSignal")));
assertNull(componentsToGroupTopic.findTopics(getTestComponentNameInCloud("YellowSignal")));
}
use of com.aws.greengrass.deployment.DeploymentService.DEPLOYMENT_SERVICE_TOPICS 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"));
}
Aggregations