Maintaining a Connector Configuration across Versions

The following code sample shows how to implement the upgrade-config capability in your connector.

For more information about this command, see Upgrading a Connector in the Exalead CloudView Administration Guide.

package com.exalead;

import com.exalead.mercury.component.*;
import com.exalead.mercury.component.config.CVComponentConfig;
import com.exalead.papi.framework.connectors.Connector;
import com.exalead.papi.framework.connectors.ConnectorConfig;
import com.exalead.papi.framework.connectors.introspection.UpgradeConfig;

import exa.bee.KeyValue;

@IntrospectableComponent(
    // register the {@link MyUpgradableConnector.Introspector} class to handle introspection queries
    introspectorClass=MyUpgradableConnector.Introspector.class,
    // tells CloudView this connector supports the config upgrade capability
    supportedQueries={ @SupportedQuery(queryClass=UpgradeConfig.class)})
public class MyUpgradableConnector extends Connector {
    public MyUpgradableConnector(final ConnectorConfig config) throws Exception {
        super(config);
    }

    public static class Introspector implements CVComponentIntrospector {
        // Member method called to process introspection queries.
        @Override
        public Object execute(
                final CVComponentConfig componentConfig,
                final IntrospectionQuery query) throws Exception {
            if (query instanceof UpgradeConfig) {
                final UpgradeConfig up = (UpgradeConfig) query;
                System.out.println("Updating configuration of connector " + up.getConnectorName());
        //Specify the component versions explicitly and the dependencies to perform the upgrade
        //The following example shows how to upgrade from version 1.0 to 2.0 if you need
        // an intermediary upgrade to version 1.1
        //You can either upgrade from 1.0 to 2.0 OR from 1.1 to 2.0
        //CAUTION: As by default CloudView is not able to provide the previous connector version (1.0 or 1.1)
        //to this method, if you choose to migrate from 1.1 to 2.0, the same code will be called.
        //In our example, it will execute the upgrade operation starting from 1.0.
               applyChangesFrom_1_0To1_1(up.getCurrentConfig());
                applyChangesFrom_1_1To2_0(up.getCurrentConfig());
                return up.getCurrentConfig();
            }
            return null;
        }
        void applyChangesFrom_1_0To1_1(final KeyValue config) {
            renameKey(config, "Foo", "Bar");
        }
        void applyChangesFrom_1_1To2_0(final KeyValue config) {
        // [...] apply required changes. For example, if version 2.0 is multithreaded and 
        // you need to set up the threadPoolSize property...
        }

        /**
          * Recursively look for a key in the connector configuration, and rename it to another value.
          * @param config The configuration to upgrade
          * @param prevKey The configuration key name to replace
          * @param newKey The new key value
          * @return The updated configuration
          */
        public KeyValue renameKey(final KeyValue config, final String prevKey, String newKey) {
            if (config.getKey() != null) {
                if (config.getKey().equals(prevKey)) {
                    config.setKey(newKey);
                }
            }
            for (int i = 0; i < config.getKeyValue().size(); ++i) {
                config.getKeyValue().set(i, renameKey(config.getKeyValue().get(i), prevKey, newKey));
            }
            return config;
        }
    }
}