From 43f506ead639607367b6bdc8a04287b57e189b01 Mon Sep 17 00:00:00 2001 From: Tony Tkacik Date: Wed, 4 Dec 2013 17:18:11 +0100 Subject: [PATCH] Moved IT code to separate project, Fix for Bug 184, created test-jar Change-Id: I9ed91016c93aba64548498b48de6ff1995cee021 Signed-off-by: Tony Tkacik --- .../integrationtest/pom.xml | 28 ++- opendaylight/md-sal/pom.xml | 9 +- .../md-sal/sal-binding-broker/pom.xml | 44 ++-- .../impl/LazyGeneratedCodecRegistry.java | 63 ++++-- .../RuntimeGeneratedMappingServiceImpl.xtend | 8 +- .../impl/TransformerGenerator.xtend | 46 +++- .../binding/impl/util/ClassLoaderUtils.java | 22 +- .../binding/test/AbstractDataServiceTest.java | 115 ++-------- .../test/util/BindingBrokerTestFactory.java | 59 ++++++ .../binding/test/util/BindingTestContext.java | 199 ++++++++++++++++++ .../md-sal/sal-binding-dom-it/pom.xml | 82 ++++++++ .../test/bugfix/DOMCodecBug01Test.java | 0 .../test/bugfix/DOMCodecBug02Test.java | 14 +- .../test/bugfix/DOMCodecBug03Test.java | 0 .../bugfix/RpcRegistrationNullPointer.java | 0 .../connect/dom/BrokerIntegrationTest.java | 0 .../dom/ChangeOriginatedInDomBrokerTest.java | 0 opendaylight/md-sal/sal-binding-it/pom.xml | 1 + .../impl/service/AbstractDataBroker.xtend | 9 + 19 files changed, 520 insertions(+), 179 deletions(-) create mode 100644 opendaylight/md-sal/sal-binding-broker/src/test/java/org/opendaylight/controller/sal/binding/test/util/BindingBrokerTestFactory.java create mode 100644 opendaylight/md-sal/sal-binding-broker/src/test/java/org/opendaylight/controller/sal/binding/test/util/BindingTestContext.java create mode 100644 opendaylight/md-sal/sal-binding-dom-it/pom.xml rename opendaylight/md-sal/{sal-binding-broker => sal-binding-dom-it}/src/test/java/org/opendaylight/controller/sal/binding/test/bugfix/DOMCodecBug01Test.java (100%) rename opendaylight/md-sal/{sal-binding-broker => sal-binding-dom-it}/src/test/java/org/opendaylight/controller/sal/binding/test/bugfix/DOMCodecBug02Test.java (94%) rename opendaylight/md-sal/{sal-binding-broker => sal-binding-dom-it}/src/test/java/org/opendaylight/controller/sal/binding/test/bugfix/DOMCodecBug03Test.java (100%) rename opendaylight/md-sal/{sal-binding-broker => sal-binding-dom-it}/src/test/java/org/opendaylight/controller/sal/binding/test/bugfix/RpcRegistrationNullPointer.java (100%) rename opendaylight/md-sal/{sal-binding-broker => sal-binding-dom-it}/src/test/java/org/opendaylight/controller/sal/binding/test/connect/dom/BrokerIntegrationTest.java (100%) rename opendaylight/md-sal/{sal-binding-broker => sal-binding-dom-it}/src/test/java/org/opendaylight/controller/sal/binding/test/connect/dom/ChangeOriginatedInDomBrokerTest.java (100%) diff --git a/opendaylight/md-sal/clustered-data-store/integrationtest/pom.xml b/opendaylight/md-sal/clustered-data-store/integrationtest/pom.xml index 968f87a402..176ab6cbe0 100644 --- a/opendaylight/md-sal/clustered-data-store/integrationtest/pom.xml +++ b/opendaylight/md-sal/clustered-data-store/integrationtest/pom.xml @@ -17,8 +17,18 @@ clustered-datastore.integrationtest 0.4.0-SNAPSHOT - + + + + xml-apis + xml-apis + 1.4.01 + + + + + com.google.guava guava @@ -47,6 +57,16 @@ org.opendaylight.controller sal-binding-broker-impl 1.0-SNAPSHOT + + + xml-apis + xml-apis + + + reflections + org.reflections + + org.opendaylight.controller @@ -126,6 +146,12 @@ config-netconf-connector ${netconf.version} test + + + xml-apis + xml-apis + + org.opendaylight.controller diff --git a/opendaylight/md-sal/pom.xml b/opendaylight/md-sal/pom.xml index 94c31dd041..0e78598c11 100644 --- a/opendaylight/md-sal/pom.xml +++ b/opendaylight/md-sal/pom.xml @@ -29,6 +29,7 @@ sal-binding-broker sal-binding-util + sal-binding-dom-it samples @@ -193,9 +194,11 @@ - - - + + xml-apis + xml-apis + 1.4.01 + diff --git a/opendaylight/md-sal/sal-binding-broker/pom.xml b/opendaylight/md-sal/sal-binding-broker/pom.xml index 89bb1e8502..ac84aab977 100644 --- a/opendaylight/md-sal/sal-binding-broker/pom.xml +++ b/opendaylight/md-sal/sal-binding-broker/pom.xml @@ -131,6 +131,19 @@ + + + + org.apache.maven.plugins + maven-jar-plugin + + + + test-jar + + + + @@ -168,6 +181,7 @@ org.reflections reflections 0.9.9-RC1 + compile org.javassist @@ -210,29 +224,11 @@ org.eclipse.xtend org.eclipse.xtend.lib - - org.eclipse.xtend - org.eclipse.xtend.standalone - 2.4.3 - runtime - org.opendaylight.controller sal-binding-config 1.0-SNAPSHOT - - org.opendaylight.controller.model - model-flow-service - 1.0-SNAPSHOT - test - - - org.opendaylight.controller.model - model-flow-management - 1.0-SNAPSHOT - test - org.opendaylight.yangtools yang-data-impl @@ -249,17 +245,5 @@ ${slf4j.version} test - - org.opendaylight.controller.model - model-flow-statistics - 1.0-SNAPSHOT - test - - - org.reflections - reflections - 0.9.9-RC1 - test - diff --git a/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/dom/serializer/impl/LazyGeneratedCodecRegistry.java b/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/dom/serializer/impl/LazyGeneratedCodecRegistry.java index de6836489e..d33272d641 100644 --- a/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/dom/serializer/impl/LazyGeneratedCodecRegistry.java +++ b/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/dom/serializer/impl/LazyGeneratedCodecRegistry.java @@ -91,7 +91,7 @@ public class LazyGeneratedCodecRegistry implements // Map> typeToClass = new ConcurrentHashMap<>(); @SuppressWarnings("rawtypes") - private ConcurrentMap typeToCaseNodes = new ConcurrentHashMap<>(); + private ConcurrentMap typeToCaseCodecs = new ConcurrentHashMap<>(); private CaseClassMapFacade classToCaseRawCodec = new CaseClassMapFacade(); @@ -136,15 +136,14 @@ public class LazyGeneratedCodecRegistry implements // } return weakRef.get(); } - + @Override - public void putPathToClass(List names,Class cls) { + public void putPathToClass(List names, Class cls) { Type reference = Types.typeForClass(cls); - pathToInstantiatedType.put(names, reference ); + pathToInstantiatedType.put(names, reference); bindingClassEncountered(cls); } - @Override public IdentifierCodec getKeyCodecForPath(List names) { @SuppressWarnings("unchecked") @@ -297,10 +296,12 @@ public class LazyGeneratedCodecRegistry implements // return potential; } ConcreteType typeref = Types.typeForClass(caseClass); - ChoiceCaseCodecImpl caseCodec = typeToCaseNodes.get(typeref); + ChoiceCaseCodecImpl caseCodec = typeToCaseCodecs.get(typeref); + checkState(caseCodec != null, "Case Codec was not created proactivelly for %s", caseClass.getName()); + checkState(caseCodec.getSchema() != null, "Case schema is not available for %s", caseClass.getName()); @SuppressWarnings("unchecked") - Class newCodec = generator.caseCodecFor(caseClass, caseCodec.schema); + Class newCodec = generator.caseCodecFor(caseClass, caseCodec.getSchema()); BindingCodec newInstance = newInstanceOf(newCodec); caseCodec.setDelegate(newInstance); caseCodecs.put(caseClass, caseCodec); @@ -322,17 +323,23 @@ public class LazyGeneratedCodecRegistry implements // for (Entry caseNode : cases.entrySet()) { ReferencedTypeImpl typeref = new ReferencedTypeImpl(caseNode.getValue().getPackageName(), caseNode .getValue().getName()); + + LOG.info("Case path: {} Type : {}", caseNode.getKey(), caseNode.getValue().getFullyQualifiedName()); + pathToType.put(caseNode.getKey(), caseNode.getValue()); + ChoiceCaseNode node = (ChoiceCaseNode) SchemaContextUtil.findDataSchemaNode(module, caseNode.getKey()); + if (node == null) { LOG.error("YANGTools Bug: SchemaNode for {}, with path {} was not found in context.", typeref.getFullyQualifiedName(), caseNode.getKey()); + @SuppressWarnings("rawtypes") + ChoiceCaseCodecImpl value = new ChoiceCaseCodecImpl(); + typeToCaseCodecs.putIfAbsent(typeref, value); continue; } - - pathToType.put(caseNode.getKey(), caseNode.getValue()); @SuppressWarnings("rawtypes") ChoiceCaseCodecImpl value = new ChoiceCaseCodecImpl(node); - typeToCaseNodes.putIfAbsent(typeref, value); + typeToCaseCodecs.putIfAbsent(typeref, value); } } @@ -352,18 +359,24 @@ public class LazyGeneratedCodecRegistry implements // choiceCodecs.put(choiceClass, newCodec); CodecMapping.setClassToCaseMap(choiceCodec, (Map, BindingCodec>) classToCaseRawCodec); CodecMapping.setCompositeNodeToCaseMap(choiceCodec, newCodec.getCompositeToCase()); - + tryToCreateCasesCodecs(schema); } private void tryToCreateCasesCodecs(ChoiceNode schema) { - for(ChoiceCaseNode caseNode : schema.getCases()) { + for (ChoiceCaseNode caseNode : schema.getCases()) { SchemaPath path = caseNode.getPath(); GeneratedTypeBuilder type; - if(path != null && (type = pathToType.get(path)) != null) { + if (path != null && (type = pathToType.get(path)) != null) { + ReferencedTypeImpl typeref = new ReferencedTypeImpl(type.getPackageName(), type.getName()); + ChoiceCaseCodecImpl partialCodec = typeToCaseCodecs.get(typeref); + if(partialCodec.getSchema() == null ) { + partialCodec.setSchema(caseNode); + } + Class caseClass = ClassLoaderUtils.tryToLoadClassWithTCCL(type.getFullyQualifiedName()); - if(caseClass != null) { + if (caseClass != null) { getCaseCodecFor(caseClass); } } @@ -381,8 +394,7 @@ public class LazyGeneratedCodecRegistry implements // } @Override - public void onDataContainerCodecCreated(Class dataClass, - Class> dataCodec) { + public void onDataContainerCodecCreated(Class dataClass, Class> dataCodec) { if (Augmentable.class.isAssignableFrom(dataClass)) { AugmentableCompositeCodec augmentableCodec = getAugmentableCodec(dataClass); CodecMapping.setAugmentationCodec(dataCodec, augmentableCodec); @@ -471,15 +483,15 @@ public class LazyGeneratedCodecRegistry implements // @SuppressWarnings("rawtypes") private static class ChoiceCaseCodecImpl implements ChoiceCaseCodec, // Delegator { - private final boolean augmenting; + private boolean augmenting; private BindingCodec delegate; - private final Set validNames; - private final Set validQNames; + private Set validNames; + private Set validQNames; private ChoiceCaseNode schema; - public ChoiceCaseCodecImpl(ChoiceCaseNode caseNode) { - this.delegate = NOT_READY_CODEC; + public void setSchema(ChoiceCaseNode caseNode) { + this.schema = schema; this.schema = caseNode; validNames = new HashSet<>(); validQNames = new HashSet<>(); @@ -491,6 +503,15 @@ public class LazyGeneratedCodecRegistry implements // augmenting = caseNode.isAugmenting(); } + public ChoiceCaseCodecImpl() { + this.delegate = NOT_READY_CODEC; + } + + public ChoiceCaseCodecImpl(ChoiceCaseNode caseNode) { + this.delegate = NOT_READY_CODEC; + setSchema(caseNode); + } + @Override public ValueWithQName deserialize(Node input) { throw new UnsupportedOperationException("Direct invocation of this codec is not allowed."); diff --git a/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/dom/serializer/impl/RuntimeGeneratedMappingServiceImpl.xtend b/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/dom/serializer/impl/RuntimeGeneratedMappingServiceImpl.xtend index 7eb473ce34..cb25f4da8b 100644 --- a/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/dom/serializer/impl/RuntimeGeneratedMappingServiceImpl.xtend +++ b/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/dom/serializer/impl/RuntimeGeneratedMappingServiceImpl.xtend @@ -78,7 +78,7 @@ class RuntimeGeneratedMappingServiceImpl implements BindingIndependentMappingSer for (entry : newBinding.moduleContexts.entrySet) { registry.onModuleContextAdded(schemaContext, entry.key, entry.value); - + binding.pathToType.putAll(entry.value.childNodes) //val module = entry.key; val context = entry.value; updateBindingFor(context.childNodes, schemaContext); @@ -174,16 +174,18 @@ class RuntimeGeneratedMappingServiceImpl implements BindingIndependentMappingSer } private def void updateBindingFor(Map map, SchemaContext module) { + for (entry : map.entrySet) { val schemaNode = SchemaContextUtil.findDataSchemaNode(module, entry.key); //LOG.info("{} : {}",entry.key,entry.value.fullyQualifiedName) + val typeRef = new ReferencedTypeImpl(entry.value.packageName,entry.value.name) + typeToDefinition.put(typeRef, entry.value); if (schemaNode != null) { - val typeRef = new ReferencedTypeImpl(entry.value.packageName,entry.value.name) typeToSchemaNode.put(typeRef, schemaNode); - typeToDefinition.put(typeRef, entry.value); updatePromisedSchemas(typeRef, schemaNode); } + } } diff --git a/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/dom/serializer/impl/TransformerGenerator.xtend b/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/dom/serializer/impl/TransformerGenerator.xtend index a732f152b2..0316614aa1 100644 --- a/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/dom/serializer/impl/TransformerGenerator.xtend +++ b/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/dom/serializer/impl/TransformerGenerator.xtend @@ -49,6 +49,8 @@ import static extension org.opendaylight.controller.sal.binding.impl.util.YangSc import org.opendaylight.yangtools.binding.generator.util.ReferencedTypeImpl import org.opendaylight.yangtools.yang.model.util.ExtendedType import org.opendaylight.yangtools.yang.model.util.EnumerationType +import static com.google.common.base.Preconditions.* +import org.opendaylight.yangtools.yang.model.api.SchemaPath class TransformerGenerator { @@ -78,6 +80,9 @@ class TransformerGenerator { @Property var Map typeToDefinition = new ConcurrentHashMap(); + @Property + var Map pathToType = new ConcurrentHashMap(); + @Property var Map typeToSchemaNode = new ConcurrentHashMap(); @@ -105,6 +110,27 @@ class TransformerGenerator { val ref = Types.typeForClass(inputType) val node = typeToSchemaNode.get(ref) val typeSpecBuilder = typeToDefinition.get(ref) + checkState(typeSpecBuilder !== null, "Could not find typedefinition for %s", inputType.name); + val typeSpec = typeSpecBuilder.toInstance(); + val newret = generateTransformerFor(inputType, typeSpec, node); + listener.onClassProcessed(inputType); + return newret as Class, Object>>; + ] + } + + def Class, Object>> transformerFor(Class inputType, DataSchemaNode node) { + return withClassLoaderAndLock(inputType.classLoader, lock) [ | + val ret = getGeneratedClass(inputType) + if (ret !== null) { + listener.onClassProcessed(inputType); + return ret as Class, Object>>; + } + val ref = Types.typeForClass(inputType) + var typeSpecBuilder = typeToDefinition.get(ref) + if (typeSpecBuilder == null) { + typeSpecBuilder = pathToType.get(node.path); + } + checkState(typeSpecBuilder !== null, "Could not find TypeDefinition for %s, $s", inputType.name, node); val typeSpec = typeSpecBuilder.toInstance(); val newret = generateTransformerFor(inputType, typeSpec, node); listener.onClassProcessed(inputType); @@ -205,11 +231,9 @@ class TransformerGenerator { keyTransformerFor(cls, type, node); } - private def serializer(Type type) { + private def serializer(Type type, DataSchemaNode node) { val cls = loadClassWithTCCL(type.resolvedName); - - transformerFor(cls); - + transformerFor(cls, node); } private def Class getValueSerializer(GeneratedTransferObject type) { @@ -367,7 +391,7 @@ class TransformerGenerator { ] val ret = ctCls.toClassImpl(inputType.classLoader, inputType.protectionDomain) as Class> - listener?.onDataContainerCodecCreated(inputType,ret); + listener?.onDataContainerCodecCreated(inputType, ret); log.info("DOM Codec for {} was generated {}", inputType, ret) return ret; } catch (Exception e) { @@ -710,7 +734,7 @@ class TransformerGenerator { Object _listItem = _iterator.next(); _is_empty = false; //System.out.println(" item" + _listItem); - Object _value = «type.actualTypeArguments.get(0).serializer.resolvedName».fromDomStatic(_localQName,_listItem); + Object _value = «type.actualTypeArguments.get(0).serializer(schema).resolvedName».fromDomStatic(_localQName,_listItem); //System.out.println(" value" + _value); «propertyName».add(_value); _hasNext = _iterator.hasNext(); @@ -762,12 +786,12 @@ class TransformerGenerator { if(_dom_«propertyName»_list != null && _dom_«propertyName»_list.size() > 0) { _is_empty = false; java.util.Map _dom_«propertyName» = (java.util.Map) _dom_«propertyName»_list.get(0); - «propertyName» = «type.serializer.resolvedName».fromDomStatic(_localQName,_dom_«propertyName»); + «propertyName» = «type.serializer(schema).resolvedName».fromDomStatic(_localQName,_dom_«propertyName»); } ''' private def dispatch CharSequence deserializeProperty(ChoiceNode schema, Type type, String propertyName) ''' - «type.resolvedName» «propertyName» = «type.serializer.resolvedName».fromDomStatic(_localQName,_compositeNode); + «type.resolvedName» «propertyName» = «type.serializer(schema).resolvedName».fromDomStatic(_localQName,_compositeNode); if(«propertyName» != null) { _is_empty = false; } @@ -1140,7 +1164,7 @@ class TransformerGenerator { boolean _hasNext = _iterator.hasNext(); while(_hasNext) { Object _listItem = _iterator.next(); - Object _domValue = «type.actualTypeArguments.get(0).serializer.resolvedName».toDomStatic(_resultName,_listItem); + Object _domValue = «type.actualTypeArguments.get(0).serializer(schema).resolvedName».toDomStatic(_resultName,_listItem); _childNodes.add(_domValue); _hasNext = _iterator.hasNext(); } @@ -1193,7 +1217,7 @@ class TransformerGenerator { String propertyName) ''' «type.resolvedName» «propertyName» = value.«propertyName»(); if(«propertyName» != null) { - java.util.List domValue = «type.serializer.resolvedName».toDomStatic(_resultName,«propertyName»); + java.util.List domValue = «type.serializer(container).resolvedName».toDomStatic(_resultName,«propertyName»); _childNodes.addAll(domValue); } ''' @@ -1219,7 +1243,7 @@ class TransformerGenerator { String propertyName) ''' «type.resolvedName» «propertyName» = value.«propertyName»(); if(«propertyName» != null) { - Object domValue = «type.serializer.resolvedName».toDomStatic(_resultName,«propertyName»); + Object domValue = «type.serializer(container).resolvedName».toDomStatic(_resultName,«propertyName»); _childNodes.add(domValue); } ''' diff --git a/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/util/ClassLoaderUtils.java b/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/util/ClassLoaderUtils.java index 596329e07b..d230fd17f9 100644 --- a/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/util/ClassLoaderUtils.java +++ b/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/util/ClassLoaderUtils.java @@ -7,9 +7,10 @@ import static com.google.common.base.Preconditions.*; import java.lang.reflect.Constructor; import java.lang.reflect.InvocationTargetException; -import java.util.ArrayList; +import java.util.Arrays; import java.util.List; +import com.google.common.base.Joiner; import com.google.common.base.Optional; public final class ClassLoaderUtils { @@ -56,15 +57,28 @@ public final class ClassLoaderUtils { if ("byte[]".equals(name)) { return byte[].class; } - - return Thread.currentThread().getContextClassLoader().loadClass(name); + try { + return Thread.currentThread().getContextClassLoader().loadClass(name); + } catch (ClassNotFoundException e) { + String[] components = name.split("\\."); + String potentialOuter; + int length = components.length; + if (length > 2 && (potentialOuter = components[length - 2]) != null && Character.isUpperCase(potentialOuter.charAt(0))) { + + String outerName = Joiner.on(".").join(Arrays.asList(components).subList(0, length - 1)); + String innerName = outerName + "$" + components[length-1]; + return Thread.currentThread().getContextClassLoader().loadClass(innerName); + } else { + throw e; + } + } } public static Class tryToLoadClassWithTCCL(String fullyQualifiedName) { try { return loadClassWithTCCL(fullyQualifiedName); } catch (ClassNotFoundException e) { - + } return null; } diff --git a/opendaylight/md-sal/sal-binding-broker/src/test/java/org/opendaylight/controller/sal/binding/test/AbstractDataServiceTest.java b/opendaylight/md-sal/sal-binding-broker/src/test/java/org/opendaylight/controller/sal/binding/test/AbstractDataServiceTest.java index c67a0176d2..a7a70c2839 100644 --- a/opendaylight/md-sal/sal-binding-broker/src/test/java/org/opendaylight/controller/sal/binding/test/AbstractDataServiceTest.java +++ b/opendaylight/md-sal/sal-binding-broker/src/test/java/org/opendaylight/controller/sal/binding/test/AbstractDataServiceTest.java @@ -14,6 +14,8 @@ import org.opendaylight.controller.sal.binding.api.data.DataProviderService; import org.opendaylight.controller.sal.binding.impl.DataBrokerImpl; import org.opendaylight.controller.sal.binding.impl.connect.dom.BindingIndependentDataServiceConnector; import org.opendaylight.controller.sal.binding.impl.connect.dom.BindingIndependentMappingService; +import org.opendaylight.controller.sal.binding.test.util.BindingBrokerTestFactory; +import org.opendaylight.controller.sal.binding.test.util.BindingTestContext; import org.opendaylight.controller.sal.binding.dom.serializer.impl.RuntimeGeneratedMappingServiceImpl; import org.opendaylight.controller.sal.core.api.data.DataBrokerService; import org.opendaylight.controller.sal.core.api.data.DataStore; @@ -37,117 +39,34 @@ public abstract class AbstractDataServiceTest { protected org.opendaylight.controller.sal.core.api.data.DataProviderService biDataService; protected DataProviderService baDataService; - - /** - * Workaround for JUNIT sharing classloaders - * - */ - protected static final ClassPool POOL = new ClassPool(); - - protected RuntimeGeneratedMappingServiceImpl mappingServiceImpl; protected BindingIndependentMappingService mappingService; - protected DataBrokerImpl baDataImpl; - protected org.opendaylight.controller.sal.dom.broker.DataBrokerImpl biDataImpl; - protected ListeningExecutorService executor; - protected BindingIndependentDataServiceConnector connectorServiceImpl; - protected HashMapDataStore rawDataStore; - protected SchemaAwareDataStoreAdapter schemaAwareDataStore; private DataStoreStatsWrapper dataStoreStats; - protected DataStore dataStore; + protected BindingTestContext testContext; @Before public void setUp() { - executor = MoreExecutors.sameThreadExecutor(); - baDataImpl = new DataBrokerImpl(); - baDataService = baDataImpl; - baDataImpl.setExecutor(executor); - - biDataImpl = new org.opendaylight.controller.sal.dom.broker.DataBrokerImpl(); - biDataService = biDataImpl; - biDataImpl.setExecutor(executor); - - rawDataStore = new HashMapDataStore(); - schemaAwareDataStore = new SchemaAwareDataStoreAdapter(); - schemaAwareDataStore.changeDelegate(rawDataStore); - dataStoreStats = new DataStoreStatsWrapper(schemaAwareDataStore); - dataStore = dataStoreStats; - - org.opendaylight.yangtools.yang.data.api.InstanceIdentifier treeRoot = org.opendaylight.yangtools.yang.data.api.InstanceIdentifier - .builder().toInstance(); - biDataImpl.registerConfigurationReader(treeRoot, dataStore); - biDataImpl.registerOperationalReader(treeRoot, dataStore); - biDataImpl.registerCommitHandler(treeRoot, dataStore); - - mappingServiceImpl = new RuntimeGeneratedMappingServiceImpl(); - mappingServiceImpl.setPool(POOL); - mappingService = mappingServiceImpl; - File pathname = new File("target/gen-classes-debug"); - // System.out.println("Generated classes are captured in " + - // pathname.getAbsolutePath()); - mappingServiceImpl.start(null); - // mappingServiceImpl.getBinding().setClassFileCapturePath(pathname); - - connectorServiceImpl = new BindingIndependentDataServiceConnector(); - connectorServiceImpl.setBaDataService(baDataService); - connectorServiceImpl.setBiDataService(biDataService); - connectorServiceImpl.setMappingService(mappingServiceImpl); - connectorServiceImpl.start(); - - String[] yangFiles = getModelFilenames(); - if (yangFiles != null && yangFiles.length > 0) { - SchemaContext context = getContext(yangFiles); - mappingServiceImpl.onGlobalContextUpdated(context); - schemaAwareDataStore.onGlobalContextUpdated(context); - } + ListeningExecutorService executor = MoreExecutors.sameThreadExecutor(); + BindingBrokerTestFactory factory = new BindingBrokerTestFactory(); + factory.setExecutor(executor); + factory.setStartWithParsedSchema(getStartWithSchema()); + testContext = factory.getTestContext(); + testContext.start(); + + baDataService = testContext.getBindingDataBroker(); + biDataService = testContext.getDomDataBroker(); + dataStore = testContext.getDomDataStore(); + mappingService = testContext.getBindingToDomMappingService(); } - protected String[] getModelFilenames() { - return getAllModelFilenames(); - } - - public static String[] getAllModelFilenames() { - Predicate predicate = new Predicate() { - @Override - public boolean apply(String input) { - return input.endsWith(".yang"); - } - }; - Reflections reflection = new Reflections("META-INF.yang", new ResourcesScanner()); - Set result = reflection.getResources(predicate); - return (String[]) result.toArray(new String[result.size()]); - } - - public static SchemaContext getContext(String[] yangFiles) { - - ClassLoader loader = AbstractDataServiceTest.class.getClassLoader(); - - List streams = new ArrayList<>(); - for (String string : yangFiles) { - InputStream stream = loader.getResourceAsStream(string); - streams.add(stream); - - } - YangParserImpl parser = new YangParserImpl(); - - Set modules = parser.parseYangModelsFromStreams(streams); - return parser.resolveSchemaContext(modules); + protected boolean getStartWithSchema() { + return true; } @After public void afterTest() { - log.info("BIDataStore Statistics: Configuration Read Count: {} TotalTime: {} ms AverageTime (ns): {} ms", - dataStoreStats.getConfigurationReadCount(), dataStoreStats.getConfigurationReadTotalTime(), - dataStoreStats.getConfigurationReadAverageTime()); - - log.info("BIDataStore Statistics: Operational Read Count: {} TotalTime: {} ms AverageTime (ns): {} ms", - dataStoreStats.getOperationalReadCount(), dataStoreStats.getOperationalReadTotalTime(), - dataStoreStats.getOperationalReadAverageTime()); - - log.info("BIDataStore Statistics: Request Commit Count: {} TotalTime: {} ms AverageTime (ns): {} ms", - dataStoreStats.getRequestCommitCount(), dataStoreStats.getRequestCommitTotalTime(), - dataStoreStats.getRequestCommitAverageTime()); + testContext.logDataStoreStatistics(); } } diff --git a/opendaylight/md-sal/sal-binding-broker/src/test/java/org/opendaylight/controller/sal/binding/test/util/BindingBrokerTestFactory.java b/opendaylight/md-sal/sal-binding-broker/src/test/java/org/opendaylight/controller/sal/binding/test/util/BindingBrokerTestFactory.java new file mode 100644 index 0000000000..bad485e679 --- /dev/null +++ b/opendaylight/md-sal/sal-binding-broker/src/test/java/org/opendaylight/controller/sal/binding/test/util/BindingBrokerTestFactory.java @@ -0,0 +1,59 @@ +package org.opendaylight.controller.sal.binding.test.util; + +import java.util.concurrent.ExecutorService; + +import javassist.ClassPool; + +import org.opendaylight.controller.sal.core.api.data.DataStore; +import org.opendaylight.controller.sal.dom.broker.impl.DataStoreStatsWrapper; +import org.opendaylight.controller.sal.dom.broker.impl.HashMapDataStore; +import org.opendaylight.controller.sal.dom.broker.impl.SchemaAwareDataStoreAdapter; + +import com.google.common.base.Preconditions; +import com.google.common.util.concurrent.ListeningExecutorService; +import com.google.common.util.concurrent.MoreExecutors; + +public class BindingBrokerTestFactory { + + private static final ClassPool CLASS_POOL = new ClassPool(); + private boolean startWithParsedSchema = true; + private ExecutorService executor; + private ClassPool classPool; + + + public boolean isStartWithParsedSchema() { + return startWithParsedSchema; + } + + public void setStartWithParsedSchema(boolean startWithParsedSchema) { + this.startWithParsedSchema = startWithParsedSchema; + } + + public ExecutorService getExecutor() { + return executor; + } + + public void setExecutor(ExecutorService executor) { + this.executor = executor; + } + + + public BindingTestContext getTestContext() { + Preconditions.checkState(executor != null, "Executor is not set."); + ListeningExecutorService listenableExecutor = MoreExecutors.listeningDecorator(executor); + return new BindingTestContext(listenableExecutor, getClassPool(),startWithParsedSchema); + } + + public ClassPool getClassPool() { + if(classPool == null) { + return CLASS_POOL; + } + + return classPool; + } + + public void setClassPool(ClassPool classPool) { + this.classPool = classPool; + } + +} diff --git a/opendaylight/md-sal/sal-binding-broker/src/test/java/org/opendaylight/controller/sal/binding/test/util/BindingTestContext.java b/opendaylight/md-sal/sal-binding-broker/src/test/java/org/opendaylight/controller/sal/binding/test/util/BindingTestContext.java new file mode 100644 index 0000000000..4e611c5fe2 --- /dev/null +++ b/opendaylight/md-sal/sal-binding-broker/src/test/java/org/opendaylight/controller/sal/binding/test/util/BindingTestContext.java @@ -0,0 +1,199 @@ +package org.opendaylight.controller.sal.binding.test.util; + +import java.io.InputStream; +import java.util.ArrayList; +import java.util.List; +import java.util.Set; + +import javassist.ClassPool; + +import org.opendaylight.controller.sal.binding.api.data.DataProviderService; +import org.opendaylight.controller.sal.binding.dom.serializer.impl.RuntimeGeneratedMappingServiceImpl; +import org.opendaylight.controller.sal.binding.impl.DataBrokerImpl; +import org.opendaylight.controller.sal.binding.impl.connect.dom.BindingIndependentDataServiceConnector; +import org.opendaylight.controller.sal.binding.impl.connect.dom.BindingIndependentMappingService; +import org.opendaylight.controller.sal.binding.test.AbstractDataServiceTest; +import org.opendaylight.controller.sal.core.api.data.DataStore; +import org.opendaylight.controller.sal.dom.broker.impl.DataStoreStatsWrapper; +import org.opendaylight.controller.sal.dom.broker.impl.HashMapDataStore; +import org.opendaylight.controller.sal.dom.broker.impl.SchemaAwareDataStoreAdapter; +import org.opendaylight.yangtools.yang.model.api.Module; +import org.opendaylight.yangtools.yang.model.api.SchemaContext; +import org.opendaylight.yangtools.yang.parser.impl.YangParserImpl; +import org.reflections.Reflections; +import org.reflections.scanners.ResourcesScanner; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.google.common.base.Predicate; +import com.google.common.util.concurrent.ListeningExecutorService; +import com.google.common.util.concurrent.MoreExecutors; + +import static com.google.common.base.Preconditions.*; + +public class BindingTestContext { + + + public static final org.opendaylight.yangtools.yang.data.api.InstanceIdentifier TREE_ROOT = org.opendaylight.yangtools.yang.data.api.InstanceIdentifier + .builder().toInstance(); + + private static final Logger LOG = LoggerFactory.getLogger(BindingTestContext.class); + + private RuntimeGeneratedMappingServiceImpl mappingServiceImpl; + private DataBrokerImpl baDataImpl; + private org.opendaylight.controller.sal.dom.broker.DataBrokerImpl biDataImpl; + + private BindingIndependentDataServiceConnector connectorServiceImpl; + private HashMapDataStore rawDataStore; + private SchemaAwareDataStoreAdapter schemaAwareDataStore; + private DataStoreStatsWrapper dataStoreStats; + private DataStore dataStore; + + + private boolean dataStoreStatisticsEnabled = false; + + private final ListeningExecutorService executor; + private final ClassPool classPool; + + private final boolean startWithSchema; + + protected BindingTestContext(ListeningExecutorService executor, ClassPool classPool, boolean startWithSchema) { + this.executor = executor; + this.classPool = classPool; + this.startWithSchema = startWithSchema; + } + + public void startDomDataStore() { + checkState(dataStore == null, "DataStore already started."); + checkState(biDataImpl != null, "Dom Data Broker not present"); + rawDataStore = new HashMapDataStore(); + schemaAwareDataStore = new SchemaAwareDataStoreAdapter(); + schemaAwareDataStore.changeDelegate(rawDataStore); + if(dataStoreStatisticsEnabled) { + dataStoreStats = new DataStoreStatsWrapper(schemaAwareDataStore); + dataStore = dataStoreStats; + } else { + dataStore = schemaAwareDataStore; + } + + biDataImpl.registerConfigurationReader(TREE_ROOT, dataStore); + biDataImpl.registerOperationalReader(TREE_ROOT, dataStore); + biDataImpl.registerCommitHandler(TREE_ROOT, dataStore); + } + + public void startDomDataBroker() { + checkState(executor != null,"Executor needs to be set"); + biDataImpl = new org.opendaylight.controller.sal.dom.broker.DataBrokerImpl(); + biDataImpl.setExecutor(executor); + } + + public void startBindingDataBroker() { + checkState(executor != null,"Executor needs to be set"); + baDataImpl = new DataBrokerImpl(); + baDataImpl.setExecutor(executor); + } + + public void startBindingToDomDataConnector() { + checkState(baDataImpl != null,"Binding Data Broker needs to be started"); + checkState(biDataImpl != null,"DOM Data Broker needs to be started."); + checkState(mappingServiceImpl != null,"DOM Mapping Service needs to be started."); + connectorServiceImpl = new BindingIndependentDataServiceConnector(); + connectorServiceImpl.setBaDataService(baDataImpl); + connectorServiceImpl.setBiDataService(biDataImpl); + connectorServiceImpl.setMappingService(mappingServiceImpl); + connectorServiceImpl.start(); + } + + public void startBindingToDomMappingService() { + checkState(classPool != null,"ClassPool needs to be present"); + mappingServiceImpl = new RuntimeGeneratedMappingServiceImpl(); + mappingServiceImpl.setPool(classPool); + mappingServiceImpl.start(null); + } + + + public void updateYangSchema(String[] files) { + SchemaContext context = getContext(files); + if(schemaAwareDataStore != null) { + schemaAwareDataStore.onGlobalContextUpdated(context); + } + if(mappingServiceImpl != null) { + mappingServiceImpl.onGlobalContextUpdated(context); + } + } + + + public static String[] getAllYangFilesOnClasspath() { + Predicate predicate = new Predicate() { + @Override + public boolean apply(String input) { + return input.endsWith(".yang"); + } + }; + Reflections reflection = new Reflections("META-INF.yang", new ResourcesScanner()); + Set result = reflection.getResources(predicate); + return (String[]) result.toArray(new String[result.size()]); + } + + private static SchemaContext getContext(String[] yangFiles) { + ClassLoader loader = BindingTestContext.class.getClassLoader(); + List streams = new ArrayList<>(); + for (String string : yangFiles) { + InputStream stream = loader.getResourceAsStream(string); + streams.add(stream); + } + YangParserImpl parser = new YangParserImpl(); + Set modules = parser.parseYangModelsFromStreams(streams); + return parser.resolveSchemaContext(modules); + } + + public void start() { + startBindingDataBroker(); + startDomDataBroker(); + startDomDataStore(); + startBindingToDomMappingService(); + startBindingToDomDataConnector(); + if(startWithSchema) { + loadYangSchemaFromClasspath(); + } + } + + public void loadYangSchemaFromClasspath() { + String[] files = getAllYangFilesOnClasspath(); + updateYangSchema(files); + } + + public DataProviderService getBindingDataBroker() { + return baDataImpl; + } + + public org.opendaylight.controller.sal.core.api.data.DataProviderService getDomDataBroker() { + return biDataImpl; + } + + public DataStore getDomDataStore() { + return dataStore; + } + + public BindingIndependentMappingService getBindingToDomMappingService() { + return mappingServiceImpl; + } + + public void logDataStoreStatistics() { + if(dataStoreStats == null) { + return; + } + + LOG.info("BIDataStore Statistics: Configuration Read Count: {} TotalTime: {} ms AverageTime (ns): {} ms", + dataStoreStats.getConfigurationReadCount(), dataStoreStats.getConfigurationReadTotalTime(), + dataStoreStats.getConfigurationReadAverageTime()); + + LOG.info("BIDataStore Statistics: Operational Read Count: {} TotalTime: {} ms AverageTime (ns): {} ms", + dataStoreStats.getOperationalReadCount(), dataStoreStats.getOperationalReadTotalTime(), + dataStoreStats.getOperationalReadAverageTime()); + + LOG.info("BIDataStore Statistics: Request Commit Count: {} TotalTime: {} ms AverageTime (ns): {} ms", + dataStoreStats.getRequestCommitCount(), dataStoreStats.getRequestCommitTotalTime(), + dataStoreStats.getRequestCommitAverageTime()); + } +} diff --git a/opendaylight/md-sal/sal-binding-dom-it/pom.xml b/opendaylight/md-sal/sal-binding-dom-it/pom.xml new file mode 100644 index 0000000000..9a143d3f00 --- /dev/null +++ b/opendaylight/md-sal/sal-binding-dom-it/pom.xml @@ -0,0 +1,82 @@ + + 4.0.0 + + org.opendaylight.controller + sal-parent + 1.0-SNAPSHOT + + sal-binding-dom-it + bundle + + scm:git:ssh://git.opendaylight.org:29418/controller.git + scm:git:ssh://git.opendaylight.org:29418/controller.git + https://wiki.opendaylight.org/view/OpenDaylight_Controller:MD-SAL + + + + + + org.eclipse.xtend + xtend-maven-plugin + + + maven-clean-plugin + + + org.jacoco + jacoco-maven-plugin + + org.opendaylight.controller.* + + + + pre-test + + prepare-agent + + + + post-test + test + + report + + + + + + + + + + org.opendaylight.controller + sal-binding-broker-impl + 1.0-SNAPSHOT + test + + + org.opendaylight.controller + sal-binding-broker-impl + 1.0-SNAPSHOT + test-jar + test + + + org.opendaylight.controller.model + model-flow-service + 1.0-SNAPSHOT + test + + + org.opendaylight.controller.model + model-flow-management + 1.0-SNAPSHOT + test + + + junit + junit + + + diff --git a/opendaylight/md-sal/sal-binding-broker/src/test/java/org/opendaylight/controller/sal/binding/test/bugfix/DOMCodecBug01Test.java b/opendaylight/md-sal/sal-binding-dom-it/src/test/java/org/opendaylight/controller/sal/binding/test/bugfix/DOMCodecBug01Test.java similarity index 100% rename from opendaylight/md-sal/sal-binding-broker/src/test/java/org/opendaylight/controller/sal/binding/test/bugfix/DOMCodecBug01Test.java rename to opendaylight/md-sal/sal-binding-dom-it/src/test/java/org/opendaylight/controller/sal/binding/test/bugfix/DOMCodecBug01Test.java diff --git a/opendaylight/md-sal/sal-binding-broker/src/test/java/org/opendaylight/controller/sal/binding/test/bugfix/DOMCodecBug02Test.java b/opendaylight/md-sal/sal-binding-dom-it/src/test/java/org/opendaylight/controller/sal/binding/test/bugfix/DOMCodecBug02Test.java similarity index 94% rename from opendaylight/md-sal/sal-binding-broker/src/test/java/org/opendaylight/controller/sal/binding/test/bugfix/DOMCodecBug02Test.java rename to opendaylight/md-sal/sal-binding-dom-it/src/test/java/org/opendaylight/controller/sal/binding/test/bugfix/DOMCodecBug02Test.java index 85d484a617..848fb6b190 100644 --- a/opendaylight/md-sal/sal-binding-broker/src/test/java/org/opendaylight/controller/sal/binding/test/bugfix/DOMCodecBug02Test.java +++ b/opendaylight/md-sal/sal-binding-dom-it/src/test/java/org/opendaylight/controller/sal/binding/test/bugfix/DOMCodecBug02Test.java @@ -53,11 +53,6 @@ public class DOMCodecBug02Test extends AbstractDataServiceTest { .toInstance(); private static final NodeRef NODE_REF = new NodeRef(NODE_INSTANCE_ID_BA); - @Override - protected String[] getModelFilenames() { - return null; - } - /** * * @@ -79,9 +74,7 @@ public class DOMCodecBug02Test extends AbstractDataServiceTest { } }); - SchemaContext ctx = getContext(getAllModelFilenames()); - schemaAwareDataStore.onGlobalContextUpdated(ctx); - mappingServiceImpl.onGlobalContextUpdated(ctx); + testContext.loadYangSchemaFromClasspath(); RpcResult result = future.get().get(); assertEquals(TransactionStatus.COMMITED, result.getResult()); @@ -95,5 +88,10 @@ public class DOMCodecBug02Test extends AbstractDataServiceTest { return (Nodes) baDataService.readOperationalData(NODES_INSTANCE_ID_BA); } + + @Override + protected boolean getStartWithSchema() { + return false; + } } diff --git a/opendaylight/md-sal/sal-binding-broker/src/test/java/org/opendaylight/controller/sal/binding/test/bugfix/DOMCodecBug03Test.java b/opendaylight/md-sal/sal-binding-dom-it/src/test/java/org/opendaylight/controller/sal/binding/test/bugfix/DOMCodecBug03Test.java similarity index 100% rename from opendaylight/md-sal/sal-binding-broker/src/test/java/org/opendaylight/controller/sal/binding/test/bugfix/DOMCodecBug03Test.java rename to opendaylight/md-sal/sal-binding-dom-it/src/test/java/org/opendaylight/controller/sal/binding/test/bugfix/DOMCodecBug03Test.java diff --git a/opendaylight/md-sal/sal-binding-broker/src/test/java/org/opendaylight/controller/sal/binding/test/bugfix/RpcRegistrationNullPointer.java b/opendaylight/md-sal/sal-binding-dom-it/src/test/java/org/opendaylight/controller/sal/binding/test/bugfix/RpcRegistrationNullPointer.java similarity index 100% rename from opendaylight/md-sal/sal-binding-broker/src/test/java/org/opendaylight/controller/sal/binding/test/bugfix/RpcRegistrationNullPointer.java rename to opendaylight/md-sal/sal-binding-dom-it/src/test/java/org/opendaylight/controller/sal/binding/test/bugfix/RpcRegistrationNullPointer.java diff --git a/opendaylight/md-sal/sal-binding-broker/src/test/java/org/opendaylight/controller/sal/binding/test/connect/dom/BrokerIntegrationTest.java b/opendaylight/md-sal/sal-binding-dom-it/src/test/java/org/opendaylight/controller/sal/binding/test/connect/dom/BrokerIntegrationTest.java similarity index 100% rename from opendaylight/md-sal/sal-binding-broker/src/test/java/org/opendaylight/controller/sal/binding/test/connect/dom/BrokerIntegrationTest.java rename to opendaylight/md-sal/sal-binding-dom-it/src/test/java/org/opendaylight/controller/sal/binding/test/connect/dom/BrokerIntegrationTest.java diff --git a/opendaylight/md-sal/sal-binding-broker/src/test/java/org/opendaylight/controller/sal/binding/test/connect/dom/ChangeOriginatedInDomBrokerTest.java b/opendaylight/md-sal/sal-binding-dom-it/src/test/java/org/opendaylight/controller/sal/binding/test/connect/dom/ChangeOriginatedInDomBrokerTest.java similarity index 100% rename from opendaylight/md-sal/sal-binding-broker/src/test/java/org/opendaylight/controller/sal/binding/test/connect/dom/ChangeOriginatedInDomBrokerTest.java rename to opendaylight/md-sal/sal-binding-dom-it/src/test/java/org/opendaylight/controller/sal/binding/test/connect/dom/ChangeOriginatedInDomBrokerTest.java diff --git a/opendaylight/md-sal/sal-binding-it/pom.xml b/opendaylight/md-sal/sal-binding-it/pom.xml index 27d426791f..6a994dbd07 100644 --- a/opendaylight/md-sal/sal-binding-it/pom.xml +++ b/opendaylight/md-sal/sal-binding-it/pom.xml @@ -124,6 +124,7 @@ + org.opendaylight.yangtools.thirdparty diff --git a/opendaylight/md-sal/sal-common-impl/src/main/java/org/opendaylight/controller/md/sal/common/impl/service/AbstractDataBroker.xtend b/opendaylight/md-sal/sal-common-impl/src/main/java/org/opendaylight/controller/md/sal/common/impl/service/AbstractDataBroker.xtend index da47438a6b..32e59b869e 100644 --- a/opendaylight/md-sal/sal-common-impl/src/main/java/org/opendaylight/controller/md/sal/common/impl/service/AbstractDataBroker.xtend +++ b/opendaylight/md-sal/sal-common-impl/src/main/java/org/opendaylight/controller/md/sal/common/impl/service/AbstractDataBroker.xtend @@ -345,10 +345,19 @@ public abstract class AbstractDataTransaction

, D> extends Abst } override readConfigurationData(P path) { + val local = this.updatedConfigurationData.get(path); + if(local != null) { + return local; + } + return broker.readConfigurationData(path); } override readOperationalData(P path) { + val local = this.updatedOperationalData.get(path); + if(local != null) { + return local; + } return broker.readOperationalData(path); } -- 2.36.6