X-Git-Url: https://git.opendaylight.org/gerrit/gitweb?p=controller.git;a=blobdiff_plain;f=opendaylight%2Fmd-sal%2Fsal-binding-broker%2Fsrc%2Fmain%2Fjava%2Forg%2Fopendaylight%2Fcontroller%2Fsal%2Fbinding%2Fdom%2Fserializer%2Fimpl%2FRuntimeGeneratedMappingServiceImpl.xtend;h=1b3acf7674eda63e4430ec8d61b7ef186a2b6c80;hp=ec69fd3b68c8ee84c39edde4e58207adb771b5bd;hb=9212fed678702583f4a555641208cf1c7b45b829;hpb=24feaa3333de6eadfc99a63cce0f95479e3b5f96 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 ec69fd3b68..1b3acf7674 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 @@ -35,6 +35,19 @@ import java.util.Hashtable import org.osgi.framework.ServiceRegistration import org.opendaylight.controller.sal.binding.impl.connect.dom.DeserializationException import java.util.concurrent.Callable +import org.opendaylight.yangtools.yang.binding.Augmentation +import org.opendaylight.controller.sal.binding.impl.util.YangSchemaUtils +import org.opendaylight.controller.sal.binding.dom.serializer.api.AugmentationCodec +import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.NodeIdentifierWithPredicates +import java.util.ArrayList +import org.opendaylight.yangtools.yang.data.api.Node +import org.opendaylight.yangtools.yang.data.impl.SimpleNodeTOImpl +import org.opendaylight.yangtools.yang.data.impl.CompositeNodeTOImpl +import org.opendaylight.yangtools.yang.binding.RpcService +import java.util.Set +import org.opendaylight.yangtools.yang.common.QName +import com.google.common.collect.FluentIterable +import org.opendaylight.yangtools.binding.generator.util.BindingGeneratorUtil class RuntimeGeneratedMappingServiceImpl implements BindingIndependentMappingService, SchemaServiceListener, AutoCloseable { @@ -57,6 +70,9 @@ class RuntimeGeneratedMappingServiceImpl implements BindingIndependentMappingSer @Property val ConcurrentMap typeToSchemaNode = new ConcurrentHashMap(); + + @Property + val ConcurrentMap> serviceTypeToRpc = new ConcurrentHashMap(); val promisedTypeDefinitions = HashMultimap.>create; @@ -76,15 +92,31 @@ class RuntimeGeneratedMappingServiceImpl implements BindingIndependentMappingSer for (entry : newBinding.moduleContexts.entrySet) { registry.onModuleContextAdded(schemaContext, entry.key, entry.value); - - //val module = entry.key; + binding.pathToType.putAll(entry.value.childNodes) + val module = entry.key; val context = entry.value; updateBindingFor(context.childNodes, schemaContext); updateBindingFor(context.cases, schemaContext); + val namespace = BindingGeneratorUtil.moduleNamespaceToPackageName(module); + + if(!module.rpcs.empty) { + val rpcs = FluentIterable.from(module.rpcs).transform[QName].toSet + val serviceClass = new ReferencedTypeImpl(namespace,BindingGeneratorUtil.parseToClassName(module.name)+"Service"); + serviceTypeToRpc.put(serviceClass,rpcs); + } val typedefs = context.typedefs; - for (typedef : typedefs.values) { - binding.typeDefinitions.put(typedef, typedef as GeneratedType); + for (typedef : typedefs.entrySet) { + val typeRef = new ReferencedTypeImpl(typedef.value.packageName,typedef.value.name) + binding.typeDefinitions.put(typeRef, typedef.value as GeneratedType); + val schemaNode = YangSchemaUtils.findTypeDefinition(schemaContext,typedef.key); + if(schemaNode != null) { + + binding.typeToSchemaNode.put(typeRef,schemaNode); + } else { + LOG.error("Type definition for {} is not available",typedef.value); + } + } val augmentations = context.augmentations; for (augmentation : augmentations) { @@ -101,9 +133,21 @@ class RuntimeGeneratedMappingServiceImpl implements BindingIndependentMappingSer override Entry toDataDom( Entry, DataObject> entry) { + + try { val key = toDataDom(entry.key) - val data = toCompositeNodeImpl(entry.value); + var CompositeNode data; + if(Augmentation.isAssignableFrom(entry.key.targetType)) { + data = toCompositeNodeImpl(key,entry.value); + } else { + data = toCompositeNodeImpl(entry.value); + } return new SimpleEntry(key, data); + + } catch (Exception e) { + LOG.error("Error during serialization for {}.", entry.key,e); + throw e; + } } private def CompositeNode toCompositeNodeImpl(DataObject object) { @@ -113,8 +157,37 @@ class RuntimeGeneratedMappingServiceImpl implements BindingIndependentMappingSer val ret = codec.serialize(new ValueWithQName(null, object)); return ret as CompositeNode; } + + + private def CompositeNode toCompositeNodeImpl(org.opendaylight.yangtools.yang.data.api.InstanceIdentifier identifier,DataObject object) { + + //val cls = object.implementedInterface; + //waitForSchema(cls); + val last = identifier.path.last; + val codec = registry.getCodecForAugmentation(object.implementedInterface as Class) as AugmentationCodec; + val ret = codec.serialize(new ValueWithQName(last.nodeType, object)); + if(last instanceof NodeIdentifierWithPredicates) { + val predicates = last as NodeIdentifierWithPredicates; + val newNodes = new ArrayList>(predicates.keyValues.size); + for(predicate : predicates.keyValues.entrySet) { + newNodes.add(new SimpleNodeTOImpl(predicate.key,null,predicate.value)); + } + newNodes.addAll(ret.children); + return new CompositeNodeTOImpl(last.nodeType,null,newNodes); + } + return ret as CompositeNode; + } - private def waitForSchema(Class class1) { + private def void waitForSchema(Class class1) { + if(Augmentation.isAssignableFrom(class1)) { + /* FIXME: We should wait also for augmentations. Currently YANGTools does not provide correct + * mapping between java Augmentation classes and augmentations. + */ + return; + } + if(registry.isCodecAvailable(class1)) { + return; + } val ref = Types.typeForClass(class1); getSchemaWithRetry(ref); } @@ -128,15 +201,7 @@ class RuntimeGeneratedMappingServiceImpl implements BindingIndependentMappingSer } override dataObjectFromDataDom(InstanceIdentifier path, CompositeNode node) { - return tryDeserialization[ | - if (node == null) { - return null; - } - val targetType = path.targetType - val transformer = registry.getCodecForDataObject(targetType); - val ret = transformer.deserialize(node)?.value as DataObject; - return ret; - ] + dataObjectFromDataDom(path.targetType,node) as DataObject; } override fromDataDom(org.opendaylight.yangtools.yang.data.api.InstanceIdentifier entry) { @@ -149,21 +214,25 @@ class RuntimeGeneratedMappingServiceImpl implements BindingIndependentMappingSer try { deserializationBlock.call() } catch (Exception e) { + // FIXME: Make this block providing more information. throw new DeserializationException(e); } } 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) { - typeToSchemaNode.put(entry.value, schemaNode); - typeToDefinition.put(entry.value, entry.value); - updatePromisedSchemas(entry.value, schemaNode); + typeToSchemaNode.put(typeRef, schemaNode); + updatePromisedSchemas(typeRef, schemaNode); } + } } @@ -181,30 +250,9 @@ class RuntimeGeneratedMappingServiceImpl implements BindingIndependentMappingSer listenerRegistration = ctx.registerService(SchemaServiceListener, this, new Hashtable()); } } - - private def getTypeDefinition(Type type) { - val typeDef = typeToDefinition.get(type); - if (typeDef !== null) { - return typeDef; - } - return type.getTypeDefInFuture.get(); - } - - private def Future getTypeDefInFuture(Type type) { - val future = SettableFuture.create() - promisedTypeDefinitions.put(type, future); - return future; - } - - private def void updatePromisedTypeDefinitions(GeneratedTypeBuilder builder) { - val futures = promisedTypeDefinitions.get(builder); - if (futures === null || futures.empty) { - return; - } - for (future : futures) { - future.set(builder); - } - promisedTypeDefinitions.removeAll(builder); + + override getRpcQNamesFor(Class service) { + return serviceTypeToRpc.get(new ReferencedTypeImpl(service.package.name,service.simpleName)); } private def getSchemaWithRetry(Type type) { @@ -212,6 +260,7 @@ class RuntimeGeneratedMappingServiceImpl implements BindingIndependentMappingSer if (typeDef !== null) { return typeDef; } + LOG.info("Thread blocked waiting for schema for: {}",type.fullyQualifiedName) return type.getSchemaInFuture.get(); } @@ -236,5 +285,16 @@ class RuntimeGeneratedMappingServiceImpl implements BindingIndependentMappingSer override close() throws Exception { listenerRegistration?.unregister(); } + + override dataObjectFromDataDom(Class container, CompositeNode domData) { + return tryDeserialization[ | + if (domData == null) { + return null; + } + val transformer = registry.getCodecForDataObject(container); + val ret = transformer.deserialize(domData)?.value as DataObject; + return ret; + ] + } }