Search in sources :

Example 6 with PluginException

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
        }
    }
}
Also used : ClusterFixture(org.apache.drill.test.ClusterFixture) PluginException(org.apache.drill.exec.store.StoragePluginRegistry.PluginException) StoragePluginConfig(org.apache.drill.common.logical.StoragePluginConfig) ClusterFixtureBuilder(org.apache.drill.test.ClusterFixtureBuilder) BaseTest(org.apache.drill.test.BaseTest) Test(org.junit.Test)

Example 7 with PluginException

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
        }
    }
}
Also used : ClusterFixture(org.apache.drill.test.ClusterFixture) FileSystemPlugin(org.apache.drill.exec.store.dfs.FileSystemPlugin) PluginException(org.apache.drill.exec.store.StoragePluginRegistry.PluginException) FileSystemConfig(org.apache.drill.exec.store.dfs.FileSystemConfig) ClusterFixtureBuilder(org.apache.drill.test.ClusterFixtureBuilder) BaseTest(org.apache.drill.test.BaseTest) Test(org.junit.Test)

Example 8 with PluginException

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"));
    }
}
Also used : ClusterFixture(org.apache.drill.test.ClusterFixture) PluginException(org.apache.drill.exec.store.StoragePluginRegistry.PluginException) ClusterFixtureBuilder(org.apache.drill.test.ClusterFixtureBuilder) StoragePluginFixtureConfig(org.apache.drill.exec.store.BasePluginRegistryTest.StoragePluginFixtureConfig) UserException(org.apache.drill.common.exceptions.UserException) BaseTest(org.apache.drill.test.BaseTest) Test(org.junit.Test)

Example 9 with PluginException

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();
    }
}
Also used : PluginException(org.apache.drill.exec.store.StoragePluginRegistry.PluginException) OperatorFixture(org.apache.drill.test.OperatorFixture) UserException(org.apache.drill.common.exceptions.UserException)

Example 10 with PluginException

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);
    }
}
Also used : Drillbit(org.apache.drill.exec.server.Drillbit) StoragePluginRegistryImpl(org.apache.drill.exec.store.StoragePluginRegistryImpl) PluginException(org.apache.drill.exec.store.StoragePluginRegistry.PluginException)

Aggregations

PluginException (org.apache.drill.exec.store.StoragePluginRegistry.PluginException)12 BaseTest (org.apache.drill.test.BaseTest)5 ClusterFixture (org.apache.drill.test.ClusterFixture)5 ClusterFixtureBuilder (org.apache.drill.test.ClusterFixtureBuilder)5 Test (org.junit.Test)5 StoragePluginConfig (org.apache.drill.common.logical.StoragePluginConfig)3 FileSystemConfig (org.apache.drill.exec.store.dfs.FileSystemConfig)3 FileSystemPlugin (org.apache.drill.exec.store.dfs.FileSystemPlugin)3 IOException (java.io.IOException)2 Path (javax.ws.rs.Path)2 Produces (javax.ws.rs.Produces)2 SchemaPlus (org.apache.calcite.schema.SchemaPlus)2 UserException (org.apache.drill.common.exceptions.UserException)2 TokenRegistry (org.apache.drill.exec.oauth.TokenRegistry)2 Drillbit (org.apache.drill.exec.server.Drillbit)2 AbstractSchema (org.apache.drill.exec.store.AbstractSchema)2 AbstractStoragePlugin (org.apache.drill.exec.store.AbstractStoragePlugin)2 StoragePlugin (org.apache.drill.exec.store.StoragePlugin)2 JsonProcessingException (com.fasterxml.jackson.core.JsonProcessingException)1 SerializableString (com.fasterxml.jackson.core.SerializableString)1