public class StoragePluginRegistryImpl extends Object implements StoragePluginRegistry
Allows multiple "locators" to provide plugin classes such as the "classic" version for classes in the same class loader, the "system" version for system-defined plugins.
provides multiple layers of abstraction:
The idea is to push most functionality into the above abstractions, leaving overall coordination here.
Plugins themselves have multiple levels of definitions:
ConnectorHandle
which defines the config class and
the locator which can create instances of that class.PluginHandle
which pairs the config with a name as
the unit that the user thinks of as a "plugin." The plugin entry
links to the ConnectorEntry
to create the instance lazily
when first requested.The code syncs the in-memory cache with the persistent store on each access (which is actually inefficient and should be reviewed.)
During refresh, it could be that another thread is doing exactly the same thing, or even fighting us by changing the config. It is impossible to ensure a totally consistent answer. The goal is to make sure that the cache ends up agreeing with the persistent store as it was at some point in time.
The PluginsMap
class provides in-memory synchronization of the
name and config maps. Careful coding is needed when handling refresh
since another thread could make the same changes.
Once the planner obtains a plugin, another user could come along and change the config for that plugin. Drill treats that change as another plugin: the original one continues to be used by the planner (but see below), while new queries use the new version.
Since the config on remote servers may have changed relative to the one this Foreman used for planning, the plan includes the plugin config itself (not just a reference to the config.) This works because the config is usually small.
The ephemeral store also acts as a graveyard for deleted or changed plugins. When removing a plugin, the old plugin is moved to ephemeral storage to allow running queries to locate it. Similarly, when a new configuration is stored, the corresponding plugin is retrieved from ephemeral storage, if it exists. This avoids odd cases where the same plugin exists in both normal and ephemeral storage.
close()
method that, if used, could render the
plugin unusable. Suppose a Cassandra plugin, say, maintains a connection
to a server used across multiple queries and threads. Any change to
the config immediately calls close()
on the plugin, even though
it may be in use in planning a query on another thread. Random failures
will result.
The same issue can affect ephemeral plugins: if the number in the cache reaches the limit, the registry will start closing old ones, without knowning if that plugin is actually in use.
The workaround is to not actually honor the close()
call. Longer
term, a reference count is needed.
UserException
. Those that violate invariants
as other forms of exception.StoragePluginRegistry.PluginEncodingException, StoragePluginRegistry.PluginException, StoragePluginRegistry.PluginFilter, StoragePluginRegistry.PluginNotFoundException
PSTORE_NAME
Constructor and Description |
---|
StoragePluginRegistryImpl(DrillbitContext context) |
Modifier and Type | Method and Description |
---|---|
Set<String> |
availablePlugins()
Returns the set of available plugin names.
|
void |
close() |
StoragePluginConfig |
copyConfig(StoragePluginConfig orig)
Copy the given storage plugin config so it may be modified.
|
StoragePluginConfig |
copyConfig(String name)
Copy a stored config so that it can be modified.
|
protected static void |
copyPluginStatus(StoragePluginConfig oldPluginConfig,
StoragePluginConfig newPluginConfig)
Identifies the enabled status for new storage plugins
config.
|
StoragePluginConfig |
decode(String json)
Return a config decoded from JSON.
|
Map<String,StoragePluginConfig> |
enabledConfigs()
Returns a copy of the set of enabled stored plugin configurations.
|
String |
encode(StoragePluginConfig config) |
String |
encode(String name)
Return a config encoded as JSON.
|
StoragePluginConfig |
getDefinedConfig(String name)
Retrieve an available configuration.
|
FormatPlugin |
getFormatPlugin(StoragePluginConfig storageConfig,
FormatPluginConfig formatConfig) |
FormatPlugin |
getFormatPluginByConfig(StoragePluginConfig storageConfig,
FormatPluginConfig formatConfig)
Get the Format plugin for the FileSystemPlugin associated with the provided
storage config and format config.
|
StoragePlugin |
getPlugin(StoragePluginConfig config) |
StoragePlugin |
getPlugin(String name)
Get a plugin by name.
|
StoragePlugin |
getPluginByConfig(StoragePluginConfig config)
Get a plugin by configuration.
|
SchemaFactory |
getSchemaFactory()
Get the Schema factory associated with this storage plugin registry.
|
StoragePluginConfig |
getStoredConfig(String name)
Configs are obtained from the persistent store.
|
void |
init()
Initialize the storage plugin registry.
|
Iterator<Map.Entry<String,StoragePlugin>> |
iterator() |
com.fasterxml.jackson.databind.ObjectMapper |
mapper()
Object mapper to read/write the JSON form of a plugin.
|
void |
put(String name,
StoragePluginConfig config)
Store a plugin by name and configuration.
|
void |
putFormatPlugin(String pluginName,
String formatName,
FormatPluginConfig formatConfig)
Safe way to add or remove a format plugin config from a stored file
system configuration.
|
void |
putJson(String name,
String json)
Put a storage plugin config from JSON.
|
void |
remove(String name)
Remove a plugin by name
|
<T extends StoragePlugin> |
resolve(StoragePluginConfig storageConfig,
Class<T> desired) |
<T extends FormatPlugin> |
resolveFormat(StoragePluginConfig storageConfig,
FormatPluginConfig formatConfig,
Class<T> desired)
Resolve a storage plugin given a storage plugin config.
|
void |
setEnabled(String name,
boolean enable)
Set the plugin to the requested enabled state.
|
Map<String,StoragePluginConfig> |
storedConfigs()
Returns a set of all stored plugin configurations,
directly from the persistent store.
|
Map<String,StoragePluginConfig> |
storedConfigs(StoragePluginRegistry.PluginFilter filter)
Return a possibly-filtered set of plugins from the persistent
store.
|
void |
validatedPut(String name,
StoragePluginConfig config)
Like
StoragePluginRegistry.put(String, StoragePluginConfig) , but forces instantiation of the
plugin to verify that the configuration is valid at this moment in time. |
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
forEach, spliterator
public StoragePluginRegistryImpl(DrillbitContext context)
public void init()
StoragePluginRegistry
init
in interface StoragePluginRegistry
protected static void copyPluginStatus(StoragePluginConfig oldPluginConfig, StoragePluginConfig newPluginConfig)
oldPluginConfig
- current storage plugin config from Persistent Store or bootstrap
config filenewPluginConfig
- new storage plugin configpublic void put(String name, StoragePluginConfig config) throws StoragePluginRegistry.PluginException
StoragePluginRegistry
put()
mimics normal runtime operation.put
in interface StoragePluginRegistry
name
- The name of the pluginconfig
- The plugin configurationStoragePluginRegistry.PluginException
- if plugin cannot be createdpublic void validatedPut(String name, StoragePluginConfig config) throws StoragePluginRegistry.PluginException
StoragePluginRegistry
StoragePluginRegistry.put(String, StoragePluginConfig)
, but forces instantiation of the
plugin to verify that the configuration is valid at this moment in time.validatedPut
in interface StoragePluginRegistry
StoragePluginRegistry.PluginException
public void setEnabled(String name, boolean enable) throws StoragePluginRegistry.PluginException
StoragePluginRegistry
#verifiedPut()
.
Use this method when changing state. Do not obtain the config and change the state directly, doing so will make the plugin config inconsistent with the internal state.
setEnabled
in interface StoragePluginRegistry
name
- name of the pluginenable
- true
to enable the plugin, false
to disableStoragePluginRegistry.PluginNotFoundException
- if the plugin is not foundStoragePluginRegistry.PluginException
- if the plugin name is not valid or
if enabling a plugin and the plugin is not validpublic StoragePluginConfig getStoredConfig(String name)
Note that each call (depending on the store implementation)
may return a distinct instance of the config. The instance will
be equal (unless the stored version changes.) However, other
versions of the store may return the same instance as is in
the cache. So, do not modify the returned config.
To modify the config, call copyConfig(String)
instead.
getStoredConfig
in interface StoragePluginRegistry
public StoragePluginConfig copyConfig(String name) throws StoragePluginRegistry.PluginException
StoragePluginRegistry
Never modify a config stored in the registry! Configs are keyed by name and value; getting a config, then modifying it, will cause the value maps to become out of sync.
copyConfig
in interface StoragePluginRegistry
name
- name of the storage plugin config to copyStoragePluginRegistry.PluginException
- if the name is undefinedpublic String encode(StoragePluginConfig config)
encode
in interface StoragePluginRegistry
public String encode(String name) throws StoragePluginRegistry.PluginException
StoragePluginRegistry
encode
in interface StoragePluginRegistry
StoragePluginRegistry.PluginException
- if the plugin is undefinedpublic StoragePluginConfig decode(String json) throws StoragePluginRegistry.PluginEncodingException
StoragePluginRegistry
decode
in interface StoragePluginRegistry
StoragePluginRegistry.PluginEncodingException
- if the JSON is invalidpublic void putJson(String name, String json) throws StoragePluginRegistry.PluginException
StoragePluginRegistry
putJson
in interface StoragePluginRegistry
StoragePluginRegistry.PluginException
- if the underlying
StoragePluginRegistry.validatedPut(String, StoragePluginConfig)
failspublic StoragePluginConfig copyConfig(StoragePluginConfig orig)
StoragePluginRegistry
copyConfig
in interface StoragePluginRegistry
orig
- the storage plugin config to copypublic StoragePluginConfig getDefinedConfig(String name)
StoragePluginRegistry
getDefinedConfig
in interface StoragePluginRegistry
public StoragePlugin getPlugin(String name) throws StoragePluginRegistry.PluginException
StoragePluginRegistry
getPlugin
in interface StoragePluginRegistry
name
- The name of the pluginStoragePluginRegistry.PluginException
- if plugin cannot be obtainedpublic StoragePlugin getPlugin(StoragePluginConfig config) throws ExecutionSetupException
getPlugin
in interface StoragePluginRegistry
ExecutionSetupException
public StoragePlugin getPluginByConfig(StoragePluginConfig config) throws StoragePluginRegistry.PluginException
StoragePluginRegistry
getPluginByConfig
in interface StoragePluginRegistry
config
- The configuration for the plugin.StoragePluginRegistry.PluginException
- if plugin cannot be obtainedpublic void remove(String name) throws StoragePluginRegistry.PluginException
StoragePluginRegistry
remove
in interface StoragePluginRegistry
name
- The name of the storage plugin to removeStoragePluginRegistry.PluginException
public Map<String,StoragePluginConfig> storedConfigs()
StoragePluginRegistry
storedConfigs
in interface StoragePluginRegistry
public Map<String,StoragePluginConfig> storedConfigs(StoragePluginRegistry.PluginFilter filter)
StoragePluginRegistry
storedConfigs
in interface StoragePluginRegistry
public Map<String,StoragePluginConfig> enabledConfigs()
StoragePluginRegistry
enabledConfigs
in interface StoragePluginRegistry
public void putFormatPlugin(String pluginName, String formatName, FormatPluginConfig formatConfig) throws StoragePluginRegistry.PluginException
StoragePluginRegistry
putFormatPlugin
in interface StoragePluginRegistry
pluginName
- name of the file system storage plugin config to
modifyformatName
- name of the format plugin to modifyformatConfig
- if null, removes the plugin, if non-null updates
the format plugin config with this valueStoragePluginRegistry.PluginException
- if the storage plugin is undefined or
is not a file format pluginpublic FormatPlugin getFormatPluginByConfig(StoragePluginConfig storageConfig, FormatPluginConfig formatConfig) throws StoragePluginRegistry.PluginException
StoragePluginRegistry
getFormatPluginByConfig
in interface StoragePluginRegistry
storageConfig
- The storage config for the associated FileSystemPluginformatConfig
- The format config for the associated FormatPluginStoragePluginRegistry.PluginException
- if plugin cannot be obtainedpublic FormatPlugin getFormatPlugin(StoragePluginConfig storageConfig, FormatPluginConfig formatConfig) throws ExecutionSetupException
getFormatPlugin
in interface StoragePluginRegistry
ExecutionSetupException
public SchemaFactory getSchemaFactory()
StoragePluginRegistry
getSchemaFactory
in interface StoragePluginRegistry
public Iterator<Map.Entry<String,StoragePlugin>> iterator()
iterator
in interface Iterable<Map.Entry<String,StoragePlugin>>
public void close() throws Exception
close
in interface AutoCloseable
Exception
public com.fasterxml.jackson.databind.ObjectMapper mapper()
StoragePluginRegistry
mapper
in interface StoragePluginRegistry
public <T extends StoragePlugin> T resolve(StoragePluginConfig storageConfig, Class<T> desired)
resolve
in interface StoragePluginRegistry
public <T extends FormatPlugin> T resolveFormat(StoragePluginConfig storageConfig, FormatPluginConfig formatConfig, Class<T> desired)
StoragePluginRegistry
resolveFormat
in interface StoragePluginRegistry
T
- the required type of the pluginstorageConfig
- storage plugin configformatConfig
- format plugin configdesired
- desired target classpublic Set<String> availablePlugins()
StoragePluginRegistry
availablePlugins
in interface StoragePluginRegistry
Copyright © 1970 The Apache Software Foundation. All rights reserved.