Search in sources :

Example 1 with EZPlugins

use of com.aws.greengrass.dependency.EZPlugins in project aws-greengrass-nucleus by aws-greengrass.

the class Kernel method locateExternalPlugin.

@SuppressWarnings({ "PMD.AvoidCatchingThrowable", "PMD.CloseResource" })
private Class<?> locateExternalPlugin(String name, Topics serviceRootTopics) throws ServiceLoadException {
    ComponentIdentifier componentId = ComponentIdentifier.fromServiceTopics(serviceRootTopics);
    Path pluginJar;
    try {
        pluginJar = nucleusPaths.artifactPath(componentId).resolve(componentId.getName() + JAR_FILE_EXTENSION);
    } catch (IOException e) {
        throw new ServiceLoadException(e);
    }
    if (!pluginJar.toFile().exists() || !pluginJar.toFile().isFile()) {
        throw new ServiceLoadException(String.format("Unable to find %s because %s does not exist", name, pluginJar));
    }
    Topic storedDigest = config.find(SERVICES_NAMESPACE_TOPIC, MAIN_SERVICE_NAME, GreengrassService.RUNTIME_STORE_NAMESPACE_TOPIC, SERVICE_DIGEST_TOPIC_KEY, componentId.toString());
    if (storedDigest == null || storedDigest.getOnce() == null) {
        logger.atError("plugin-load-error").kv(GreengrassService.SERVICE_NAME_KEY, name).log("Local external plugin is not supported by this greengrass version");
        throw new ServiceLoadException("Custom plugins is not supported by this greengrass version");
    }
    ComponentStore componentStore = context.get(ComponentStore.class);
    if (!componentStore.validateComponentRecipeDigest(componentId, Coerce.toString(storedDigest))) {
        logger.atError("plugin-load-error").kv(GreengrassService.SERVICE_NAME_KEY, name).log("Local plugin does not match the version in cloud!!");
        throw new ServiceLoadException("Plugin has been modified after it was downloaded");
    }
    Class<?> clazz;
    try {
        AtomicReference<Class<?>> classReference = new AtomicReference<>();
        EZPlugins ezPlugins = context.get(EZPlugins.class);
        ezPlugins.loadPlugin(pluginJar, (sc) -> sc.matchClassesWithAnnotation(ImplementsService.class, (c) -> {
            // Only use the class whose name matches what we want
            ImplementsService serviceImplementation = c.getAnnotation(ImplementsService.class);
            if (serviceImplementation.name().equals(name)) {
                if (classReference.get() != null) {
                    logger.atWarn().log("Multiple classes implementing service found in {} " + "for component {}. Using the first one found: {}", pluginJar, name, classReference.get());
                    return;
                }
                classReference.set(c);
            }
        }));
        clazz = classReference.get();
    } catch (Throwable e) {
        throw new ServiceLoadException(String.format("Unable to load %s as a plugin", name), e);
    }
    if (clazz == null) {
        throw new ServiceLoadException(String.format("Unable to find %s. Could not find any ImplementsService annotation with the same name.", name));
    }
    return clazz;
}
Also used : Path(java.nio.file.Path) Arrays(java.util.Arrays) Deployment(com.aws.greengrass.deployment.model.Deployment) SERVICE_LIFECYCLE_NAMESPACE_TOPIC(com.aws.greengrass.lifecyclemanager.GreengrassService.SERVICE_LIFECYCLE_NAMESPACE_TOPIC) BootstrapManager(com.aws.greengrass.deployment.bootstrap.BootstrapManager) YAMLMapper(com.fasterxml.jackson.dataformat.yaml.YAMLMapper) Map(java.util.Map) LogManager(com.aws.greengrass.logging.impl.LogManager) DeploymentCapability(com.amazon.aws.iot.greengrass.configuration.common.DeploymentCapability) Path(java.nio.file.Path) Configuration(com.aws.greengrass.config.Configuration) Node(com.aws.greengrass.config.Node) Collection(java.util.Collection) ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap) ScheduledThreadPoolExecutor(java.util.concurrent.ScheduledThreadPoolExecutor) Pair(com.aws.greengrass.util.Pair) Executors(java.util.concurrent.Executors) SERVICES_NAMESPACE_TOPIC(com.aws.greengrass.lifecyclemanager.GreengrassService.SERVICES_NAMESPACE_TOPIC) Topics(com.aws.greengrass.config.Topics) CrashableFunction(com.aws.greengrass.util.CrashableFunction) NucleusPaths(com.aws.greengrass.util.NucleusPaths) List(java.util.List) Writer(java.io.Writer) ImplementsService(com.aws.greengrass.dependency.ImplementsService) CommitableWriter(com.aws.greengrass.util.CommitableWriter) ComponentStore(com.aws.greengrass.componentmanager.ComponentStore) ComponentIdentifier(com.aws.greengrass.componentmanager.models.ComponentIdentifier) ProxyUtils(com.aws.greengrass.util.ProxyUtils) DependencyOrder(com.aws.greengrass.util.DependencyOrder) Setter(lombok.Setter) DeploymentDirectoryManager(com.aws.greengrass.deployment.DeploymentDirectoryManager) VERSION_CONFIG_KEY(com.aws.greengrass.componentmanager.KernelConfigResolver.VERSION_CONFIG_KEY) Getter(lombok.Getter) InputValidationException(com.aws.greengrass.lifecyclemanager.exceptions.InputValidationException) ThreadPoolExecutor(java.util.concurrent.ThreadPoolExecutor) JsonGenerator(com.fasterxml.jackson.core.JsonGenerator) EZPlugins(com.aws.greengrass.dependency.EZPlugins) DeploymentQueue(com.aws.greengrass.deployment.DeploymentQueue) HashMap(java.util.HashMap) Singleton(javax.inject.Singleton) DeviceConfiguration(com.aws.greengrass.deployment.DeviceConfiguration) Coerce(com.aws.greengrass.util.Coerce) Constructor(java.lang.reflect.Constructor) AtomicReference(java.util.concurrent.atomic.AtomicReference) Platform(com.aws.greengrass.util.platforms.Platform) HashSet(java.util.HashSet) MAIN_SERVICE_NAME(com.aws.greengrass.lifecyclemanager.KernelCommandLine.MAIN_SERVICE_NAME) AccessLevel(lombok.AccessLevel) ScheduledExecutorService(java.util.concurrent.ScheduledExecutorService) JAR_FILE_EXTENSION(com.aws.greengrass.dependency.EZPlugins.JAR_FILE_EXTENSION) Context(com.aws.greengrass.dependency.Context) REQUEST_REBOOT(com.aws.greengrass.deployment.bootstrap.BootstrapSuccessCode.REQUEST_REBOOT) REQUEST_RESTART(com.aws.greengrass.deployment.bootstrap.BootstrapSuccessCode.REQUEST_RESTART) SERVICE_DEPENDENCIES_NAMESPACE_TOPIC(com.aws.greengrass.lifecyclemanager.GreengrassService.SERVICE_DEPENDENCIES_NAMESPACE_TOPIC) LinkedHashSet(java.util.LinkedHashSet) ExecutorService(java.util.concurrent.ExecutorService) Nullable(javax.annotation.Nullable) DeploymentStage(com.aws.greengrass.deployment.model.Deployment.DeploymentStage) ServiceLoadException(com.aws.greengrass.lifecyclemanager.exceptions.ServiceLoadException) Files(java.nio.file.Files) Executor(java.util.concurrent.Executor) ObjectMapper(com.fasterxml.jackson.databind.ObjectMapper) ConfigurationWriter(com.aws.greengrass.config.ConfigurationWriter) IOException(java.io.IOException) DependencyType(com.amazon.aws.iot.greengrass.component.common.DependencyType) Topic(com.aws.greengrass.config.Topic) Utils(com.aws.greengrass.util.Utils) DeploymentActivatorFactory(com.aws.greengrass.deployment.activator.DeploymentActivatorFactory) ServiceUpdateException(com.aws.greengrass.deployment.exceptions.ServiceUpdateException) DeviceConfigurationException(com.aws.greengrass.deployment.exceptions.DeviceConfigurationException) Clock(java.time.Clock) Collections(java.util.Collections) Logger(com.aws.greengrass.logging.api.Logger) DEFAULT_VALUE_TIMESTAMP(com.aws.greengrass.config.Topic.DEFAULT_VALUE_TIMESTAMP) ComponentIdentifier(com.aws.greengrass.componentmanager.models.ComponentIdentifier) AtomicReference(java.util.concurrent.atomic.AtomicReference) IOException(java.io.IOException) ComponentStore(com.aws.greengrass.componentmanager.ComponentStore) EZPlugins(com.aws.greengrass.dependency.EZPlugins) ImplementsService(com.aws.greengrass.dependency.ImplementsService) Topic(com.aws.greengrass.config.Topic) ServiceLoadException(com.aws.greengrass.lifecyclemanager.exceptions.ServiceLoadException)

