use of software.amazon.awssdk.aws.greengrass.model.SystemResourceLimits 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 software.amazon.awssdk.aws.greengrass.model.SystemResourceLimits in project aws-greengrass-cli by aws-greengrass.
the class DeploymentCommandTest method GIVEN_WHEN_components_runwith_provided_THEN_request_contains_the_info.
@Test
void GIVEN_WHEN_components_runwith_provided_THEN_request_contains_the_info() throws Exception {
int exitCode = runCommandLine("deployment", "create", "--runWith", "Component1:windowsUser=foobar", "--runWith", "Component2:windowsUser=foobar", "--runWith", "Component2:posixUser=1234", "--systemLimits", Paths.get(this.getClass().getResource("resource_limits.json").toURI()).toString());
Map<String, RunWithInfo> componentToRunWithInfo = new HashMap<>();
RunWithInfo runWithInfo = new RunWithInfo();
runWithInfo.setWindowsUser("foobar");
MapType mapType = mapper.getTypeFactory().constructMapType(HashMap.class, String.class, SystemResourceLimits.class);
Map<String, SystemResourceLimits> systemResourceLimits = mapper.readValue(getClass().getResource("resource_limits.json"), mapType);
runWithInfo.setSystemResourceLimits(systemResourceLimits.get("Component1"));
componentToRunWithInfo.put("Component1", runWithInfo);
runWithInfo = new RunWithInfo();
runWithInfo.setPosixUser("1234");
runWithInfo.setWindowsUser("foobar");
componentToRunWithInfo.put("Component2", runWithInfo);
CreateLocalDeploymentRequest request = new CreateLocalDeploymentRequest();
request.setComponentToRunWithInfo(componentToRunWithInfo);
verify(nucleusAdapteripc).createLocalDeployment(request);
assertThat(exitCode, is(0));
}
use of software.amazon.awssdk.aws.greengrass.model.SystemResourceLimits in project aws-greengrass-cli by aws-greengrass.
the class DeploymentCommand method create.
// GG_NEEDS_REVIEW: TODO: input validation and better error handling https://sim.amazon.com/issues/P39478724
@CommandLine.Command(name = "create", description = "Create local deployment with provided recipes, artifacts, and runtime parameters", mixinStandardHelpOptions = true, versionProvider = com.aws.greengrass.cli.module.VersionProvider.class)
public int create(@CommandLine.Option(names = { "-m", "--merge" }, paramLabel = "Component and version") Map<String, String> componentsToMerge, @CommandLine.Option(names = { "--remove" }, paramLabel = "Component Names") List<String> componentsToRemove, @CommandLine.Option(names = { "-g", "--groupId" }, paramLabel = "Thing group ID") String groupId, @CommandLine.Option(names = { "-r", "--recipeDir" }, paramLabel = "Recipe directory") String recipeDir, @CommandLine.Option(names = { "-a", "--artifactDir" }, paramLabel = "Artifacts directory") String artifactDir, @CommandLine.Option(names = { "--runWith" }, paramLabel = "Component user and/or group") Map<String, String> runWithOptions, @CommandLine.Option(names = { "--systemLimits" }, paramLabel = "Component system resource limits") String systemLimits, @CommandLine.Option(names = { "-c", "--update-config" }, paramLabel = "Component configuration") String configUpdate) throws IOException {
// GG_NEEDS_REVIEW: TODO Validate folder exists and folder structure
Map<String, Map<String, Object>> configurationUpdate = null;
if (configUpdate != null && !configUpdate.isEmpty()) {
try {
// Try to read JSON from a file if it is a path and the file exists
try {
Optional<Path> filePath = deTilde(configUpdate);
if (filePath.isPresent() && Files.exists(filePath.get())) {
configurationUpdate = mapper.readValue(filePath.get().toFile(), Map.class);
}
} catch (InvalidPathException ignored) {
// If the input is a JSON, InvalidPathException is thrown from deTilde and needs to be ignored
}
// If it wasn't a file or a path, then try reading it as a JSON string
if (configurationUpdate == null) {
configurationUpdate = mapper.readValue(configUpdate, Map.class);
}
} catch (JsonProcessingException e) {
System.err.println(spec.commandLine().getColorScheme().errorText("Update configuration parameter is not a properly formatted JSON " + "file or a JSON string"));
System.err.println(spec.commandLine().getColorScheme().errorText(e.getMessage()));
return 1;
}
}
MapType mapType = mapper.getTypeFactory().constructMapType(HashMap.class, String.class, SystemResourceLimits.class);
Map<String, SystemResourceLimits> systemResourceLimits = new HashMap<>();
if (systemLimits != null && !systemLimits.isEmpty()) {
try {
// Try to read JSON from a file if it is a path and the file exists
try {
Optional<Path> filePath = deTilde(systemLimits);
if (filePath.isPresent() && Files.exists(filePath.get())) {
systemResourceLimits = mapper.readValue(filePath.get().toFile(), mapType);
}
} catch (InvalidPathException ignored) {
// If the input is a JSON, InvalidPathException is thrown from deTilde and needs to be ignored
}
// If it wasn't a file or a path, then try reading it as a JSON string
if (systemResourceLimits.isEmpty()) {
systemResourceLimits = mapper.readValue(systemLimits, mapType);
}
} catch (JsonProcessingException e) {
System.err.println(spec.commandLine().getColorScheme().errorText("systemLimits parameter file is not a properly formatted JSON"));
System.err.println(spec.commandLine().getColorScheme().errorText(e.getMessage()));
return 1;
}
}
CreateLocalDeploymentRequest createLocalDeploymentRequest = new CreateLocalDeploymentRequest();
createLocalDeploymentRequest.setGroupName(groupId);
createLocalDeploymentRequest.setComponentToConfiguration(configurationUpdate);
createLocalDeploymentRequest.setRootComponentVersionsToAdd(componentsToMerge);
createLocalDeploymentRequest.setRootComponentsToRemove(componentsToRemove);
createLocalDeploymentRequest.setComponentToRunWithInfo(getComponentToRunWithInfo(runWithOptions, systemResourceLimits));
Optional<Path> recipeDirPath = deTilde(recipeDir);
createLocalDeploymentRequest.setRecipeDirectoryPath(recipeDirPath.isPresent() ? recipeDirPath.get().toString() : null);
Optional<Path> artifactDirPath = deTilde(artifactDir);
createLocalDeploymentRequest.setArtifactsDirectoryPath(artifactDirPath.isPresent() ? artifactDirPath.get().toString() : null);
String deploymentId = nucleusAdapterIpc.createLocalDeployment(createLocalDeploymentRequest);
System.out.println("Local deployment submitted! Deployment Id: " + deploymentId);
return 0;
}
use of software.amazon.awssdk.aws.greengrass.model.SystemResourceLimits in project aws-greengrass-cli by aws-greengrass.
the class DeploymentCommand method getComponentToRunWithInfo.
private Map<String, RunWithInfo> getComponentToRunWithInfo(Map<String, String> runWithOptions, Map<String, SystemResourceLimits> systemLimits) {
if (runWithOptions == null) {
runWithOptions = new HashMap<>();
}
Map<String, RunWithInfo> componentToRunWithInfo = new HashMap<>();
for (Map.Entry<String, String> entry : runWithOptions.entrySet()) {
String componentNameAndRunWithOption = entry.getKey();
String[] parts = componentNameAndRunWithOption.split(":");
if (parts.length != 2) {
throw new IllegalArgumentException("--runWith must be in the following format " + "<component>:{posixUser|windowsUser}=<user>[:<group>] ");
}
String componentName = parts[0];
String runWithOption = parts[1];
RunWithInfo runWithInfo = componentToRunWithInfo.computeIfAbsent(componentName, k -> new RunWithInfo());
switch(runWithOption) {
case RUN_WITH_OPTION_POSIX_USER:
runWithInfo.setPosixUser(entry.getValue());
break;
case RUN_WITH_OPTION_WINDOWS_USER:
runWithInfo.setWindowsUser(entry.getValue());
break;
default:
throw new IllegalArgumentException("Invalid --runWith option: " + runWithOption);
}
}
for (Map.Entry<String, SystemResourceLimits> mapEntry : systemLimits.entrySet()) {
String componentName = mapEntry.getKey();
componentToRunWithInfo.compute(componentName, (k, v) -> {
if (v == null) {
v = new RunWithInfo();
}
v.setSystemResourceLimits(mapEntry.getValue());
return v;
});
}
return componentToRunWithInfo.isEmpty() ? null : componentToRunWithInfo;
}
Aggregations