Solved bugs and added tests in sal-rest-connector
[controller.git] / opendaylight / md-sal / sal-rest-connector / src / main / java / org / opendaylight / controller / sal / restconf / impl / ControllerContext.xtend
index daad4cff4f5cd07de7ad38d167668429eae01c7b..419ca50ee995a032e5a63b3dc7ea1f50d79ba50e 100644 (file)
@@ -1,30 +1,30 @@
 package org.opendaylight.controller.sal.restconf.impl
 
-import org.opendaylight.yangtools.yang.model.api.SchemaContext
-import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier
-import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.PathArgument
-import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.NodeIdentifier
-import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.NodeIdentifierWithPredicates
+import com.google.common.collect.BiMap
+import com.google.common.collect.HashBiMap
 import java.net.URI
-import java.util.Map
+import java.net.URLDecoder
+import java.net.URLEncoder
 import java.util.HashMap
+import java.util.List
+import java.util.Map
 import org.opendaylight.yangtools.yang.common.QName
-import org.opendaylight.yangtools.yang.model.api.ChoiceNode
-import org.opendaylight.yangtools.yang.model.api.DataSchemaNode
+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.model.api.ChoiceCaseNode
+import org.opendaylight.yangtools.yang.model.api.ChoiceNode
 import org.opendaylight.yangtools.yang.model.api.ContainerSchemaNode
-import org.opendaylight.yangtools.yang.model.api.ListSchemaNode
-
-import java.net.URLEncoder
 import org.opendaylight.yangtools.yang.model.api.DataNodeContainer
-import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.InstanceIdentifierBuilder
-import java.util.List
-import static com.google.common.base.Preconditions.*;
-import com.google.common.collect.Collections2
-import com.google.common.collect.BiMap
-import com.google.common.collect.HashBiMap
+import org.opendaylight.yangtools.yang.model.api.DataSchemaNode
 import org.opendaylight.yangtools.yang.model.api.LeafSchemaNode
-import java.net.URLDecoder
+import org.opendaylight.yangtools.yang.model.api.ListSchemaNode
+import org.opendaylight.yangtools.yang.model.api.SchemaContext
+
+import static com.google.common.base.Preconditions.*
+import java.util.Date
 
 class ControllerContext {
 
@@ -34,15 +34,38 @@ class ControllerContext {
     private val BiMap<URI, String> uriToModuleName = HashBiMap.create();
     private val Map<String, URI> moduleNameToUri = uriToModuleName.inverse();
 
-    public def InstanceIdentifier toInstanceIdentifier(String restconfInstance) {
+    public def InstanceIdWithSchemaNode toInstanceIdentifier(String restconfInstance) {
         val ret = InstanceIdentifier.builder();
         val pathArgs = restconfInstance.split("/");
-        val first = pathArgs.get(0);
-        val startModule = first.toModuleName();
-        val module = schemas.findModuleByNamespace(moduleNameToUri.get(startModule));
-        checkArgument(module.size == 1); // Only one version supported now
-        ret.collectPathArguments(pathArgs, module.iterator.next);
-        return ret.toInstance
+        if (pathArgs.empty) {
+            return null;
+        }
+        val schemaNode = ret.collectPathArguments(pathArgs, restconfInstance.findModule);
+        new InstanceIdWithSchemaNode(ret.toInstance, schemaNode)
+    }
+
+    def findModule(String restconfInstance) {
+        checkNotNull(restconfInstance);
+        val pathArgs = restconfInstance.split("/");
+        if (pathArgs.empty) {
+            return null;
+        }
+        val modulWithFirstYangStatement = pathArgs.filter[s|s.contains(":")].head
+        val startModule = modulWithFirstYangStatement.toModuleName();
+        schemas.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]
+        var latestModule = modules.head
+        for (module : modules) {
+            if (module.revision.after(latestModule.revision)) {
+                latestModule = module
+            }
+        }
+        return latestModule
     }
 
     def String toFullRestconfIdentifier(InstanceIdentifier path) {
@@ -133,30 +156,27 @@ class ControllerContext {
         return URLEncoder.encode(object.toString)
     }
 
-    def void collectPathArguments(InstanceIdentifierBuilder builder, List<String> strings, DataNodeContainer parentNode) {
+    def DataSchemaNode collectPathArguments(InstanceIdentifierBuilder builder, List<String> strings,
+        DataNodeContainer parentNode) {
         checkNotNull(strings)
-        if (strings.length == 0) {
-            return;
+        if (strings.empty) {
+            return parentNode as DataSchemaNode;
         }
-        val nodeRef = strings.get(0);
+        val nodeRef = strings.head;
 
         //val moduleName = nodeRef.toModuleName();
         val nodeName = nodeRef.toNodeName();
-        val naiveTargetNode = parentNode.getDataChildByName(nodeName);
-
-        //var URI namespace;
-        var DataSchemaNode targetNode = naiveTargetNode;
+        val targetNode = parentNode.getDataChildByName(nodeName);
+        if (targetNode == null) {
+            return null
+        }
 
-        /*if(moduleName !== null) {
-            namespace = moduleNameToUri.get(moduleName);
-            
-        }*/
         // Number of consumed elements
         var consumed = 1;
         if (targetNode instanceof ListSchemaNode) {
             val listNode = targetNode as ListSchemaNode;
             val keysSize = listNode.keyDefinition.size
-            val uriKeyValues = strings.subList(1, keysSize);
+            val uriKeyValues = strings.subList(consumed, consumed + keysSize);
             val keyValues = new HashMap<QName, Object>();
             var i = 0;
             for (key : listNode.keyDefinition) {
@@ -172,9 +192,12 @@ class ControllerContext {
             builder.node(targetNode.QName);
         }
         if (targetNode instanceof DataNodeContainer) {
-            val remaining = strings.subList(consumed, strings.length - 1);
-            builder.collectPathArguments(remaining, targetNode as DataNodeContainer);
+            val remaining = strings.subList(consumed, strings.length);
+            val result = builder.collectPathArguments(remaining, targetNode as DataNodeContainer);
+            return result
         }
+
+        return targetNode
     }
 
     def void addKeyValue(HashMap<QName, Object> map, DataSchemaNode node, String uriValue) {
@@ -186,6 +209,7 @@ class ControllerContext {
     }
 
     def String toModuleName(String str) {
+        checkNotNull(str)
         if (str.contains(":")) {
             val args = str.split(":");
             checkArgument(args.size === 2);
@@ -204,9 +228,7 @@ class ControllerContext {
             return str;
         }
     }
-    
+
     public def QName toRpcQName(String name) {
-        
-        
     }
 }