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=eec2d452a178c15da2f0c70befa8c1367aae31eb;hb=a890d6516837f32d7d13ebd9ffa1f9cc19b652be;hp=2b3a3042c2ce9119c9ee9d0176dcf88ed52807cb;hpb=71122c533df3457035350b561362f5601d171780;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 2b3a3042c2..eec2d452a1 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,6 +1,7 @@ package org.opendaylight.controller.sal.restconf.impl 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 @@ -8,12 +9,18 @@ import java.net.URLEncoder import java.util.HashMap import java.util.List import java.util.Map +import java.util.concurrent.ConcurrentHashMap +import javax.ws.rs.core.Response +import org.opendaylight.controller.sal.core.api.model.SchemaServiceListener +import org.opendaylight.controller.sal.rest.impl.RestUtil +import org.opendaylight.controller.sal.rest.impl.RestconfProvider import org.opendaylight.yangtools.yang.common.QName import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.InstanceIdentifierBuilder import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.NodeIdentifier import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.NodeIdentifierWithPredicates import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.PathArgument +import org.opendaylight.yangtools.yang.data.impl.codec.TypeDefinitionAwareCodec import org.opendaylight.yangtools.yang.model.api.ChoiceCaseNode import org.opendaylight.yangtools.yang.model.api.ChoiceNode import org.opendaylight.yangtools.yang.model.api.ContainerSchemaNode @@ -21,25 +28,26 @@ import org.opendaylight.yangtools.yang.model.api.DataNodeContainer import org.opendaylight.yangtools.yang.model.api.DataSchemaNode import org.opendaylight.yangtools.yang.model.api.LeafSchemaNode import org.opendaylight.yangtools.yang.model.api.ListSchemaNode +import org.opendaylight.yangtools.yang.model.api.RpcDefinition import org.opendaylight.yangtools.yang.model.api.SchemaContext +import org.opendaylight.yangtools.yang.model.api.type.IdentityrefTypeDefinition +import org.slf4j.LoggerFactory import static com.google.common.base.Preconditions.* -import org.opendaylight.controller.sal.core.api.model.SchemaServiceListener class ControllerContext implements SchemaServiceListener { - + val static LOG = LoggerFactory.getLogger(ControllerContext) val static ControllerContext INSTANCE = new ControllerContext - val static NULL_VALUE = "null" - @Property - SchemaContext schemas; + var SchemaContext schemas; private val BiMap uriToModuleName = HashBiMap.create(); private val Map moduleNameToUri = uriToModuleName.inverse(); + private val Map qnameToRpc = new ConcurrentHashMap(); private new() { - if (INSTANCE != null) { + if (INSTANCE !== null) { throw new IllegalStateException("Already instantiated"); } } @@ -48,6 +56,16 @@ class ControllerContext implements SchemaServiceListener { return INSTANCE } + private def void checkPreconditions() { + if (schemas === null) { + throw new ResponseException(Response.Status.SERVICE_UNAVAILABLE, RestconfProvider::NOT_INITALIZED_MSG) + } + } + + def setSchemas(SchemaContext schemas) { + onGlobalContextUpdated(schemas) + } + public def InstanceIdWithSchemaNode toInstanceIdentifier(String restconfInstance) { val ret = InstanceIdentifier.builder(); val pathArgs = restconfInstance.split("/"); @@ -58,13 +76,14 @@ class ControllerContext implements SchemaServiceListener { pathArgs.remove(0) } val schemaNode = ret.collectPathArguments(pathArgs, restconfInstance.findModule); - if (schemaNode == null) { + if (schemaNode === null) { return null } - new InstanceIdWithSchemaNode(ret.toInstance, schemaNode) + return new InstanceIdWithSchemaNode(ret.toInstance, schemaNode) } private def findModule(String restconfInstance) { + checkPreconditions checkNotNull(restconfInstance); val pathArgs = restconfInstance.split("/"); if (pathArgs.empty) { @@ -72,13 +91,13 @@ class ControllerContext implements SchemaServiceListener { } val modulWithFirstYangStatement = pathArgs.filter[s|s.contains(":")].head val startModule = modulWithFirstYangStatement.toModuleName(); - schemas.getLatestModule(startModule) + return getLatestModule(startModule) } - private def getLatestModule(SchemaContext schema, String moduleName) { - checkNotNull(schema) - checkArgument(moduleName != null && !moduleName.empty) - val modules = schema.modules.filter[m|m.name == moduleName] + def getLatestModule(String moduleName) { + checkPreconditions + checkArgument(moduleName !== null && !moduleName.empty) + val modules = schemas.modules.filter[m|m.name == moduleName] var latestModule = modules.head for (module : modules) { if (module.revision.after(latestModule.revision)) { @@ -89,6 +108,7 @@ class ControllerContext implements SchemaServiceListener { } def String toFullRestconfIdentifier(InstanceIdentifier path) { + checkPreconditions val elements = path.path; val ret = new StringBuilder(); val startQName = elements.get(0).nodeType; @@ -115,11 +135,48 @@ class ControllerContext implements SchemaServiceListener { throw new IllegalArgumentException("Conversion of generic path argument is not supported"); } + def findModuleByNamespace(URI namespace) { + checkPreconditions + var module = uriToModuleName.get(namespace) + if (module === null) { + val moduleSchemas = schemas.findModuleByNamespace(namespace); + if(moduleSchemas === null) return null + var latestModule = moduleSchemas.head + for (m : moduleSchemas) { + if (m.revision.after(latestModule.revision)) { + latestModule = m + } + } + if(latestModule === null) return null + uriToModuleName.put(namespace, latestModule.name) + module = latestModule.name; + } + return module + } + + def findNamespaceByModule(String module) { + var namespace = moduleNameToUri.get(module) + if (namespace === null) { + val moduleSchemas = schemas.modules.filter[it|it.name.equals(module)] + var latestModule = moduleSchemas.head + for (m : moduleSchemas) { + if (m.revision.after(latestModule.revision)) { + latestModule = m + } + } + if(latestModule === null) return null + namespace = latestModule.namespace + uriToModuleName.put(namespace, latestModule.name) + } + return namespace + } + def CharSequence toRestconfIdentifier(QName qname) { + checkPreconditions var module = uriToModuleName.get(qname.namespace) - if (module == null) { + if (module === null) { val moduleSchema = schemas.findModuleByNamespaceAndRevision(qname.namespace, qname.revision); - if(moduleSchema == null) throw new IllegalArgumentException() + if(moduleSchema === null) throw new IllegalArgumentException() uriToModuleName.put(qname.namespace, moduleSchema.name) module = moduleSchema.name; } @@ -172,13 +229,16 @@ class ControllerContext implements SchemaServiceListener { } private def toUriString(Object object) { - if(object == null) return ""; + if(object === null) return ""; return URLEncoder.encode(object.toString) } private def DataSchemaNode collectPathArguments(InstanceIdentifierBuilder builder, List strings, DataNodeContainer parentNode) { checkNotNull(strings) + if (parentNode === null) { + return null; + } if (strings.empty) { return parentNode as DataSchemaNode; } @@ -186,14 +246,14 @@ class ControllerContext implements SchemaServiceListener { val nodeName = nodeRef.toNodeName(); val targetNode = parentNode.getDataChildByName(nodeName); - if (targetNode == null) { + if (targetNode === null) { val children = parentNode.childNodes for (child : children) { if (child instanceof ChoiceNode) { val choice = child as ChoiceNode for (caze : choice.cases) { val result = builder.collectPathArguments(strings, caze as DataNodeContainer); - if (result != null) + if (result !== null) return result } } @@ -246,9 +306,17 @@ class ControllerContext implements SchemaServiceListener { private def void addKeyValue(HashMap map, DataSchemaNode node, String uriValue) { checkNotNull(uriValue); checkArgument(node instanceof LeafSchemaNode); - val decoded = URLDecoder.decode(uriValue); + val urlDecoded = URLDecoder.decode(uriValue); + val typedef = (node as LeafSchemaNode).type; + + var decoded = TypeDefinitionAwareCodec.from(typedef)?.deserialize(urlDecoded) + if(decoded === null) { + var baseType = RestUtil.resolveBaseTypeFrom(typedef) + if(baseType instanceof IdentityrefTypeDefinition) { + decoded = toQName(urlDecoded) + } + } map.put(node.QName, decoded); - } private def String toModuleName(String str) { @@ -272,11 +340,25 @@ class ControllerContext implements SchemaServiceListener { } } - public def QName toRpcQName(String name) { + private def QName toQName(String name) { + val module = name.toModuleName; + val node = name.toNodeName; + val namespace = FluentIterable.from(schemas.modules.sort[o1,o2 | o1.revision.compareTo(o2.revision)]) // + .transform[QName.create(namespace,revision,it.name)].findFirst[module == localName] + ; + return QName.create(namespace,node); + } + + def getRpcDefinition(String name) { + return qnameToRpc.get(name.toQName) } override onGlobalContextUpdated(SchemaContext context) { this.schemas = context; + for (operation : context.operations) { + val qname = operation.QName; + qnameToRpc.put(qname, operation); + } } }