use of com.aws.greengrass.dependency.ImplementsService 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;
}
use of com.aws.greengrass.dependency.ImplementsService in project aws-greengrass-nucleus by aws-greengrass.
the class KernelLifecycle method findBuiltInServicesAndPlugins.
@SuppressWarnings("PMD.CloseResource")
private Queue<String> findBuiltInServicesAndPlugins() {
Queue<String> autostart = new LinkedList<>();
try {
EZPlugins pim = kernel.getContext().get(EZPlugins.class);
pim.withCacheDirectory(nucleusPaths.pluginPath());
pim.annotated(ImplementsService.class, cl -> {
if (!GreengrassService.class.isAssignableFrom(cl)) {
logger.atError().log("{} needs to be a subclass of GreengrassService " + "in order to use ImplementsService", cl);
return;
}
ImplementsService is = cl.getAnnotation(ImplementsService.class);
if (is.autostart()) {
autostart.add(is.name());
}
serviceImplementors.put(is.name(), cl);
logger.atInfo().log("Found Plugin: {}", cl.getSimpleName());
});
} catch (IOException t) {
logger.atError().log("Error finding built in service plugins", t);
}
return autostart;
}
Aggregations