package nl.tno.sensorstorm.config; import java.util.HashMap; import java.util.Map; import java.util.Map.Entry; import java.util.concurrent.atomic.AtomicReference; import nl.tno.storm.configuration.api.ConfigurationListener; import nl.tno.storm.configuration.api.StormConfigurationException; import org.slf4j.Logger; import org.slf4j.LoggerFactory; public abstract class ConfigManager implements ConfigurationListener { private final Logger logger = LoggerFactory.getLogger(ConfigManager.class); private final Map<String, AtomicReference<?>> keyValueContainers = new HashMap<String, AtomicReference<?>>(); /** * Register a parameter to be linked to a zookeeper configuration. The key * must match the key name in zookeeper. The value must be stored in a * AtomicReference due to the threading issues between zookeeper and storm. * * @param key * @param keyValueContainer * @throws StormConfigurationException */ public void registerParameter(String key, AtomicReference<?> keyValueContainer) throws StormConfigurationException { if (keyValueContainer == null) { throw new StormConfigurationException( "keyValueContainer may not be null."); } if (canHandleAtomicReference(keyValueContainer)) { keyValueContainers.put(key, keyValueContainer); } else { throw new StormConfigurationException( "Value type is unsupported (must be a String, Double, Long)"); } } /** * Unregister a parameter, so that its AtomicReference will no longer be * updated. * * @param key */ public void unregisterParameter(String key) { keyValueContainers.remove(key); } @Override public void configurationChanged(Map<String, String> newConfiguration) { for (Entry<String, String> keyValueContainer : newConfiguration .entrySet()) { setKeyValueContainer(keyValueContainer.getKey(), keyValueContainer.getValue()); } } private boolean canHandleAtomicReference( AtomicReference<?> keyValueContainer) { if (keyValueContainer.get() instanceof Long) { return true; } else if (keyValueContainer.get() instanceof Double) { return true; } else if (keyValueContainer.get() instanceof String) { return true; } else { return false; } } @SuppressWarnings("unchecked") private void setKeyValueContainer(String key, String value) { AtomicReference<?> keyValueContainer = keyValueContainers.get(key); if (keyValueContainer == null) return; try { if (keyValueContainer.get() instanceof Long) { ((AtomicReference<Long>) keyValueContainer).set(Long .parseLong(value)); } else if (keyValueContainer.get() instanceof Double) { ((AtomicReference<Double>) keyValueContainer).set(Double .parseDouble(value)); } else if (keyValueContainer.get() instanceof String) { ((AtomicReference<String>) keyValueContainer).set(value); } else { logger.error("Can not convert configuration parameter [" + key + ", " + value + "] into its container"); } } catch (NumberFormatException e) { logger.error("Can not set config parameter " + key + " of type " + keyValueContainer.get().getClass().getName() + " to value " + value + " msg=" + e); } } }