Example 2 with EZPlugins

use of com.aws.greengrass.dependency.EZPlugins in project aws-greengrass-nucleus by aws-greengrass.

the class KernelLifecycleTest method GIVEN_kernel_WHEN_launch_with_autostart_services_THEN_autostarts_added_as_dependencies_of_main.

@SuppressWarnings("PMD.CloseResource")
@Test
void GIVEN_kernel_WHEN_launch_with_autostart_services_THEN_autostarts_added_as_dependencies_of_main() throws Exception {
    GreengrassService mockMain = mock(GreengrassService.class);
    GreengrassService mockOthers = mock(GreengrassService.class);
    doReturn(mockMain).when(mockKernel).locateIgnoreError(eq("main"));
    doReturn(mockOthers).when(mockKernel).locate(not(eq("main")));
    // Mock out EZPlugins so I can return a deterministic set of services to be added as auto-start
    EZPlugins pluginMock = mock(EZPlugins.class);
    kernelLifecycle.setStartables(new ArrayList<>());
    when(mockContext.get(EZPlugins.class)).thenReturn(pluginMock);
    doAnswer((i) -> {
        ClassAnnotationMatchProcessor func = i.getArgument(1);
        func.processMatch(UpdateSystemPolicyService.class);
        func.processMatch(DeploymentService.class);
        return null;
    }).when(pluginMock).annotated(eq(ImplementsService.class), any());
    kernelLifecycle.launch();
    // Expect 2 times because I returned 2 plugins from above: SafeUpdate and Deployment
    verify(mockMain, times(2)).addOrUpdateDependency(eq(mockOthers), eq(DependencyType.HARD), eq(true));
}
Also used : ClassAnnotationMatchProcessor(io.github.lukehutch.fastclasspathscanner.matchprocessor.ClassAnnotationMatchProcessor) EZPlugins(com.aws.greengrass.dependency.EZPlugins) ImplementsService(com.aws.greengrass.dependency.ImplementsService) Test(org.junit.jupiter.api.Test)

