Eliminate DatastoreContext CSS dependency 83/72483/3
authorTom Pantelis <tompantelis@gmail.com>
Wed, 30 May 2018 01:31:48 +0000 (21:31 -0400)
committerRobert Varga <nite@hq.sk>
Fri, 1 Jun 2018 12:37:32 +0000 (12:37 +0000)
The CSS-generated Config/OperatonalProperties classes were
used to obtain the default values from the yang. That is now
done by creating an empty container NormalizedNode and running
it thru BindingNormalizedNodeSerializer#fromNormalizedNode to
fill in the default values which are then injected into the
DatastoreContext builder via reflection.

Change-Id: I0963dfcf7850b705d048030056f4b233cc7e4566
Signed-off-by: Tom Pantelis <tompantelis@gmail.com>
opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/datastore/DatastoreContextIntrospector.java
opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/datastore/DatastoreContextIntrospectorFactory.java [new file with mode: 0644]
opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/config/yang/config/distributed_datastore_provider/DistributedConfigDataStoreProviderModule.java
opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/config/yang/config/distributed_datastore_provider/DistributedOperationalDataStoreProviderModule.java
opendaylight/md-sal/sal-distributed-datastore/src/main/resources/org/opendaylight/blueprint/clustered-datastore.xml
opendaylight/md-sal/sal-distributed-datastore/src/main/yang/distributed-datastore-provider.yang
opendaylight/md-sal/sal-distributed-datastore/src/test/java/org/opendaylight/controller/cluster/datastore/DatastoreContextContextPropertiesUpdaterTest.java
opendaylight/md-sal/sal-distributed-datastore/src/test/java/org/opendaylight/controller/cluster/datastore/DatastoreContextIntrospectorTest.java

index e8fce52..8b34f9d 100644 (file)
@@ -20,18 +20,26 @@ import java.beans.PropertyDescriptor;
 import java.lang.reflect.Constructor;
 import java.lang.reflect.InvocationTargetException;
 import java.lang.reflect.Method;
+import java.util.AbstractMap.SimpleImmutableEntry;
 import java.util.ArrayList;
 import java.util.Collection;
 import java.util.Collections;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
+import java.util.Map.Entry;
 import java.util.Set;
 import javax.annotation.concurrent.GuardedBy;
 import org.apache.commons.lang3.StringUtils;
 import org.apache.commons.text.WordUtils;
 import org.opendaylight.controller.cluster.datastore.DatastoreContext.Builder;
