use of com.aws.greengrass.deployment.model.LocalOverrideRequest in project aws-greengrass-nucleus by aws-greengrass.
the class MultiGroupDeploymentTest method submitLocalDocument.
private void submitLocalDocument(Map<String, String> components, String groupName, String requestId) throws Exception {
copyRecipeAndArtifacts();
LocalOverrideRequest request = LocalOverrideRequest.builder().requestId(requestId).componentsToMerge(components).groupName(groupName).requestTimestamp(System.currentTimeMillis()).build();
Deployment deployment = new Deployment(OBJECT_MAPPER.writeValueAsString(request), Deployment.DeploymentType.LOCAL, request.getRequestId());
deploymentQueue.offer(deployment);
}
use of com.aws.greengrass.deployment.model.LocalOverrideRequest in project aws-greengrass-nucleus by aws-greengrass.
the class DeploymentService method copyRecipesAndArtifacts.
@SuppressWarnings("PMD.ExceptionAsFlowControl")
private void copyRecipesAndArtifacts(Deployment deployment) throws InvalidRequestException, IOException {
try {
LocalOverrideRequest localOverrideRequest = SerializerFactory.getFailSafeJsonObjectMapper().readValue(deployment.getDeploymentDocument(), LocalOverrideRequest.class);
if (!Utils.isEmpty(localOverrideRequest.getRecipeDirectoryPath())) {
Path recipeDirectoryPath = Paths.get(localOverrideRequest.getRecipeDirectoryPath());
copyRecipesToComponentStore(recipeDirectoryPath);
}
if (!Utils.isEmpty(localOverrideRequest.getArtifactsDirectoryPath())) {
Path kernelArtifactsDirectoryPath = kernel.getNucleusPaths().componentStorePath().resolve(ComponentStore.ARTIFACT_DIRECTORY);
Path artifactsDirectoryPath = Paths.get(localOverrideRequest.getArtifactsDirectoryPath());
try {
Utils.copyFolderRecursively(artifactsDirectoryPath, kernelArtifactsDirectoryPath, (Path src, Path dst) -> {
// existing component and then do the deployment to make it work.
if (PlatformResolver.isWindows) {
try {
if (Files.exists(dst) && FileUtils.contentEquals(src.toFile(), dst.toFile())) {
return false;
}
} catch (IOException e) {
logger.atError().log("Unable to determine if files are equal", e);
return true;
}
}
return true;
}, StandardCopyOption.REPLACE_EXISTING);
} catch (IOException e) {
throw new IOException(String.format("Unable to copy artifacts from %s due to: %s", artifactsDirectoryPath, e.getMessage()), e);
}
}
} catch (JsonProcessingException e) {
throw new InvalidRequestException("Unable to parse the deployment request - Invalid JSON", e);
}
}
use of com.aws.greengrass.deployment.model.LocalOverrideRequest in project aws-greengrass-nucleus by aws-greengrass.
the class DeploymentDocumentConverterTest method GIVEN_Full_Local_Override_Request_config_update_And_Current_Root_WHEN_convert_THEN_Return_expected_Deployment_Document.
// Existing: ROOT_COMPONENT_TO_REMOVE_1-1.0.0, ROOT_COMPONENT_TO_REMOVE_2-2.0.0, EXISTING_ROOT_COMPONENT-2.0.0
// To Remove: ROOT_COMPONENT_TO_REMOVE_1, ROOT_COMPONENT_TO_REMOVE_2
// To Add: NEW_ROOT_COMPONENT-2.0.0
// To Update: EXISTING_ROOT_COMPONENT-1.0.0 -> 2.0.0
// Result roots: NEW_ROOT_COMPONENT-2.0.0, EXISTING_ROOT_COMPONENT-2.0.0
@Test
void GIVEN_Full_Local_Override_Request_config_update_And_Current_Root_WHEN_convert_THEN_Return_expected_Deployment_Document() throws Exception {
String dependencyUpdateConfigString = "{ \"MERGE\": { \"Company\": { \"Office\": { \"temperature\": 22 } }, \"path1\": { \"Object2\": { \"key2\": \"val2\" } } }, \"RESET\": [ \"/secret/first\" ] }";
Map<String, ConfigurationUpdateOperation> updateConfig = new HashMap<>();
updateConfig.put(DEPENDENCY_COMPONENT, mapper.readValue(dependencyUpdateConfigString, ConfigurationUpdateOperation.class));
String existingUpdateConfigString = "{ \"MERGE\": {\"foo\": \"bar\"}}";
updateConfig.put(EXISTING_ROOT_COMPONENT, mapper.readValue(existingUpdateConfigString, ConfigurationUpdateOperation.class));
Map<String, RunWithInfo> componentToRunWithInfo = new HashMap<>();
RunWithInfo runWithInfo = new RunWithInfo();
runWithInfo.setPosixUser("foo:bar");
runWithInfo.setWindowsUser("testWindowsUser");
SystemResourceLimits limits = new SystemResourceLimits();
limits.setMemory(102400L);
limits.setCpus(1.5);
runWithInfo.setSystemResourceLimits(limits);
componentToRunWithInfo.put(NEW_ROOT_COMPONENT, runWithInfo);
runWithInfo = new RunWithInfo();
runWithInfo.setPosixUser("1234");
runWithInfo.setWindowsUser("testWindowsUser2");
componentToRunWithInfo.put(DEPENDENCY_COMPONENT, runWithInfo);
// Existing: ROOT_COMPONENT_TO_REMOVE_1-1.0.0, ROOT_COMPONENT_TO_REMOVE_2-2.0.0, EXISTING_ROOT_COMPONENT-2.0.0
// To Remove: ROOT_COMPONENT_TO_REMOVE_1, ROOT_COMPONENT_TO_REMOVE_2
// To Add: NEW_ROOT_COMPONENT-2.0.0
// To Update: EXISTING_ROOT_COMPONENT-1.0.0 -> 2.0.0
// Result roots: NEW_ROOT_COMPONENT-2.0.0, EXISTING_ROOT_COMPONENT-2.0.0
LocalOverrideRequest testRequest = LocalOverrideRequest.builder().requestId(REQUEST_ID).requestTimestamp(REQUEST_TIMESTAMP).componentsToMerge(ROOT_COMPONENTS_TO_MERGE).componentsToRemove(Arrays.asList(ROOT_COMPONENT_TO_REMOVE_1, ROOT_COMPONENT_TO_REMOVE_2)).configurationUpdate(updateConfig).componentToRunWithInfo(componentToRunWithInfo).build();
DeploymentDocument deploymentDocument = DeploymentDocumentConverter.convertFromLocalOverrideRequestAndRoot(testRequest, CURRENT_ROOT_COMPONENTS);
assertThat(deploymentDocument.getFailureHandlingPolicy(), is(FailureHandlingPolicy.DO_NOTHING));
assertThat(deploymentDocument.getDeploymentId(), is(REQUEST_ID));
assertThat(deploymentDocument.getTimestamp(), is(REQUEST_TIMESTAMP));
assertThat(deploymentDocument.getRootPackages(), is(Arrays.asList(EXISTING_ROOT_COMPONENT, NEW_ROOT_COMPONENT)));
List<DeploymentPackageConfiguration> deploymentPackageConfigurations = deploymentDocument.getDeploymentPackageConfigurationList();
assertThat(deploymentPackageConfigurations.size(), is(3));
// verify deploymentConfigs
DeploymentPackageConfiguration existingRootComponentConfig = deploymentPackageConfigurations.stream().filter(e -> e.getPackageName().equals(EXISTING_ROOT_COMPONENT)).findAny().get();
assertThat(existingRootComponentConfig.getResolvedVersion(), is("2.0.0"));
assertThat(existingRootComponentConfig.getConfigurationUpdateOperation(), is(mapper.readValue(existingUpdateConfigString, ConfigurationUpdateOperation.class)));
DeploymentPackageConfiguration newRootComponentConfig = deploymentPackageConfigurations.stream().filter(e -> e.getPackageName().equals(NEW_ROOT_COMPONENT)).findAny().get();
assertThat(newRootComponentConfig.getResolvedVersion(), is("2.0.0"));
assertNull(newRootComponentConfig.getConfigurationUpdateOperation());
assertEquals("foo:bar", newRootComponentConfig.getRunWith().getPosixUser());
assertEquals("testWindowsUser", newRootComponentConfig.getRunWith().getWindowsUser());
assertEquals(1.5, newRootComponentConfig.getRunWith().getSystemResourceLimits().getCpus());
assertEquals(102400L, newRootComponentConfig.getRunWith().getSystemResourceLimits().getMemory());
DeploymentPackageConfiguration DependencyComponentConfig = deploymentPackageConfigurations.stream().filter(e -> e.getPackageName().equals(DEPENDENCY_COMPONENT)).findAny().get();
assertEquals(DependencyComponentConfig.getConfigurationUpdateOperation(), mapper.readValue(dependencyUpdateConfigString, ConfigurationUpdateOperation.class));
assertThat(DependencyComponentConfig.getResolvedVersion(), is("*"));
}
use of com.aws.greengrass.deployment.model.LocalOverrideRequest in project aws-greengrass-nucleus by aws-greengrass.
the class IotJobsFleetStatusServiceTest method WHEN_deployment_bumps_up_component_version_THEN_status_of_new_version_is_updated_to_cloud.
@Test
void WHEN_deployment_bumps_up_component_version_THEN_status_of_new_version_is_updated_to_cloud() throws Exception {
((Map) kernel.getContext().getvIfExists(Kernel.SERVICE_TYPE_TO_CLASS_MAP_KEY).get()).put("plugin", GreengrassService.class.getName());
assertNotNull(deviceConfiguration.getThingName());
CountDownLatch jobsDeploymentLatch = new CountDownLatch(1);
CountDownLatch fssPublishLatch = new CountDownLatch(1);
logListener = eslm -> {
if (eslm.getMessage() != null && eslm.getMessage().equals(UPDATE_DEPLOYMENT_STATUS_ACCEPTED) && eslm.getContexts().get("JobId").equals("simpleApp2")) {
jobsDeploymentLatch.countDown();
}
if (jobsDeploymentLatch.getCount() == 0 && eslm.getEventType() != null && eslm.getEventType().equals("fss-status-update-published") && eslm.getMessage().equals("Status update published to FSS")) {
fssPublishLatch.countDown();
}
};
Slf4jLogAdapter.addGlobalListener(logListener);
// First local deployment adds SimpleApp v1
Map<String, String> componentsToMerge = new HashMap<>();
componentsToMerge.put("SimpleApp", "1.0.0");
LocalOverrideRequest request = LocalOverrideRequest.builder().requestId("SimpleApp1").componentsToMerge(componentsToMerge).requestTimestamp(System.currentTimeMillis()).build();
submitLocalDocument(request);
// Second local deployment removes SimpleApp v1
request = LocalOverrideRequest.builder().requestId("removeSimpleApp").componentsToRemove(Arrays.asList("SimpleApp")).requestTimestamp(System.currentTimeMillis()).build();
submitLocalDocument(request);
// Cloud deployment adds SimpleApp v2. First two deployments are local because this edge case is hit when device is
// offline after receiving the deployment and cannot emit FSS update. Since local deployment do not emit FSS update,
// this test simulates the device being offline by using local deployments.
offerSampleIoTJobsDeployment("FleetConfigSimpleApp2.json", "simpleApp2");
assertTrue(fssPublishLatch.await(180, TimeUnit.SECONDS));
verify(mqttClient, atLeastOnce()).publish(captor.capture());
List<PublishRequest> prs = captor.getAllValues();
// Get the last FSS publish request which should have component info of simpleApp v2 and other built in services
PublishRequest pr = prs.get(prs.size() - 1);
try {
FleetStatusDetails fleetStatusDetails = OBJECT_MAPPER.readValue(pr.getPayload(), FleetStatusDetails.class);
assertEquals("ThingName", fleetStatusDetails.getThing());
assertEquals(OverallStatus.HEALTHY, fleetStatusDetails.getOverallStatus());
assertNotNull(fleetStatusDetails.getComponentStatusDetails());
assertEquals(componentNamesToCheck.size(), fleetStatusDetails.getComponentStatusDetails().size());
fleetStatusDetails.getComponentStatusDetails().forEach(componentStatusDetails -> {
componentNamesToCheck.remove(componentStatusDetails.getComponentName());
if (componentStatusDetails.getComponentName().equals("SimpleApp")) {
assertEquals("2.0.0", componentStatusDetails.getVersion());
assertEquals(1, componentStatusDetails.getFleetConfigArns().size());
assertEquals(MOCK_FLEET_CONFIG_ARN, componentStatusDetails.getFleetConfigArns().get(0));
assertEquals(State.FINISHED, componentStatusDetails.getState());
assertTrue(componentStatusDetails.isRoot());
} else {
assertFalse(componentStatusDetails.isRoot());
}
});
} catch (UnrecognizedPropertyException ignored) {
}
assertEquals(0, componentNamesToCheck.size());
Slf4jLogAdapter.removeGlobalListener(logListener);
}
use of com.aws.greengrass.deployment.model.LocalOverrideRequest in project aws-greengrass-cli by aws-greengrass.
the class CLIEventStreamAgentTest method testCreateLocalDeployment_successful.
@Test
void testCreateLocalDeployment_successful() throws JsonProcessingException {
Topics mockCliConfig = mock(Topics.class);
Topics localDeployments = mock(Topics.class);
Topics localDeploymentDetailsTopics = mock(Topics.class);
when(localDeployments.lookupTopics(any())).thenReturn(localDeploymentDetailsTopics);
when(mockCliConfig.lookupTopics(PERSISTENT_LOCAL_DEPLOYMENTS)).thenReturn(localDeployments);
when(deploymentQueue.offer(any())).thenReturn(true);
cliEventStreamAgent.setDeploymentQueue(deploymentQueue);
CreateLocalDeploymentRequest request = new CreateLocalDeploymentRequest();
request.setGroupName(MOCK_GROUP);
request.setRootComponentVersionsToAdd(ImmutableMap.of(TEST_SERVICE, "1.0.0"));
request.setRootComponentsToRemove(Arrays.asList("SomeService"));
Map<String, String> componentConfigToMerge = new HashMap<>();
componentConfigToMerge.put("param1", "value1");
Map<String, Map<String, Object>> action = new HashMap<>();
action.put(TEST_SERVICE, ImmutableMap.of("MERGE", componentConfigToMerge));
request.setComponentToConfiguration(action);
cliEventStreamAgent.getCreateLocalDeploymentHandler(mockContext, mockCliConfig).handleRequest(request);
ArgumentCaptor<Deployment> deploymentCaptor = ArgumentCaptor.forClass(Deployment.class);
verify(deploymentQueue).offer(deploymentCaptor.capture());
String deploymentDoc = deploymentCaptor.getValue().getDeploymentDocument();
LocalOverrideRequest localOverrideRequest = OBJECT_MAPPER.readValue(deploymentDoc, LocalOverrideRequest.class);
assertEquals(MOCK_GROUP, localOverrideRequest.getGroupName());
assertTrue(localOverrideRequest.getComponentsToMerge().containsKey(TEST_SERVICE));
assertTrue(localOverrideRequest.getComponentsToMerge().containsValue("1.0.0"));
assertTrue(localOverrideRequest.getComponentsToRemove().contains("SomeService"));
assertNotNull(localOverrideRequest.getConfigurationUpdate().get(TEST_SERVICE));
assertEquals("value1", localOverrideRequest.getConfigurationUpdate().get(TEST_SERVICE).getValueToMerge().get("param1"));
verify(localDeployments).lookupTopics(localOverrideRequest.getRequestId());
ArgumentCaptor<Map> deploymentDetailsCaptor = ArgumentCaptor.forClass(Map.class);
verify(localDeploymentDetailsTopics).replaceAndWait(deploymentDetailsCaptor.capture());
CLIEventStreamAgent.LocalDeploymentDetails localDeploymentDetails = OBJECT_MAPPER.convertValue((Map<String, Object>) deploymentDetailsCaptor.getValue(), CLIEventStreamAgent.LocalDeploymentDetails.class);
assertEquals(Deployment.DeploymentType.LOCAL, localDeploymentDetails.getDeploymentType());
assertEquals(DeploymentStatus.QUEUED, localDeploymentDetails.getStatus());
}
Aggregations