From: Tom Pantelis Date: Wed, 30 May 2018 01:31:48 +0000 (-0400) Subject: Eliminate DatastoreContext CSS dependency X-Git-Tag: release/fluorine~93 X-Git-Url: https://git.opendaylight.org/gerrit/gitweb?p=controller.git;a=commitdiff_plain;h=995da01ef2d635230c37afc7cf4fdd724bf68856 Eliminate DatastoreContext CSS dependency 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 --- diff --git a/opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/datastore/DatastoreContextIntrospector.java b/opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/datastore/DatastoreContextIntrospector.java index e8fce52d82..8b34f9d364 100644 --- a/opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/datastore/DatastoreContextIntrospector.java +++ b/opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/datastore/DatastoreContextIntrospector.java @@ -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> DATA_STORE_PROP_TYPES = new HashMap<>(); + private static final Map, Method>> DATA_STORE_PROP_INFO = new HashMap<>(); private static final Map, 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 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, 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, 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 index 0000000000..1b7c0281a6 --- /dev/null +++ b/opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/datastore/DatastoreContextIntrospectorFactory.java @@ -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; + } +} diff --git a/opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/config/yang/config/distributed_datastore_provider/DistributedConfigDataStoreProviderModule.java b/opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/config/yang/config/distributed_datastore_provider/DistributedConfigDataStoreProviderModule.java index 79b276d8be..2163449b66 100644 --- a/opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/config/yang/config/distributed_datastore_provider/DistributedConfigDataStoreProviderModule.java +++ b/opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/config/yang/config/distributed_datastore_provider/DistributedConfigDataStoreProviderModule.java @@ -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; } diff --git a/opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/config/yang/config/distributed_datastore_provider/DistributedOperationalDataStoreProviderModule.java b/opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/config/yang/config/distributed_datastore_provider/DistributedOperationalDataStoreProviderModule.java index e9c34545b6..d06d2ec392 100644 --- a/opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/config/yang/config/distributed_datastore_provider/DistributedOperationalDataStoreProviderModule.java +++ b/opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/config/yang/config/distributed_datastore_provider/DistributedOperationalDataStoreProviderModule.java @@ -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; } diff --git a/opendaylight/md-sal/sal-distributed-datastore/src/main/resources/org/opendaylight/blueprint/clustered-datastore.xml b/opendaylight/md-sal/sal-distributed-datastore/src/main/resources/org/opendaylight/blueprint/clustered-datastore.xml index 395930b3a9..cda74adf85 100644 --- a/opendaylight/md-sal/sal-distributed-datastore/src/main/resources/org/opendaylight/blueprint/clustered-datastore.xml +++ b/opendaylight/md-sal/sal-distributed-datastore/src/main/resources/org/opendaylight/blueprint/clustered-datastore.xml @@ -12,6 +12,8 @@ + + - + + + + - - + + @@ -64,7 +68,9 @@ - + + + @@ -87,11 +93,8 @@ - - - - + + @@ -103,7 +106,9 @@ - + + + diff --git a/opendaylight/md-sal/sal-distributed-datastore/src/main/yang/distributed-datastore-provider.yang b/opendaylight/md-sal/sal-distributed-datastore/src/main/yang/distributed-datastore-provider.yang index ea5dabfd73..be658835be 100644 --- a/opendaylight/md-sal/sal-distributed-datastore/src/main/yang/distributed-datastore-provider.yang +++ b/opendaylight/md-sal/sal-distributed-datastore/src/main/yang/distributed-datastore-provider.yang @@ -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 { diff --git a/opendaylight/md-sal/sal-distributed-datastore/src/test/java/org/opendaylight/controller/cluster/datastore/DatastoreContextContextPropertiesUpdaterTest.java b/opendaylight/md-sal/sal-distributed-datastore/src/test/java/org/opendaylight/controller/cluster/datastore/DatastoreContextContextPropertiesUpdaterTest.java index 4659b16035..38a89d0c75 100644 --- a/opendaylight/md-sal/sal-distributed-datastore/src/test/java/org/opendaylight/controller/cluster/datastore/DatastoreContextContextPropertiesUpdaterTest.java +++ b/opendaylight/md-sal/sal-distributed-datastore/src/test/java/org/opendaylight/controller/cluster/datastore/DatastoreContextContextPropertiesUpdaterTest.java @@ -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 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 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 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(); diff --git a/opendaylight/md-sal/sal-distributed-datastore/src/test/java/org/opendaylight/controller/cluster/datastore/DatastoreContextIntrospectorTest.java b/opendaylight/md-sal/sal-distributed-datastore/src/test/java/org/opendaylight/controller/cluster/datastore/DatastoreContextIntrospectorTest.java index 5d5d2f8db2..2eb078f790 100644 --- a/opendaylight/md-sal/sal-distributed-datastore/src/test/java/org/opendaylight/controller/cluster/datastore/DatastoreContextIntrospectorTest.java +++ b/opendaylight/md-sal/sal-distributed-datastore/src/test/java/org/opendaylight/controller/cluster/datastore/DatastoreContextIntrospectorTest.java @@ -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 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 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");