<version>1.0-SNAPSHOT</version>
<scope>test</scope>
</dependency>
+ <dependency>
+ <groupId>org.opendaylight.controller.model</groupId>
+ <artifactId>model-flow-management</artifactId>
+ <version>1.0-SNAPSHOT</version>
+ <scope>test</scope>
+ </dependency>
<dependency>
<groupId>org.opendaylight.yangtools</groupId>
<artifactId>yang-data-impl</artifactId>
<version>${slf4j.version}</version>
<scope>test</scope>
</dependency>
+ <dependency>
+ <groupId>org.reflections</groupId>
+ <artifactId>reflections</artifactId>
+ <version>0.9.9-RC1</version>
+ <scope>test</scope>
+ </dependency>
</dependencies>
</project>
--- /dev/null
+package org.opendaylight.controller.sal.binding.codegen;
+
+public class CodeGenerationException extends RuntimeException{
+
+ public CodeGenerationException() {
+ super();
+ }
+
+ public CodeGenerationException(String message, Throwable cause, boolean enableSuppression,
+ boolean writableStackTrace) {
+ super(message, cause, enableSuppression, writableStackTrace);
+ }
+
+ public CodeGenerationException(String message, Throwable cause) {
+ super(message, cause);
+ }
+
+ public CodeGenerationException(String message) {
+ super(message);
+ }
+
+ public CodeGenerationException(Throwable cause) {
+ super(cause);
+ }
+}
import org.opendaylight.yangtools.yang.binding.BindingSerializer
import org.opendaylight.yangtools.yang.binding.BindingCodec
import org.slf4j.LoggerFactory
+import org.opendaylight.controller.sal.binding.codegen.CodeGenerationException
+import org.opendaylight.yangtools.yang.model.api.ChoiceNode
+import java.security.ProtectionDomain
+import java.io.File
class TransformerGenerator {
CtClass ctQName
+ @Property
+ var File classFileCapturePath;
+
+
@Property
var Map<Type, Type> typeDefinitions;
]
}
- def Class<?> keyTransformerFor(Class<?> inputType, GeneratedType type, ListSchemaNode schema) {
+ private def Class<?> keyTransformerFor(Class<?> inputType, GeneratedType type, ListSchemaNode schema) {
return withClassLoader(inputType.classLoader) [ |
val transformer = generatedClasses.get(inputType);
if (transformer != null) {
}
- def Class<?> getValueSerializer(GeneratedTransferObject type) {
+ private def Class<?> getValueSerializer(GeneratedTransferObject type) {
val cls = loadClassWithTCCL(type.resolvedName);
val transformer = generatedClasses.get(cls);
if (transformer !== null) {
'''
]
]
- val ret = ctCls.toClass(inputType.classLoader, inputType.protectionDomain)
+ val ret = ctCls.toClassImpl(inputType.classLoader, inputType.protectionDomain)
log.info("DOM Codec for {} was generated {}",inputType,ret)
return ret as Class<? extends BindingCodec<Map<QName,Object>, ?>>;
} catch (Exception e) {
- log.error("Cannot compile DOM Codec for {}. Exception {}",inputType,e);
- val exception = new IllegalStateException("Cannot compile Transformator for " + inputType);
- exception.addSuppressed(e);
- throw exception;
+ processException(inputType,e);
+ return null;
}
}
- private def <D> Class<? extends BindingCodec<Map<QName, Object>, D>> generateTransformerFor(Class<D> inputType,
+ private def dispatch Class<? extends BindingCodec<Map<QName, Object>, Object>> generateTransformerFor(Class inputType,
GeneratedType typeSpec, SchemaNode node) {
try {
log.info("Generating DOM Codec for {} with {}",inputType,inputType.classLoader)
]
]
- val ret = ctCls.toClass(inputType.classLoader, inputType.protectionDomain)
- return ret as Class<? extends BindingCodec<Map<QName,Object>, D>>;
+ val ret = ctCls.toClassImpl(inputType.classLoader, inputType.protectionDomain)
+ return ret as Class<? extends BindingCodec<Map<QName,Object>, Object>>;
} catch (Exception e) {
- log.error("Cannot compile DOM Codec for {}. Exception {}",inputType,e);
- val exception = new IllegalStateException("Cannot compile Transformator for " + inputType);
- exception.addSuppressed(e);
- throw exception;
+ processException(inputType,e);
+ return null;
}
}
+
+
+ private def dispatch Class<? extends BindingCodec<Map<QName, Object>, Object>> generateTransformerFor(Class inputType,
+ GeneratedType typeSpec, ChoiceNode node) {
+ try {
+ log.info("Generating DOM Codec for {} with {}",inputType,inputType.classLoader)
+ val ctCls = createClass(typeSpec.transformatorFqn) [
+ //staticField(Map,"AUGMENTATION_SERIALIZERS");
+ //staticQNameField(inputType);
+ implementsType(ctTransformator)
+ method(Object, "toDomStatic", QName, Object) [
+ modifiers = PUBLIC + FINAL + STATIC
+ body = '''
+ return null;
+ '''
+ ]
+ method(Object, "serialize", Object) [
+ body = '''
+ return null;
+ '''
+ ]
+ method(Object, "fromDomStatic", QName, Object) [
+ modifiers = PUBLIC + FINAL + STATIC
+ body = '''
+ return null;
+ '''
+ ]
+ method(Object, "deserialize", Object) [
+ body = '''
+ return null;
+ '''
+ ]
+ ]
+
+ val ret = ctCls.toClassImpl(inputType.classLoader, inputType.protectionDomain)
+ return ret as Class<? extends BindingCodec<Map<QName,Object>, Object>>;
+ } catch (Exception e) {
+ processException(inputType,e);
+ return null;
+ }
+ }
+
private def keyConstructorList(List<QName> qnames) {
val names = new TreeSet<String>()
DataNodeContainer node) {
val ret = '''
«FOR child : node.childNodes.filter[!augmenting]»
- «val signature = properties.get(child.getterName)»
+ «val signature = properties.getFor(child)»
«deserializeProperty(child, signature.returnType, signature)»
_builder.«signature.name.toSetter»(«signature.name»);
«ENDFOR»
if (returnType == null) {
val ctCls = createDummyImplementation(inputType, typeSpec);
- val ret = ctCls.toClass(inputType.classLoader, inputType.protectionDomain)
+ val ret = ctCls.toClassImpl(inputType.classLoader, inputType.protectionDomain)
return ret as Class<? extends BindingCodec<Map<QName,Object>, Object>>;
}
val ctCls = createClass(typeSpec.transformatorFqn) [
if($1 == null) {
return null;
}
- «returnType.name» _simpleValue = «deserializeValue(returnType, "$1")»;
+ «returnType.resolvedName» _simpleValue = «deserializeValue(returnType, "$1")»;
«typeSpec.resolvedName» _value = new «typeSpec.resolvedName»(_simpleValue);
return _value;
}
]
]
- val ret = ctCls.toClass(inputType.classLoader, inputType.protectionDomain)
+ val ret = ctCls.toClassImpl(inputType.classLoader, inputType.protectionDomain)
log.info("DOM Codec for {} was generated {}",inputType,ret)
return ret as Class<? extends BindingCodec<Map<QName,Object>, Object>>;
} catch (Exception e) {
- log.error("Cannot compile DOM Codec for {}. Exception {}",inputType,e);
- val exception = new IllegalStateException("Cannot compile Transformator for " + inputType);
+ log.error("Cannot compile DOM Codec for {}",inputType,e);
+ val exception = new CodeGenerationException("Cannot compile Transformator for " + inputType);
exception.addSuppressed(e);
throw exception;
}
]
}
- def Type getValueReturnType(GeneratedTransferObject object) {
+ private def Type getValueReturnType(GeneratedTransferObject object) {
for (prop : object.properties) {
if (prop.name == "value") {
return prop.returnType;
]
]
- val ret = ctCls.toClass(inputType.classLoader, inputType.protectionDomain)
+ val ret = ctCls.toClassImpl(inputType.classLoader, inputType.protectionDomain)
log.info("DOM Codec for {} was generated {}",inputType,ret)
return ret as Class<? extends BindingCodec<Map<QName,Object>, Object>>;
+ } catch (CodeGenerationException e) {
+ throw new CodeGenerationException("Cannot compile Transformator for " + inputType,e);
} catch (Exception e) {
- log.error("Cannot compile DOM Codec for {}. Exception {}",inputType,e);
- val exception = new IllegalStateException("Cannot compile Transformator for " + inputType);
+ log.error("Cannot compile DOM Codec for {}",inputType,e);
+ val exception = new CodeGenerationException("Cannot compile Transformator for " + inputType);
exception.addSuppressed(e);
throw exception;
}
+ }
+
+ def Class<?> toClassImpl(CtClass newClass, ClassLoader loader, ProtectionDomain domain) {
+ val cls = newClass.toClass(loader,domain);
+ if(classFileCapturePath !== null) {
+ newClass.writeFile(classFileCapturePath.absolutePath);
+ }
+ return cls;
+ }
+
+ def debugWriteClass(CtClass class1) {
+ val path = class1.name.replace(".","/")+".class"
+
+ val captureFile = new File(classFileCapturePath,path);
+ captureFile.createNewFile
+
+
}
private def dispatch String deserializeValue(Type type, String domParameter) '''(«type.resolvedName») «domParameter»'''
}
'''
+ private def dispatch String serializeBody(GeneratedType type, ChoiceCaseNode node) '''
+ {
+ «QName.name» resultName = «QName.name».create($1,QNAME.getLocalName());
+ java.util.List childNodes = new java.util.ArrayList();
+ «type.resolvedName» value = («type.resolvedName») $2;
+ «transformDataContainerBody(type.allProperties, node)»
+ return ($r) java.util.Collections.singletonMap(resultName,childNodes);
+ }
+ '''
+
+ private def dispatch String serializeBody(GeneratedType type, SchemaNode node) '''
+ {
+ «QName.name» resultName = «QName.name».create($1,QNAME.getLocalName());
+ java.util.List childNodes = new java.util.ArrayList();
+ «type.resolvedName» value = («type.resolvedName») $2;
+ return ($r) java.util.Collections.singletonMap(resultName,childNodes);
+ }
+ '''
+
+
private def transformDataContainerBody(Map<String, MethodSignature> properties, DataNodeContainer node) {
val ret = '''
«FOR child : node.childNodes.filter[!augmenting]»
- «val signature = properties.get(child.getterName)»
+ «var signature = properties.getFor(child)»
«serializeProperty(child, signature.returnType, signature)»
«ENDFOR»
'''
return ret;
}
+
+ def MethodSignature getFor(Map<String,MethodSignature> map, DataSchemaNode node) {
+ val sig = map.get(node.getterName);
+ if(sig == null) {
+ return map.get(node.booleanGetterName);
+ }
+ return sig;
+ }
+
+ private static def String getBooleanGetterName(DataSchemaNode node) {
+ return "is" + BindingGeneratorUtil.parseToClassName(node.QName.localName);
+ }
private static def String getGetterName(DataSchemaNode node) {
return "get" + BindingGeneratorUtil.parseToClassName(node.QName.localName);
MethodSignature property) '''
«property.returnType.resolvedName» «property.name» = value.«property.name»();
if(«property.name» != null) {
- Object domValue = «type.serializer».toDomStatic(QNAME,«property.name»);
+ Object domValue = «type.serializer.name».toDomStatic(QNAME,«property.name»);
childNodes.add(domValue);
}
'''
- private def dispatch String serializeBody(GeneratedType type, SchemaNode node) '''
- {
- return ($r) java.util.Collections.singletonMap(this.QNAME,null);
- }
- '''
+
private def transformatorFqn(GeneratedType typeSpec) {
return '''«typeSpec.resolvedName»$Broker$Codec$DOM'''
val cls = loadClassWithTCCL(type.fullyQualifiedName)
return cls.asCtClass;
}
+
+
+
+ private def dispatch processException(Class<?> inputType,CodeGenerationException e){
+ log.error("Cannot compile DOM Codec for {}. One of it's prerequisites was not generated.",inputType);
+ throw e;
+ }
+
+ private def dispatch processException(Class<?> inputType,Exception e){
+ log.error("Cannot compile DOM Codec for {}",inputType,e);
+ val exception = new CodeGenerationException("Cannot compile Transformator for " + inputType,e);
+ throw exception;
+ }
}
class BindingMapping {
-
-
@Property
val Map<Type, GeneratedTypeBuilder> typeToDefinition = new HashMap();
public static Class<?> loadClassWithTCCL(String name) throws ClassNotFoundException {
+ if("byte[]".equals(name)) {
+ return byte[].class;
+ }
+
return Thread.currentThread().getContextClassLoader().loadClass(name);
}
}
\ No newline at end of file
--- /dev/null
+package org.opendaylight.controller.sal.binding.test;
+
+import java.io.File;
+import java.io.InputStream;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Set;
+
+import org.junit.Before;
+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.impl.connect.dom.RuntimeGeneratedMappingServiceImpl;
+import org.opendaylight.controller.sal.binding.test.connect.dom.MappingServiceTest;
+import org.opendaylight.controller.sal.core.api.data.DataBrokerService;
+import org.opendaylight.controller.sal.dom.broker.impl.HashMapDataStore;
+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 com.google.common.base.Predicate;
+import com.google.common.util.concurrent.ListeningExecutorService;
+import com.google.common.util.concurrent.MoreExecutors;
+
+public abstract class AbstractDataServiceTest {
+ protected DataBrokerService biDataService;
+ protected DataProviderService baDataService;
+
+ 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 dataStore;
+
+
+ @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);
+
+ dataStore = new HashMapDataStore();
+ 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();
+ mappingService = mappingServiceImpl;
+ File pathname = new File("target/gen-classes-debug");
+ //System.out.println("Generated classes are captured in " + pathname.getAbsolutePath());
+ mappingServiceImpl.start();
+ //mappingServiceImpl.getBinding().setClassFileCapturePath(pathname);
+
+ connectorServiceImpl = new BindingIndependentDataServiceConnector();
+ connectorServiceImpl.setBaDataService(baDataService);
+ connectorServiceImpl.setBiDataService(biDataService);
+ connectorServiceImpl.setMappingService(mappingServiceImpl);
+ connectorServiceImpl.start();
+
+ String[] yangFiles= getModelFilenames();
+ mappingServiceImpl.onGlobalContextUpdated(getContext(yangFiles));
+ }
+
+
+ protected String[] getModelFilenames() {
+ return getModelFilenamesImpl();
+ }
+
+ public static String[] getModelFilenamesImpl() {
+ Predicate<String> predicate = new Predicate<String>() {
+ @Override
+ public boolean apply(String input) {
+ return input.endsWith(".yang");
+ }
+ };
+ Reflections reflection= new Reflections("META-INF.yang", new ResourcesScanner());
+ Set<String> result = reflection.getResources(predicate);
+ return (String[]) result.toArray(new String[result.size()]);
+ }
+
+ public static SchemaContext getContext(String[] yangFiles) {
+
+ ClassLoader loader = AbstractDataServiceTest.class.getClassLoader();
+
+ List<InputStream> streams = new ArrayList<>();
+ for (String string : yangFiles) {
+ InputStream stream = loader.getResourceAsStream(string);
+ streams.add(stream);
+
+ }
+ YangParserImpl parser = new YangParserImpl();
+
+ Set<Module> modules = parser.parseYangModelsFromStreams(streams);
+ return parser.resolveSchemaContext(modules);
+ }
+}
--- /dev/null
+package org.opendaylight.controller.sal.binding.test.bugfix;
+
+import java.util.Collections;
+import java.util.Map;
+
+import org.junit.Test;
+import org.opendaylight.controller.md.sal.common.api.TransactionStatus;
+import org.opendaylight.controller.sal.binding.test.AbstractDataServiceTest;
+import org.opendaylight.controller.sal.binding.api.data.DataModificationTransaction;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.config.rev130819.Flows;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.config.rev130819.flows.Flow;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.config.rev130819.flows.FlowBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.config.rev130819.flows.FlowKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.Match;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.MatchBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeId;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeRef;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.Nodes;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.NodeKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.l2.types.rev130827.VlanId;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.VlanMatchBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.vlan.match.fields.VlanIdBuilder;
+import org.opendaylight.yangtools.yang.binding.DataObject;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.opendaylight.yangtools.yang.common.QName;
+import org.opendaylight.yangtools.yang.common.RpcResult;
+import org.opendaylight.yangtools.yang.data.api.CompositeNode;
+
+import com.google.common.collect.ImmutableMap;
+
+import static org.junit.Assert.*;
+
+/**
+ *
+ * Testcase for https://bugs.opendaylight.org/show_bug.cgi?id=144
+ *
+ * Cannot compile CoDec for org.opendaylight.yang.gen.v1.urn.opendaylight.flow.config.rev130819.flows.Flow
+ *
+ * @author ttkacik
+ *
+ */
+public class DOMCodecBug01Test extends AbstractDataServiceTest {
+
+ private static final QName NODE_ID_QNAME = QName.create(Node.QNAME, "id");
+ private static final QName FLOW_ID_QNAME = QName.create(Flow.QNAME, "id");
+ private static final QName FLOW_NODE_QNAME = QName.create(Flow.QNAME, "node");
+
+ private static final String FLOW_ID = "foo";
+ private static final String NODE_ID = "node:1";
+
+ private static final NodeKey NODE_KEY = new NodeKey(new NodeId(NODE_ID));
+ private static final InstanceIdentifier<Node> NODE_INSTANCE_ID_BA = InstanceIdentifier.builder().node(Nodes.class)
+ .node(Node.class, NODE_KEY).toInstance();
+
+
+ private static final Map<QName, Object> NODE_KEY_BI = Collections.<QName, Object> singletonMap(NODE_ID_QNAME,
+ NODE_ID);
+
+ private static final org.opendaylight.yangtools.yang.data.api.InstanceIdentifier NODE_INSTANCE_ID_BI = //
+ org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.builder() //
+ .node(Nodes.QNAME) //
+ .nodeWithKey(Node.QNAME, NODE_KEY_BI) //
+ .toInstance();
+ private static final NodeRef NODE_REF = new NodeRef(NODE_INSTANCE_ID_BA);
+
+ private static final FlowKey FLOW_KEY = new FlowKey(FLOW_ID, NODE_REF);
+
+ private static final Map<QName, Object> FLOW_KEY_BI = //
+ ImmutableMap.<QName,Object>of(FLOW_ID_QNAME, FLOW_ID, FLOW_NODE_QNAME, NODE_REF);
+
+
+
+
+ private static final org.opendaylight.yangtools.yang.data.api.InstanceIdentifier FLOW_INSTANCE_ID_BI = //
+ org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.builder() //
+ .node(Flows.QNAME) //
+ .nodeWithKey(Flow.QNAME, FLOW_KEY_BI) //
+ .toInstance();
+ private static final InstanceIdentifier<? extends DataObject> FLOW_INSTANCE_ID_BA = //
+ InstanceIdentifier.builder() //
+ .node(Flows.class) //
+ .node(Flow.class, FLOW_KEY) //
+ .toInstance();
+ /**
+ *
+ * When invoking following code in the consumer, user got an
+ * IllegalStateException during creation of mapping between Java DTOs and
+ * data-dom.
+ *
+ * Exception was compilation error which was caused by incorect generation
+ * of code.
+ *
+ *
+ */
+ @Test
+ public void testIndirectGeneration() throws Exception {
+
+ DataModificationTransaction modification = baDataService.beginTransaction();
+
+ FlowBuilder flow = new FlowBuilder();
+ MatchBuilder match = new MatchBuilder();
+ VlanMatchBuilder vlanBuilder = new VlanMatchBuilder();
+ VlanIdBuilder vlanIdBuilder = new VlanIdBuilder();
+ VlanId vlanId = new VlanId(10);
+ vlanBuilder.setVlanId(vlanIdBuilder.setVlanId(vlanId).build());
+ match.setVlanMatch(vlanBuilder.build());
+
+ flow.setKey(FLOW_KEY);
+ flow.setMatch(match.build());
+ flow.setNode(NODE_REF);
+
+ modification.putConfigurationData(FLOW_INSTANCE_ID_BA, flow.build());
+ RpcResult<TransactionStatus> ret = modification.commit().get();
+ assertNotNull(ret);
+ assertEquals(TransactionStatus.COMMITED, ret.getResult());
+
+ verifyDataAreStoredProperly();
+
+
+ DataModificationTransaction modification2 = baDataService.beginTransaction();
+ modification2.removeConfigurationData(FLOW_INSTANCE_ID_BA);
+
+ DataObject originalData = modification2.getOriginalConfigurationData().get(FLOW_INSTANCE_ID_BA);
+ assertNotNull(originalData);
+ RpcResult<TransactionStatus> ret2 = modification2.commit().get();
+
+ assertNotNull(ret2);
+ assertEquals(TransactionStatus.COMMITED, ret2.getResult());
+
+
+ // Data are not in the store.
+ assertNull(baDataService.readOperationalData(FLOW_INSTANCE_ID_BA));
+
+
+ }
+
+ private void verifyDataAreStoredProperly() {
+ CompositeNode biFlow = biDataService.readConfigurationData(FLOW_INSTANCE_ID_BI);
+ assertNotNull(biFlow);
+ CompositeNode biMatch = biFlow.getFirstCompositeByName(QName.create(Flow.QNAME,Match.QNAME.getLocalName()));
+ assertNotNull(biMatch);
+ }
+}
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
-import java.util.concurrent.Executors;
+
import java.util.concurrent.Future;
-import org.junit.Before;
+
import org.junit.Test;
import org.opendaylight.controller.md.sal.common.api.TransactionStatus;
import org.opendaylight.controller.sal.binding.api.data.DataModificationTransaction;
-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.impl.connect.dom.MappingServiceImpl;
-import org.opendaylight.controller.sal.binding.impl.connect.dom.RuntimeGeneratedMappingServiceImpl;
-import org.opendaylight.controller.sal.core.api.data.DataBrokerService;
-import org.opendaylight.controller.sal.dom.broker.impl.HashMapDataStore;
+
+import org.opendaylight.controller.sal.binding.test.AbstractDataServiceTest;
+
import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeId;
import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeRef;
import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.Nodes;
import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
import org.opendaylight.yangtools.yang.common.RpcResult;
-import com.google.common.util.concurrent.ListeningExecutorService;
-import com.google.common.util.concurrent.MoreExecutors;
-
-public class BrokerIntegrationTest {
-
- DataBrokerService biDataService;
- DataProviderService baDataService;
- private RuntimeGeneratedMappingServiceImpl mappingServiceImpl;
- private BindingIndependentMappingService mappingService;
- private DataBrokerImpl baDataImpl;
- private org.opendaylight.controller.sal.dom.broker.DataBrokerImpl biDataImpl;
- private ListeningExecutorService executor;
- private BindingIndependentDataServiceConnector connectorServiceImpl;
- private HashMapDataStore dataStore;
-
-
- @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);
-
- dataStore = new HashMapDataStore();
- 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();
- mappingService = mappingServiceImpl;
- mappingServiceImpl.start();
-
- connectorServiceImpl = new BindingIndependentDataServiceConnector();
- connectorServiceImpl.setBaDataService(baDataService);
- connectorServiceImpl.setBiDataService(biDataService);
- connectorServiceImpl.setMappingService(mappingServiceImpl);
- connectorServiceImpl.start();
-
- String[] yangFiles = new String[] { "yang-ext.yang", "ietf-inet-types.yang", "ietf-yang-types.yang",
- "node-inventory.yang" };
-
- mappingServiceImpl.onGlobalContextUpdated(MappingServiceTest.getContext(yangFiles));
-
- }
-
+public class BrokerIntegrationTest extends AbstractDataServiceTest {
+
@Test
public void simpleModifyOperation() throws Exception {
-
-
+
NodeRef node1 = createNodeRef("0");
- DataObject node = baDataService.readConfigurationData(node1.getValue());
+ DataObject node = baDataService.readConfigurationData(node1.getValue());
assertNull(node);
Node nodeData1 = createNode("0");
-
-
+
DataModificationTransaction transaction = baDataService.beginTransaction();
transaction.putConfigurationData(node1.getValue(), nodeData1);
Future<RpcResult<TransactionStatus>> commitResult = transaction.commit();
assertNotNull(commitResult);
-
+
RpcResult<TransactionStatus> result = commitResult.get();
-
+
assertNotNull(result);
assertNotNull(result.getResult());
assertEquals(TransactionStatus.COMMITED, result.getResult());
-
+
Node readedData = (Node) baDataService.readConfigurationData(node1.getValue());
assertNotNull(readedData);
assertEquals(nodeData1.getKey(), readedData.getKey());
-
-
+
NodeRef nodeFoo = createNodeRef("foo");
NodeRef nodeBar = createNodeRef("bar");
Node nodeFooData = createNode("foo");
Node nodeBarData = createNode("bar");
-
-
+
DataModificationTransaction insertMoreTr = baDataService.beginTransaction();
insertMoreTr.putConfigurationData(nodeFoo.getValue(), nodeFooData);
insertMoreTr.putConfigurationData(nodeBar.getValue(), nodeBarData);
RpcResult<TransactionStatus> result2 = insertMoreTr.commit().get();
-
+
assertNotNull(result2);
assertNotNull(result2.getResult());
assertEquals(TransactionStatus.COMMITED, result.getResult());
-
- Nodes allNodes = (Nodes) baDataService.readConfigurationData(InstanceIdentifier.builder().node(Nodes.class).toInstance());
+
+ Nodes allNodes = (Nodes) baDataService.readConfigurationData(InstanceIdentifier.builder().node(Nodes.class)
+ .toInstance());
assertNotNull(allNodes);
assertNotNull(allNodes.getNode());
assertEquals(3, allNodes.getNode().size());
-
-
+
/**
* We create transaction no 2
*
*/
DataModificationTransaction removalTransaction = baDataService.beginTransaction();
assertNotNull(transaction);
-
+
/**
* We remove node 1
*
*/
removalTransaction.removeConfigurationData(node1.getValue());
-
+
/**
* We commit transaction
*/
Future<RpcResult<TransactionStatus>> commitResult2 = removalTransaction.commit();
assertNotNull(commitResult2);
-
+
RpcResult<TransactionStatus> result3 = commitResult2.get();
-
+
assertNotNull(result3);
assertNotNull(result3.getResult());
assertEquals(TransactionStatus.COMMITED, result2.getResult());
-
+
DataObject readedData2 = baDataService.readConfigurationData(node1.getValue());
assertNull(readedData2);
}
-
+
private static NodeRef createNodeRef(String string) {
NodeKey key = new NodeKey(new NodeId(string));
InstanceIdentifier<Node> path = InstanceIdentifier.builder().node(Nodes.class).node(Node.class, key)
.toInstance();
return new NodeRef(path);
}
-
+
private static Node createNode(String string) {
NodeBuilder ret = new NodeBuilder();
ret.setId(new NodeId(string));
import org.junit.Test;
import org.opendaylight.controller.sal.binding.impl.connect.dom.BindingIndependentMappingService;
import org.opendaylight.controller.sal.binding.impl.connect.dom.MappingServiceImpl;
+import org.opendaylight.controller.sal.binding.test.AbstractDataServiceTest;
import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeId;
import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.Nodes;
import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodesBuilder;
@Test
public void baDataToBiData() throws Exception {
- String[] yangFiles = new String[] { "yang-ext.yang", "ietf-inet-types.yang", "ietf-yang-types.yang",
- "node-inventory.yang" };
+ String[] yangFiles = AbstractDataServiceTest.getModelFilenamesImpl();
- SchemaContext ctx = getContext(yangFiles);
+ SchemaContext ctx = AbstractDataServiceTest.getContext(yangFiles);
impl.onGlobalContextUpdated(ctx);
@Test
public void instanceIdentifierTest() throws Exception {
- String[] yangFiles = new String[] { "yang-ext.yang", "ietf-inet-types.yang", "ietf-yang-types.yang",
- "node-inventory.yang" };
- SchemaContext ctx = getContext(yangFiles);
+ String[] yangFiles = AbstractDataServiceTest.getModelFilenamesImpl();
+ SchemaContext ctx = AbstractDataServiceTest.getContext(yangFiles);
impl.onGlobalContextUpdated(ctx);
NodeKey nodeKey = new NodeKey(new NodeId("foo"));
assertEquals(2, result.getPath().size());
}
- public static SchemaContext getContext(String[] yangFiles) {
-
- ClassLoader loader = MappingServiceTest.class.getClassLoader();
-
- List<InputStream> streams = new ArrayList<>();
- for (String string : yangFiles) {
- InputStream stream = loader.getResourceAsStream("META-INF/yang/" + string);
- streams.add(stream);
-
- }
- YangParserImpl parser = new YangParserImpl();
-
- Set<Module> modules = parser.parseYangModelsFromStreams(streams);
- return parser.resolveSchemaContext(modules);
- }
-
private Node createChildNode(String id) {
NodeBuilder node = new NodeBuilder();
NodeId nodeId = new NodeId(id);