You are viewing the RapidMiner Developers documentation for version 10.0 - Check here for latest version
Converting Legacy Configurators to New Connection Management
Up until now, we had three separate connection types: JDBC connections for databases, Configurables and Configurators for "simple" property based connections like Twitter or any of the cloud connections, and Radoop, which has more extra files and configurations. To streamline this, we moved to the new connection management in 9.3 that can serve all three purposes with the added benefit of being able to use different driver versions for JDBC for each connection.
This is a guide how to move legacy configurator connections to the new connection management, using some helper classes for minimal effort. You can follow along the changes with the provided extension project, which showcases a small feature set of the new connections and its UI. It also provides a git history so you can follow along step by step. We recommend to build your extension against RapidMiner Studio 9.6.0, which has some more convenience methods than the original introduction of the new connection management (9.3.0). This is especially helpful for the UI.
Using the following steps you get a lot of things "for free", including a nice convert button in the old configurator UI, so users can easily move to the new connection management without retyping all configurations. It is still possible that passwords or api keys might break and need to be set in the new connection again. Make sure to test the connection after conversion.
Change the super class of your Configurable from
AbstractConfigurable
toConnectionAdapter
Change the super class of your Configurator from
AbstractConfigurator
toConnectionAdapterHandler
- Add a public default constructor that calls the super constructor with the namespace of your extension
(e.g.
cloud_connectivity
for the Cloud Connectivity extension). Best practice is to have the namespace as a constant in thePluginInit* class
. An alternative to the public constructor is to make the class a singleton. - Override the
parametersByGroup
method if you want to split up your parameters; this must include all keys available through thegetParameterTypes
method. By default, all parameters are in the group with the key "basic". - Implement the
test
andvalidate
methods if you need specialty checks; These methods are called when your connection should be saved (validate
) or you want to test your connection (test
). The test method is exposed through a button in the UI. There is a default implementation provided for both methods. In general the fast validation method only checks on the surface, e.g. if all needed parameters are set. The test method includes more time consuming checks, it uses the injection mechanism and tests the actual connection. There is no need to call the validation inside the testing. If your old configurator provided a test action, you do not need to override this method. - If you had additional actions, you can override
getAdditionalActions
to make them known in the new system, too. Make sure you actually need those additional actions. (Currently, this does not appear in the UI if you do not implement that yourself!)
- Add a public default constructor that calls the super constructor with the namespace of your extension
(e.g.
Register the Configurator with
ConnectionAdapterHandler.registerHandler
instead of registering it with theConfigurationManager
(usually done in thePluginInit*
class). The registration withConfigurationManager
will be done implicitly, so if it might get removed in a future version, you do not have to take care of that.Adapt each associated operator and other related classes
The operator needs to implement
ConnectionSelectionProvider
. The methods of this interface are accessed by the framework itself, so the only thing you need to do is to add a privateConnectionInformationSelector
field in your operator class and use it in the two method implementations. If you need something more sophisticated, you can create and set it in the operator constructor yourself or even create your own subclass if necessary. See also the javadoc forgetConnectionParameters
to get more information.If the hands-off approach is chosen, the selector will add a pass through port pair to your operator (both called "connection") and will automatically pass data through when you request the connection adapter (see 4.4).
Change the associated parameters for your operator. Create the old parameter (of type
ParameterTypeConfigurable
), and callConnectionAdapterHandler.getConnectionParameters
with the appropriate arguments. This will give you a list of parameter types, namely a dropdown to choose between predefined and repository, the old parameter and the new connection location parameter. The default value depends on the compatibility level of the operator, see the next step for details; predefined will be selected to keep compatibility to older versions, but new operators will have "repository" preselected. Add this list to your parameter type list instead of the old connection parameterParameterTypeConfigurable configurable = new ParameterTypeConfigurable("old_parameter_key", "Old description", TYPE_ID); parameterTypes.addAll(ConnectionAdapterHandler.getConnectionParameters(this, TYPE_ID, configurable)));
Note: Make sure that the old parameter did not have the key "connection_source" or "connection_entry"! If that is the case, we recommend to deprecate the old operator (and keep it for compatibility) and create a new one that only accepts the connection repository objects. See the documentation for details how to setup the selector and the parameters.
(Optional) Add a new compatibility level to your operator, namely
ConnectionHandlerRegistry.BEFORE_NEW_CONNECTION_MANAGEMENT
(RapidMiner version 9.2.1). It can look something like this:@Override public OperatorVersion[] getIncompatibleVersionChanges() { return (OperatorVersion[]) ArrayUtils.add(super.getIncompatibleVersionChanges(), ConnectionHandlerRegistry.BEFORE_NEW_CONNECTION_MANAGEMENT); }
As described above, this will change which connection source will be preselected. If your extension version does not correspond to the RapidMiner version (e.g. your extension is version 2.1.0), this will have no effect. But there should be a warning on your operator automatically to encourage people to use the new connection management.
- Check your
doWork
method and metadata transformation forConfigurationManager.getInstance().lookup
calls and replace them with appropriateConnectionAdapterHandler.getAdapter
calls. This is also relevant for other classes/places where the lookup is used! ThetypeID
stays the same as before, but you will also need to provide the key (not the value!) of the old parameter (see step 4.2) ). To make sure to capture errors regarding mismatched connection types or wrong repository entries, add a new meta data transformation rule in the constructor of your operator, with the following call:
getTransformer().addRule(ConnectionAdapterHandler.createProcessSetupRule(this));
Create all relevant i18n keys (the namespace referenced here is the namespace of your extension)
You can use a helper class like the following that depends on
CreateI18NKeysForConnectionHandler
to create the initial i18n keys that might be necessary. This will reuse a lot of i18n/descriptions from the old configurable where possible. Make sure to proofread those generated i18n mappings for validity!import static com.rapidminer.connection.CreateI18NKeysForConnectionHandler.appendOrReplaceConnectionKeys; import static com.rapidminer.connection.CreateI18NKeysForConnectionHandler.connectionAdaptionHandlerDefaultValues; import java.io.IOException; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; import java.nio.file.StandardCopyOption; import java.util.Properties; import java.util.function.BiFunction; /** * Helper class to update Gui*.properties file with connection keys */ public class I18NHelper { /** * Run this to update the GUI*.properties file * * @see com.rapidminer.connection.CreateI18NKeysForConnectionHandler CreateI18NKeysForConnectionHandler */ public static void main(String[] args) throws IOException { Runnable initializer = PluginInit<ExtensionName>::initPlugin; String namespace = PluginInit<ExtensionName>.NAMESPACE; Path propertyPath = Paths.get("src/main/resources/com/rapidminer/extension/resources/i18n/GUI<ExtensionName>.properties").toAbsolutePath(); BiFunction<String, Properties, String> defaultValues = connectionAdaptionHandlerDefaultValues(namespace); Path newPath = appendOrReplaceConnectionKeys(initializer, namespace, propertyPath, defaultValues); if (newPath == null) { return; } Files.copy(Files.newInputStream(newPath), propertyPath, StandardCopyOption.REPLACE_EXISTING); } }
The helper class will create a backup of the old file (file ending .bak) and the new file (file ending .new) and overwrite the original with the new version.
- You can reuse the icon (needed in 16px and @2x) and name you used for the configurable; the old key was
gui.configurable.{baseKey}.[icon|name]
, the new one isgui.label.connection.type.{namespace}.{type}.[icon|label]
Each group and parameter can be i18n resolved, by the keygui.label.connection.[group|parameter].{namespace}.{type}.{group}.[{parameter}].[label|tip|icon]
For more information, look at the class ConnectionI18N or see the documentation on i18n.
Register the Configurator with the default UI or write your own. The registration is typically done in the
PluginInit*.initGUI
method. For more details, see the general UI section. The example project mentioned in the beginning shows a basic implementation, including a combo box, checkbox and dependencies.If you don't have any specific needs and just want a label/textfield style UI, you don't have to do anything, but we recommend registering the default UI anyway to prevent warnings in the log file.
ConnectionGUIRegistry.INSTANCE.registerGUIProvider(new DefaultConnectionGUIProvider(), <namespace:typeID>);
- If you want still a simple, but not too involved UI, you can subclass the DefaultConnectionGui[Provider] and register that.
- If you want to have a fully customized UI, override AbstractConnectionGUI and register that.
Lastly, update all operator documentation! This could look something like this: