X-Git-Url: https://git.opendaylight.org/gerrit/gitweb?a=blobdiff_plain;f=opendaylight%2Fmd-sal%2Fsal-rest-connector%2Fsrc%2Fmain%2Fjava%2Forg%2Fopendaylight%2Fcontroller%2Fsal%2Frestconf%2Fimpl%2FControllerContext.xtend;h=2dfe5062c89af5b2f0151dfee3721d0ba7486521;hb=80887bb706a758b78cae70fcdb7531661139256c;hp=61237f01a16933ef742041c787874ec9ee8fc957;hpb=3d7c462c9ae27873c3a6cd484f2f228f74cd8b12;p=controller.git diff --git a/opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/restconf/impl/ControllerContext.xtend b/opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/restconf/impl/ControllerContext.xtend index 61237f01a1..2dfe5062c8 100644 --- a/opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/restconf/impl/ControllerContext.xtend +++ b/opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/restconf/impl/ControllerContext.xtend @@ -1,16 +1,25 @@ +/* + * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v1.0 which accompanies this distribution, + * and is available at http://www.eclipse.org/legal/epl-v10.html + */ package org.opendaylight.controller.sal.restconf.impl +import com.google.common.base.Preconditions import com.google.common.collect.BiMap import com.google.common.collect.FluentIterable import com.google.common.collect.HashBiMap import java.net.URI import java.net.URLDecoder import java.net.URLEncoder +import java.util.ArrayList import java.util.HashMap import java.util.List import java.util.Map import java.util.concurrent.ConcurrentHashMap -import org.opendaylight.controller.sal.core.api.model.SchemaServiceListener +import org.opendaylight.controller.sal.core.api.mount.MountInstance import org.opendaylight.controller.sal.core.api.mount.MountService import org.opendaylight.controller.sal.rest.impl.RestUtil import org.opendaylight.controller.sal.rest.impl.RestconfProvider @@ -32,12 +41,12 @@ import org.opendaylight.yangtools.yang.model.api.ListSchemaNode import org.opendaylight.yangtools.yang.model.api.Module import org.opendaylight.yangtools.yang.model.api.RpcDefinition import org.opendaylight.yangtools.yang.model.api.SchemaContext +import org.opendaylight.yangtools.yang.model.api.SchemaServiceListener import org.opendaylight.yangtools.yang.model.api.type.IdentityrefTypeDefinition import org.slf4j.LoggerFactory import static com.google.common.base.Preconditions.* import static javax.ws.rs.core.Response.Status.* -import org.opendaylight.controller.sal.core.api.mount.MountInstance class ControllerContext implements SchemaServiceListener { val static LOG = LoggerFactory.getLogger(ControllerContext) @@ -45,7 +54,7 @@ class ControllerContext implements SchemaServiceListener { val static NULL_VALUE = "null" val static MOUNT_MODULE = "yang-ext" val static MOUNT_NODE = "mount" - val static MOUNT = "yang-ext:mount" + public val static MOUNT = "yang-ext:mount" @Property var SchemaContext globalSchema; @@ -129,6 +138,7 @@ class ControllerContext implements SchemaServiceListener { def findModuleByNamespace(URI namespace) { checkPreconditions + checkArgument(namespace !== null) val moduleSchemas = globalSchema.findModuleByNamespace(namespace) return moduleSchemas?.filterLatestModule } @@ -170,41 +180,56 @@ class ControllerContext implements SchemaServiceListener { def findModuleNameByNamespace(URI namespace) { checkPreconditions - var module = uriToModuleName.get(namespace) - if (module === null) { - val moduleSchemas = globalSchema.findModuleByNamespace(namespace); - if(moduleSchemas === null) return null - var latestModule = moduleSchemas.filterLatestModule - if(latestModule === null) return null - uriToModuleName.put(namespace, latestModule.name) - module = latestModule.name; + var moduleName = uriToModuleName.get(namespace) + if (moduleName === null) { + val module = findModuleByNamespace(namespace) + if (module === null) return null + moduleName = module.name + uriToModuleName.put(namespace, moduleName) } - return module + return moduleName + } + + def findModuleNameByNamespace(MountInstance mountPoint, URI namespace) { + val module = mountPoint.findModuleByNamespace(namespace); + return module?.name } - def findNamespaceByModuleName(String module) { - var namespace = moduleNameToUri.get(module) + def findNamespaceByModuleName(String moduleName) { + var namespace = moduleNameToUri.get(moduleName) if (namespace === null) { - var latestModule = globalSchema.getLatestModule(module) - if(latestModule === null) return null - namespace = latestModule.namespace - uriToModuleName.put(namespace, latestModule.name) + var module = findModuleByName(moduleName) + if(module === null) return null + namespace = module.namespace + uriToModuleName.put(namespace, moduleName) } return namespace } + + def findNamespaceByModuleName(MountInstance mountPoint, String moduleName) { + val module = mountPoint.findModuleByName(moduleName) + return module?.namespace + } def CharSequence toRestconfIdentifier(QName qname) { checkPreconditions var module = uriToModuleName.get(qname.namespace) if (module === null) { val moduleSchema = globalSchema.findModuleByNamespaceAndRevision(qname.namespace, qname.revision); - if(moduleSchema === null) throw new IllegalArgumentException() + if(moduleSchema === null) return null uriToModuleName.put(qname.namespace, moduleSchema.name) module = moduleSchema.name; } return '''«module»:«qname.localName»'''; } + def CharSequence toRestconfIdentifier(MountInstance mountPoint, QName qname) { + val moduleSchema = mountPoint?.schemaContext.findModuleByNamespaceAndRevision(qname.namespace, qname.revision); + if(moduleSchema === null) return null + val module = moduleSchema.name; + return '''«module»:«qname.localName»'''; + } + private static dispatch def DataSchemaNode childByQName(ChoiceNode container, QName name) { for (caze : container.cases) { val ret = caze.childByQName(name) @@ -327,19 +352,32 @@ class ControllerContext implements SchemaServiceListener { "URI has bad format. \"" + moduleName + "\" module does not exist in mount point.") } } - targetNode = parentNode.findInstanceDataChild(nodeName, module.namespace) + targetNode = parentNode.findInstanceDataChildByNameAndNamespace(nodeName, module.namespace) if (targetNode === null) { throw new ResponseException(BAD_REQUEST, "URI has bad format. Possible reasons:\n" + "1. \"" + strings.head + "\" was not found in parent data node.\n" + "2. \"" + strings.head + "\" is behind mount point. Then it should be in format \"/" + MOUNT + "/" + strings.head + "\".") } } else { // string without module name - targetNode = parentNode.findInstanceDataChild(nodeName, null) + val potentialSchemaNodes = parentNode.findInstanceDataChildrenByName(nodeName) + if (potentialSchemaNodes.size > 1) { + val StringBuilder namespacesOfPotentialModules = new StringBuilder; + for (potentialNodeSchema : potentialSchemaNodes) { + namespacesOfPotentialModules.append(" ").append(potentialNodeSchema.QName.namespace.toString).append("\n") + } + throw new ResponseException(BAD_REQUEST, "URI has bad format. Node \"" + nodeName + "\" is added as augment from more than one module. " + + "Therefore the node must have module name and it has to be in format \"moduleName:nodeName\"." + + "\nThe node is added as augment from modules with namespaces:\n" + namespacesOfPotentialModules) + } + targetNode = potentialSchemaNodes.head if (targetNode === null) { throw new ResponseException(BAD_REQUEST, "URI has bad format. \"" + nodeName + "\" was not found in parent data node.\n") } } + if (!(targetNode instanceof ListSchemaNode) && !(targetNode instanceof ContainerSchemaNode)) { + throw new ResponseException(BAD_REQUEST,"URI has bad format. Node \"" + strings.head + "\" must be Container or List yang type.") + } // Number of consumed elements var consumed = 1; if (targetNode instanceof ListSchemaNode) { @@ -381,28 +419,36 @@ class ControllerContext implements SchemaServiceListener { return new InstanceIdWithSchemaNode(builder.toInstance, targetNode, mountPoint) } - def DataSchemaNode findInstanceDataChild(DataNodeContainer container, String name, URI moduleNamespace) { - var DataSchemaNode potentialNode = null - if (moduleNamespace === null) { - potentialNode = container.getDataChildByName(name); - } else { - potentialNode = container.childNodes.filter[n|n.QName.localName == name && n.QName.namespace == moduleNamespace].head - } - - if (potentialNode.instantiatedDataSchema) { - return potentialNode; + def DataSchemaNode findInstanceDataChildByNameAndNamespace(DataNodeContainer container, + String name, URI namespace) { + Preconditions.checkNotNull(namespace) + val potentialSchemaNodes = container.findInstanceDataChildrenByName(name) + return potentialSchemaNodes.filter[n|n.QName.namespace == namespace].head + } + + def List findInstanceDataChildrenByName(DataNodeContainer container, String name) { + Preconditions.checkNotNull(container) + Preconditions.checkNotNull(name) + val instantiatedDataNodeContainers = new ArrayList + instantiatedDataNodeContainers.collectInstanceDataNodeContainers(container, name) + return instantiatedDataNodeContainers + } + + private def void collectInstanceDataNodeContainers(List potentialSchemaNodes, DataNodeContainer container, + String name) { + val nodes = container.childNodes.filter[n|n.QName.localName == name] + for (potentialNode : nodes) { + if (potentialNode.isInstantiatedDataSchema) { + potentialSchemaNodes.add(potentialNode) + } } val allCases = container.childNodes.filter(ChoiceNode).map[cases].flatten for (caze : allCases) { - potentialNode = caze.findInstanceDataChild(name, moduleNamespace); - if (potentialNode !== null) { - return potentialNode; - } + collectInstanceDataNodeContainers(potentialSchemaNodes, caze, name) } - return null; } - static def boolean isInstantiatedDataSchema(DataSchemaNode node) { + def boolean isInstantiatedDataSchema(DataSchemaNode node) { switch node { LeafSchemaNode: return true LeafListSchemaNode: return true @@ -411,7 +457,7 @@ class ControllerContext implements SchemaServiceListener { default: return false } } - + private def void addKeyValue(HashMap map, DataSchemaNode node, String uriValue) { checkNotNull(uriValue); checkArgument(node instanceof LeafSchemaNode);