+import org.opendaylight.mdsal.binding.dom.codec.api.BindingNormalizedNodeSerializer;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.config.distributed.datastore.provider.rev140612.DataStoreProperties;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.config.distributed.datastore.provider.rev140612.DataStorePropertiesContainer;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.opendaylight.yangtools.yang.binding.util.BindingReflections;
+import org.opendaylight.yangtools.yang.common.QName;
+import org.opendaylight.yangtools.yang.data.impl.schema.ImmutableNodes;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -43,7 +51,7 @@ import org.slf4j.LoggerFactory;
 public class DatastoreContextIntrospector {
     private static final Logger LOG = LoggerFactory.getLogger(DatastoreContextIntrospector.class);
 
-    private static final Map<String, Class<?>> DATA_STORE_PROP_TYPES = new HashMap<>();
+    private static final Map<String, Entry<Class<?>, Method>> DATA_STORE_PROP_INFO = new HashMap<>();
 
     private static final Map<Class<?>, Constructor<?>> CONSTRUCTORS = new HashMap<>();
 
@@ -105,7 +113,7 @@ public class DatastoreContextIntrospector {
     private static void introspectDataStoreProperties() throws IntrospectionException {
         final BeanInfo beanInfo = Introspector.getBeanInfo(DataStoreProperties.class);
         for (final PropertyDescriptor desc: beanInfo.getPropertyDescriptors()) {
-            processDataStoreProperty(desc.getName(), desc.getPropertyType());
+            processDataStoreProperty(desc.getName(), desc.getPropertyType(), desc.getReadMethod());
         }
 
         // Getter methods that return Boolean and start with "is" instead of "get" aren't recognized as
@@ -116,7 +124,7 @@ public class DatastoreContextIntrospector {
             final String methodName = desc.getName();
             if (Boolean.class.equals(desc.getMethod().getReturnType()) && methodName.startsWith("is")) {
                 final String propertyName = WordUtils.uncapitalize(methodName.substring(2));
-                processDataStoreProperty(propertyName, Boolean.class);
+                processDataStoreProperty(propertyName, Boolean.class, desc.getMethod());
             }
         }
     }
@@ -125,13 +133,13 @@ public class DatastoreContextIntrospector {
      * Processes a property defined on the DataStoreProperties interface.
      */
     @SuppressWarnings("checkstyle:IllegalCatch")
-    private static void processDataStoreProperty(final String name, final Class<?> propertyType) {
+    private static void processDataStoreProperty(final String name, final Class<?> propertyType, Method readMethod) {
         Preconditions.checkArgument(BUILDER_SETTERS.containsKey(name), String.format(
                 "DataStoreProperties property \"%s\" does not have corresponding setter in DatastoreContext.Builder",
                 name));
         try {
             processPropertyType(propertyType);
-            DATA_STORE_PROP_TYPES.put(name, propertyType);
+            DATA_STORE_PROP_INFO.put(name, new SimpleImmutableEntry<>(propertyType, readMethod));
         } catch (final Exception e) {
             LOG.error("Error finding constructor for type {}", propertyType, e);
         }
@@ -191,8 +199,30 @@ public class DatastoreContextIntrospector {
     @GuardedBy(value = "this")
     private Map<String, Object> currentProperties;
 
-    public DatastoreContextIntrospector(final DatastoreContext context) {
-        this.context = context;
+    public DatastoreContextIntrospector(final DatastoreContext context,
+            final BindingNormalizedNodeSerializer bindingSerializer) {
+        final QName qname = BindingReflections.findQName(DataStorePropertiesContainer.class);
+        final DataStorePropertiesContainer defaultPropsContainer = (DataStorePropertiesContainer)
+                bindingSerializer.fromNormalizedNode(bindingSerializer.toYangInstanceIdentifier(
+                        InstanceIdentifier.builder(DataStorePropertiesContainer.class).build()),
+                ImmutableNodes.containerNode(qname)).getValue();
+
+        final Builder builder = DatastoreContext.newBuilderFrom(context);
+        for (Entry<String, Entry<Class<?>, Method>> entry: DATA_STORE_PROP_INFO.entrySet()) {
+            Object value;
+            try {
+                value = entry.getValue().getValue().invoke(defaultPropsContainer);
+            } catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException e) {
+                LOG.error("Error obtaining default value for property {}", entry.getKey(), e);
+                value = null;
+            }
+
+            if (value != null) {
+                convertValueAndInvokeSetter(entry.getKey(), value, builder);
+            }
+        }
+
+        this.context = builder.build();
     }
 
     public synchronized DatastoreContext getContext() {
@@ -222,7 +252,7 @@ public class DatastoreContextIntrospector {
 
             if (key.startsWith(shardNamePrefix)) {
                 key = key.replaceFirst(shardNamePrefix, "");
-                convertValueAndInvokeSetter(key, value, builder);
+                convertValueAndInvokeSetter(key, value.toString(), builder);
             }
         }
 
@@ -262,7 +292,7 @@ public class DatastoreContextIntrospector {
                 key = key.replaceFirst(dataStoreTypePrefix, "");
             }
 
-            if (convertValueAndInvokeSetter(key, value, builder)) {
+            if (convertValueAndInvokeSetter(key, value.toString(), builder)) {
                 updated = true;
             }
         }
@@ -327,19 +357,21 @@ public class DatastoreContextIntrospector {
 
     private Object convertValue(final String name, final Object from)
             throws InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
-        final Class<?> propertyType = DATA_STORE_PROP_TYPES.get(name);
-        if (propertyType == null) {
+        final Entry<Class<?>, Method> propertyInfo = DATA_STORE_PROP_INFO.get(name);
+        if (propertyInfo == null) {
             LOG.debug("Property not found for {}", name);
             return null;
         }
 
+        final Class<?> propertyType = propertyInfo.getKey();
+
         LOG.debug("Type for property {}: {}, converting value {} ({})",
                 name, propertyType.getSimpleName(), from, from.getClass().getSimpleName());
 
         // Recurse the chain of constructors depth-first to get the resulting value. Eg, if the
         // property type is the yang-generated NonZeroUint32Type, it's constructor takes a Long so
         // we have to first construct a Long instance from the input value.
-        Object converted = constructorValueRecursively(propertyType, from.toString());
+        Object converted = constructorValueRecursively(propertyType, from);
 
         // If the converted type is a yang-generated type, call the getter to obtain the actual value.
         final Method getter = YANG_TYPE_GETTERS.get(converted.getClass());
@@ -355,6 +387,10 @@ public class DatastoreContextIntrospector {
         LOG.trace("convertValueRecursively - toType: {}, fromValue {} ({})",
                 toType.getSimpleName(), fromValue, fromValue.getClass().getSimpleName());
 
+        if (toType.equals(fromValue.getClass())) {
+            return fromValue;
+        }
+
         final Constructor<?> ctor = CONSTRUCTORS.get(toType);
 
         LOG.trace("Found {}", ctor);
@@ -365,9 +401,8 @@ public class DatastoreContextIntrospector {
 
         Object value = fromValue;
 
-        // Since the original input type is a String, once we find a constructor that takes a String
-        // argument, we're done recursing.
-        if (!ctor.getParameterTypes()[0].equals(String.class)) {
+        // Once we find a constructor that takes the original type as an argument, we're done recursing.
+        if (!ctor.getParameterTypes()[0].equals(fromValue.getClass())) {
             value = constructorValueRecursively(ctor.getParameterTypes()[0], fromValue);
         }
 
diff --git a/opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/datastore/DatastoreContextIntrospectorFactory.java b/opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/datastore/DatastoreContextIntrospectorFactory.java
new file mode 100644 (file)
index 0000000..1b7c028
--- /dev/null
@@ -0,0 +1,53 @@
+/*
+ * Copyright (c) 2018 Inocybe Technologies 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;
+
+import com.google.common.annotations.VisibleForTesting;
+import javassist.ClassPool;
+import org.opendaylight.mdsal.binding.dom.codec.api.BindingNormalizedNodeSerializer;
+import org.opendaylight.mdsal.binding.dom.codec.gen.impl.StreamWriterGenerator;
+import org.opendaylight.mdsal.binding.dom.codec.impl.BindingNormalizedNodeCodecRegistry;
+import org.opendaylight.mdsal.binding.generator.api.ClassLoadingStrategy;
+import org.opendaylight.mdsal.binding.generator.util.BindingRuntimeContext;
+import org.opendaylight.mdsal.binding.generator.util.JavassistUtils;
+import org.opendaylight.mdsal.common.api.LogicalDatastoreType;
+import org.opendaylight.mdsal.dom.api.DOMSchemaService;
+
+/**
+ * Factory for creating DatastoreContextIntrospector instances.
+ *
+ * @author Thomas Pantelis
+ */
+public class DatastoreContextIntrospectorFactory {
+    private final DOMSchemaService schemaService;
+    private final ClassLoadingStrategy classLoadingStrategy;
+
+    public DatastoreContextIntrospectorFactory(DOMSchemaService schemaService,
+            ClassLoadingStrategy classLoadingStrategy) {
+        this.schemaService = schemaService;
+        this.classLoadingStrategy = classLoadingStrategy;
+    }
+
+    public DatastoreContextIntrospector newInstance(LogicalDatastoreType datastoreType) {
+        return new DatastoreContextIntrospector(DatastoreContext.newBuilder()
+                .logicalStoreType(datastoreType).tempFileDirectory("./data").build(), newBindingSerializer());
+    }
+
+    @VisibleForTesting
+    DatastoreContextIntrospector newInstance(DatastoreContext context) {
+        return new DatastoreContextIntrospector(context, newBindingSerializer());
+    }
+
+    private BindingNormalizedNodeSerializer newBindingSerializer() {
+        BindingNormalizedNodeCodecRegistry codecRegistry = new BindingNormalizedNodeCodecRegistry(
+                StreamWriterGenerator.create(JavassistUtils.forClassPool(ClassPool.getDefault())));
+        codecRegistry.onBindingRuntimeContextUpdated(BindingRuntimeContext.create(classLoadingStrategy,
+                schemaService.getGlobalContext()));
+        return codecRegistry;
+    }
+}
index 79b276d..2163449 100644 (file)
@@ -8,13 +8,11 @@
 
 package org.opendaylight.controller.config.yang.config.distributed_datastore_provider;
 
-import org.opendaylight.controller.cluster.datastore.DatastoreContext;
 import org.opendaylight.controller.cluster.datastore.DistributedDataStoreInterface;
 import org.opendaylight.controller.cluster.datastore.compat.LegacyDOMStoreAdapter;
 import org.opendaylight.controller.config.api.DependencyResolver;
 import org.opendaylight.controller.config.api.ModuleIdentifier;
 import org.opendaylight.controller.config.api.osgi.WaitingServiceTracker;
-import org.opendaylight.mdsal.common.api.LogicalDatastoreType;
 import org.osgi.framework.BundleContext;
 
 @Deprecated
@@ -58,60 +56,6 @@ public class DistributedConfigDataStoreProviderModule extends AbstractDistribute
         };
     }
 
-    public static DatastoreContext newDatastoreContext() {
-        return newDatastoreContext(null);
-    }
-
-    private static DatastoreContext newDatastoreContext(final ConfigProperties inProps) {
-        ConfigProperties props = inProps;
-        if (props == null) {
-            props = new ConfigProperties();
-        }
-
-        return DatastoreContext.newBuilder()
-                .logicalStoreType(LogicalDatastoreType.CONFIGURATION)
-                .tempFileDirectory("./data")
-                .fileBackedStreamingThresholdInMegabytes(props.getFileBackedStreamingThresholdInMegabytes()
-                        .getValue().intValue())
-                .maxShardDataChangeExecutorPoolSize(props.getMaxShardDataChangeExecutorPoolSize().getValue().intValue())
-                .maxShardDataChangeExecutorQueueSize(props.getMaxShardDataChangeExecutorQueueSize()
-                        .getValue().intValue())
-                .maxShardDataChangeListenerQueueSize(props.getMaxShardDataChangeListenerQueueSize()
-                        .getValue().intValue())
-                .maxShardDataStoreExecutorQueueSize(props.getMaxShardDataStoreExecutorQueueSize().getValue().intValue())
-                .shardTransactionIdleTimeoutInMinutes(props.getShardTransactionIdleTimeoutInMinutes().getValue())
-                .operationTimeoutInSeconds(props.getOperationTimeoutInSeconds().getValue())
-                .shardJournalRecoveryLogBatchSize(props.getShardJournalRecoveryLogBatchSize()
-                        .getValue().intValue())
-                .shardSnapshotBatchCount(props.getShardSnapshotBatchCount().getValue().intValue())
-                .shardSnapshotDataThresholdPercentage(props.getShardSnapshotDataThresholdPercentage()
-                        .getValue().intValue())
-                .shardHeartbeatIntervalInMillis(props.getShardHeartbeatIntervalInMillis().getValue())
-                .shardInitializationTimeoutInSeconds(props.getShardInitializationTimeoutInSeconds().getValue())
-                .shardLeaderElectionTimeoutInSeconds(props.getShardLeaderElectionTimeoutInSeconds().getValue())
-                .shardTransactionCommitTimeoutInSeconds(
-                        props.getShardTransactionCommitTimeoutInSeconds().getValue().intValue())
-                .shardTransactionCommitQueueCapacity(
-                        props.getShardTransactionCommitQueueCapacity().getValue().intValue())
-                .persistent(props.getPersistent().booleanValue())
-                .shardIsolatedLeaderCheckIntervalInMillis(
-                    props.getShardIsolatedLeaderCheckIntervalInMillis().getValue())
-                .shardElectionTimeoutFactor(props.getShardElectionTimeoutFactor().getValue())
-                .transactionCreationInitialRateLimit(props.getTransactionCreationInitialRateLimit().getValue())
-                .shardBatchedModificationCount(props.getShardBatchedModificationCount().getValue().intValue())
-                .shardCommitQueueExpiryTimeoutInSeconds(
-                        props.getShardCommitQueueExpiryTimeoutInSeconds().getValue().intValue())
-                .transactionDebugContextEnabled(props.getTransactionDebugContextEnabled())
-                .customRaftPolicyImplementation(props.getCustomRaftPolicyImplementation())
-                .maximumMessageSliceSize(props.getMaximumMessageSliceSize().getValue().intValue())
-                .useTellBasedProtocol(props.getUseTellBasedProtocol())
-                .syncIndexThreshold(props.getSyncIndexThreshold().getValue())
-                .backendAlivenessTimerIntervalInSeconds(props.getBackendAlivenessTimerIntervalInSeconds().getValue())
-                .frontendRequestTimeoutInSeconds(props.getFrontendRequestTimeoutInSeconds().getValue())
-                .frontendNoProgressTimeoutInSeconds(props.getFrontendNoProgressTimeoutInSeconds().getValue())
-                .build();
-    }
-
     public void setBundleContext(final BundleContext bundleContext) {
         this.bundleContext = bundleContext;
     }
index e9c3454..d06d2ec 100644 (file)
@@ -8,13 +8,11 @@
 
 package org.opendaylight.controller.config.yang.config.distributed_datastore_provider;
 
-import org.opendaylight.controller.cluster.datastore.DatastoreContext;
 import org.opendaylight.controller.cluster.datastore.DistributedDataStoreInterface;
 import org.opendaylight.controller.cluster.datastore.compat.LegacyDOMStoreAdapter;
 import org.opendaylight.controller.config.api.DependencyResolver;
 import org.opendaylight.controller.config.api.ModuleIdentifier;
 import org.opendaylight.controller.config.api.osgi.WaitingServiceTracker;
-import org.opendaylight.mdsal.common.api.LogicalDatastoreType;
 import org.osgi.framework.BundleContext;
 
 @Deprecated
@@ -58,60 +56,6 @@ public class DistributedOperationalDataStoreProviderModule
         };
     }
 
-    public static DatastoreContext newDatastoreContext() {
-        return newDatastoreContext(null);
-    }
-
-    private static DatastoreContext newDatastoreContext(final OperationalProperties inProps) {
-        OperationalProperties props = inProps;
-        if (props == null) {
-            props = new OperationalProperties();
-        }
-
-        return DatastoreContext.newBuilder()
-                .logicalStoreType(LogicalDatastoreType.OPERATIONAL)
-                .tempFileDirectory("./data")
-                .fileBackedStreamingThresholdInMegabytes(props.getFileBackedStreamingThresholdInMegabytes()
-                        .getValue().intValue())
-                .maxShardDataChangeExecutorPoolSize(props.getMaxShardDataChangeExecutorPoolSize().getValue().intValue())
-                .maxShardDataChangeExecutorQueueSize(props.getMaxShardDataChangeExecutorQueueSize()
-                        .getValue().intValue())
-                .maxShardDataChangeListenerQueueSize(props.getMaxShardDataChangeListenerQueueSize()
-                        .getValue().intValue())
-                .maxShardDataStoreExecutorQueueSize(props.getMaxShardDataStoreExecutorQueueSize().getValue().intValue())
-                .shardTransactionIdleTimeoutInMinutes(props.getShardTransactionIdleTimeoutInMinutes().getValue())
-                .operationTimeoutInSeconds(props.getOperationTimeoutInSeconds().getValue())
-                .shardJournalRecoveryLogBatchSize(props.getShardJournalRecoveryLogBatchSize()
-                        .getValue().intValue())
-                .shardSnapshotBatchCount(props.getShardSnapshotBatchCount().getValue().intValue())
-                .shardSnapshotDataThresholdPercentage(props.getShardSnapshotDataThresholdPercentage()
-                        .getValue().intValue())
-                .shardHeartbeatIntervalInMillis(props.getShardHeartbeatIntervalInMillis().getValue())
-                .shardInitializationTimeoutInSeconds(props.getShardInitializationTimeoutInSeconds().getValue())
-                .shardLeaderElectionTimeoutInSeconds(props.getShardLeaderElectionTimeoutInSeconds().getValue())
-                .shardTransactionCommitTimeoutInSeconds(
-                        props.getShardTransactionCommitTimeoutInSeconds().getValue().intValue())
-                .shardTransactionCommitQueueCapacity(
-                        props.getShardTransactionCommitQueueCapacity().getValue().intValue())
-                .persistent(props.getPersistent().booleanValue())
-                .shardIsolatedLeaderCheckIntervalInMillis(
-                        props.getShardIsolatedLeaderCheckIntervalInMillis().getValue())
-                .shardElectionTimeoutFactor(props.getShardElectionTimeoutFactor().getValue())
-                .transactionCreationInitialRateLimit(props.getTransactionCreationInitialRateLimit().getValue())
-                .shardBatchedModificationCount(props.getShardBatchedModificationCount().getValue().intValue())
-                .shardCommitQueueExpiryTimeoutInSeconds(
-                        props.getShardCommitQueueExpiryTimeoutInSeconds().getValue().intValue())
-                .transactionDebugContextEnabled(props.getTransactionDebugContextEnabled())
-                .customRaftPolicyImplementation(props.getCustomRaftPolicyImplementation())
-                .maximumMessageSliceSize(props.getMaximumMessageSliceSize().getValue().intValue())
-                .useTellBasedProtocol(props.getUseTellBasedProtocol())
-                .syncIndexThreshold(props.getSyncIndexThreshold().getValue())
-                .backendAlivenessTimerIntervalInSeconds(props.getBackendAlivenessTimerIntervalInSeconds().getValue())
-                .frontendRequestTimeoutInSeconds(props.getFrontendRequestTimeoutInSeconds().getValue())
-                .frontendNoProgressTimeoutInSeconds(props.getFrontendNoProgressTimeoutInSeconds().getValue())
-                .build();
-    }
-
     public void setBundleContext(final BundleContext bundleContext) {
         this.bundleContext = bundleContext;
     }
index 395930b..cda74ad 100644 (file)
@@ -12,6 +12,8 @@
 
   <odl:static-reference id="schemaService" interface="org.opendaylight.mdsal.dom.api.DOMSchemaService" />
 
+  <reference id="classLoadingStrategy" interface="org.opendaylight.mdsal.binding.generator.api.ClassLoadingStrategy" />
+
   <!-- ActorSystemProvider -->
 
   <bean id="bundleClassLoader" class="org.opendaylight.controller.config.yang.config.actor_system_provider.impl.factory.osgi.BundleClassLoaderFactory"
     <argument value="./clustered-datastore-restore"/>
   </bean>
 
-  <bean id="configDatastoreContext" class="org.opendaylight.controller.config.yang.config.distributed_datastore_provider.DistributedConfigDataStoreProviderModule"
-          factory-method="newDatastoreContext" />
+  <bean id="introspectorFactory" class="org.opendaylight.controller.cluster.datastore.DatastoreContextIntrospectorFactory">
+    <argument ref="schemaService"/>
+    <argument ref="classLoadingStrategy"/>
+  </bean>
 
-  <bean id="introspectorConfig" class="org.opendaylight.controller.cluster.datastore.DatastoreContextIntrospector">
-    <argument ref="configDatastoreContext"/>
+  <bean id="introspectorConfig" factory-ref="introspectorFactory" factory-method="newInstance">
+    <argument type="org.opendaylight.mdsal.common.api.LogicalDatastoreType" value="CONFIGURATION"/>
   </bean>
 
   <bean id="updaterConfig" class="org.opendaylight.controller.cluster.datastore.DatastoreContextPropertiesUpdater">
@@ -64,7 +68,9 @@
   <bean id="configDatastore" class="org.opendaylight.controller.cluster.datastore.DistributedDataStoreFactory"
           factory-method="createInstance" destroy-method="close">
     <argument ref="schemaService"/>
-    <argument ref="configDatastoreContext"/>
+    <argument>
+      <bean factory-ref="introspectorConfig" factory-method="getContext" />
+    </argument>
     <argument ref="datastoreSnapshotRestore"/>
     <argument ref="actorSystemProvider"/>
     <argument ref="introspectorConfig"/>
     <argument ref="fileModuleShardConfigProvider"/>
   </bean>
 
-  <bean id="operDatastoreContext" class="org.opendaylight.controller.config.yang.config.distributed_datastore_provider.DistributedOperationalDataStoreProviderModule"
-          factory-method="newDatastoreContext" />
-
-  <bean id="introspectorOper" class="org.opendaylight.controller.cluster.datastore.DatastoreContextIntrospector">
-    <argument ref="operDatastoreContext"/>
+  <bean id="introspectorOper" factory-ref="introspectorFactory" factory-method="newInstance">
+    <argument type="org.opendaylight.mdsal.common.api.LogicalDatastoreType" value="OPERATIONAL"/>
   </bean>
 
   <bean id="updaterOper" class="org.opendaylight.controller.cluster.datastore.DatastoreContextPropertiesUpdater">
   <bean id="operDatastore" class="org.opendaylight.controller.cluster.datastore.DistributedDataStoreFactory"
           factory-method="createInstance" destroy-method="close">
     <argument ref="schemaService"/>
-    <argument ref="operDatastoreContext"/>
+    <argument>
+      <bean factory-ref="introspectorOper" factory-method="getContext" />
+    </argument>
     <argument ref="datastoreSnapshotRestore"/>
     <argument ref="actorSystemProvider"/>
     <argument ref="introspectorOper"/>
index ea5dabf..be65883 100644 (file)
@@ -286,6 +286,10 @@ module distributed-datastore-provider {
         }
     }
 
+    container data-store-properties-container {
+        uses data-store-properties;
+    }
+
     // Augments the 'configuration' choice node under modules/module.
     augment "/config:modules/config:module/config:configuration" {
         case distributed-config-datastore-provider {
index 4659b16..38a89d0 100644 (file)
@@ -10,6 +10,8 @@ package org.opendaylight.controller.cluster.datastore;
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertNotNull;
 import static org.junit.Assert.assertTrue;
+import static org.opendaylight.controller.cluster.datastore.DatastoreContextIntrospectorTest.INTROSPECTOR_FACTORY;
+import static org.opendaylight.mdsal.common.api.LogicalDatastoreType.CONFIGURATION;
 
 import java.lang.reflect.Field;
 import java.util.HashMap;
@@ -24,9 +26,8 @@ public class DatastoreContextContextPropertiesUpdaterTest {
     public void updateOnConstructionTest() throws Exception {
         final Map<String, Object> properties = new HashMap<>();
         properties.put("shardTransactionIdleTimeoutInMinutes", 10);
-        final DatastoreContext datastoreContext = DatastoreContext.newBuilder().build();
 
-        final DatastoreContextIntrospector introspector = new DatastoreContextIntrospector(datastoreContext);
+        final DatastoreContextIntrospector introspector = INTROSPECTOR_FACTORY.newInstance(CONFIGURATION);
 
         final DatastoreContextPropertiesUpdater updater = new DatastoreContextPropertiesUpdater(introspector,
                 properties);
@@ -42,9 +43,8 @@ public class DatastoreContextContextPropertiesUpdaterTest {
     public void onUpdateTest() throws Exception {
         final Map<String, Object> properties = new HashMap<>();
         properties.put("shardTransactionIdleTimeoutInMinutes", 10);
-        final DatastoreContext datastoreContext = DatastoreContext.newBuilder().build();
-        assertNotNull(datastoreContext);
-        final DatastoreContextIntrospector introspector = new DatastoreContextIntrospector(datastoreContext);
+
+        final DatastoreContextIntrospector introspector = INTROSPECTOR_FACTORY.newInstance(CONFIGURATION);
         assertNotNull(introspector);
         final DatastoreContextPropertiesUpdater updater = new DatastoreContextPropertiesUpdater(introspector,
                 properties);
@@ -66,8 +66,7 @@ public class DatastoreContextContextPropertiesUpdaterTest {
         final Map<String, Object> properties = new HashMap<>();
         properties.put("shardTransactionIdleTimeoutInMinutes", 10);
 
-        final DatastoreContext datastoreContext = DatastoreContext.newBuilder().build();
-        final DatastoreContextIntrospector introspector = new DatastoreContextIntrospector(datastoreContext);
+        final DatastoreContextIntrospector introspector = INTROSPECTOR_FACTORY.newInstance(CONFIGURATION);
         final DatastoreContextPropertiesUpdater updater = new DatastoreContextPropertiesUpdater(introspector,
                 properties);
         final DummyListenerImpl dummyListener = new DummyListenerImpl();
index 5d5d2f8..2eb078f 100644 (file)
@@ -8,32 +8,71 @@
 package org.opendaylight.controller.cluster.datastore;
 
 import static org.junit.Assert.assertEquals;
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.mock;
 import static org.opendaylight.controller.cluster.datastore.DatastoreContext.DEFAULT_HEARTBEAT_INTERVAL_IN_MILLIS;
 import static org.opendaylight.controller.cluster.datastore.DatastoreContext.DEFAULT_OPERATION_TIMEOUT_IN_MS;
 import static org.opendaylight.controller.cluster.datastore.DatastoreContext.DEFAULT_SHARD_INITIALIZATION_TIMEOUT;
 import static org.opendaylight.controller.cluster.datastore.DatastoreContext.DEFAULT_SHARD_SNAPSHOT_DATA_THRESHOLD_PERCENTAGE;
 import static org.opendaylight.controller.cluster.datastore.DatastoreContext.DEFAULT_SHARD_TRANSACTION_IDLE_TIMEOUT;
 import static org.opendaylight.controller.cluster.datastore.DatastoreContext.DEFAULT_SHARD_TX_COMMIT_TIMEOUT_IN_SECONDS;
+import static org.opendaylight.mdsal.common.api.LogicalDatastoreType.CONFIGURATION;
+import static org.opendaylight.mdsal.common.api.LogicalDatastoreType.OPERATIONAL;
 
+import java.util.Arrays;
 import java.util.HashMap;
 import java.util.Hashtable;
 import java.util.Map;
 import org.junit.Test;
-import org.opendaylight.mdsal.common.api.LogicalDatastoreType;
+import org.opendaylight.mdsal.binding.generator.impl.GeneratedClassLoadingStrategy;
+import org.opendaylight.mdsal.binding.generator.impl.ModuleInfoBackedContext;
+import org.opendaylight.mdsal.dom.api.DOMSchemaService;
 import org.opendaylight.mdsal.dom.store.inmemory.InMemoryDOMDataStoreConfigProperties;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.config.distributed.datastore.provider.rev140612.DataStorePropertiesContainer;
+import org.opendaylight.yangtools.yang.binding.util.BindingReflections;
+import org.opendaylight.yangtools.yang.model.api.SchemaContext;
 
 /**
  * Unit tests for DatastoreContextIntrospector.
  *
  * @author Thomas Pantelis
  */
+@SuppressWarnings("checkstyle:IllegalCatch")
 public class DatastoreContextIntrospectorTest {
 
+    static SchemaContext SCHEMA_CONTEXT;
+    static DatastoreContextIntrospectorFactory INTROSPECTOR_FACTORY;
+
+    static {
+        final ModuleInfoBackedContext moduleContext = ModuleInfoBackedContext.create();
+        try {
+            moduleContext.addModuleInfos(Arrays.asList(
+                    BindingReflections.getModuleInfo(DataStorePropertiesContainer.class)));
+        } catch (Exception e) {
+            throw new RuntimeException(e);
+        }
+        SCHEMA_CONTEXT = moduleContext.tryToCreateSchemaContext().get();
+
+        DOMSchemaService mockSchemaService = mock(DOMSchemaService.class);
+        doReturn(SCHEMA_CONTEXT).when(mockSchemaService).getGlobalContext();
+        INTROSPECTOR_FACTORY = new DatastoreContextIntrospectorFactory(mockSchemaService,
+                GeneratedClassLoadingStrategy.getTCCLClassLoadingStrategy());
+    }
+
+    @Test
+    public void testYangDefaults() {
+        final DatastoreContextIntrospector introspector = INTROSPECTOR_FACTORY.newInstance(
+                DatastoreContext.newBuilder().shardBatchedModificationCount(2)
+                .transactionDebugContextEnabled(true).build());
+        DatastoreContext context = introspector.getContext();
+
+        assertEquals(1000, context.getShardBatchedModificationCount());
+        assertEquals(false, context.isTransactionDebugContextEnabled());
+    }
+
     @Test
     public void testUpdate() {
-        DatastoreContext context = DatastoreContext.newBuilder()
-                .logicalStoreType(LogicalDatastoreType.OPERATIONAL).build();
-        final DatastoreContextIntrospector introspector = new DatastoreContextIntrospector(context);
+        final DatastoreContextIntrospector introspector = INTROSPECTOR_FACTORY.newInstance(OPERATIONAL);
 
         final Map<String, Object> properties = new HashMap<>();
         properties.put("shard-transaction-idle-timeout-in-minutes", "31");
@@ -58,7 +97,7 @@ public class DatastoreContextIntrospectorTest {
 
         boolean updated = introspector.update(properties);
         assertEquals("updated", true, updated);
-        context = introspector.getContext();
+        DatastoreContext context = introspector.getContext();
 
         assertEquals(31, context.getShardTransactionIdleTimeout().toMinutes());
         assertEquals(26000, context.getOperationTimeoutInMillis());
@@ -121,9 +160,7 @@ public class DatastoreContextIntrospectorTest {
 
     @Test
     public void testUpdateWithInvalidValues() {
-        DatastoreContext context = DatastoreContext.newBuilder()
-                .logicalStoreType(LogicalDatastoreType.OPERATIONAL).build();
-        final DatastoreContextIntrospector introspector = new DatastoreContextIntrospector(context);
+        final DatastoreContextIntrospector introspector = INTROSPECTOR_FACTORY.newInstance(OPERATIONAL);
 
         final Map<String, Object> properties = new HashMap<>();
         properties.put("shard-transaction-idle-timeout-in-minutes", "0"); // bad - must be > 0
@@ -140,7 +177,7 @@ public class DatastoreContextIntrospectorTest {
 
         final boolean updated = introspector.update(properties);
         assertEquals("updated", true, updated);
-        context = introspector.getContext();
+        DatastoreContext context = introspector.getContext();
 
         assertEquals(DEFAULT_SHARD_TRANSACTION_IDLE_TIMEOUT, context.getShardTransactionIdleTimeout());
         assertEquals(199, context.getShardRaftConfig().getJournalRecoveryLogBatchSize());
@@ -171,23 +208,19 @@ public class DatastoreContextIntrospectorTest {
         properties.put("persistent", "false"); // global setting
         properties.put("operational.Persistent", "true"); // operational override
 
-        DatastoreContext operContext = DatastoreContext.newBuilder()
-                .logicalStoreType(LogicalDatastoreType.OPERATIONAL).build();
-        final DatastoreContextIntrospector operIntrospector = new DatastoreContextIntrospector(operContext);
+        final DatastoreContextIntrospector operIntrospector = INTROSPECTOR_FACTORY.newInstance(OPERATIONAL);
         boolean updated = operIntrospector.update(properties);
         assertEquals("updated", true, updated);
-        operContext = operIntrospector.getContext();
+        DatastoreContext operContext = operIntrospector.getContext();
 
         assertEquals(33, operContext.getShardTransactionIdleTimeout().toMinutes());
         assertEquals(true, operContext.isPersistent());
         assertEquals(333, operContext.getDataStoreProperties().getMaxDataChangeExecutorPoolSize());
 
-        DatastoreContext configContext = DatastoreContext.newBuilder()
-                .logicalStoreType(LogicalDatastoreType.CONFIGURATION).build();
-        final DatastoreContextIntrospector configIntrospector = new DatastoreContextIntrospector(configContext);
+        final DatastoreContextIntrospector configIntrospector = INTROSPECTOR_FACTORY.newInstance(CONFIGURATION);
         updated = configIntrospector.update(properties);
         assertEquals("updated", true, updated);
-        configContext = configIntrospector.getContext();
+        DatastoreContext configContext = configIntrospector.getContext();
 
         assertEquals(44, configContext.getShardTransactionIdleTimeout().toMinutes());
         assertEquals(false, configContext.isPersistent());
@@ -202,25 +235,21 @@ public class DatastoreContextIntrospectorTest {
         properties.put("config.shard-transaction-idle-timeout-in-minutes", "44"); // config override
         properties.put("topology.shard-transaction-idle-timeout-in-minutes", "55"); // global shard override
 
-        DatastoreContext operContext = DatastoreContext.newBuilder()
-                .logicalStoreType(LogicalDatastoreType.OPERATIONAL).build();
-        final DatastoreContextIntrospector operIntrospector = new DatastoreContextIntrospector(operContext);
+        final DatastoreContextIntrospector operIntrospector = INTROSPECTOR_FACTORY.newInstance(OPERATIONAL);
 
         DatastoreContext shardContext = operIntrospector.newContextFactory().getShardDatastoreContext("topology");
         assertEquals(10, shardContext.getShardTransactionIdleTimeout().toMinutes());
 
         operIntrospector.update(properties);
-        operContext = operIntrospector.getContext();
+        DatastoreContext operContext = operIntrospector.getContext();
         assertEquals(33, operContext.getShardTransactionIdleTimeout().toMinutes());
 
         shardContext = operIntrospector.newContextFactory().getShardDatastoreContext("topology");
         assertEquals(55, shardContext.getShardTransactionIdleTimeout().toMinutes());
 
-        DatastoreContext configContext = DatastoreContext.newBuilder()
-                .logicalStoreType(LogicalDatastoreType.CONFIGURATION).build();
-        final DatastoreContextIntrospector configIntrospector = new DatastoreContextIntrospector(configContext);
+        final DatastoreContextIntrospector configIntrospector = INTROSPECTOR_FACTORY.newInstance(CONFIGURATION);
         configIntrospector.update(properties);
-        configContext = configIntrospector.getContext();
+        DatastoreContext configContext = configIntrospector.getContext();
         assertEquals(44, configContext.getShardTransactionIdleTimeout().toMinutes());
 
         shardContext = configIntrospector.newContextFactory().getShardDatastoreContext("topology");

©2013 OpenDaylight, A Linux Foundation Collaborative Project. All Rights Reserved.
OpenDaylight is a registered trademark of The OpenDaylight Project, Inc.
Linux Foundation and OpenDaylight are registered trademarks of the Linux Foundation.
Linux is a registered trademark of Linus Torvalds.