net.anotheria.extensions.php.ConfigBootstrapper Maven / Gradle / Ivy
package net.anotheria.extensions.php;
import net.anotheria.extensions.php.config.ConfigChangedNotifier;
import net.anotheria.extensions.php.config.ConnectorConfig;
import net.anotheria.extensions.php.config.MapperConfig;
import net.anotheria.extensions.php.config.MoskitoPHPConfig;
import net.anotheria.extensions.php.connectors.Connector;
import net.anotheria.extensions.php.exceptions.ConnectorInitException;
import net.anotheria.extensions.php.exceptions.PHPPluginBootstrapException;
import net.anotheria.extensions.php.mappers.Mapper;
import net.anotheria.moskito.core.registry.IProducerRegistry;
import org.configureme.ConfigurationManager;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.util.Properties;
/**
* Processes Moskito PHP plugin configuration.
* Loads mappers and connectors and wires them together
*/
class ConfigBootstrapper {
private final static Logger log = LoggerFactory.getLogger(ConfigBootstrapper.class);
private ConnectorsRegistry connectorsRegistry = new ConnectorsRegistry();
private MoskitoPHPConfig config;
private OnProducerDataReceivedListener listener;
private Properties startupProperties;
private static final String PROPERTY_CONNECTORS_FORCE_ENABLED = "forceEnablePHPConnectors";
private static final String PROPERTY_TRUE_VALUE = "true";
ConfigBootstrapper(String configurationName) {
config = new MoskitoPHPConfig();
ConfigurationManager.INSTANCE.configureAs(config, configurationName);
startupProperties = new Properties();
startupProperties.put(PROPERTY_CONNECTORS_FORCE_ENABLED,
System.getProperty(PROPERTY_CONNECTORS_FORCE_ENABLED, "false")
);
}
/**
* Helper method for mappers and connectors classes instantiation
* @param className name of class to create instance
* @return given class by name instance
*
* @throws ClassNotFoundException on given class not found
* @throws NoSuchMethodException if default constructor not found in given class
* @throws IllegalAccessException if default constructor in given class has non-public access
* @throws InvocationTargetException if given class constructor throws an exception
* @throws InstantiationException on given class instantiation fail
*/
private static Object createInstance(String className)
throws ClassNotFoundException, NoSuchMethodException,
IllegalAccessException, InvocationTargetException,
InstantiationException {
Class> clazz = Class.forName(className);
Constructor> constructor = clazz.getConstructor();
return constructor.newInstance();
}
private Connector createConnector(ConnectorConfig config, OnProducerDataReceivedListener listener)
throws ClassNotFoundException, NoSuchMethodException,
InvocationTargetException, InstantiationException,
IllegalAccessException, ClassCastException {
Connector connector = (Connector) createInstance(config.getConnectorClass());
connector.setOnProducerDataReceivedListener(listener);
return connector;
}
/**
* Bootstraps Moskito PHP plugin
*
* @param producerRegistry producer registry to use
* @throws PHPPluginBootstrapException on invalid configuration
*/
void bootstrapPlugin(IProducerRegistry producerRegistry) throws PHPPluginBootstrapException {
config.setConfigChangedNotifier(new ConfigChangedNotifierImpl());
MappersRegistry mappersRegistry = new MappersRegistry();
listener = new OnProducerDataReceivedListenerImpl(mappersRegistry, producerRegistry);
for (MapperConfig mapperConfig : config.getMappers()) {
try {
mappersRegistry.registerMapper(
mapperConfig.getMapperId(),
((Mapper) createInstance(mapperConfig.getMapperClass()))
);
} catch (ClassNotFoundException e) {
throw new PHPPluginBootstrapException(
"Mapper class " + mapperConfig.getMapperClass() + " not found", e
);
} catch (NoSuchMethodException | IllegalAccessException e) {
throw new PHPPluginBootstrapException(
"Mapper class must have default public constructor", e
);
} catch (InvocationTargetException e) {
throw new PHPPluginBootstrapException(
"Mapper constructor throws exception", e
);
} catch (InstantiationException e) {
throw new PHPPluginBootstrapException(
"Failed to instance mapper of class " + mapperConfig.getMapperClass(), e
);
} catch (ClassCastException e) {
throw new PHPPluginBootstrapException(
"Class " + mapperConfig.getMapperClass() +
" is not instance of " + Mapper.class.getCanonicalName(), e
);
}
}
boolean enableConnectorsInitOnStartup
= PROPERTY_TRUE_VALUE.equals(startupProperties.getProperty(PROPERTY_CONNECTORS_FORCE_ENABLED));
configureConnectors(enableConnectorsInitOnStartup);
}
private void updatePlugin() {
configureConnectors(false);
}
void destroyPlugin() {
connectorsRegistry.disableAllConnectors();
}
private void configureConnectors(boolean forceEnable) {
for (ConnectorConfig connectorConfig : config.getConnectors()) {
if (!connectorsRegistry.connectorExists(connectorConfig.getConnectorClass())) {
Connector connector = null;
try {
connector = createConnector(connectorConfig, listener);
} catch (ClassNotFoundException e) {
log.error(
"Connector class " + connectorConfig.getConnectorClass() + " not found", e
);
} catch (NoSuchMethodException | IllegalAccessException e) {
log.error(
"Connector class must have default public constructor", e
);
} catch (InvocationTargetException e) {
log.error(
"Connector constructor throws exception", e
);
} catch (InstantiationException e) {
log.error(
"Failed to instance connector of class " + connectorConfig.getConnectorClass(), e
);
} catch (ClassCastException e) {
log.error(
"Class " + connectorConfig.getConnectorClass() +
" is not instance of " + Connector.class.getCanonicalName(), e
);
}
connectorsRegistry.addConnector(connector);
}
if (forceEnable || connectorConfig.isEnabled()) {
Properties connectorProperties = new Properties();
connectorProperties.putAll(connectorConfig.getConnectorProperties());
try {
connectorsRegistry.enableConnector(
connectorConfig.getConnectorClass(),
connectorProperties
);
} catch (ConnectorInitException e) {
log.error("Failed to init connector " + connectorConfig.getConnectorClass(), e);
}
}
else {
connectorsRegistry.disableConnector(connectorConfig.getConnectorClass());
}
}
}
class ConfigChangedNotifierImpl implements ConfigChangedNotifier {
public void notifyConfigChanged() {
updatePlugin();
}
}
}