use of co.cask.cdap.api.artifact.ArtifactId in project cdap by caskdata.
the class ArtifactRepositoryTest method testPluginSelector.
@Test
public void testPluginSelector() throws Exception {
// No plugin yet
ArtifactRange appArtifactRange = new ArtifactRange(APP_ARTIFACT_ID.getNamespace().getId(), APP_ARTIFACT_ID.getName(), APP_ARTIFACT_ID.getVersion(), true, APP_ARTIFACT_ID.getVersion(), true);
try {
artifactRepository.findPlugin(NamespaceId.DEFAULT, appArtifactRange, "plugin", "TestPlugin2", new PluginSelector());
Assert.fail();
} catch (PluginNotExistsException e) {
// expected
}
File pluginDir = DirUtils.createTempDir(tmpDir);
// Create a plugin jar. It contains two plugins, TestPlugin and TestPlugin2 inside.
Id.Artifact artifact1Id = Id.Artifact.from(Id.Namespace.DEFAULT, "myPlugin", "1.0");
Manifest manifest = createManifest(ManifestFields.EXPORT_PACKAGE, TestPlugin.class.getPackage().getName());
File jarFile = createPluginJar(TestPlugin.class, new File(tmpDir, "myPlugin-1.0.jar"), manifest);
// Build up the plugin repository.
Set<ArtifactRange> parents = ImmutableSet.of(new ArtifactRange(APP_ARTIFACT_ID.getNamespace().getId(), APP_ARTIFACT_ID.getName(), new ArtifactVersion("1.0.0"), new ArtifactVersion("2.0.0")));
artifactRepository.addArtifact(artifact1Id, jarFile, parents, null);
// Should get the only version.
Map.Entry<ArtifactDescriptor, PluginClass> plugin = artifactRepository.findPlugin(NamespaceId.DEFAULT, appArtifactRange, "plugin", "TestPlugin2", new PluginSelector());
Assert.assertNotNull(plugin);
Assert.assertEquals(new ArtifactVersion("1.0"), plugin.getKey().getArtifactId().getVersion());
Assert.assertEquals("TestPlugin2", plugin.getValue().getName());
Files.copy(Locations.newInputSupplier(plugin.getKey().getLocation()), new File(pluginDir, Artifacts.getFileName(plugin.getKey().getArtifactId())));
// Create another plugin jar with later version and update the repository
Id.Artifact artifact2Id = Id.Artifact.from(Id.Namespace.DEFAULT, "myPlugin", "2.0");
jarFile = createPluginJar(TestPlugin.class, new File(tmpDir, "myPlugin-2.0.jar"), manifest);
artifactRepository.addArtifact(artifact2Id, jarFile, parents, null);
// Should select the latest version
plugin = artifactRepository.findPlugin(NamespaceId.DEFAULT, appArtifactRange, "plugin", "TestPlugin2", new PluginSelector());
Assert.assertNotNull(plugin);
Assert.assertEquals(new ArtifactVersion("2.0"), plugin.getKey().getArtifactId().getVersion());
Assert.assertEquals("TestPlugin2", plugin.getValue().getName());
Files.copy(Locations.newInputSupplier(plugin.getKey().getLocation()), new File(pluginDir, Artifacts.getFileName(plugin.getKey().getArtifactId())));
// Load the Plugin class from the classLoader.
try (PluginInstantiator instantiator = new PluginInstantiator(cConf, appClassLoader, pluginDir)) {
ClassLoader pluginClassLoader = instantiator.getArtifactClassLoader(plugin.getKey().getArtifactId());
Class<?> pluginClass = pluginClassLoader.loadClass(TestPlugin2.class.getName());
// Use a custom plugin selector to select with smallest version
plugin = artifactRepository.findPlugin(NamespaceId.DEFAULT, appArtifactRange, "plugin", "TestPlugin2", new PluginSelector() {
@Override
public Map.Entry<ArtifactId, PluginClass> select(SortedMap<ArtifactId, PluginClass> plugins) {
return plugins.entrySet().iterator().next();
}
});
Assert.assertNotNull(plugin);
Assert.assertEquals(new ArtifactVersion("1.0"), plugin.getKey().getArtifactId().getVersion());
Assert.assertEquals("TestPlugin2", plugin.getValue().getName());
// Load the Plugin class again from the current plugin selected
// The plugin class should be different (from different ClassLoader)
// The empty class should be the same (from the plugin lib ClassLoader)
pluginClassLoader = instantiator.getArtifactClassLoader(plugin.getKey().getArtifactId());
Assert.assertNotSame(pluginClass, pluginClassLoader.loadClass(TestPlugin2.class.getName()));
// From the pluginClassLoader, loading export classes from the template jar should be allowed
Class<?> cls = pluginClassLoader.loadClass(PluginTestRunnable.class.getName());
// The class should be loaded from the parent artifact's classloader
Assert.assertSame(appClassLoader.loadClass(PluginTestRunnable.class.getName()), cls);
// From the plugin classloader, all cdap api classes is loadable as well.
cls = pluginClassLoader.loadClass(Application.class.getName());
// The Application class should be the same as the one in the system classloader
Assert.assertSame(Application.class, cls);
}
}
use of co.cask.cdap.api.artifact.ArtifactId in project cdap by caskdata.
the class ArtifactRepositoryTest method testMacroPlugin.
@Test
public void testMacroPlugin() throws Exception {
File pluginDir = TMP_FOLDER.newFolder();
addPluginArtifact();
SortedMap<ArtifactDescriptor, Set<PluginClass>> plugins = getPlugins();
copyArtifacts(pluginDir, plugins);
// set up test macro evaluator's substitutions
Map<String, String> propertySubstitutions = ImmutableMap.<String, String>builder().put("expansiveHostname", "${hostname}/${path}:${port}").put("hostname", "${one}").put("path", "${two}").put("port", "${three}").put("one", "${host${hostScopeMacro}}").put("hostScopeMacro", "-local").put("host-local", "${l}${o}${c}${a}${l}${hostSuffix}").put("l", "l").put("o", "o").put("c", "c").put("a", "a").put("hostSuffix", "host").put("two", "${filename${fileTypeMacro}}").put("three", "${firstPortDigit}${secondPortDigit}").put("filename", "index").put("fileTypeMacro", "-html").put("filename-html", "index.html").put("filename-php", "index.php").put("firstPortDigit", "8").put("secondPortDigit", "0").put("aBoolean", "true").put("aByte", "101").put("aChar", "k").put("aDouble", "64.0").put("aFloat", "52.0").put("anInt", "42").put("aLong", "32").put("aShort", "81").build();
// Instantiate the plugins and execute them
try (PluginInstantiator instantiator = new PluginInstantiator(cConf, appClassLoader, pluginDir)) {
for (Map.Entry<ArtifactDescriptor, Set<PluginClass>> entry : plugins.entrySet()) {
for (PluginClass pluginClass : entry.getValue()) {
Plugin pluginInfo = new Plugin(new ArrayList<ArtifactId>(), entry.getKey().getArtifactId(), pluginClass, PluginProperties.builder().add("class.name", TEST_EMPTY_CLASS).add("nullableLongFlag", "10").add("host", "${expansiveHostname}").add("aBoolean", "${aBoolean}").add("aByte", "${aByte}").add("aChar", "${aChar}").add("aDouble", "${aDouble}").add("anInt", "${anInt}").add("aFloat", "${aFloat}").add("aLong", "${aLong}").add("aShort", "${aShort}").build());
TestMacroEvaluator testMacroEvaluator = new TestMacroEvaluator(propertySubstitutions, new HashMap<String, String>());
Callable<String> plugin = instantiator.newInstance(pluginInfo, testMacroEvaluator);
Assert.assertEquals("localhost/index.html:80,true,101,k,64.0,52.0,42,32,81", plugin.call());
String pluginId = "5";
PluginContext pluginContext = new DefaultPluginContext(instantiator, NamespaceId.DEFAULT.app("abc").worker("w"), ImmutableMap.of(pluginId, pluginInfo));
PluginProperties resolvedProperties = pluginContext.getPluginProperties(pluginId, testMacroEvaluator);
Map<String, String> expected = new HashMap<>();
expected.put("class.name", TEST_EMPTY_CLASS);
expected.put("nullableLongFlag", "10");
expected.put("host", "localhost/index.html:80");
expected.put("aBoolean", "true");
expected.put("aByte", "101");
expected.put("aChar", "k");
expected.put("aDouble", "64.0");
expected.put("anInt", "42");
expected.put("aFloat", "52.0");
expected.put("aLong", "32");
expected.put("aShort", "81");
Assert.assertEquals(expected, resolvedProperties.getProperties());
}
}
}
}
use of co.cask.cdap.api.artifact.ArtifactId in project cdap by caskdata.
the class MapReduceContextConfigTest method testManyMacrosInAppSpec.
@Test
public void testManyMacrosInAppSpec() {
Configuration hConf = new Configuration();
MapReduceContextConfig cfg = new MapReduceContextConfig(hConf);
StringBuilder appCfg = new StringBuilder();
for (int i = 0; i < 100; i++) {
appCfg.append("${").append(i).append("}");
hConf.setInt(String.valueOf(i), i);
}
ApplicationSpecification appSpec = new DefaultApplicationSpecification("name", "desc", appCfg.toString(), new ArtifactId("artifact", new ArtifactVersion("1.0.0"), ArtifactScope.USER), Collections.<String, StreamSpecification>emptyMap(), Collections.<String, String>emptyMap(), Collections.<String, DatasetCreationSpec>emptyMap(), Collections.<String, FlowSpecification>emptyMap(), Collections.<String, MapReduceSpecification>emptyMap(), Collections.<String, SparkSpecification>emptyMap(), Collections.<String, WorkflowSpecification>emptyMap(), Collections.<String, ServiceSpecification>emptyMap(), Collections.<String, ScheduleCreationSpec>emptyMap(), Collections.<String, WorkerSpecification>emptyMap(), Collections.<String, Plugin>emptyMap());
cfg.setApplicationSpecification(appSpec);
Assert.assertEquals(appSpec.getConfiguration(), cfg.getApplicationSpecification().getConfiguration());
}
use of co.cask.cdap.api.artifact.ArtifactId in project cdap by caskdata.
the class ArtifactSelector method select.
@Override
public Map.Entry<ArtifactId, PluginClass> select(SortedMap<ArtifactId, PluginClass> plugins) {
NavigableMap<ArtifactId, PluginClass> pluginMap;
if (plugins instanceof NavigableMap) {
pluginMap = (NavigableMap<ArtifactId, PluginClass>) plugins;
} else {
pluginMap = new TreeMap<>();
pluginMap.putAll(plugins);
}
for (Map.Entry<ArtifactId, PluginClass> entry : pluginMap.descendingMap().entrySet()) {
ArtifactId artifactId = entry.getKey();
if ((scope == null || artifactId.getScope().equals(scope)) && (name == null || artifactId.getName().equals(name)) && (range == null || range.versionIsInRange(artifactId.getVersion()))) {
return entry;
}
}
throw new IllegalArgumentException(errMsg);
}
Aggregations