Example 3 with EZPlugins

use of com.aws.greengrass.dependency.EZPlugins in project aws-greengrass-nucleus by aws-greengrass.

the class KernelLifecycleTest method GIVEN_kernel_WHEN_launch_with_provisioning_plugin_AND_plugin_methods_throw_runtime_Exception_THEN_offline_mode.

@SuppressWarnings("PMD.CloseResource")
@Test
void GIVEN_kernel_WHEN_launch_with_provisioning_plugin_AND_plugin_methods_throw_runtime_Exception_THEN_offline_mode(ExtensionContext context) throws Exception {
    ignoreExceptionOfType(context, RuntimeException.class);
    mockProvisioning();
    when(mockProvisioningPlugin.updateIdentityConfiguration(any())).thenThrow(new RuntimeException("Error provisioning"));
    EZPlugins pluginMock = mock(EZPlugins.class);
    when(mockContext.get(EZPlugins.class)).thenReturn(pluginMock);
    doAnswer((i) -> {
        ImplementingClassMatchProcessor func = i.getArgument(1);
        func.processMatch(mockPluginClass);
        return null;
    }).when(pluginMock).implementing(eq(DeviceIdentityInterface.class), any());
    kernelLifecycle.launch();
    verify(mockProvisioningPlugin, timeout(1000).times(1)).updateIdentityConfiguration(any(ProvisionContext.class));
    verify(mockProvisioningConfigUpdateHelper, times(0)).updateNucleusConfiguration(any(NucleusConfiguration.class), eq(UpdateBehaviorTree.UpdateBehavior.MERGE));
    verify(mockProvisioningConfigUpdateHelper, times(0)).updateSystemConfiguration(any(SystemConfiguration.class), eq(UpdateBehaviorTree.UpdateBehavior.MERGE));
}
Also used : EZPlugins(com.aws.greengrass.dependency.EZPlugins) DeviceIdentityInterface(com.aws.greengrass.provisioning.DeviceIdentityInterface) ProvisionContext(com.aws.greengrass.provisioning.ProvisionContext) NucleusConfiguration(com.aws.greengrass.provisioning.ProvisionConfiguration.NucleusConfiguration) ImplementingClassMatchProcessor(io.github.lukehutch.fastclasspathscanner.matchprocessor.ImplementingClassMatchProcessor) SystemConfiguration(com.aws.greengrass.provisioning.ProvisionConfiguration.SystemConfiguration) Test(org.junit.jupiter.api.Test)

