use of com.aws.greengrass.componentmanager.exceptions.PackagingException in project aws-greengrass-nucleus by aws-greengrass.
the class DeploymentTaskTest method GIVEN_deploymentDocument_WHEN_resolveDependencies_errored_THEN_deploymentTask_aborted.
@Test
void GIVEN_deploymentDocument_WHEN_resolveDependencies_errored_THEN_deploymentTask_aborted(ExtensionContext context) throws Exception {
ignoreExceptionUltimateCauseOfType(context, PackagingException.class);
when(mockExecutorService.submit(any(Callable.class))).thenReturn(mockResolveDependencyFuture);
when(mockResolveDependencyFuture.get()).thenThrow(new ExecutionException(new PackagingException("unknown package")));
DeploymentResult result = deploymentTask.call();
assertEquals(DeploymentResult.DeploymentStatus.FAILED_NO_STATE_CHANGE, result.getDeploymentStatus());
assertTrue(result.getFailureCause() instanceof PackagingException);
verify(mockComponentManager, times(0)).preparePackages(anyList());
verify(mockKernelConfigResolver, times(0)).resolve(anyList(), eq(deploymentDocument), anyList());
verify(mockDeploymentConfigMerger, times(0)).mergeInNewConfig(any(), any());
}
use of com.aws.greengrass.componentmanager.exceptions.PackagingException in project aws-greengrass-nucleus by aws-greengrass.
the class DependencyResolver method checkNonExplicitNucleusUpdate.
void checkNonExplicitNucleusUpdate(List<String> targetComponents, List<ComponentIdentifier> resolvedComponents) throws PackagingException {
List<ComponentIdentifier> resolvedNucleusComponents = new ArrayList<>();
for (ComponentIdentifier componentIdentifier : resolvedComponents) {
if (ComponentType.NUCLEUS.equals(componentStore.getPackageRecipe(componentIdentifier).getComponentType())) {
resolvedNucleusComponents.add(componentIdentifier);
}
}
if (resolvedNucleusComponents.size() > 1) {
throw new PackagingException(String.format("Deployment cannot have more than 1 component of type Nucleus " + "%s", Arrays.toString(resolvedNucleusComponents.toArray())));
}
if (resolvedNucleusComponents.isEmpty()) {
return;
}
Optional<GreengrassService> activeNucleusOption = kernel.orderedDependencies().stream().filter(s -> ComponentType.NUCLEUS.name().equals(s.getServiceType())).findFirst();
if (!activeNucleusOption.isPresent()) {
return;
}
GreengrassService activeNucleus = activeNucleusOption.get();
String activeNucleusVersionConfig = Coerce.toString(activeNucleus.getServiceConfig().find(VERSION_KEY));
if (Utils.isEmpty(activeNucleusVersionConfig)) {
throw new PackagingException(NO_ACTIVE_NUCLEUS_VERSION_ERROR_MSG);
}
Semver activeNucleusVersion = new Semver(activeNucleusVersionConfig);
ComponentIdentifier activeNucleusId = new ComponentIdentifier(activeNucleus.getServiceName(), activeNucleusVersion);
ComponentIdentifier resolvedNucleusId = resolvedNucleusComponents.get(0);
if (!resolvedNucleusId.equals(activeNucleusId) && !targetComponents.contains(resolvedNucleusId.getName())) {
Semver.VersionDiff diff = activeNucleusVersion.diff(resolvedNucleusId.getVersion());
if (Semver.VersionDiff.MINOR.equals(diff) || Semver.VersionDiff.MAJOR.equals(diff)) {
throw new PackagingException(String.format(NON_EXPLICIT_NUCLEUS_UPDATE_ERROR_MESSAGE_FMT, activeNucleusId.getName(), activeNucleusId.getVersion().toString(), resolvedNucleusId.getName(), resolvedNucleusId.getVersion().toString()));
}
}
}
use of com.aws.greengrass.componentmanager.exceptions.PackagingException in project aws-greengrass-nucleus by aws-greengrass.
the class ComponentManager method negotiateVersionWithCloud.
@SuppressWarnings({ "PMD.AvoidCatchingGenericException", "PMD.AvoidRethrowingException", "PMD.NullAssignment", "PMD.AvoidInstanceofChecksInCatchClause", "PMD.PreserveStackTrace" })
private ComponentIdentifier negotiateVersionWithCloud(String componentName, Map<String, Requirement> versionRequirements, ComponentIdentifier localCandidate) throws PackagingException, InterruptedException {
ResolvedComponentVersion resolvedComponentVersion;
if (localCandidate == null) {
try {
resolvedComponentVersion = RetryUtils.runWithRetry(clientExceptionRetryConfig, () -> componentServiceHelper.resolveComponentVersion(componentName, null, versionRequirements), "resolve-component-version", logger);
} catch (InterruptedException e) {
throw e;
} catch (Exception e) {
// Don't bother logging the full stacktrace when it is NoAvailableComponentVersionException since we
// know the reason for that error
logger.atError().setCause(e instanceof NoAvailableComponentVersionException ? null : e).kv(COMPONENT_NAME, componentName).kv("versionRequirement", versionRequirements).log("Failed to negotiate version with cloud and no local version to fall back to");
// know what the cause is.
if (e instanceof NoAvailableComponentVersionException) {
throw new NoAvailableComponentVersionException("No local or cloud component version satisfies the requirements.", componentName, versionRequirements);
} else {
throw new NoAvailableComponentVersionException("No local or cloud component version satisfies the requirements.", componentName, versionRequirements, e);
}
}
} else {
try {
resolvedComponentVersion = componentServiceHelper.resolveComponentVersion(componentName, localCandidate.getVersion(), versionRequirements);
} catch (Exception e) {
// Don't bother logging the full stacktrace when it is NoAvailableComponentVersionException since we
// know the reason for that error
logger.atInfo().setCause(e instanceof NoAvailableComponentVersionException ? null : e).kv(COMPONENT_NAME, componentName).kv("versionRequirement", versionRequirements).kv("localVersion", localCandidate).log("Failed to negotiate version with cloud and fall back to use the local version");
return localCandidate;
}
}
ComponentIdentifier resolvedComponentId = new ComponentIdentifier(resolvedComponentVersion.componentName(), new Semver(resolvedComponentVersion.componentVersion()));
String downloadedRecipeContent = StandardCharsets.UTF_8.decode(resolvedComponentVersion.recipe().asByteBuffer()).toString();
com.amazon.aws.iot.greengrass.component.common.ComponentRecipe cloudResolvedRecipe = // cloud sends JSON
RecipeLoader.parseRecipe(downloadedRecipeContent, RecipeLoader.RecipeFormat.JSON);
// Persist the recipe
String savedRecipeContent = componentStore.saveComponentRecipe(cloudResolvedRecipe);
// Since plugin runs in the same JVM as Nucleus does, we need to calculate the digest for its recipe and
// persist it, so that we can use it to detect and prevent a tampered plugin (recipe) gets loaded
storeRecipeDigestInConfigStoreForPlugin(cloudResolvedRecipe, savedRecipeContent);
// Save the arn to the recipe meta data file
componentStore.saveRecipeMetadata(resolvedComponentId, new RecipeMetadata(resolvedComponentVersion.arn()));
return resolvedComponentId;
}
Aggregations