use of co.cask.cdap.api.plugin.PluginClass in project cdap by caskdata.
the class AppSystemMetadataWriter method getSystemPropertiesToAdd.
@Override
protected Map<String, String> getSystemPropertiesToAdd() {
ImmutableMap.Builder<String, String> properties = ImmutableMap.builder();
properties.put(ENTITY_NAME_KEY, appSpec.getName());
properties.put(VERSION_KEY, appId.getVersion());
String description = appSpec.getDescription();
if (!Strings.isNullOrEmpty(description)) {
properties.put(DESCRIPTION_KEY, description);
}
if (!existing) {
properties.put(CREATION_TIME_KEY, String.valueOf(System.currentTimeMillis()));
}
addPrograms(properties);
addSchedules(properties);
// appSpec.getPlugins() returns all instances of all plugins, so there may be duplicates.
// we only store unique plugins right now
Set<PluginClass> existingPluginClasses = new HashSet<>();
for (Plugin plugin : appSpec.getPlugins().values()) {
if (!existingPluginClasses.contains(plugin.getPluginClass())) {
addPlugin(plugin.getPluginClass(), null, properties);
existingPluginClasses.add(plugin.getPluginClass());
}
}
return properties.build();
}
use of co.cask.cdap.api.plugin.PluginClass in project cdap by caskdata.
the class ArtifactSystemMetadataWriter method getSystemPropertiesToAdd.
@Override
protected Map<String, String> getSystemPropertiesToAdd() {
ImmutableMap.Builder<String, String> properties = ImmutableMap.builder();
properties.put(ENTITY_NAME_KEY, artifactInfo.getName());
ArtifactClasses classes = artifactInfo.getClasses();
for (PluginClass pluginClass : classes.getPlugins()) {
addPlugin(pluginClass, artifactInfo.getVersion(), properties);
}
if (!existing) {
properties.put(CREATION_TIME_KEY, String.valueOf(System.currentTimeMillis()));
}
return properties.build();
}
use of co.cask.cdap.api.plugin.PluginClass in project cdap by caskdata.
the class ArtifactInspector method inspectPlugins.
/**
* Inspects the plugin file and extracts plugin classes information.
*/
private ArtifactClasses.Builder inspectPlugins(ArtifactClasses.Builder builder, File artifactFile, ArtifactId artifactId, PluginInstantiator pluginInstantiator) throws IOException, InvalidArtifactException {
// See if there are export packages. Plugins should be in those packages
Set<String> exportPackages = getExportPackages(artifactFile);
if (exportPackages.isEmpty()) {
return builder;
}
try {
ClassLoader pluginClassLoader = pluginInstantiator.getArtifactClassLoader(artifactId);
for (Class<?> cls : getPluginClasses(exportPackages, pluginClassLoader)) {
Plugin pluginAnnotation = cls.getAnnotation(Plugin.class);
if (pluginAnnotation == null) {
continue;
}
Map<String, PluginPropertyField> pluginProperties = Maps.newHashMap();
try {
String configField = getProperties(TypeToken.of(cls), pluginProperties);
Set<String> pluginEndpoints = getPluginEndpoints(cls);
PluginClass pluginClass = new PluginClass(pluginAnnotation.type(), getPluginName(cls), getPluginDescription(cls), cls.getName(), configField, pluginProperties, pluginEndpoints);
builder.addPlugin(pluginClass);
} catch (UnsupportedTypeException e) {
LOG.warn("Plugin configuration type not supported. Plugin ignored. {}", cls, e);
}
}
} catch (Throwable t) {
throw new InvalidArtifactException(String.format("Class could not be found while inspecting artifact for plugins. " + "Please check dependencies are available, and that the correct parent artifact was specified. " + "Error class: %s, message: %s.", t.getClass(), t.getMessage()), t);
}
return builder;
}
use of co.cask.cdap.api.plugin.PluginClass in project cdap by caskdata.
the class PluginInstantiator method newInstance.
/**
* Creates a new instance of the given plugin class with all property macros substituted if a MacroEvaluator is given.
* At runtime, plugin property fields that are macro-enabled and contain macro syntax will remain in the macroFields
* set in the plugin config.
* @param plugin {@link Plugin}
* @param macroEvaluator the MacroEvaluator that performs macro substitution
* @param <T> Type of the plugin
* @return a new plugin instance with macros substituted
* @throws IOException if failed to expand the plugin jar to create the plugin ClassLoader
* @throws ClassNotFoundException if failed to load the given plugin class
*/
public <T> T newInstance(Plugin plugin, @Nullable MacroEvaluator macroEvaluator) throws IOException, ClassNotFoundException, InvalidMacroException {
ClassLoader classLoader = getPluginClassLoader(plugin);
PluginClass pluginClass = plugin.getPluginClass();
@SuppressWarnings("unchecked") TypeToken<T> pluginType = TypeToken.of((Class<T>) classLoader.loadClass(pluginClass.getClassName()));
try {
String configFieldName = pluginClass.getConfigFieldName();
// Plugin doesn't have config. Simply return a new instance.
if (configFieldName == null) {
return instantiatorFactory.get(pluginType).create();
}
// Create the config instance
Field field = Fields.findField(pluginType.getType(), configFieldName);
TypeToken<?> configFieldType = pluginType.resolveType(field.getGenericType());
Object config = instantiatorFactory.get(configFieldType).create();
// perform macro substitution if an evaluator is provided, collect fields with macros only at configure time
PluginProperties pluginProperties = substituteMacros(plugin, macroEvaluator);
Set<String> macroFields = (macroEvaluator == null) ? getFieldsWithMacro(plugin) : Collections.emptySet();
Reflections.visit(config, configFieldType.getType(), new ConfigFieldSetter(pluginClass, plugin.getArtifactId(), pluginProperties, macroFields));
// Create the plugin instance
return newInstance(pluginType, field, configFieldType, config);
} catch (NoSuchFieldException e) {
throw new InvalidPluginConfigException("Config field not found in plugin class: " + pluginClass, e);
} catch (IllegalAccessException e) {
throw new InvalidPluginConfigException("Failed to set plugin config field: " + pluginClass, e);
}
}
use of co.cask.cdap.api.plugin.PluginClass in project cdap by caskdata.
the class PluginFinderTestBase method testFindPlugin.
@Test
public void testFindPlugin() throws Exception {
// Deploy some artifacts
File appArtifact = createAppJar(PluginTestApp.class);
File pluginArtifact = createPluginJar(Plugin1.class);
ArtifactId appArtifactId = NamespaceId.DEFAULT.artifact("app", "1.0");
artifactRepo.addArtifact(Id.Artifact.fromEntityId(appArtifactId), appArtifact);
ArtifactId pluginArtifactId = NamespaceId.DEFAULT.artifact("plugin", "1.0");
artifactRepo.addArtifact(Id.Artifact.fromEntityId(pluginArtifactId), pluginArtifact, Collections.singleton(new ArtifactRange(appArtifactId.getNamespace(), appArtifactId.getArtifact(), new ArtifactVersion(appArtifactId.getVersion()), true, new ArtifactVersion(appArtifactId.getVersion()), true)), null);
// Find the plugin
PluginFinder finder = getPluginFinder();
Map.Entry<ArtifactDescriptor, PluginClass> entry = finder.findPlugin(NamespaceId.DEFAULT, appArtifactId, "dummy", "Plugin1", new PluginSelector());
Assert.assertNotNull(entry);
Assert.assertEquals(pluginArtifactId.toApiArtifactId(), entry.getKey().getArtifactId());
Assert.assertEquals("Plugin1", entry.getValue().getName());
Assert.assertEquals("dummy", entry.getValue().getType());
// Looking for a non-existing should throw
try {
finder.findPlugin(NamespaceId.DEFAULT, appArtifactId, "dummy2", "pluginx", new PluginSelector());
Assert.fail("A PluginNotExistsException is expected");
} catch (PluginNotExistsException e) {
// expected
}
// Deploy the same plugin artifact to the system namespace, without any parent
ArtifactId systemPluginArtifactId = NamespaceId.SYSTEM.artifact("pluginsystem", "1.0");
artifactRepo.addArtifact(Id.Artifact.fromEntityId(systemPluginArtifactId), pluginArtifact);
entry = finder.findPlugin(NamespaceId.DEFAULT, appArtifactId, "dummy", "Plugin1", new PluginSelector());
// The selector always select the last one, hence the USER once will be selected
Assert.assertNotNull(entry);
Assert.assertEquals(pluginArtifactId.toApiArtifactId(), entry.getKey().getArtifactId());
Assert.assertEquals("Plugin1", entry.getValue().getName());
Assert.assertEquals("dummy", entry.getValue().getType());
// Use a different selector that returns the first entry, hence expect the SYSTEM one being returned
entry = finder.findPlugin(NamespaceId.DEFAULT, appArtifactId, "dummy", "Plugin1", new PluginSelector() {
@Override
public Map.Entry<co.cask.cdap.api.artifact.ArtifactId, PluginClass> select(SortedMap<co.cask.cdap.api.artifact.ArtifactId, PluginClass> plugins) {
return plugins.entrySet().iterator().next();
}
});
Assert.assertNotNull(entry);
Assert.assertEquals(systemPluginArtifactId.toApiArtifactId(), entry.getKey().getArtifactId());
Assert.assertEquals("Plugin1", entry.getValue().getName());
Assert.assertEquals("dummy", entry.getValue().getType());
}
Aggregations