Example 4 with EZPlugins

use of com.aws.greengrass.dependency.EZPlugins in project aws-greengrass-nucleus by aws-greengrass.

the class KernelLifecycleTest method GIVEN_kernel_WHEN_launch_with_provisioning_plugin_THEN_plugin_methods_are_invoked.

@SuppressWarnings("PMD.CloseResource")
@Test
void GIVEN_kernel_WHEN_launch_with_provisioning_plugin_THEN_plugin_methods_are_invoked() throws Exception {
    mockProvisioning();
    when(mockProvisioningPlugin.updateIdentityConfiguration(any())).thenReturn(mock(ProvisionConfiguration.class));
    EZPlugins pluginMock = mock(EZPlugins.class);
    when(mockContext.get(EZPlugins.class)).thenReturn(pluginMock);
    doAnswer((i) -> {
        ImplementingClassMatchProcessor func = i.getArgument(1);
        func.processMatch(mockPluginClass);
        return null;
    }).when(pluginMock).implementing(eq(DeviceIdentityInterface.class), any());
    kernelLifecycle.launch();
    verify(mockProvisioningPlugin, timeout(1000).times(1)).updateIdentityConfiguration(any(ProvisionContext.class));
}
Also used : EZPlugins(com.aws.greengrass.dependency.EZPlugins) DeviceIdentityInterface(com.aws.greengrass.provisioning.DeviceIdentityInterface) ProvisionContext(com.aws.greengrass.provisioning.ProvisionContext) ProvisionConfiguration(com.aws.greengrass.provisioning.ProvisionConfiguration) ImplementingClassMatchProcessor(io.github.lukehutch.fastclasspathscanner.matchprocessor.ImplementingClassMatchProcessor) Test(org.junit.jupiter.api.Test)

Example 5 with EZPlugins

use of com.aws.greengrass.dependency.EZPlugins in project aws-greengrass-nucleus by aws-greengrass.

