}
+ public boolean isStrategyConfigured(String entityType){
+ return entityTypeToStrategyInfo.get(entityType) != null;
+ }
+
public EntityOwnerSelectionStrategy createStrategy(String entityType){
final EntityOwnerSelectionStrategy strategy;
final EntityOwnerSelectionStrategy existingStrategy = entityTypeToOwnerSelectionStrategy.get(entityType);
--- /dev/null
+/*
+ * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.controller.cluster.datastore.entityownership.selectionstrategy;
+
+import com.google.common.base.Preconditions;
+import java.io.IOException;
+import java.util.Dictionary;
+import java.util.Enumeration;
+import javax.annotation.Nullable;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.ServiceReference;
+import org.osgi.service.cm.Configuration;
+import org.osgi.service.cm.ConfigurationAdmin;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class EntityOwnerSelectionStrategyConfigReader {
+ public static final String CONFIG_ID = "org.opendaylight.controller.cluster.entity-owner-selection-strategies";
+
+ private static final Logger LOG = LoggerFactory.getLogger(EntityOwnerSelectionStrategyConfigReader.class);
+ private final BundleContext bundleContext;
+ private final EntityOwnerSelectionStrategyConfig config;
+
+ public EntityOwnerSelectionStrategyConfigReader(BundleContext bundleContext) {
+ this.bundleContext = Preconditions.checkNotNull(bundleContext);
+ ServiceReference<ConfigurationAdmin> configAdminServiceReference =
+ bundleContext.getServiceReference(ConfigurationAdmin.class);
+ if(configAdminServiceReference == null) {
+ LOG.warn("No ConfigurationAdmin service found");
+ this.config = EntityOwnerSelectionStrategyConfig.newBuilder().build();
+ } else {
+ this.config = readConfiguration(configAdminServiceReference);
+ }
+ }
+
+ private EntityOwnerSelectionStrategyConfig readConfiguration(ServiceReference<ConfigurationAdmin> configAdminServiceReference) {
+ EntityOwnerSelectionStrategyConfig.Builder builder = EntityOwnerSelectionStrategyConfig.newBuilder();
+ ConfigurationAdmin configAdmin = null;
+ try {
+ configAdmin = bundleContext.getService(configAdminServiceReference);
+ Dictionary<String, Object> properties = getProperties(configAdmin);
+ if(properties != null) {
+ Enumeration<String> keys = properties.keys();
+ while (keys.hasMoreElements()) {
+ String key = keys.nextElement();
+ String strategyProps = (String) properties.get(key);
+ String[] strategyClassAndDelay = strategyProps.split(",");
+ if(strategyClassAndDelay.length >= 1) {
+ @SuppressWarnings("unchecked")
+ Class<? extends EntityOwnerSelectionStrategy> aClass
+ = (Class<? extends EntityOwnerSelectionStrategy>) getClass().getClassLoader().loadClass(strategyClassAndDelay[0]);
+ long delay = 0;
+ if(strategyClassAndDelay.length > 1){
+ delay = Long.parseLong(strategyClassAndDelay[1]);
+ }
+ builder.addStrategy(key, aClass, delay);
+ }
+ }
+ }
+ } catch(Exception e){
+ LOG.warn("Failed to read selection strategy configuration file. All configuration will be ignored.", e);
+ } finally {
+ if(configAdmin != null) {
+ try {
+ bundleContext.ungetService(configAdminServiceReference);
+ } catch (Exception e) {
+ LOG.debug("Error from ungetService", e);
+ }
+ }
+ }
+
+ return builder.build();
+ }
+
+ @Nullable
+ private static Dictionary<String, Object> getProperties(ConfigurationAdmin configAdmin) throws IOException {
+ Configuration config = configAdmin.getConfiguration(CONFIG_ID);
+ return config != null ? config.getProperties() : null;
+ }
+
+ public EntityOwnerSelectionStrategyConfig getConfig() {
+ return config;
+ }
+}
import org.opendaylight.controller.cluster.datastore.DistributedDataStore;
import org.opendaylight.controller.cluster.datastore.entityownership.DistributedEntityOwnershipService;
import org.opendaylight.controller.cluster.datastore.entityownership.selectionstrategy.EntityOwnerSelectionStrategyConfig;
+import org.opendaylight.controller.cluster.datastore.entityownership.selectionstrategy.EntityOwnerSelectionStrategyConfigReader;
import org.opendaylight.controller.sal.core.spi.data.DOMStore;
+import org.osgi.framework.BundleContext;
public class DistributedEntityOwnershipServiceProviderModule extends org.opendaylight.controller.config.yang.config.distributed_entity_ownership_service.AbstractDistributedEntityOwnershipServiceProviderModule {
+ private BundleContext bundleContext;
+
public DistributedEntityOwnershipServiceProviderModule(org.opendaylight.controller.config.api.ModuleIdentifier identifier, org.opendaylight.controller.config.api.DependencyResolver dependencyResolver) {
super(identifier, dependencyResolver);
}
DOMStore dataStore = getDataStoreDependency();
Preconditions.checkArgument(dataStore instanceof DistributedDataStore,
"Injected DOMStore must be an instance of DistributedDataStore");
- DistributedEntityOwnershipService service = new DistributedEntityOwnershipService((DistributedDataStore)dataStore, EntityOwnerSelectionStrategyConfig.newBuilder().build());
+ EntityOwnerSelectionStrategyConfig strategyConfig = new EntityOwnerSelectionStrategyConfigReader(bundleContext).getConfig();
+ DistributedEntityOwnershipService service = new DistributedEntityOwnershipService((DistributedDataStore)dataStore, strategyConfig);
service.start();
return service;
}
+
+ public void setBundleContext(BundleContext bundleContext) {
+ this.bundleContext = bundleContext;
+ }
}
* Do not modify this file unless it is present under src/main directory
*/
package org.opendaylight.controller.config.yang.config.distributed_entity_ownership_service;
+
+import org.opendaylight.controller.config.api.DependencyResolver;
+import org.opendaylight.controller.config.api.DynamicMBeanWithInstance;
+import org.opendaylight.controller.config.spi.Module;
+import org.osgi.framework.BundleContext;
+
public class DistributedEntityOwnershipServiceProviderModuleFactory extends org.opendaylight.controller.config.yang.config.distributed_entity_ownership_service.AbstractDistributedEntityOwnershipServiceProviderModuleFactory {
+ @Override
+ public Module createModule(String instanceName, DependencyResolver dependencyResolver, BundleContext bundleContext) {
+ DistributedEntityOwnershipServiceProviderModule module = (DistributedEntityOwnershipServiceProviderModule) super.createModule(instanceName, dependencyResolver, bundleContext);
+ module.setBundleContext(bundleContext);
+ return module;
+ }
+
+ @Override
+ public Module createModule(String instanceName, DependencyResolver dependencyResolver, DynamicMBeanWithInstance old, BundleContext bundleContext) throws Exception {
+ DistributedEntityOwnershipServiceProviderModule module = (DistributedEntityOwnershipServiceProviderModule) super.createModule(instanceName, dependencyResolver, old, bundleContext);
+ module.setBundleContext(bundleContext);
+ return module;
+ }
}
--- /dev/null
+/*
+ * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.controller.cluster.datastore.entityownership.selectionstrategy;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.doThrow;
+import java.io.IOException;
+import java.util.Hashtable;
+import org.junit.Before;
+import org.junit.Test;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.ServiceReference;
+import org.osgi.service.cm.Configuration;
+import org.osgi.service.cm.ConfigurationAdmin;
+
+public class EntityOwnerSelectionStrategyConfigReaderTest {
+ @Mock
+ private BundleContext mockBundleContext;
+
+ @Mock
+ private ServiceReference<ConfigurationAdmin> mockConfigAdminServiceRef;
+
+ @Mock
+ private ConfigurationAdmin mockConfigAdmin;
+
+ @Mock
+ private Configuration mockConfig;
+
+ @Before
+ public void setup() throws IOException {
+ MockitoAnnotations.initMocks(this);
+
+ doReturn(mockConfigAdminServiceRef).when(mockBundleContext).getServiceReference(ConfigurationAdmin.class);
+ doReturn(mockConfigAdmin).when(mockBundleContext).getService(mockConfigAdminServiceRef);
+
+ doReturn(mockConfig).when(mockConfigAdmin).getConfiguration(EntityOwnerSelectionStrategyConfigReader.CONFIG_ID);
+ }
+
+ @Test
+ public void testReadStrategies(){
+ Hashtable<String, Object> props = new Hashtable<>();
+ props.put("test", "org.opendaylight.controller.cluster.datastore.entityownership.selectionstrategy.LastCandidateSelectionStrategy,100");
+
+ doReturn(props).when(mockConfig).getProperties();
+
+ EntityOwnerSelectionStrategyConfig config = new EntityOwnerSelectionStrategyConfigReader(mockBundleContext).getConfig();
+
+ assertTrue(config.isStrategyConfigured("test"));
+
+ EntityOwnerSelectionStrategy strategy = config.createStrategy("test");
+ assertTrue(strategy instanceof LastCandidateSelectionStrategy);
+ assertEquals(100L, strategy.getSelectionDelayInMillis());
+ }
+
+ @Test
+ public void testReadStrategiesWithIOException() throws IOException {
+ doThrow(IOException.class).when(mockConfigAdmin).getConfiguration(EntityOwnerSelectionStrategyConfigReader.CONFIG_ID);
+
+ EntityOwnerSelectionStrategyConfig config = new EntityOwnerSelectionStrategyConfigReader(mockBundleContext).getConfig();
+
+ assertFalse(config.isStrategyConfigured("test"));
+ }
+
+ @Test
+ public void testReadStrategiesWithNullConfiguration() throws IOException {
+ doReturn(null).when(mockConfigAdmin).getConfiguration(EntityOwnerSelectionStrategyConfigReader.CONFIG_ID);
+
+ EntityOwnerSelectionStrategyConfig config = new EntityOwnerSelectionStrategyConfigReader(mockBundleContext).getConfig();
+
+ assertFalse(config.isStrategyConfigured("test"));
+ }
+
+ @Test
+ public void testReadStrategiesWithNullConfigurationProperties() throws IOException {
+ doReturn(null).when(mockConfig).getProperties();
+
+ EntityOwnerSelectionStrategyConfig config = new EntityOwnerSelectionStrategyConfigReader(mockBundleContext).getConfig();
+
+ assertFalse(config.isStrategyConfigured("test"));
+ }
+
+ @Test
+ public void testReadStrategiesInvalidDelay(){
+ Hashtable<String, Object> props = new Hashtable<>();
+ props.put("test", "org.opendaylight.controller.cluster.datastore.entityownership.selectionstrategy.LastCandidateSelectionStrategy,foo");
+
+ doReturn(props).when(mockConfig).getProperties();
+
+ EntityOwnerSelectionStrategyConfig config = new EntityOwnerSelectionStrategyConfigReader(mockBundleContext).getConfig();
+
+ assertFalse(config.isStrategyConfigured("test"));
+ }
+
+ @Test
+ public void testReadStrategiesInvalidClassType(){
+ Hashtable<String, Object> props = new Hashtable<>();
+ props.put("test", "String,100");
+
+ doReturn(props).when(mockConfig).getProperties();
+
+ EntityOwnerSelectionStrategyConfig config = new EntityOwnerSelectionStrategyConfigReader(mockBundleContext).getConfig();
+
+ assertFalse(config.isStrategyConfigured("test"));
+ }
+
+ @Test
+ public void testReadStrategiesMissingDelay(){
+ Hashtable<String, Object> props = new Hashtable<>();
+ props.put("test", "org.opendaylight.controller.cluster.datastore.entityownership.selectionstrategy.LastCandidateSelectionStrategy,100");
+ props.put("test1", "org.opendaylight.controller.cluster.datastore.entityownership.selectionstrategy.LastCandidateSelectionStrategy");
+
+ doReturn(props).when(mockConfig).getProperties();
+
+ EntityOwnerSelectionStrategyConfig config = new EntityOwnerSelectionStrategyConfigReader(mockBundleContext).getConfig();
+
+ assertEquals(100, config.createStrategy("test").getSelectionDelayInMillis());
+ assertEquals(0, config.createStrategy("test2").getSelectionDelayInMillis());
+ }
+
+}
\ No newline at end of file