import java.util.concurrent.locks.Lock
import java.util.concurrent.Callable
import org.opendaylight.controller.sal.binding.impl.util.ClassLoaderUtils
+import org.opendaylight.yangtools.yang.model.api.TypeDefinition
+import org.opendaylight.yangtools.yang.model.api.type.UnionTypeDefinition
+import org.opendaylight.yangtools.yang.model.api.type.BitsTypeDefinition
+import java.util.HashSet
+import java.util.Collections
+import org.opendaylight.yangtools.yang.model.api.type.BitsTypeDefinition.Bit
+import java.util.Set
+import org.opendaylight.controller.sal.binding.codegen.impl.XtendHelper
class TransformerGenerator {
transformerFor(cls, node);
}
- private def Class<?> getValueSerializer(GeneratedTransferObject type) {
+ private def Class<?> valueSerializer(GeneratedTransferObject type, TypeDefinition<?> typeDefinition) {
val cls = loadClassWithTCCL(type.resolvedName);
val transformer = cls.generatedClass;
if (transformer !== null) {
return transformer;
}
+ var baseType = typeDefinition;
+ while (baseType.baseType != null) {
+ baseType = baseType.baseType;
+ }
+ val finalType = baseType;
return withClassLoaderAndLock(cls.classLoader, lock) [ |
- val valueTransformer = generateValueTransformer(cls, type);
+ val valueTransformer = generateValueTransformer(cls, type, finalType);
return valueTransformer;
]
}
- private def Class<?> getValueSerializer(Enumeration type) {
+ private def Class<?> valueSerializer(Enumeration type, TypeDefinition<?> typeDefinition) {
val cls = loadClassWithTCCL(type.resolvedName);
val transformer = cls.generatedClass;
if (transformer !== null) {
]
]
val ret = ctCls.toClassImpl(inputType.classLoader, inputType.protectionDomain)
- log.info("DOM Codec for {} was generated {}", inputType, ret)
+ log.debug("DOM Codec for {} was generated {}", inputType, ret)
return ret as Class<? extends BindingCodec<Map<QName,Object>, ?>>;
} catch (Exception e) {
processException(inputType, e);
method(Object, "deserialize", Object) [
bodyChecked = '''
{
- //System.out.println("«type.name»#deserialize: " +$1);
+ ////System.out.println("«type.name»#deserialize: " +$1);
java.util.Map.Entry _input = (java.util.Map.Entry) $1;
return fromDomStatic((«QName.name»)_input.getKey(),_input.getValue());
}
val ret = ctCls.toClassImpl(inputType.classLoader, inputType.protectionDomain) as Class<? extends BindingCodec<Object, Object>>
listener?.onDataContainerCodecCreated(inputType, ret);
- log.info("DOM Codec for {} was generated {}", inputType, ret)
+ log.debug("DOM Codec for {} was generated {}", inputType, ret)
return ret;
} catch (Exception e) {
processException(inputType, e);
val ret = ctCls.toClassImpl(inputType.classLoader, inputType.protectionDomain) as Class<? extends BindingCodec<Map<QName,Object>, Object>>
listener?.onDataContainerCodecCreated(inputType, ret);
- log.info("DOM Codec for {} was generated {}", inputType, ret)
+ log.debug("DOM Codec for {} was generated {}", inputType, ret)
return ret;
} catch (Exception e) {
processException(inputType, e);
modifiers = PUBLIC + FINAL + STATIC
bodyChecked = '''
{
- //System.out.println("Qname " + $1);
- //System.out.println("Value " + $2);
+ ////System.out.println("Qname " + $1);
+ ////System.out.println("Value " + $2);
«QName.name» _resultName = «QName.name».create(QNAME,QNAME.getLocalName());
java.util.List _childNodes = new java.util.ArrayList();
«type.resolvedName» value = («type.resolvedName») $2;
«FOR child : node.childNodes»
«var signature = properties.getFor(child)»
- //System.out.println("«signature.key»" + value.«signature.key»());
+ ////System.out.println("«signature.key»" + value.«signature.key»());
«serializeProperty(child, signature.value, signature.key)»
«ENDFOR»
return ($r) _childNodes;
return null;
}
java.util.Map _compositeNode = (java.util.Map) $2;
- //System.out.println(_localQName + " " + _compositeNode);
+ ////System.out.println(_localQName + " " + _compositeNode);
«type.builderName» _builder = new «type.builderName»();
boolean _is_empty = true;
«FOR child : node.childNodes»
}
java.util.Map.Entry _input = new «SimpleEntry.name»($1,_baValue);
Object _ret = _codec.serialize(_input);
- //System.out.println("«typeSpec.name»#toDomStatic: " + _ret);
+ ////System.out.println("«typeSpec.name»#toDomStatic: " + _ret);
return («List.name») _ret;
}
'''
val rawRet = ctCls.toClassImpl(inputType.classLoader, inputType.protectionDomain)
val ret = rawRet as Class<? extends BindingCodec<Map<QName,Object>, Object>>;
listener?.onChoiceCodecCreated(inputType, ret, node);
- log.info("DOM Codec for {} was generated {}", inputType, ret)
+ log.debug("DOM Codec for {} was generated {}", inputType, ret)
return ret;
} catch (Exception e) {
processException(inputType, e);
return null;
}
java.util.Map _compositeNode = (java.util.Map) $2;
- //System.out.println(_localQName + " " + _compositeNode);
+ ////System.out.println(_localQName + " " + _compositeNode);
«type.builderName» _builder = new «type.builderName»();
«deserializeDataNodeContainerBody(type, node)»
«deserializeAugmentations»
«Iterator.name» _entries = _augmentation.entrySet().iterator();
while(_entries.hasNext()) {
java.util.Map.Entry _entry = (java.util.Map.Entry) _entries.next();
- //System.out.println("Aug. key:" + _entry.getKey());
+ ////System.out.println("Aug. key:" + _entry.getKey());
Class _type = (Class) _entry.getKey();
«Augmentation.resolvedName» _value = («Augmentation.name») _entry.getValue();
if(_value != null) {
String propertyName) '''
java.util.List _dom_«propertyName» = _compositeNode.get(«QName.name».create(_localQName,"«schema.QName.
localName»"));
- //System.out.println("«propertyName»#deCode"+_dom_«propertyName»);
+ ////System.out.println("«propertyName»#deCode"+_dom_«propertyName»);
java.util.List «propertyName» = new java.util.ArrayList();
if(_dom_«propertyName» != null) {
java.util.List _serialized = new java.util.ArrayList();
while(_hasNext) {
Object _listItem = _iterator.next();
_is_empty = false;
- //System.out.println(" item" + _listItem);
+ ////System.out.println(" item" + _listItem);
Object _value = «type.actualTypeArguments.get(0).serializer(schema).resolvedName».fromDomStatic(_localQName,_listItem);
- //System.out.println(" value" + _value);
+ ////System.out.println(" value" + _value);
«propertyName».add(_value);
_hasNext = _iterator.hasNext();
}
}
- //System.out.println(" list" + «propertyName»);
+ ////System.out.println(" list" + «propertyName»);
'''
private def dispatch CharSequence deserializeProperty(LeafListSchemaNode schema, ParameterizedType type,
Object _listItem = _iterator.next();
if(_listItem instanceof java.util.Map.Entry) {
Object _innerValue = ((java.util.Map.Entry) _listItem).getValue();
- Object _value = «deserializeValue(type.actualTypeArguments.get(0), "_innerValue")»;
+ Object _value = «deserializeValue(type.actualTypeArguments.get(0), "_innerValue", schema.type)»;
«propertyName».add(_value);
}
_hasNext = _iterator.hasNext();
_is_empty = false;
java.util.Map.Entry _dom_«propertyName» = (java.util.Map.Entry) _dom_«propertyName»_list.get(0);
Object _inner_value = _dom_«propertyName».getValue();
- «propertyName» = «deserializeValue(type, "_inner_value")»;
+ «propertyName» = «deserializeValue(type, "_inner_value", schema.type)»;
}
'''
}
'''
- private def dispatch String deserializeValue(GeneratedTransferObject type, String domParameter) '''
- («type.resolvedName») «type.valueSerializer.resolvedName».fromDomValue(«domParameter»)
+ private def dispatch String deserializeValue(GeneratedTransferObject type, String domParameter,
+ TypeDefinition<?> typeDefinition) '''
+ («type.resolvedName») «type.valueSerializer(typeDefinition).resolvedName».fromDomValue(«domParameter»)
'''
- private def dispatch String deserializeValue(Enumeration type, String domParameter) '''
- («type.resolvedName») «type.valueSerializer.resolvedName».fromDomValue(«domParameter»)
+ private def dispatch String deserializeValue(Enumeration type, String domParameter, TypeDefinition<?> typeDefinition) '''
+ («type.resolvedName») «type.valueSerializer(typeDefinition).resolvedName».fromDomValue(«domParameter»)
'''
private def dispatch Class<? extends BindingCodec<Map<QName, Object>, Object>> generateValueTransformer(
- Class<?> inputType, GeneratedTransferObject typeSpec) {
+ Class<?> inputType, GeneratedTransferObject typeSpec, TypeDefinition<?> typeDef) {
try {
val returnType = typeSpec.valueReturnType;
val ret = ctCls.toClassImpl(inputType.classLoader, inputType.protectionDomain)
return ret as Class<? extends BindingCodec<Map<QName,Object>, Object>>;
}
- if (returnType.name == 'char[]') {
- val ctCls = createUnionImplementation(inputType, typeSpec);
- val ret = ctCls.toClassImpl(inputType.classLoader, inputType.protectionDomain)
- return ret as Class<? extends BindingCodec<Map<QName,Object>, Object>>;
- }
val ctCls = createClass(typeSpec.codecClassName) [
//staticField(Map,"AUGMENTATION_SERIALIZERS");
val ctSpec = typeSpec.asCtClass;
bodyChecked = '''
{
- //System.out.println("«inputType.simpleName»#toDomValue: "+$1);
+ ////System.out.println("«inputType.simpleName»#toDomValue: "+$1);
if($1 == null) {
return null;
}
«typeSpec.resolvedName» _encapsulatedValue = («typeSpec.resolvedName») $1;
- //System.out.println("«inputType.simpleName»#toDomValue:Enc: "+_encapsulatedValue);
+ ////System.out.println("«inputType.simpleName»#toDomValue:Enc: "+_encapsulatedValue);
«returnType.resolvedName» _value = _encapsulatedValue.getValue();
- //System.out.println("«inputType.simpleName»#toDomValue:DeEnc: "+_value);
- Object _domValue = «serializeValue(returnType, "_value")»;
+ ////System.out.println("«inputType.simpleName»#toDomValue:DeEnc: "+_value);
+ Object _domValue = «serializeValue(returnType, "_value", null)»;
return _domValue;
}
'''
modifiers = PUBLIC + FINAL + STATIC
bodyChecked = '''
{
- //System.out.println("«inputType.simpleName»#fromDomValue: "+$1);
+ ////System.out.println("«inputType.simpleName»#fromDomValue: "+$1);
if($1 == null) {
return null;
}
- «returnType.resolvedName» _simpleValue = «deserializeValue(returnType, "$1")»;
+ «returnType.resolvedName» _simpleValue = «deserializeValue(returnType, "$1", null)»;
«typeSpec.resolvedName» _value = new «typeSpec.resolvedName»(_simpleValue);
return _value;
}
]
val ret = ctCls.toClassImpl(inputType.classLoader, inputType.protectionDomain)
- log.info("DOM Codec for {} was generated {}", inputType, ret)
+ log.debug("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 {}", inputType, e);
exception.addSuppressed(e);
throw exception;
}
-
}
- def createUnionImplementation(Class<?> inputType, GeneratedTransferObject typeSpec) {
- return createClass(typeSpec.codecClassName) [
- val properties = typeSpec.allProperties;
- //staticField(Map,"AUGMENTATION_SERIALIZERS");
- if (inputType.isYangBindingAvailable) {
- implementsType(BINDING_CODEC)
- staticField(it, INSTANCE_IDENTIFIER_CODEC, BindingCodec)
- staticField(it, IDENTITYREF_CODEC, BindingCodec)
- implementsType(BindingDeserializer.asCtClass)
- }
- method(Object, "toDomValue", Object) [
- modifiers = PUBLIC + FINAL + STATIC
- val ctSpec = inputType.asCtClass;
- bodyChecked = '''
- {
- //System.out.println("«inputType.simpleName»#toDomValue: "+$1);
-
- if($1 == null) {
+ private def dispatch Class<? extends BindingCodec<Map<QName, Object>, Object>> generateValueTransformer(
+ Class<?> inputType, GeneratedTransferObject typeSpec, UnionTypeDefinition typeDef) {
+ try {
+ val ctCls = createClass(typeSpec.codecClassName) [
+ val properties = typeSpec.allProperties;
+ val getterToTypeDefinition = XtendHelper.getTypes(typeDef).toMap[type | type.QName.getterName];
+ //staticField(Map,"AUGMENTATION_SERIALIZERS");
+ if (inputType.isYangBindingAvailable) {
+ implementsType(BINDING_CODEC)
+ staticField(it, INSTANCE_IDENTIFIER_CODEC, BindingCodec)
+ staticField(it, IDENTITYREF_CODEC, BindingCodec)
+ implementsType(BindingDeserializer.asCtClass)
+ }
+ method(Object, "toDomValue", Object) [
+ modifiers = PUBLIC + FINAL + STATIC
+ val ctSpec = inputType.asCtClass;
+
+ bodyChecked = '''
+ {
+ ////System.out.println("«inputType.simpleName»#toDomValue: "+$1);
+
+ if($1 == null) {
+ return null;
+ }
+ «typeSpec.resolvedName» _value = («typeSpec.resolvedName») $1;
+ «FOR property : properties.entrySet»
+ «IF property.key != "getValue"»
+ «property.value.resolvedName» «property.key» = («property.value.resolvedName») _value.«property.
+ key»();
+ if(«property.key» != null) {
+ return «serializeValue(property.value, property.key, getterToTypeDefinition.get(property.key))»;
+ }
+ «ENDIF»
+ «ENDFOR»
+
return null;
}
- «typeSpec.resolvedName» _value = («typeSpec.resolvedName») $1;
- «FOR property : properties.entrySet»
- «IF property.key != "getValue"»
- «property.value.resolvedName» «property.key» = («property.value.resolvedName») _value.«property.key»();
- if(«property.key» != null) {
- return «serializeValue(property.value, property.key)»;
- }
- «ENDIF»
- «ENDFOR»
-
- return null;
- }
- '''
- ]
- method(Object, "serialize", Object) [
- bodyChecked = '''
- {
- return toDomValue($1);
- }
- '''
- ]
- method(Object, "fromDomValue", Object) [
- modifiers = PUBLIC + FINAL + STATIC
- bodyChecked = '''
- {
- //System.out.println("«inputType.simpleName»#fromDomValue: "+$1);
-
- if($1 == null) {
- return null;
+ '''
+ ]
+ method(Object, "serialize", Object) [
+ bodyChecked = '''
+ {
+ return toDomValue($1);
}
- if($1 instanceof String) {
- String _simpleValue = (String) $1;
- return new «typeSpec.resolvedName»(_simpleValue.toCharArray());
+ '''
+ ]
+ method(Object, "fromDomValue", Object) [
+ modifiers = PUBLIC + FINAL + STATIC
+ bodyChecked = '''
+ {
+ ////System.out.println("«inputType.simpleName»#fromDomValue: "+$1);
+
+ if($1 == null) {
+ return null;
+ }
+ if($1 instanceof String) {
+ String _simpleValue = (String) $1;
+ return new «typeSpec.resolvedName»(_simpleValue.toCharArray());
+ }
+ return null;
}
- return null;
+ '''
+ ]
+ method(Object, "deserialize", Object) [
+ bodyChecked = '''{
+ return fromDomValue($1);
}
- '''
+ '''
+ ]
]
- method(Object, "deserialize", Object) [
- bodyChecked = '''{
+
+ val ret = ctCls.toClassImpl(inputType.classLoader, inputType.protectionDomain)
+ log.debug("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 {}", inputType, e);
+ val exception = new CodeGenerationException("Cannot compile Transformator for " + inputType);
+ exception.addSuppressed(e);
+ throw exception;
+ }
+ }
+
+
+ private def dispatch Class<? extends BindingCodec<Map<QName, Object>, Object>> generateValueTransformer(
+ Class<?> inputType, GeneratedTransferObject typeSpec, BitsTypeDefinition typeDef) {
+ try {
+ val ctCls = createClass(typeSpec.codecClassName) [
+ //staticField(Map,"AUGMENTATION_SERIALIZERS");
+ if (inputType.isYangBindingAvailable) {
+ implementsType(BINDING_CODEC)
+ staticField(it, INSTANCE_IDENTIFIER_CODEC, BindingCodec)
+ staticField(it, IDENTITYREF_CODEC, BindingCodec)
+ implementsType(BindingDeserializer.asCtClass)
+ }
+ method(Object, "toDomValue", Object) [
+ modifiers = PUBLIC + FINAL + STATIC
+ val ctSpec = typeSpec.asCtClass;
+ bodyChecked = '''
+ {
+ ////System.out.println("«inputType.simpleName»#toDomValue: "+$1);
+
+ if($1 == null) {
+ return null;
+ }
+ «typeSpec.resolvedName» _encapsulatedValue = («typeSpec.resolvedName») $1;
+ «HashSet.resolvedName» _value = new «HashSet.resolvedName»();
+ //System.out.println("«inputType.simpleName»#toDomValue:Enc: "+_encapsulatedValue);
+
+ «FOR bit : typeDef.bits»
+ «val getter = bit.getterName()»
+ if(Boolean.TRUE.equals(_encapsulatedValue.«getter»())) {
+ _value.add("«bit.name»");
+ }
+ «ENDFOR»
+ «Set.resolvedName» _domValue = «Collections.resolvedName».unmodifiableSet(_value);
+ //System.out.println("«inputType.simpleName»#toDomValue:DeEnc: "+_domValue);
+
+ return _domValue;
+ }
+ '''
+ ]
+ method(Object, "serialize", Object) [
+ bodyChecked = '''
+ {
+ return toDomValue($1);
+ }
+ '''
+ ]
+ method(Object, "fromDomValue", Object) [
+ modifiers = PUBLIC + FINAL + STATIC
+ val sortedBits = typeDef.bits.sort[o1, o2|o1.propertyName.compareTo(o2.propertyName)]
+ bodyChecked = '''
+ {
+ //System.out.println("«inputType.simpleName»#fromDomValue: "+$1);
+
+ if($1 == null) {
+ return null;
+ }
+ «Set.resolvedName» _domValue = («Set.resolvedName») $1;
+ «FOR bit : sortedBits»
+ Boolean «bit.propertyName» = Boolean.valueOf(_domValue.contains("«bit.name»"));
+ «ENDFOR»
+
+ return new «inputType.resolvedName»(«FOR bit : sortedBits SEPARATOR ","»«bit.propertyName»«ENDFOR»);
+ }
+ '''
+ ]
+ method(Object, "deserialize", Object) [
+ bodyChecked = '''{
return fromDomValue($1);
}
'''
+ ]
]
- ]
+
+ val ret = ctCls.toClassImpl(inputType.classLoader, inputType.protectionDomain)
+ log.debug("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 {}", inputType, e);
+ val exception = new CodeGenerationException("Cannot compile Transformator for " + inputType);
+ exception.addSuppressed(e);
+ throw exception;
+ }
+ }
+
+ def String getPropertyName(Bit bit) {
+ '''_«BindingGeneratorUtil.parseToValidParamName(bit.name)»'''
+ }
+
+ def String getterName(Bit bit) {
+
+ val paramName = BindingGeneratorUtil.parseToValidParamName(bit.name);
+ return '''is«paramName.toFirstUpper»''';
}
def boolean isYangBindingAvailable(Class<?> class1) {
return null;
}
- private def dispatch Class<?> generateValueTransformer(Class<?> inputType, Enumeration typeSpec) {
+ private def Class<?> generateValueTransformer(Class<?> inputType, Enumeration typeSpec) {
try {
val typeRef = new ReferencedTypeImpl(typeSpec.packageName, typeSpec.name);
val schema = typeToSchemaNode.get(typeRef) as ExtendedType;
]
val ret = ctCls.toClassImpl(inputType.classLoader, inputType.protectionDomain)
- log.info("DOM Codec for {} was generated {}", inputType, ret)
+ log.debug("DOM Codec for {} was generated {}", inputType, ret)
return ret;
} catch (CodeGenerationException e) {
throw new CodeGenerationException("Cannot compile Transformator for " + inputType, e);
}
- private def dispatch String deserializeValue(Type type, String domParameter) {
+ private def dispatch String deserializeValue(Type type, String domParameter, TypeDefinition<?> typeDef) {
if (INSTANCE_IDENTIFIER.equals(type)) {
return '''(«InstanceIdentifier.name») «INSTANCE_IDENTIFIER_CODEC».deserialize(«domParameter»)'''
} else if (CLASS_TYPE.equals(type)) {
«FOR child : node.childNodes»
«val signature = properties.getFor(child)»
«IF signature !== null»
- //System.out.println("«type.name»#«signature.key»" + value.«signature.key»());
+ ////System.out.println("«type.name»#«signature.key»" + value.«signature.key»());
«serializeProperty(child, signature.value, signature.key)»
«ENDIF»
«ENDFOR»
private def dispatch CharSequence serializeProperty(ListSchemaNode schema, ParameterizedType type,
String propertyName) '''
«type.resolvedName» «propertyName» = value.«propertyName»();
- //System.out.println("«propertyName»:" + «propertyName»);
+ ////System.out.println("«propertyName»:" + «propertyName»);
if(«propertyName» != null) {
java.util.Iterator _iterator = «propertyName».iterator();
boolean _hasNext = _iterator.hasNext();
if(«propertyName» != null) {
«QName.name» _qname = «QName.name».create(_resultName,"«schema.QName.localName»");
- Object _propValue = «serializeValue(type, propertyName)»;
+ Object _propValue = «serializeValue(type, propertyName, schema.type)»;
if(_propValue != null) {
Object _domValue = java.util.Collections.singletonMap(_qname,_propValue);
_childNodes.add(_domValue);
}
'''
- private def dispatch serializeValue(GeneratedTransferObject type, String parameter) '''«type.valueSerializer.
- resolvedName».toDomValue(«parameter»)'''
+ private def dispatch serializeValue(GeneratedTransferObject type, String parameter, TypeDefinition<?> typeDefinition) {
+ '''«type.valueSerializer(typeDefinition).resolvedName».toDomValue(«parameter»)'''
+ }
- private def dispatch serializeValue(Enumeration type, String parameter) '''«type.valueSerializer.resolvedName».toDomValue(«parameter»)'''
+ private def dispatch serializeValue(Enumeration type, String parameter, TypeDefinition<?> typeDefinition) {
+ '''«type.valueSerializer(typeDefinition).resolvedName».toDomValue(«parameter»)'''
+ }
- private def dispatch serializeValue(Type signature, String property) {
+ private def dispatch serializeValue(Type signature, String property, TypeDefinition<?> typeDefinition) {
if (INSTANCE_IDENTIFIER == signature) {
return '''«INSTANCE_IDENTIFIER_CODEC».serialize(«property»)'''
} else if (CLASS_TYPE.equals(signature)) {
boolean _hasNext = _iterator.hasNext();
while(_hasNext) {
Object _listItem = _iterator.next();
- Object _propValue = «serializeValue(type.actualTypeArguments.get(0), "_listItem")»;
+ Object _propValue = «serializeValue(type.actualTypeArguments.get(0), "_listItem", schema.type)»;
Object _domValue = java.util.Collections.singletonMap(_qname,_propValue);
_childNodes.add(_domValue);
_hasNext = _iterator.hasNext();
--- /dev/null
+package org.opendaylight.controller.sal.binding.test.bugfix;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.Callable;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+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.action.types.rev131112.action.action.PopMplsActionCaseBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.pop.mpls.action._case.PopMplsActionBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.list.Action;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.list.ActionBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNode;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowId;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.Table;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.TableKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.Flow;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.FlowBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.FlowKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.FlowModFlags;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.InstructionsBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.MatchBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.instruction.ApplyActionsCaseBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.instruction.apply.actions._case.ApplyActionsBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.list.Instruction;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.list.InstructionBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.list.InstructionKey;
+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.match.layer._3.match.Ipv4MatchBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.layer._4.match.TcpMatchBuilder;
+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 com.google.common.collect.ImmutableSet;
+import com.google.common.util.concurrent.Futures;
+import com.google.common.util.concurrent.ListenableFuture;
+import com.google.common.util.concurrent.ListeningExecutorService;
+import com.google.common.util.concurrent.MoreExecutors;
+
+import static org.junit.Assert.*;
+
+public class FlagsSerializationTest 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 long FLOW_ID = 1234;
+ private static final short TABLE_ID = (short)0;
+ private static final String NODE_ID = "node:1";
+
+ private static final NodeKey NODE_KEY = new NodeKey(new NodeId(NODE_ID));
+ private static final FlowKey FLOW_KEY = new FlowKey(new FlowId(FLOW_ID));
+ private static final TableKey TABLE_KEY = new TableKey(TABLE_ID);
+
+ private static final Map<QName, Object> NODE_KEY_BI = Collections.<QName, Object> singletonMap(NODE_ID_QNAME,
+ NODE_ID);
+
+ private static final InstanceIdentifier<Node> NODE_INSTANCE_ID_BA = InstanceIdentifier.builder(Nodes.class) //
+ .child(Node.class, NODE_KEY).toInstance();
+
+ 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 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_INSTANCE_ID_BA) //
+ .augmentation(FlowCapableNode.class)
+ .child(Table.class,TABLE_KEY)
+ .child(Flow.class, FLOW_KEY) //
+ .toInstance();
+ private static final QName FLOW_FLAGS_QNAME = QName.create(Flow.QNAME, "flags");
+
+ @Test
+ public void testIndirectGeneration() throws Exception {
+
+ FlowModFlags checkOverlapFlags = new FlowModFlags(true,false,false,false,false);
+ ImmutableSet<String> domCheckOverlapFlags = ImmutableSet.<String>of("CHECK_OVERLAP");
+ testFlags(checkOverlapFlags,domCheckOverlapFlags);
+
+
+
+ FlowModFlags allFalseFlags = new FlowModFlags(false,false,false,false,false);
+ ImmutableSet<String> domAllFalseFlags = ImmutableSet.<String>of();
+ testFlags(allFalseFlags,domAllFalseFlags);
+
+ FlowModFlags allTrueFlags = new FlowModFlags(true,true,true,true,true);
+ ImmutableSet<String> domAllTrueFlags = ImmutableSet.<String>of("CHECK_OVERLAP","NO_BYT_COUNTS", "NO_PKT_COUNTS", "RESET_COUNTS", "SEND_FLOW_REM");
+ testFlags(allTrueFlags,domAllTrueFlags);
+
+ FlowModFlags nullFlags = null;
+ ImmutableSet<String> domNullFlags = null;
+ testFlags(null,null);
+
+
+
+ }
+
+ private void testFlags(FlowModFlags flagsToTest, ImmutableSet<String> domFlags) throws Exception {
+ Flow flow = createFlow(flagsToTest);
+ assertNotNull(flow);
+
+ CompositeNode domFlow = biDataService.readConfigurationData(mappingService.toDataDom(FLOW_INSTANCE_ID_BA));
+
+ assertNotNull(domFlow);
+ org.opendaylight.yangtools.yang.data.api.Node<?> readedFlags = domFlow.getFirstSimpleByName(FLOW_FLAGS_QNAME);
+
+ if(domFlags != null) {
+ assertNotNull(readedFlags);
+ assertEquals(domFlags,readedFlags.getValue());
+ } else {
+ assertNull(readedFlags);
+ }
+ assertEquals(flagsToTest, flow.getFlags());
+
+ DataModificationTransaction transaction = baDataService.beginTransaction();
+ transaction.removeConfigurationData(FLOW_INSTANCE_ID_BA);
+ RpcResult<TransactionStatus> result = transaction.commit().get();
+ assertEquals(TransactionStatus.COMMITED, result.getResult());
+
+ }
+
+ private Flow createFlow(FlowModFlags flagsToTest) 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.setFlags(flagsToTest);
+
+ InstructionsBuilder instructions = new InstructionsBuilder();
+ InstructionBuilder instruction = new InstructionBuilder();
+
+ instruction.setOrder(10);
+ ApplyActionsBuilder applyActions = new ApplyActionsBuilder();
+ List<Action> actionList = new ArrayList<>();
+ PopMplsActionBuilder popMplsAction = new PopMplsActionBuilder();
+ popMplsAction.setEthernetType(34);
+ actionList.add(new ActionBuilder().setAction(new PopMplsActionCaseBuilder().setPopMplsAction(popMplsAction.build()).build()).setOrder(10).build());
+
+ applyActions.setAction(actionList );
+
+ instruction.setInstruction(new ApplyActionsCaseBuilder().setApplyActions(applyActions.build()).build());
+
+
+ List<Instruction> instructionList = Collections.<Instruction>singletonList(instruction.build());
+ instructions.setInstruction(instructionList );
+
+ flow.setInstructions(instructions.build());
+ modification.putConfigurationData(FLOW_INSTANCE_ID_BA, flow.build());
+ RpcResult<TransactionStatus> ret = modification.commit().get();
+ assertNotNull(ret);
+ assertEquals(TransactionStatus.COMMITED, ret.getResult());
+ return (Flow) baDataService.readConfigurationData(FLOW_INSTANCE_ID_BA);
+ }
+}