use of org.apache.drill.exec.store.StoragePluginRegistry.PluginException in project drill by apache.
the class TestPluginRegistry method testEnabledState.
/**
* Tests the dedicated setEnabled() method to cleanly update the
* enabled status of a plugin by name.
*/
@Test
public void testEnabledState() throws Exception {
ClusterFixtureBuilder builder = ClusterFixture.builder(dirTestWatcher);
try (ClusterFixture cluster = builder.build()) {
StoragePluginRegistry registry = cluster.storageRegistry();
// Disable an enabled plugin
StoragePluginConfig config = registry.getStoredConfig(CP_PLUGIN_NAME);
assertTrue(config.isEnabled());
// Enable/disable has traditionally been done by changing
// the plugin outside of the registry, which leads to obvious
// race conditions.
// Tests synchronized version.
registry.setEnabled(CP_PLUGIN_NAME, true);
StoragePluginConfig savedConfig = registry.getStoredConfig(CP_PLUGIN_NAME);
assertEquals(config, savedConfig);
assertTrue(savedConfig.isEnabled());
registry.setEnabled(CP_PLUGIN_NAME, false);
savedConfig = registry.getStoredConfig(CP_PLUGIN_NAME);
assertEquals(config, savedConfig);
assertFalse(savedConfig.isEnabled());
// OK to disable twice
registry.setEnabled(CP_PLUGIN_NAME, false);
savedConfig = registry.getStoredConfig(CP_PLUGIN_NAME);
assertEquals(config, savedConfig);
assertFalse(savedConfig.isEnabled());
// Disabled plugins appear in the stored config map
Map<String, StoragePluginConfig> configMap = registry.storedConfigs();
assertTrue(configMap.containsKey(CP_PLUGIN_NAME));
assertEquals(config, configMap.get(CP_PLUGIN_NAME));
// Re-enable
registry.setEnabled(CP_PLUGIN_NAME, true);
savedConfig = registry.getStoredConfig(CP_PLUGIN_NAME);
assertEquals(config, savedConfig);
assertTrue(savedConfig.isEnabled());
// Error if plugin does not exist
try {
registry.setEnabled("foo", true);
fail();
} catch (PluginException e) {
// expected
}
try {
registry.setEnabled("foo", false);
fail();
} catch (PluginException e) {
// expected
}
// Error to mess with a system plugins
try {
registry.setEnabled(SYS_PLUGIN_NAME, true);
fail();
} catch (PluginException e) {
// expected
}
try {
registry.setEnabled(SYS_PLUGIN_NAME, false);
fail();
} catch (PluginException e) {
// expected
}
}
}
use of org.apache.drill.exec.store.StoragePluginRegistry.PluginException in project drill by apache.
the class TestPluginRegistry method testEphemeralLifecycle.
/**
* Test the ephemeral cache where plugin instances live after their
* configs are changed or disabled so that any running queries see
* the prior plugin config an instance.
* <p>
* Note that each call to update a plugin must work with a copy of
* a config. Results are undefined if a client changes a stored
* config.
*/
@Test
public void testEphemeralLifecycle() throws Exception {
ClusterFixtureBuilder builder = ClusterFixture.builder(dirTestWatcher);
try (ClusterFixture cluster = builder.build()) {
StoragePluginRegistry registry = cluster.storageRegistry();
// Create a plugin
FileSystemConfig pConfig1 = myConfig1();
registry.put(MY_PLUGIN_NAME, pConfig1);
StoragePlugin plugin1 = registry.getPlugin(MY_PLUGIN_NAME);
// Update the plugin
FileSystemConfig pConfig2 = myConfig2();
registry.put(MY_PLUGIN_NAME, pConfig2);
StoragePlugin plugin2 = registry.getPlugin(MY_PLUGIN_NAME);
assertNotSame(plugin1, plugin2);
assertTrue(plugin2 instanceof FileSystemPlugin);
FileSystemPlugin fsStorage = (FileSystemPlugin) plugin2;
assertSame(pConfig2, fsStorage.getConfig());
assertSame(plugin2, registry.getPluginByConfig(pConfig2));
// Suppose a query was planned with plugin1 and now starts
// to execute. Plugin1 has been replaced with plugin2. However
// the registry moved the old plugin to ephemeral storage where
// it can still be found by configuration.
FileSystemConfig pConfig1a = myConfig1();
StoragePlugin ePlugin1 = registry.getPluginByConfig(pConfig1a);
assertSame(plugin1, ePlugin1);
assertNotSame(plugin2, ePlugin1);
// Change the stored plugin back to the first config.
FileSystemConfig pConfig1b = myConfig1();
registry.put(MY_PLUGIN_NAME, pConfig1b);
// Now, lets suppose thread 3 starts to execute. It sees the original plugin
assertSame(plugin1, registry.getPlugin(MY_PLUGIN_NAME));
// But, the ephemeral plugin lives on. Go back to the second
// config.
FileSystemConfig pConfig2b = myConfig2();
registry.put(MY_PLUGIN_NAME, pConfig2b);
assertSame(plugin2, registry.getPlugin(MY_PLUGIN_NAME));
// Thread 4, using the first config from planning in thread 3,
// still sees the first plugin.
assertSame(plugin1, registry.getPluginByConfig(pConfig1b));
// Disable
registry.setEnabled(MY_PLUGIN_NAME, false);
assertNull(registry.getPlugin(MY_PLUGIN_NAME));
// Though disabled, a running query will create an ephemeral
// plugin for the config.
assertSame(plugin1, registry.getPluginByConfig(pConfig1b));
assertSame(plugin2, registry.getPluginByConfig(pConfig2b));
// Enable. We notice the config is in the ephemeral store and
// so we restore it.
registry.setEnabled(MY_PLUGIN_NAME, true);
assertSame(plugin2, registry.getPlugin(MY_PLUGIN_NAME));
assertSame(plugin2, registry.getPluginByConfig(pConfig2b));
assertTrue(registry.storedConfigs().containsKey(MY_PLUGIN_KEY));
assertTrue(registry.enabledConfigs().containsKey(MY_PLUGIN_KEY));
// Delete the plugin
registry.remove(MY_PLUGIN_NAME);
assertNull(registry.getPlugin(MY_PLUGIN_NAME));
// Again a running query will retrieve the plugin from ephemeral storage
assertSame(plugin1, registry.getPluginByConfig(pConfig1));
assertSame(plugin2, registry.getPluginByConfig(pConfig2));
// Delete again, no-op
registry.remove(MY_PLUGIN_NAME);
// The retrieve-from-ephemeral does not kick in if we create
// a new plugin with the same config but a different name.
FileSystemConfig pConfig1c = myConfig1();
pConfig1c.setEnabled(true);
registry.put("alias", pConfig1c);
StoragePlugin plugin4 = registry.getPlugin("alias");
assertNotNull(plugin4);
assertNotSame(plugin1, plugin4);
// Delete the second name. The config is the same as one already
// in ephemeral store, so the second is closed. The first will
// be returned on subsequent queries.
registry.remove("alias");
assertNull(registry.getPlugin("alias"));
assertSame(plugin1, registry.getPluginByConfig(pConfig1));
// Try to change a system plugin
StoragePlugin sysPlugin = registry.getPlugin(SYS_PLUGIN_NAME);
assertNotNull(sysPlugin);
FileSystemConfig pConfig3 = myConfig2();
try {
registry.put(SYS_PLUGIN_NAME, pConfig3);
fail();
} catch (PluginException e) {
// Expected
}
pConfig3.setEnabled(false);
try {
registry.put(SYS_PLUGIN_NAME, pConfig3);
fail();
} catch (PluginException e) {
// Expected
}
assertSame(sysPlugin, registry.getPlugin(SYS_PLUGIN_NAME));
// Try to delete a system plugin
try {
registry.remove(SYS_PLUGIN_NAME);
fail();
} catch (PluginException e) {
// Expected
}
}
}
use of org.apache.drill.exec.store.StoragePluginRegistry.PluginException in project drill by apache.
the class TestPluginRegistry method testBadPlugin.
/**
* Test to illustrate problems discussed in DRILL-7624
*/
@Test
public void testBadPlugin() throws Exception {
ClusterFixtureBuilder builder = ClusterFixture.builder(dirTestWatcher);
builder.configBuilder().put(ExecConstants.PRIVATE_CONNECTORS, Collections.singletonList(StoragePluginFixture.class.getName()));
try (ClusterFixture cluster = builder.build()) {
StoragePluginRegistry registry = cluster.storageRegistry();
// Create a config that causes a crash because the plugin
// is not created on update.
StoragePluginFixtureConfig badConfig = new StoragePluginFixtureConfig("crash-ctor");
badConfig.setEnabled(true);
// instantiating the plugin.
try {
registry.validatedPut("bad", badConfig);
fail();
} catch (PluginException e) {
// Expected
}
assertNull(registry.getStoredConfig("bad"));
assertFalse(registry.availablePlugins().contains("bad"));
// Try the same with JSON
String json = registry.encode(badConfig);
try {
registry.putJson("bad", json);
fail();
} catch (PluginException e) {
// Expected
}
assertFalse(registry.availablePlugins().contains("bad"));
// Now, lets pretend the plugin was valid when we did the above,
// but later the external system failed.
registry.put("bad", badConfig);
assertEquals(badConfig, registry.getStoredConfig("bad"));
assertTrue(registry.availablePlugins().contains("bad"));
// Ask for the actual plugin. Now will fail.
try {
registry.getPlugin("bad");
fail();
} catch (UserException e) {
assertTrue(e.getMessage().contains("bad"));
}
assertTrue(registry.availablePlugins().contains("bad"));
// No plugin created. Will fail the next time also.
try {
registry.getPlugin("bad");
fail();
} catch (UserException e) {
// Expected
}
assertTrue(registry.availablePlugins().contains("bad"));
// The iterator used to find planning rules will skip the failed
// plugin. (That the planner uses all rules is, itself, a bug.)
int n = registry.availablePlugins().size();
int count = 0;
for (@SuppressWarnings("unused") Entry<String, StoragePlugin> entry : registry) {
count++;
}
assertEquals(n - 1, count);
// Reset to known good state
registry.remove("bad");
// Get tricky. Create a good plugin, then replace with
// a disabled bad one.
StoragePluginFixtureConfig goodConfig = new StoragePluginFixtureConfig("ok");
goodConfig.setEnabled(true);
json = registry.encode(goodConfig);
registry.putJson("test", json);
assertTrue(registry.availablePlugins().contains("test"));
assertEquals(goodConfig, registry.getPlugin("test").getConfig());
// Replace with a disabled bad plugin
badConfig = new StoragePluginFixtureConfig("crash-ctor");
badConfig.setEnabled(false);
json = registry.encode(badConfig);
registry.putJson("test", json);
assertFalse(registry.availablePlugins().contains("test"));
assertNull(registry.getPlugin("test"));
assertNotNull(registry.getStoredConfig("test"));
assertEquals(badConfig, registry.getStoredConfig("test"));
// Attempt to disable a disabled plugin. Should be OK.
registry.setEnabled("test", false);
// system, fix that system first.)
try {
registry.setEnabled("test", true);
fail();
} catch (PluginException e) {
// Expected
}
assertFalse(registry.availablePlugins().contains("test"));
}
}
use of org.apache.drill.exec.store.StoragePluginRegistry.PluginException in project drill by apache.
the class TestPluginsMap method testIntrinsic.
public void testIntrinsic() throws Exception {
OperatorFixture.Builder builder = OperatorFixture.builder(dirTestWatcher);
try (OperatorFixture fixture = builder.build()) {
PluginRegistryContextFixture context = new PluginRegistryContextFixture(fixture);
ConnectorLocator locator = new SystemPluginLocator(context);
locator.init();
Collection<StoragePlugin> sysPlugins = locator.intrinsicPlugins();
assertTrue(!sysPlugins.isEmpty());
StoragePlugin sysPlugin = sysPlugins.iterator().next();
ConnectorHandle connector = ConnectorHandle.intrinsicConnector(locator, sysPlugin);
assertTrue(connector.isIntrinsic());
StoragePluginMap map = new StoragePluginMap();
PluginHandle sysEntry = new PluginHandle(sysPlugin, connector, PluginType.INTRINSIC);
assertNull(map.put(sysEntry));
assertSame(sysEntry, map.get(sysPlugin.getName()));
// Second request to put the same (system) plugin is ignored
assertNull(map.put(sysEntry));
// Attempt to overwrite a system plugin is forcefully denied.
// Users can make this mistake, so a UserException is thrown
StoragePluginFixtureConfig config1 = new StoragePluginFixtureConfig("ok1");
PluginHandle entry1 = new PluginHandle(sysPlugin.getName(), config1, connector);
try {
map.put(entry1);
fail();
} catch (UserException e) {
// Expected
}
assertSame(sysEntry, map.get(sysPlugin.getName()));
// putIfAbsent does not replace an existing plugin
assertSame(sysEntry, map.putIfAbsent(entry1));
assertSame(sysEntry, map.get(sysPlugin.getName()));
// is intrinsic.
try {
map.replace(sysEntry, entry1);
fail();
} catch (IllegalArgumentException e) {
// Expected
}
assertSame(sysEntry, map.get(sysPlugin.getName()));
// Remove by entry fails for the same reasons as above.
try {
map.remove(sysEntry.name());
fail();
} catch (PluginException e) {
// Expected
}
assertSame(sysEntry, map.get(sysPlugin.getName()));
// Request to remove by name is ignored
// Caller can't be expected to know the meaning of the name
// Request to remove an intrinsic plugin by name is treated the
// same as a request to remove a non-existent plugin
assertNull(map.remove(sysPlugin.getName()));
assertSame(sysEntry, map.get(sysPlugin.getName()));
// Request to remove by name and config fails
// as above.
assertNull(map.remove(sysPlugin.getName(), sysPlugin.getConfig()));
assertSame(sysEntry, map.get(sysPlugin.getName()));
// Close does close intrinsic plugins, but no way to check
// it without elaborate mocking
map.close();
}
}
use of org.apache.drill.exec.store.StoragePluginRegistry.PluginException in project drill by apache.
the class ClusterFixture method defineStoragePlugin.
public void defineStoragePlugin(String name, StoragePluginConfig config) {
try {
for (Drillbit drillbit : drillbits()) {
StoragePluginRegistryImpl registry = (StoragePluginRegistryImpl) drillbit.getContext().getStorage();
registry.put(name, config);
}
} catch (PluginException e) {
throw new IllegalStateException("Plugin definition failed", e);
}
}
Aggregations