the class GreengrassSetupTest method GIVEN_setup_script_WHEN_trusted_plugin_provided_THEN_jar_copied_to_trusted_plugin_path.

@Test
@SuppressWarnings("PMD.CloseResource")
void GIVEN_setup_script_WHEN_trusted_plugin_provided_THEN_jar_copied_to_trusted_plugin_path() throws Exception {
    Path pluginJarPath = Files.createTempFile(null, ".jar");
    Path mockTrustedDirectory = Files.createTempDirectory(null);
    GreengrassSetup greengrassSetup = new GreengrassSetup(System.out, System.err, deviceProvisioningHelper, platform, kernel, "-i", "mock_config_path", "-r", "mock_root", "-tn", "mock_thing_name", "-trn", "mock_tes_role_name", "-ss", "false", "--aws-region", "us-east-1", "--trusted-plugin", pluginJarPath.toString());
    NucleusPaths mockNucleusPaths = mock(NucleusPaths.class);
    Path mockPluginPath = mock(Path.class);
    when(mockNucleusPaths.pluginPath()).thenReturn(mockPluginPath);
    when(kernel.getNucleusPaths()).thenReturn(mockNucleusPaths);
    EZPlugins mockEZPlugin = mock(EZPlugins.class);
    when(mockEZPlugin.withCacheDirectory(eq(mockPluginPath))).thenReturn(mockEZPlugin);
    when(mockEZPlugin.getTrustedCacheDirectory()).thenReturn(mockTrustedDirectory);
    when(context.get(eq(EZPlugins.class))).thenReturn(mockEZPlugin);
    greengrassSetup.parseArgs();
    greengrassSetup.performSetup();
    assertTrue(Files.exists(mockTrustedDirectory.resolve(Utils.namePart(pluginJarPath.toString()))));
}
Also used : Path(java.nio.file.Path) EZPlugins(com.aws.greengrass.dependency.EZPlugins) NucleusPaths(com.aws.greengrass.util.NucleusPaths) Test(org.junit.jupiter.api.Test) ParameterizedTest(org.junit.jupiter.params.ParameterizedTest)

Aggregations

EZPlugins (com.aws.greengrass.dependency.EZPlugins)13 Test (org.junit.jupiter.api.Test)9 DeviceIdentityInterface (com.aws.greengrass.provisioning.DeviceIdentityInterface)7 ImplementingClassMatchProcessor (io.github.lukehutch.fastclasspathscanner.matchprocessor.ImplementingClassMatchProcessor)5 ImplementsService (com.aws.greengrass.dependency.ImplementsService)4 NucleusConfiguration (com.aws.greengrass.provisioning.ProvisionConfiguration.NucleusConfiguration)4 SystemConfiguration (com.aws.greengrass.provisioning.ProvisionConfiguration.SystemConfiguration)4 ProvisionContext (com.aws.greengrass.provisioning.ProvisionContext)4 IOException (java.io.IOException)4 RetryableProvisioningException (com.aws.greengrass.provisioning.exceptions.RetryableProvisioningException)2 NucleusPaths (com.aws.greengrass.util.NucleusPaths)2 Utils.deepToString (com.aws.greengrass.util.Utils.deepToString)2 Path (java.nio.file.Path)2 DependencyType (com.amazon.aws.iot.greengrass.component.common.DependencyType)1 DeploymentCapability (com.amazon.aws.iot.greengrass.configuration.common.DeploymentCapability)1 ComponentStore (com.aws.greengrass.componentmanager.ComponentStore)1 VERSION_CONFIG_KEY (com.aws.greengrass.componentmanager.KernelConfigResolver.VERSION_CONFIG_KEY)1 ComponentIdentifier (com.aws.greengrass.componentmanager.models.ComponentIdentifier)1 Configuration (com.aws.greengrass.config.Configuration)1 ConfigurationWriter (com.aws.greengrass.config.ConfigurationWriter)1