use of software.amazon.awssdk.iot.iotshadow.IotShadowClient in project aws-greengrass-nucleus by aws-greengrass.
the class MultipleGroupsDeploymentE2ETest method listenToShadowDeploymentUpdates.
private CountDownLatch listenToShadowDeploymentUpdates() {
IotShadowClient shadowClient = new IotShadowClient(new WrapperMqttClientConnection(kernel.getContext().get(MqttClient.class)));
UpdateNamedShadowSubscriptionRequest req = new UpdateNamedShadowSubscriptionRequest();
req.shadowName = DEPLOYMENT_SHADOW_NAME;
req.thingName = thingInfo.getThingName();
CountDownLatch reportSucceededCdl = new CountDownLatch(1);
shadowClient.SubscribeToUpdateNamedShadowAccepted(req, QualityOfService.AT_LEAST_ONCE, (response) -> {
if (response.state.reported == null) {
return;
}
String reportedStatus = (String) response.state.reported.get(STATUS_KEY);
if (JobStatus.SUCCEEDED.toString().equals(reportedStatus)) {
reportSucceededCdl.countDown();
}
});
return reportSucceededCdl;
}
use of software.amazon.awssdk.iot.iotshadow.IotShadowClient in project aws-greengrass-nucleus by aws-greengrass.
the class ShadowDeploymentE2ETest method GIVEN_device_deployment_WHEN_shadow_update_messages_gets_delivered_out_of_order_THEN_shadow_updated_with_latest_deployment_status.
@Test
void GIVEN_device_deployment_WHEN_shadow_update_messages_gets_delivered_out_of_order_THEN_shadow_updated_with_latest_deployment_status() throws Exception {
CreateDeploymentRequest createDeploymentRequest = CreateDeploymentRequest.builder().targetArn(thingInfo.getThingArn()).components(Utils.immutableMap("CustomerApp", ComponentDeploymentSpecification.builder().componentVersion("1.0.0").build(), "SomeService", ComponentDeploymentSpecification.builder().componentVersion("1.0.0").build())).build();
draftAndCreateDeployment(createDeploymentRequest);
assertThat(kernel.getMain()::getState, eventuallyEval(is(State.FINISHED)));
IotShadowClient shadowClient = new IotShadowClient(new WrapperMqttClientConnection(kernel.getContext().get(MqttClient.class)));
UpdateNamedShadowSubscriptionRequest req = new UpdateNamedShadowSubscriptionRequest();
req.shadowName = DEPLOYMENT_SHADOW_NAME;
req.thingName = thingInfo.getThingName();
CountDownLatch reportSucceededCdl = new CountDownLatch(1);
CountDownLatch deviceSyncedStateToSucceededCdl = new CountDownLatch(1);
AtomicReference<HashMap<String, Object>> reportedSection = new AtomicReference<>();
AtomicReference<Integer> shadowVersionWhenDeviceFirstReportedSuccess = new AtomicReference<>();
AtomicReference<Integer> shadowVersionWhenDeviceReportedInProgress = new AtomicReference<>();
shadowClient.SubscribeToUpdateNamedShadowAccepted(req, QualityOfService.AT_LEAST_ONCE, (response) -> {
try {
logger.info("Got shadow update: {}", new ObjectMapper().writeValueAsString(response));
} catch (JsonProcessingException e) {
// ignore
}
if (response.state.reported == null) {
return;
}
String reportedStatus = (String) response.state.reported.get(STATUS_KEY);
if (JobStatus.IN_PROGRESS.toString().equals(reportedStatus)) {
reportedSection.set(response.state.reported);
shadowVersionWhenDeviceReportedInProgress.set(response.version);
} else if (JobStatus.SUCCEEDED.toString().equals(reportedStatus)) {
// state to SUCCESS second time the shadow version
if (reportSucceededCdl.getCount() == 0 && response.version > shadowVersionWhenDeviceFirstReportedSuccess.get()) {
deviceSyncedStateToSucceededCdl.countDown();
}
shadowVersionWhenDeviceFirstReportedSuccess.set(response.version);
reportSucceededCdl.countDown();
}
});
// waiting for the device to report success
assertTrue(reportSucceededCdl.await(60, TimeUnit.SECONDS));
// Updating the shadow with deployment status IN_PROGRESS to simulate out-of-order update of shadow
ShadowState shadowState = new ShadowState();
shadowState.reported = reportedSection.get();
UpdateNamedShadowRequest updateNamedShadowRequest = new UpdateNamedShadowRequest();
updateNamedShadowRequest.shadowName = DEPLOYMENT_SHADOW_NAME;
updateNamedShadowRequest.thingName = thingInfo.getThingName();
updateNamedShadowRequest.state = shadowState;
shadowClient.PublishUpdateNamedShadow(updateNamedShadowRequest, QualityOfService.AT_LEAST_ONCE).get(30, TimeUnit.SECONDS);
// verify that the device updates shadow state to SUCCEEDED
assertTrue(deviceSyncedStateToSucceededCdl.await(60, TimeUnit.SECONDS));
// Updating the shadow with a lower version number to trigger a message to /update/rejected event
shadowState = new ShadowState();
shadowState.reported = reportedSection.get();
updateNamedShadowRequest = new UpdateNamedShadowRequest();
updateNamedShadowRequest.shadowName = DEPLOYMENT_SHADOW_NAME;
updateNamedShadowRequest.thingName = thingInfo.getThingName();
updateNamedShadowRequest.state = shadowState;
updateNamedShadowRequest.version = shadowVersionWhenDeviceReportedInProgress.get();
shadowClient.PublishUpdateNamedShadow(updateNamedShadowRequest, QualityOfService.AT_LEAST_ONCE).get(30, TimeUnit.SECONDS);
CountDownLatch deviceRetrievedShadowCdl = new CountDownLatch(1);
GetNamedShadowSubscriptionRequest getNamedShadowSubscriptionRequest = new GetNamedShadowSubscriptionRequest();
getNamedShadowSubscriptionRequest.shadowName = DEPLOYMENT_SHADOW_NAME;
getNamedShadowSubscriptionRequest.thingName = thingInfo.getThingName();
shadowClient.SubscribeToGetNamedShadowAccepted(getNamedShadowSubscriptionRequest, QualityOfService.AT_MOST_ONCE, getShadowResponse -> {
deviceRetrievedShadowCdl.countDown();
}).get(30, TimeUnit.SECONDS);
// verify that the device retrieved the shadow when an update operation was rejected.
assertTrue(deviceRetrievedShadowCdl.await(60, TimeUnit.SECONDS));
}
use of software.amazon.awssdk.iot.iotshadow.IotShadowClient in project aws-greengrass-nucleus by aws-greengrass.
the class ShadowDeploymentE2ETest method GIVEN_kernel_running_WHEN_device_deployment_adds_packages_THEN_new_services_should_be_running.
@Test
void GIVEN_kernel_running_WHEN_device_deployment_adds_packages_THEN_new_services_should_be_running() throws Exception {
CountDownLatch cdlDeploymentFinished = new CountDownLatch(1);
Consumer<GreengrassLogMessage> listener = m -> {
if (m.getMessage() != null && m.getMessage().contains("Current deployment finished")) {
cdlDeploymentFinished.countDown();
}
};
Slf4jLogAdapter.addGlobalListener(listener);
CreateDeploymentRequest createDeploymentRequest = CreateDeploymentRequest.builder().targetArn(thingInfo.getThingArn()).components(Utils.immutableMap("CustomerApp", ComponentDeploymentSpecification.builder().componentVersion("1.0.0").configurationUpdate(ComponentConfigurationUpdate.builder().merge("{\"sampleText\":\"FCS integ test\"}").build()).build(), "SomeService", ComponentDeploymentSpecification.builder().componentVersion("1.0.0").build())).build();
draftAndCreateDeployment(createDeploymentRequest);
assertThat(kernel.getMain()::getState, eventuallyEval(is(State.FINISHED)));
IotShadowClient shadowClient = new IotShadowClient(new WrapperMqttClientConnection(kernel.getContext().get(MqttClient.class)));
UpdateNamedShadowSubscriptionRequest req = new UpdateNamedShadowSubscriptionRequest();
req.shadowName = DEPLOYMENT_SHADOW_NAME;
req.thingName = thingInfo.getThingName();
CountDownLatch reportInProgressCdl = new CountDownLatch(1);
CountDownLatch reportSucceededCdl = new CountDownLatch(1);
shadowClient.SubscribeToUpdateNamedShadowAccepted(req, QualityOfService.AT_LEAST_ONCE, (response) -> {
try {
logger.info("Got shadow update: {}", new ObjectMapper().writeValueAsString(response));
} catch (JsonProcessingException e) {
// ignore
}
if (response.state.reported == null) {
return;
}
String reportedStatus = (String) response.state.reported.get(STATUS_KEY);
if (JobStatus.IN_PROGRESS.toString().equals(reportedStatus)) {
reportInProgressCdl.countDown();
} else if (JobStatus.SUCCEEDED.toString().equals(reportedStatus)) {
reportSucceededCdl.countDown();
}
});
// wait for the shadow's reported section to be updated
assertTrue(reportInProgressCdl.await(30, TimeUnit.SECONDS));
assertTrue(reportSucceededCdl.await(30, TimeUnit.SECONDS));
// deployment should succeed
assertTrue(cdlDeploymentFinished.await(30, TimeUnit.SECONDS));
Slf4jLogAdapter.removeGlobalListener(listener);
assertThat(getCloudDeployedComponent("CustomerApp")::getState, eventuallyEval(is(State.FINISHED)));
assertThat(getCloudDeployedComponent("SomeService")::getState, eventuallyEval(is(State.FINISHED)));
}
use of software.amazon.awssdk.iot.iotshadow.IotShadowClient in project aws-greengrass-nucleus by aws-greengrass.
the class ShadowDeploymentE2ETest method GIVEN_kernel_running_WHEN_device_deployment_has_large_config_THEN_config_downloaded.
@Test
void GIVEN_kernel_running_WHEN_device_deployment_has_large_config_THEN_config_downloaded() throws Exception {
CountDownLatch cdlDeploymentFinished = new CountDownLatch(1);
Consumer<GreengrassLogMessage> listener = m -> {
if (m.getMessage() != null && m.getMessage().contains("Current deployment finished")) {
cdlDeploymentFinished.countDown();
}
};
// Threshold for triggering large config is 8 KB for shadow deployment. Using a 32000 bytes string.
String largeConfigValue = StringUtils.repeat("*", 32 * 1000);
try (AutoCloseable l = TestUtils.createCloseableLogListener(listener)) {
CreateDeploymentRequest createDeploymentRequest = CreateDeploymentRequest.builder().targetArn(thingInfo.getThingArn()).components(Utils.immutableMap("CustomerApp", ComponentDeploymentSpecification.builder().componentVersion("1.0.0").configurationUpdate(ComponentConfigurationUpdate.builder().merge("{\"largeConfigKey\":\"" + largeConfigValue + "\"}").build()).build())).build();
draftAndCreateDeployment(createDeploymentRequest);
assertThat(kernel.getMain()::getState, eventuallyEval(is(State.FINISHED)));
IotShadowClient shadowClient = new IotShadowClient(new WrapperMqttClientConnection(kernel.getContext().get(MqttClient.class)));
UpdateNamedShadowSubscriptionRequest req = new UpdateNamedShadowSubscriptionRequest();
req.shadowName = DEPLOYMENT_SHADOW_NAME;
req.thingName = thingInfo.getThingName();
CountDownLatch reportInProgressCdl = new CountDownLatch(1);
CountDownLatch reportSucceededCdl = new CountDownLatch(1);
shadowClient.SubscribeToUpdateNamedShadowAccepted(req, QualityOfService.AT_LEAST_ONCE, (response) -> {
try {
logger.info("Got shadow update: {}", new ObjectMapper().writeValueAsString(response));
} catch (JsonProcessingException e) {
// ignore
}
if (response.state.reported == null) {
return;
}
String reportedStatus = (String) response.state.reported.get(STATUS_KEY);
if (JobStatus.IN_PROGRESS.toString().equals(reportedStatus)) {
reportInProgressCdl.countDown();
} else if (JobStatus.SUCCEEDED.toString().equals(reportedStatus)) {
reportSucceededCdl.countDown();
}
});
// wait for the shadow's reported section to be updated
assertTrue(reportInProgressCdl.await(600, TimeUnit.SECONDS));
assertTrue(reportSucceededCdl.await(600, TimeUnit.SECONDS));
// deployment should succeed
assertTrue(cdlDeploymentFinished.await(30, TimeUnit.SECONDS));
Slf4jLogAdapter.removeGlobalListener(listener);
assertThat(getCloudDeployedComponent("CustomerApp")::getState, eventuallyEval(is(State.FINISHED)));
Topics customerApp = getCloudDeployedComponent("CustomerApp").getConfig();
assertEquals(largeConfigValue, Coerce.toString(customerApp.find("configuration", "largeConfigKey")));
}
}
use of software.amazon.awssdk.iot.iotshadow.IotShadowClient in project aws-greengrass-nucleus by aws-greengrass.
the class ShadowDeploymentListener method postInject.
@Override
public void postInject() {
if (iotShadowClient == null) {
this.iotShadowClient = new IotShadowClient(getMqttClientConnection());
}
mqttClient.addToCallbackEvents(callbacks);
deviceConfiguration.onAnyChange((what, node) -> {
if (WhatHappened.childChanged.equals(what) && node != null && deviceConfiguration.provisionInfoNodeChanged(node, isSubscribedToShadowTopics.get())) {
try {
connectToShadowService(deviceConfiguration);
} catch (DeviceConfigurationException e) {
logger.atWarn().kv("errorMessage", e.getMessage()).log(DEVICE_OFFLINE_MESSAGE);
return;
}
}
});
try {
connectToShadowService(deviceConfiguration);
} catch (DeviceConfigurationException e) {
logger.atWarn().log(DEVICE_OFFLINE_MESSAGE);
return;
}
}
Aggregations