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=7461ba89264d6505ce184f2ccb8748d49272bbf4;hp=0ddc2c88c8bd5bc99c85260bb13f7ce1c86f592b;hb=2d9dc00aaaa1a059dcca7861484698a95de0644e;hpb=3979e330c9f95a898c54a9234f3a07e3b2ae4349 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 0ddc2c88c8..7461ba8926 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 @@ -33,6 +33,21 @@ import org.opendaylight.yangtools.binding.generator.util.Types import org.osgi.framework.BundleContext 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 { @@ -55,11 +70,14 @@ class RuntimeGeneratedMappingServiceImpl implements BindingIndependentMappingSer @Property val ConcurrentMap typeToSchemaNode = new ConcurrentHashMap(); + + @Property + val ConcurrentMap> serviceTypeToRpc = new ConcurrentHashMap(); val promisedTypeDefinitions = HashMultimap.>create; val promisedSchemas = HashMultimap.>create; - + ServiceRegistration listenerRegistration override onGlobalContextUpdated(SchemaContext arg0) { @@ -74,22 +92,37 @@ 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) { binding.typeToDefinition.put(augmentation, augmentation); } - + binding.typeToAugmentation.putAll(context.typeToAugmentation); } } @@ -100,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) { @@ -112,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); } @@ -127,28 +201,38 @@ class RuntimeGeneratedMappingServiceImpl implements BindingIndependentMappingSer } override dataObjectFromDataDom(InstanceIdentifier path, CompositeNode node) { - 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) { - return registry.instanceIdentifierCodec.deserialize(entry); + return tryDeserialization[ | + registry.instanceIdentifierCodec.deserialize(entry); + ] + } + + private static def T tryDeserialization(Callable deserializationBlock) throws DeserializationException { + 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); } + } } @@ -162,34 +246,13 @@ class RuntimeGeneratedMappingServiceImpl implements BindingIndependentMappingSer binding.typeToDefinition = typeToDefinition binding.typeToSchemaNode = typeToSchemaNode binding.typeDefinitions = typeDefinitions - if(ctx !== null) { - listenerRegistration = ctx.registerService(SchemaServiceListener,this,new Hashtable()); - } - } - - private def getTypeDefinition(Type type) { - val typeDef = typeToDefinition.get(type); - if (typeDef !== null) { - return typeDef; + if (ctx !== null) { + listenerRegistration = ctx.registerService(SchemaServiceListener, this, new Hashtable()); } - 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) { @@ -197,6 +260,7 @@ class RuntimeGeneratedMappingServiceImpl implements BindingIndependentMappingSer if (typeDef !== null) { return typeDef; } + LOG.trace("Thread blocked waiting for schema for: {}",type.fullyQualifiedName) return type.getSchemaInFuture.get(); } @@ -217,9 +281,20 @@ class RuntimeGeneratedMappingServiceImpl implements BindingIndependentMappingSer } promisedSchemas.removeAll(builder); } - + 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; + ] + } + }