Merge "BUG 1082 Migrate sal-rest-connector to Async Data Broker API"
authorTony Tkacik <ttkacik@cisco.com>
Sun, 3 Aug 2014 18:10:03 +0000 (18:10 +0000)
committerGerrit Code Review <gerrit@opendaylight.org>
Sun, 3 Aug 2014 18:10:03 +0000 (18:10 +0000)
52 files changed:
opendaylight/commons/opendaylight/pom.xml
opendaylight/distribution/opendaylight/pom.xml
opendaylight/md-sal/sal-rest-connector/pom.xml
opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/config/yang/md/sal/rest/connector/RestConnectorModule.java
opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/config/yang/md/sal/rest/connector/RestConnectorModuleFactory.java
opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/rest/api/RestconfService.java
opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/rest/impl/JsonMapper.java
opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/rest/impl/JsonToCompositeNodeProvider.java
opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/rest/impl/RestconfProviderImpl.java
opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/rest/impl/XmlToCompositeNodeProvider.java
opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/rest/impl/XmlToCompositeNodeReader.java
opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/rest/impl/XmlToNormalizedNodeReaderWithSchema.java [new file with mode: 0644]
opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/restconf/impl/BrokerFacade.java
opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/restconf/impl/ControllerContext.java
opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/restconf/impl/InstanceIdWithSchemaNode.java
opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/restconf/impl/RestCodec.java
opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/restconf/impl/RestconfImpl.java
opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/restconf/impl/StructuredData.java
opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/restconf/rpc/impl/MountPointRpcExecutor.java
opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/streams/listeners/ListenerAdapter.java
opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/streams/listeners/Notificator.java
opendaylight/md-sal/sal-rest-connector/src/main/yang/sal-remote-augment.yang [new file with mode: 0644]
opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/cnsn/to/json/test/CnSnJsonBasicYangTypesTest.java
opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/cnsn/to/json/test/CnSnJsonChoiceCaseTest.java
opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/cnsn/to/json/test/CnSnToJsonBasicDataTypesTest.java
opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/cnsn/to/json/test/CnSnToJsonIncorrectTopLevelTest.java
opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/cnsn/to/json/test/CnSnToJsonLeafrefType.java
opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/cnsn/to/json/test/CnSnToJsonWithAugmentTest.java
opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/input/to/cnsn/test/RestPutListDataTest.java
opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/json/to/cnsn/test/JsonIdentityrefToCnSnTest.java
opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/json/to/cnsn/test/JsonLeafrefToCnSnTest.java
opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/json/to/cnsn/test/JsonToCnSnTest.java
opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/test/BrokerFacadeTest.java
opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/test/InvokeRpcMethodTest.java
opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/test/MultipleEqualNamesForDataNodesTest.java
opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/test/RestDeleteOperationTest.java
opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/test/RestGetOperationTest.java
opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/test/RestPostOperationTest.java
opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/test/RestPutOperationTest.java
opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/test/RestconfImplTest.java
opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/test/TestUtils.java
opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/test/URIParametersParsing.java [new file with mode: 0644]
opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/test/URITest.java
opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/test/XmlAndJsonToCnSnInstanceIdentifierTest.java
opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/test/XmlAndJsonToCnSnLeafRefTest.java
opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/websockets/test/RestStream.java
opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/xml/to/cnsn/test/XmlAugmentedElementToCnSnTest.java
opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/xml/to/cnsn/test/XmlLeafrefToCnSnTest.java
opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/xml/to/cnsn/test/XmlToCnSnTest.java
opendaylight/md-sal/sal-rest-connector/src/test/resources/datastore-and-scope-specification/opendaylight-inventory.yang [new file with mode: 0644]
opendaylight/md-sal/sal-rest-connector/src/test/resources/datastore-and-scope-specification/sal-remote-augment.yang [new file with mode: 0644]
opendaylight/md-sal/sal-rest-connector/src/test/resources/datastore-and-scope-specification/sal-remote@2014-01-14.yang [new file with mode: 0644]

index c4ab2edcb3a41f654106fc7b7b58b473faca6b84..5ce5840da8fc4deb45df33c1d2fc102933c2fe7e 100644 (file)
         <artifactId>util</artifactId>
         <version>${yangtools.version}</version>
       </dependency>
+      <dependency>
+        <groupId>org.opendaylight.yangtools</groupId>
+        <artifactId>yang-data-composite-node</artifactId>
+        <version>${yangtools.version}</version>
+      </dependency>
 
       <!-- yangtools dependencies -->
       <dependency>
index 4d0770f8cb8837cfd12b897401c2db07546b2538..7c3289adb5e0a7857227549535a8997be6837114 100644 (file)
           <groupId>org.opendaylight.yangtools</groupId>
           <artifactId>yang-parser-impl</artifactId>
         </dependency>
+        <dependency>
+          <groupId>org.opendaylight.yangtools</groupId>
+          <artifactId>yang-data-composite-node</artifactId>
+        </dependency>
         <!-- yang model dependencies -->
         <dependency>
           <groupId>org.opendaylight.yangtools.model</groupId>
index 09fb5b3677538442f154f4ca4a16cbdc4cf05647..2856a302d25d68b734aaad90f270cb5cd086d5fa 100644 (file)
       <groupId>org.opendaylight.controller</groupId>
       <artifactId>sal-core-spi</artifactId>
     </dependency>
+    <dependency>
+      <groupId>org.opendaylight.yangtools</groupId>
+      <artifactId>yang-data-composite-node</artifactId>
+      <version>0.6.2-SNAPSHOT</version>
+    </dependency>
   </dependencies>
 
   <build>
index 582c657868d5d16e0b2213aba36216e59538cb4e..52115a8f32f5ca5c04a5fb0d7c994456cc114544 100644 (file)
@@ -2,6 +2,7 @@ package org.opendaylight.controller.config.yang.md.sal.rest.connector;
 
 import org.opendaylight.controller.sal.rest.impl.RestconfProviderImpl;
 
+
 public class RestConnectorModule extends org.opendaylight.controller.config.yang.md.sal.rest.connector.AbstractRestConnectorModule {
 
     public RestConnectorModule(org.opendaylight.controller.config.api.ModuleIdentifier identifier, org.opendaylight.controller.config.api.DependencyResolver dependencyResolver) {
@@ -28,3 +29,4 @@ public class RestConnectorModule extends org.opendaylight.controller.config.yang
         return instance;
     }
 }
+
index a6c4ea5ab8d7877930983ed782d4cbc318def278..9c149a21e60e70ff88c0371e936e3844c05b5985 100644 (file)
@@ -23,6 +23,7 @@ import javax.ws.rs.core.Response;
 import javax.ws.rs.core.UriInfo;
 import org.opendaylight.controller.sal.restconf.impl.StructuredData;
 import org.opendaylight.yangtools.yang.data.api.CompositeNode;
+import org.opendaylight.yangtools.yang.data.api.Node;
 
 /**
  * The URI hierarchy for the RESTCONF resources consists of an entry point container, 4 top-level resources, and 1
@@ -30,15 +31,18 @@ import org.opendaylight.yangtools.yang.data.api.CompositeNode;
  * <ul>
  * <li><b>/restconf</b> - {@link #getRoot()}
  * <ul>
- * <li><b>/config</b> - {@link #readConfigurationData(String)} {@link #updateConfigurationData(String, CompositeNode)}
- * {@link #createConfigurationData(CompositeNode)} {@link #createConfigurationData(String, CompositeNode)}
+ *      <li><b>/config</b> - {@link #readConfigurationData(String)}
+ *                              {@link #updateConfigurationData(String, CompositeNode)}
+ *                              {@link #createConfigurationData(CompositeNode)}
+ *                              {@link #createConfigurationData(String, CompositeNode)}
  * {@link #deleteConfigurationData(String)}
  * <li><b>/operational</b> - {@link #readOperationalData(String)}
  * <li>/modules - {@link #getModules()}
  * <ul>
  * <li>/module
  * </ul>
- * <li><b>/operations</b> - {@link #invokeRpc(String, CompositeNode)} {@link #invokeRpc(String, CompositeNode)}
+ *      <li><b>/operations</b> - {@link #invokeRpc(String, CompositeNode)}
+ *                               {@link #invokeRpc(String, CompositeNode)}
  * <li>/version (field)
  * </ul>
  * </ul>
@@ -119,19 +123,19 @@ public interface RestconfService {
     @Path("/config/{identifier:.+}")
     @Consumes({ Draft02.MediaTypes.DATA + JSON, Draft02.MediaTypes.DATA + XML, MediaType.APPLICATION_JSON,
             MediaType.APPLICATION_XML, MediaType.TEXT_XML })
-    public Response updateConfigurationData(@Encoded @PathParam("identifier") String identifier, CompositeNode payload);
+    public Response updateConfigurationData(@Encoded @PathParam("identifier") String identifier, Node<?> payload);
 
     @POST
     @Path("/config/{identifier:.+}")
     @Consumes({ Draft02.MediaTypes.DATA + JSON, Draft02.MediaTypes.DATA + XML, MediaType.APPLICATION_JSON,
             MediaType.APPLICATION_XML, MediaType.TEXT_XML })
-    public Response createConfigurationData(@Encoded @PathParam("identifier") String identifier, CompositeNode payload);
+    public Response createConfigurationData(@Encoded @PathParam("identifier") String identifier, Node<?> payload);
 
     @POST
     @Path("/config")
     @Consumes({ Draft02.MediaTypes.DATA + JSON, Draft02.MediaTypes.DATA + XML, MediaType.APPLICATION_JSON,
             MediaType.APPLICATION_XML, MediaType.TEXT_XML })
-    public Response createConfigurationData(CompositeNode payload);
+    public Response createConfigurationData(Node<?> payload);
 
     @DELETE
     @Path("/config/{identifier:.+}")
index 34aa829b6f5a50e7511583485d33693155d123d8..863de10325bab60e59fa5ea578bf5f31f2d0f3a1 100644 (file)
@@ -19,7 +19,7 @@ import java.util.HashSet;
 import java.util.List;
 import java.util.Set;
 import javax.activation.UnsupportedDataTypeException;
-import org.opendaylight.controller.sal.core.api.mount.MountInstance;
+import org.opendaylight.controller.md.sal.dom.api.DOMMountPoint;
 import org.opendaylight.controller.sal.restconf.impl.ControllerContext;
 import org.opendaylight.controller.sal.restconf.impl.IdentityValuesDTO;
 import org.opendaylight.controller.sal.restconf.impl.IdentityValuesDTO.IdentityValue;
@@ -52,9 +52,9 @@ import org.slf4j.LoggerFactory;
 
 class JsonMapper {
     private static final Logger LOG = LoggerFactory.getLogger(JsonMapper.class);
-    private final MountInstance mountPoint;
+    private final DOMMountPoint mountPoint;
 
-    public JsonMapper(final MountInstance mountPoint) {
+    public JsonMapper(final DOMMountPoint mountPoint) {
         this.mountPoint = mountPoint;
     }
 
index 2f3499e26968e17e9fa5f662ab66063965657815..caff848180e84400c5a810bfd1939da1e295a22c 100644 (file)
@@ -22,14 +22,14 @@ import org.opendaylight.controller.sal.rest.api.RestconfService;
 import org.opendaylight.controller.sal.restconf.impl.RestconfDocumentedException;
 import org.opendaylight.controller.sal.restconf.impl.RestconfError.ErrorTag;
 import org.opendaylight.controller.sal.restconf.impl.RestconfError.ErrorType;
-import org.opendaylight.yangtools.yang.data.api.CompositeNode;
+import org.opendaylight.yangtools.yang.data.api.Node;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 @Provider
 @Consumes({ Draft02.MediaTypes.DATA + RestconfService.JSON, Draft02.MediaTypes.OPERATION + RestconfService.JSON,
         MediaType.APPLICATION_JSON })
-public enum JsonToCompositeNodeProvider implements MessageBodyReader<CompositeNode> {
+public enum JsonToCompositeNodeProvider implements MessageBodyReader<Node<?>> {
     INSTANCE;
 
     private final static Logger LOG = LoggerFactory.getLogger(JsonToCompositeNodeProvider.class);
@@ -41,7 +41,7 @@ public enum JsonToCompositeNodeProvider implements MessageBodyReader<CompositeNo
     }
 
     @Override
-    public CompositeNode readFrom(final Class<CompositeNode> type, final Type genericType,
+    public Node<?> readFrom(final Class<Node<?>> type, final Type genericType,
             final Annotation[] annotations, final MediaType mediaType,
             final MultivaluedMap<String, String> httpHeaders, final InputStream entityStream) throws IOException,
             WebApplicationException {
index 559be5aa6fe1358881d6df6f7f81a50409dfed49..2fa99819d5f833a27c0de9d6fa02053e955b87ce 100644 (file)
@@ -9,12 +9,11 @@ package org.opendaylight.controller.sal.rest.impl;
 
 import java.util.Collection;
 import java.util.Collections;
-
+import org.opendaylight.controller.md.sal.dom.api.DOMDataBroker;
+import org.opendaylight.controller.md.sal.dom.api.DOMMountPointService;
 import org.opendaylight.controller.sal.core.api.Broker.ProviderSession;
 import org.opendaylight.controller.sal.core.api.Provider;
-import org.opendaylight.controller.sal.core.api.data.DataBrokerService;
 import org.opendaylight.controller.sal.core.api.model.SchemaService;
-import org.opendaylight.controller.sal.core.api.mount.MountService;
 import org.opendaylight.controller.sal.rest.api.RestConnector;
 import org.opendaylight.controller.sal.restconf.impl.BrokerFacade;
 import org.opendaylight.controller.sal.restconf.impl.ControllerContext;
@@ -37,15 +36,15 @@ public class RestconfProviderImpl implements Provider, AutoCloseable, RestConnec
 
     @Override
     public void onSessionInitiated(ProviderSession session) {
-        DataBrokerService dataService = session.getService(DataBrokerService.class);
+        final DOMDataBroker domDataBroker = session.getService(DOMDataBroker.class);
 
         BrokerFacade.getInstance().setContext(session);
-        BrokerFacade.getInstance().setDataService(dataService);
+        BrokerFacade.getInstance().setDomDataBroker( domDataBroker);
 
         SchemaService schemaService = session.getService(SchemaService.class);
         listenerRegistration = schemaService.registerSchemaContextListener(ControllerContext.getInstance());
         ControllerContext.getInstance().setSchemas(schemaService.getGlobalContext());
-        ControllerContext.getInstance().setMountService(session.getService(MountService.class));
+        ControllerContext.getInstance().setMountService(session.getService(DOMMountPointService.class));
 
         webSocketServerThread = new Thread(WebSocketServer.createInstance(port.getValue().intValue()));
         webSocketServerThread.setName("Web socket server on port " + port);
index 31e9c96462541e75205d9ef9c6aac9508abc6e43..d56a32e36ee084c7180b37e7d444f77fedded580 100644 (file)
@@ -23,25 +23,25 @@ import org.opendaylight.controller.sal.rest.api.RestconfService;
 import org.opendaylight.controller.sal.restconf.impl.RestconfDocumentedException;
 import org.opendaylight.controller.sal.restconf.impl.RestconfError.ErrorTag;
 import org.opendaylight.controller.sal.restconf.impl.RestconfError.ErrorType;
-import org.opendaylight.yangtools.yang.data.api.CompositeNode;
+import org.opendaylight.yangtools.yang.data.api.Node;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 @Provider
 @Consumes({ Draft02.MediaTypes.DATA + RestconfService.XML, Draft02.MediaTypes.OPERATION + RestconfService.XML,
         MediaType.APPLICATION_XML, MediaType.TEXT_XML })
-public enum XmlToCompositeNodeProvider implements MessageBodyReader<CompositeNode> {
+public enum XmlToCompositeNodeProvider implements MessageBodyReader<Node<?>> {
     INSTANCE;
-
     private final static Logger LOG = LoggerFactory.getLogger(XmlToCompositeNodeProvider.class);
 
     @Override
-    public boolean isReadable(Class<?> type, Type genericType, Annotation[] annotations, MediaType mediaType) {
+    public boolean isReadable(final Class<?> type, final Type genericType, final Annotation[] annotations,
+            final MediaType mediaType) {
         return true;
     }
 
     @Override
-    public CompositeNode readFrom(Class<CompositeNode> type, Type genericType, Annotation[] annotations,
+    public Node<?> readFrom(final Class<Node<?>> type, final Type genericType, final Annotation[] annotations,
             MediaType mediaType, MultivaluedMap<String, String> httpHeaders, InputStream entityStream)
             throws IOException, WebApplicationException {
         XmlToCompositeNodeReader xmlReader = new XmlToCompositeNodeReader();
index 413823f52081ebb235cc33db3530e2bdbbf7c149..5944d6003e9e1e33dba8a0b482a60de5f01ac4c0 100644 (file)
@@ -33,10 +33,11 @@ public class XmlToCompositeNodeReader {
     private final static XMLInputFactory xmlInputFactory = XMLInputFactory.newInstance();
     private XMLEventReader eventReader;
 
-    public CompositeNodeWrapper read(InputStream entityStream) throws XMLStreamException, UnsupportedFormatException,
-            IOException {
-        // Get an XML stream which can be marked, and reset, so we can check and
-        // see if there is any content being provided.
+    public Node<?> read(InputStream entityStream) throws XMLStreamException,
+                                                                      UnsupportedFormatException,
+                                                                      IOException {
+        //Get an XML stream which can be marked, and reset, so we can check and see if there is
+        //any content being provided.
         entityStream = getMarkableStream(entityStream);
 
         if (isInputStreamEmpty(entityStream)) {
@@ -52,12 +53,8 @@ public class XmlToCompositeNodeReader {
             }
         }
 
-        if (eventReader.hasNext() && !isCompositeNodeEvent(eventReader.peek())) {
-            throw new UnsupportedFormatException("Root element of XML has to be composite element.");
-        }
-
         final Stack<NodeWrapper<?>> processingQueue = new Stack<>();
-        CompositeNodeWrapper root = null;
+        NodeWrapper<?> root = null;
         NodeWrapper<?> element = null;
         while (eventReader.hasNext()) {
             final XMLEvent event = eventReader.nextEvent();
@@ -70,17 +67,15 @@ public class XmlToCompositeNodeReader {
                 }
                 NodeWrapper<?> newNode = null;
                 if (isCompositeNodeEvent(event)) {
+                    newNode = resolveCompositeNodeFromStartElement(startElement);
                     if (root == null) {
-                        root = resolveCompositeNodeFromStartElement(startElement);
-                        newNode = root;
-                    } else {
-                        newNode = resolveCompositeNodeFromStartElement(startElement);
+                        root = newNode;
                     }
                 } else if (isSimpleNodeEvent(event)) {
+                    newNode = resolveSimpleNodeFromStartElement(startElement);
                     if (root == null) {
-                        throw new UnsupportedFormatException("Root element of XML has to be composite element.");
+                        root = newNode;
                     }
-                    newNode = resolveSimpleNodeFromStartElement(startElement);
                 }
 
                 if (newNode != null) {
@@ -98,7 +93,7 @@ public class XmlToCompositeNodeReader {
             throw new UnsupportedFormatException("XML should contain only one root element");
         }
 
-        return root;
+        return (Node<?>) root;
     }
 
     /**
diff --git a/opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/rest/impl/XmlToNormalizedNodeReaderWithSchema.java b/opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/rest/impl/XmlToNormalizedNodeReaderWithSchema.java
new file mode 100644 (file)
index 0000000..935d96c
--- /dev/null
@@ -0,0 +1,352 @@
+/*
+ * 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.rest.impl;
+
+import static com.google.common.base.Preconditions.checkArgument;
+
+import java.io.BufferedInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.URI;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Stack;
+import javax.xml.stream.XMLEventReader;
+import javax.xml.stream.XMLInputFactory;
+import javax.xml.stream.XMLStreamConstants;
+import javax.xml.stream.XMLStreamException;
+import javax.xml.stream.events.Characters;
+import javax.xml.stream.events.StartElement;
+import javax.xml.stream.events.XMLEvent;
+import org.opendaylight.controller.sal.restconf.impl.CompositeNodeWrapper;
+import org.opendaylight.controller.sal.restconf.impl.IdentityValuesDTO;
+import org.opendaylight.controller.sal.restconf.impl.InstanceIdWithSchemaNode;
+import org.opendaylight.controller.sal.restconf.impl.NodeWrapper;
+import org.opendaylight.controller.sal.restconf.impl.RestCodec;
+import org.opendaylight.controller.sal.restconf.impl.RestconfDocumentedException;
+import org.opendaylight.controller.sal.restconf.impl.RestconfError.ErrorTag;
+import org.opendaylight.controller.sal.restconf.impl.RestconfError.ErrorType;
+import org.opendaylight.controller.sal.restconf.impl.SimpleNodeWrapper;
+import org.opendaylight.yangtools.yang.common.QName;
+import org.opendaylight.yangtools.yang.data.api.Node;
+import org.opendaylight.yangtools.yang.model.api.ContainerSchemaNode;
+import org.opendaylight.yangtools.yang.model.api.DataNodeContainer;
+import org.opendaylight.yangtools.yang.model.api.DataSchemaNode;
+import org.opendaylight.yangtools.yang.model.api.LeafListSchemaNode;
+import org.opendaylight.yangtools.yang.model.api.LeafSchemaNode;
+import org.opendaylight.yangtools.yang.model.api.ListSchemaNode;
+import org.opendaylight.yangtools.yang.model.api.TypeDefinition;
+
+public class XmlToNormalizedNodeReaderWithSchema {
+
+    private final static XMLInputFactory xmlInputFactory = XMLInputFactory.newInstance();
+    private XMLEventReader eventReader;
+    private InstanceIdWithSchemaNode iiWithSchema;
+
+    public XmlToNormalizedNodeReaderWithSchema(final InstanceIdWithSchemaNode iiWithSchema) {
+        this.iiWithSchema = iiWithSchema;
+    }
+
+    public Node<?> read(InputStream entityStream) throws XMLStreamException, UnsupportedFormatException, IOException {
+        // Get an XML stream which can be marked, and reset, so we can check and see if there is
+        // any content being provided.
+        entityStream = getMarkableStream(entityStream);
+
+        if (isInputStreamEmpty(entityStream)) {
+            return null;
+        }
+
+        eventReader = xmlInputFactory.createXMLEventReader(entityStream);
+        if (eventReader.hasNext()) {
+            XMLEvent element = eventReader.peek();
+            if (element.isStartDocument()) {
+                eventReader.nextEvent();
+            }
+        }
+
+        final Stack<NodeWrapper<?>> processingQueue = new Stack<>();
+        NodeWrapper<?> root = null;
+        NodeWrapper<?> element = null;
+        Stack<DataSchemaNode> processingQueueSchema = new Stack<>();
+
+        while (eventReader.hasNext()) {
+            final XMLEvent event = eventReader.nextEvent();
+
+            if (event.isStartElement()) {
+                final StartElement startElement = event.asStartElement();
+                CompositeNodeWrapper compParentNode = null;
+                if (!processingQueue.isEmpty() && processingQueue.peek() instanceof CompositeNodeWrapper) {
+                    compParentNode = (CompositeNodeWrapper) processingQueue.peek();
+                    findSchemaNodeForElement(startElement, processingQueueSchema);
+                } else {
+                    processingQueueSchema = checkElementAndSchemaNodeNameAndNamespace(startElement,
+                            iiWithSchema.getSchemaNode());
+                    DataSchemaNode currentSchemaNode = processingQueueSchema.peek();
+                    if (!(currentSchemaNode instanceof ListSchemaNode)
+                            && !(currentSchemaNode instanceof ContainerSchemaNode)) {
+                        throw new UnsupportedFormatException(
+                                "Top level element has to be of type list or container schema node.");
+                    }
+                }
+
+                NodeWrapper<?> newNode = null;
+                if (isCompositeNodeEvent(event)) {
+                    newNode = resolveCompositeNodeFromStartElement(processingQueueSchema.peek().getQName());
+                    if (root == null) {
+                        root = newNode;
+                    }
+                } else if (isSimpleNodeEvent(event)) {
+                    newNode = resolveSimpleNodeFromStartElement(processingQueueSchema.peek(), getValueOf(startElement));
+                    if (root == null) {
+                        root = newNode;
+                    }
+                }
+
+                if (newNode != null) {
+                    processingQueue.push(newNode);
+                    if (compParentNode != null) {
+                        compParentNode.addValue(newNode);
+                    }
+                }
+            } else if (event.isEndElement()) {
+                element = processingQueue.pop();
+//                if(((EndElement)event).getName().getLocalPart().equals
+                processingQueueSchema.pop();
+            }
+        }
+
+        if (!root.getLocalName().equals(element.getLocalName())) {
+            throw new UnsupportedFormatException("XML should contain only one root element");
+        }
+
+        return root.unwrap();
+    }
+
+    private void findSchemaNodeForElement(StartElement element, Stack<DataSchemaNode> processingQueueSchema) {
+        DataSchemaNode currentSchemaNode = processingQueueSchema.peek();
+        if (currentSchemaNode instanceof DataNodeContainer) {
+            final URI realNamespace = getNamespaceFor(element);
+            final String realName = getLocalNameFor(element);
+            Map<URI, DataSchemaNode> childNamesakes = resolveChildsWithNameAsElement(
+                    ((DataNodeContainer) currentSchemaNode), realName);
+            DataSchemaNode childDataSchemaNode = childNamesakes.get(realNamespace);
+            if (childDataSchemaNode == null) {
+                throw new RestconfDocumentedException("Element " + realName + " has namespace " + realNamespace
+                        + ". Available namespaces are: " + childNamesakes.keySet(), ErrorType.APPLICATION,
+                        ErrorTag.INVALID_VALUE);
+            }
+            processingQueueSchema.push(childDataSchemaNode);
+        } else {
+            throw new RestconfDocumentedException("Element " + processingQueueSchema.peek().getQName().getLocalName()
+                    + " should be data node container .", ErrorType.APPLICATION, ErrorTag.INVALID_VALUE);
+        }
+
+    }
+
+    /**
+     * Returns map of data schema node which are accesible by URI which have equal name
+     */
+    private Map<URI, DataSchemaNode> resolveChildsWithNameAsElement(final DataNodeContainer dataNodeContainer,
+            final String realName) {
+        final Map<URI, DataSchemaNode> namespaceToDataSchemaNode = new HashMap<URI, DataSchemaNode>();
+        for (DataSchemaNode dataSchemaNode : dataNodeContainer.getChildNodes()) {
+            if (dataSchemaNode.equals(realName)) {
+                namespaceToDataSchemaNode.put(dataSchemaNode.getQName().getNamespace(), dataSchemaNode);
+            }
+        }
+        return namespaceToDataSchemaNode;
+    }
+
+    private final Stack<DataSchemaNode> checkElementAndSchemaNodeNameAndNamespace(final StartElement startElement,
+            final DataSchemaNode node) {
+        checkArgument(startElement != null, "Start Element cannot be NULL!");
+        final String expectedName = node.getQName().getLocalName();
+        final String xmlName = getLocalNameFor(startElement);
+        final URI expectedNamespace = node.getQName().getNamespace();
+        final URI xmlNamespace = getNamespaceFor(startElement);
+        if (!expectedName.equals(xmlName)) {
+            throw new RestconfDocumentedException("Xml element name: " + xmlName + "\nSchema node name: "
+                    + expectedName, org.opendaylight.controller.sal.restconf.impl.RestconfError.ErrorType.APPLICATION,
+                    ErrorTag.INVALID_VALUE);
+        }
+
+        if (xmlNamespace != null && !expectedNamespace.equals(xmlNamespace)) {
+            throw new RestconfDocumentedException("Xml element ns: " + xmlNamespace + "\nSchema node ns: "
+                    + expectedNamespace,
+                    org.opendaylight.controller.sal.restconf.impl.RestconfError.ErrorType.APPLICATION,
+                    ErrorTag.INVALID_VALUE);
+        }
+        Stack<DataSchemaNode> processingQueueSchema = new Stack<>();
+        processingQueueSchema.push(node);
+        return processingQueueSchema;
+    }
+
+    /**
+     * If the input stream is not markable, then it wraps the input stream with a buffered stream, which is mark able.
+     * That way we can check if the stream is empty safely.
+     *
+     * @param entityStream
+     * @return
+     */
+    private InputStream getMarkableStream(InputStream entityStream) {
+        if (!entityStream.markSupported()) {
+            entityStream = new BufferedInputStream(entityStream);
+        }
+        return entityStream;
+    }
+
+    private boolean isInputStreamEmpty(final InputStream entityStream) throws IOException {
+        boolean isEmpty = false;
+        entityStream.mark(1);
+        if (entityStream.read() == -1) {
+            isEmpty = true;
+        }
+        entityStream.reset();
+        return isEmpty;
+    }
+
+    private boolean isSimpleNodeEvent(final XMLEvent event) throws XMLStreamException {
+        checkArgument(event != null, "XML Event cannot be NULL!");
+        if (event.isStartElement()) {
+            XMLEvent innerEvent = skipCommentsAndWhitespace();
+            if (innerEvent != null && (innerEvent.isCharacters() || innerEvent.isEndElement())) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    private boolean isCompositeNodeEvent(final XMLEvent event) throws XMLStreamException {
+        checkArgument(event != null, "XML Event cannot be NULL!");
+        if (event.isStartElement()) {
+            XMLEvent innerEvent = skipCommentsAndWhitespace();
+            if (innerEvent != null) {
+                if (innerEvent.isStartElement()) {
+                    return true;
+                }
+            }
+        }
+        return false;
+    }
+
+    private XMLEvent skipCommentsAndWhitespace() throws XMLStreamException {
+        while (eventReader.hasNext()) {
+            XMLEvent event = eventReader.peek();
+            if (event.getEventType() == XMLStreamConstants.COMMENT) {
+                eventReader.nextEvent();
+                continue;
+            }
+
+            if (event.isCharacters()) {
+                Characters chars = event.asCharacters();
+                if (chars.isWhiteSpace()) {
+                    eventReader.nextEvent();
+                    continue;
+                }
+            }
+            return event;
+        }
+        return null;
+    }
+
+    private CompositeNodeWrapper resolveCompositeNodeFromStartElement(final QName qName) {
+        // checkArgument(startElement != null, "Start Element cannot be NULL!");
+        CompositeNodeWrapper compositeNodeWrapper = new CompositeNodeWrapper("dummy");
+        compositeNodeWrapper.setQname(qName);
+        return compositeNodeWrapper;
+
+    }
+
+    private SimpleNodeWrapper resolveSimpleNodeFromStartElement(final DataSchemaNode node, final String value)
+            throws XMLStreamException {
+        // checkArgument(startElement != null, "Start Element cannot be NULL!");
+        Object deserializedValue = null;
+
+        if (node instanceof LeafSchemaNode) {
+            TypeDefinition<?> baseType = RestUtil.resolveBaseTypeFrom(((LeafSchemaNode) node).getType());
+            deserializedValue = RestCodec.from(baseType, iiWithSchema.getMountPoint()).deserialize(value);
+        } else if (node instanceof LeafListSchemaNode) {
+            TypeDefinition<?> baseType = RestUtil.resolveBaseTypeFrom(((LeafListSchemaNode) node).getType());
+            deserializedValue = RestCodec.from(baseType, iiWithSchema.getMountPoint()).deserialize(value);
+        }
+        // String data;
+        // if (data == null) {
+        // return new EmptyNodeWrapper(getNamespaceFor(startElement), getLocalNameFor(startElement));
+        // }
+        SimpleNodeWrapper simpleNodeWrapper = new SimpleNodeWrapper("dummy", deserializedValue);
+        simpleNodeWrapper.setQname(node.getQName());
+        return simpleNodeWrapper;
+    }
+
+    private String getValueOf(final StartElement startElement) throws XMLStreamException {
+        String data = null;
+        if (eventReader.hasNext()) {
+            final XMLEvent innerEvent = eventReader.peek();
+            if (innerEvent.isCharacters()) {
+                final Characters chars = innerEvent.asCharacters();
+                if (!chars.isWhiteSpace()) {
+                    data = innerEvent.asCharacters().getData();
+                    data = data + getAdditionalData(eventReader.nextEvent());
+                }
+            } else if (innerEvent.isEndElement()) {
+                if (startElement.getLocation().getCharacterOffset() == innerEvent.getLocation().getCharacterOffset()) {
+                    data = null;
+                } else {
+                    data = "";
+                }
+            }
+        }
+        return data == null ? null : data.trim();
+    }
+
+    private String getAdditionalData(final XMLEvent event) throws XMLStreamException {
+        String data = "";
+        if (eventReader.hasNext()) {
+            final XMLEvent innerEvent = eventReader.peek();
+            if (innerEvent.isCharacters() && !innerEvent.isEndElement()) {
+                final Characters chars = innerEvent.asCharacters();
+                if (!chars.isWhiteSpace()) {
+                    data = innerEvent.asCharacters().getData();
+                    data = data + getAdditionalData(eventReader.nextEvent());
+                }
+            }
+        }
+        return data;
+    }
+
+    private String getLocalNameFor(final StartElement startElement) {
+        return startElement.getName().getLocalPart();
+    }
+
+    private URI getNamespaceFor(final StartElement startElement) {
+        String namespaceURI = startElement.getName().getNamespaceURI();
+        return namespaceURI.isEmpty() ? null : URI.create(namespaceURI);
+    }
+
+    private Object resolveValueOfElement(final String value, final StartElement startElement) {
+        // it could be instance-identifier Built-In Type
+        if (value.startsWith("/")) {
+            IdentityValuesDTO iiValue = RestUtil.asInstanceIdentifier(value, new RestUtil.PrefixMapingFromXml(
+                    startElement));
+            if (iiValue != null) {
+                return iiValue;
+            }
+        }
+        // it could be identityref Built-In Type
+        String[] namespaceAndValue = value.split(":");
+        if (namespaceAndValue.length == 2) {
+            String namespace = startElement.getNamespaceContext().getNamespaceURI(namespaceAndValue[0]);
+            if (namespace != null && !namespace.isEmpty()) {
+                return new IdentityValuesDTO(namespace, namespaceAndValue[1], namespaceAndValue[0], value);
+            }
+        }
+        // it is not "prefix:value" but just "value"
+        return value;
+    }
+
+}
index 861aaac3d81552957b5798c3b775501d830fadce..be24fd26dd416f7d69838121cb7bf4f7ae2fdb0e 100644 (file)
@@ -7,38 +7,43 @@
  */
 package org.opendaylight.controller.sal.restconf.impl;
 
-import com.google.common.util.concurrent.Futures;
+import static org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType.CONFIGURATION;
+import static org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType.OPERATIONAL;
 
+import com.google.common.base.Optional;
+import com.google.common.util.concurrent.CheckedFuture;
+import com.google.common.util.concurrent.ListenableFuture;
+import java.util.concurrent.ExecutionException;
 import java.util.concurrent.Future;
-
 import javax.ws.rs.core.Response.Status;
-
-import org.opendaylight.controller.md.sal.common.api.TransactionStatus;
-import org.opendaylight.controller.md.sal.common.api.data.DataReader;
+import org.opendaylight.controller.md.sal.common.api.data.AsyncDataBroker.DataChangeScope;
+import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
+import org.opendaylight.controller.md.sal.common.api.data.TransactionCommitFailedException;
+import org.opendaylight.controller.md.sal.dom.api.DOMDataBroker;
+import org.opendaylight.controller.md.sal.dom.api.DOMDataChangeListener;
+import org.opendaylight.controller.md.sal.dom.api.DOMDataReadTransaction;
+import org.opendaylight.controller.md.sal.dom.api.DOMDataReadWriteTransaction;
+import org.opendaylight.controller.md.sal.dom.api.DOMDataWriteTransaction;
+import org.opendaylight.controller.md.sal.dom.api.DOMMountPoint;
 import org.opendaylight.controller.sal.core.api.Broker.ConsumerSession;
-import org.opendaylight.controller.sal.core.api.data.DataBrokerService;
-import org.opendaylight.controller.sal.core.api.data.DataChangeListener;
-import org.opendaylight.controller.sal.core.api.data.DataModificationTransaction;
-import org.opendaylight.controller.sal.core.api.mount.MountInstance;
 import org.opendaylight.controller.sal.restconf.impl.RestconfError.ErrorTag;
 import org.opendaylight.controller.sal.restconf.impl.RestconfError.ErrorType;
 import org.opendaylight.controller.sal.streams.listeners.ListenerAdapter;
 import org.opendaylight.yangtools.concepts.ListenerRegistration;
 import org.opendaylight.yangtools.yang.common.QName;
 import org.opendaylight.yangtools.yang.common.RpcResult;
-import org.opendaylight.yangtools.yang.common.RpcResultBuilder;
 import org.opendaylight.yangtools.yang.data.api.CompositeNode;
 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
+import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-public class BrokerFacade implements DataReader<YangInstanceIdentifier, CompositeNode> {
+public class BrokerFacade {
     private final static Logger LOG = LoggerFactory.getLogger(BrokerFacade.class);
 
     private final static BrokerFacade INSTANCE = new BrokerFacade();
-
-    private volatile DataBrokerService dataService;
     private volatile ConsumerSession context;
+    private DOMDataBroker domDataBroker;
 
     private BrokerFacade() {
     }
@@ -47,154 +52,175 @@ public class BrokerFacade implements DataReader<YangInstanceIdentifier, Composit
         this.context = context;
     }
 
-    public void setDataService(final DataBrokerService dataService) {
-        this.dataService = dataService;
-    }
-
     public static BrokerFacade getInstance() {
         return BrokerFacade.INSTANCE;
     }
 
     private void checkPreconditions() {
-        if (context == null || dataService == null) {
+        if (context == null || domDataBroker == null) {
             throw new RestconfDocumentedException(Status.SERVICE_UNAVAILABLE);
         }
     }
 
-    @Override
-    public CompositeNode readConfigurationData(final YangInstanceIdentifier path) {
-        this.checkPreconditions();
-
-        LOG.trace("Read Configuration via Restconf: {}", path);
+    // READ configuration
+    public NormalizedNode<?, ?> readConfigurationData(final YangInstanceIdentifier path) {
+        checkPreconditions();
+        return readDataViaTransaction(domDataBroker.newReadOnlyTransaction(), CONFIGURATION, path);
+    }
 
-        return dataService.readConfigurationData(path);
+    public NormalizedNode<?, ?> readConfigurationData(final DOMMountPoint mountPoint, final YangInstanceIdentifier path) {
+        final Optional<DOMDataBroker> domDataBrokerService = mountPoint.getService(DOMDataBroker.class);
+        if (domDataBrokerService.isPresent()) {
+            return readDataViaTransaction(domDataBrokerService.get().newReadOnlyTransaction(), CONFIGURATION, path);
+        }
+        throw new RestconfDocumentedException("DOM data broker service isn't available for mount point.");
     }
 
-    public CompositeNode readConfigurationDataBehindMountPoint(final MountInstance mountPoint,
-            final YangInstanceIdentifier path) {
-        this.checkPreconditions();
+    // READ operational
+    public NormalizedNode<?, ?> readOperationalData(final YangInstanceIdentifier path) {
+        checkPreconditions();
+        return readDataViaTransaction(domDataBroker.newReadOnlyTransaction(), OPERATIONAL, path);
+    }
 
-        LOG.trace("Read Configuration via Restconf: {}", path);
+    public NormalizedNode<?, ?> readOperationalData(final DOMMountPoint mountPoint, final YangInstanceIdentifier path) {
+        final Optional<DOMDataBroker> domDataBrokerService = mountPoint.getService(DOMDataBroker.class);
+        if (domDataBrokerService.isPresent()) {
+            return readDataViaTransaction(domDataBrokerService.get().newReadOnlyTransaction(), OPERATIONAL, path);
+        }
+        throw new RestconfDocumentedException("DOM data broker service isn't available for mount point.");
+    }
 
-        return mountPoint.readConfigurationData(path);
+    // PUT configuration
+    public CheckedFuture<Void, TransactionCommitFailedException> commitConfigurationDataPut(
+            final YangInstanceIdentifier path, final NormalizedNode<?, ?> payload) {
+        checkPreconditions();
+        return putDataViaTransaction(domDataBroker.newWriteOnlyTransaction(), CONFIGURATION, path, payload);
     }
 
-    @Override
-    public CompositeNode readOperationalData(final YangInstanceIdentifier path) {
-        this.checkPreconditions();
+    public CheckedFuture<Void, TransactionCommitFailedException> commitConfigurationDataPut(
+            final DOMMountPoint mountPoint, final YangInstanceIdentifier path, final NormalizedNode<?, ?> payload) {
+        final Optional<DOMDataBroker> domDataBrokerService = mountPoint.getService(DOMDataBroker.class);
+        if (domDataBrokerService.isPresent()) {
+            return putDataViaTransaction(domDataBrokerService.get().newWriteOnlyTransaction(), CONFIGURATION, path,
+                    payload);
+        }
+        throw new RestconfDocumentedException("DOM data broker service isn't available for mount point.");
+    }
 
-        BrokerFacade.LOG.trace("Read Operational via Restconf: {}", path);
+    // POST configuration
+    public CheckedFuture<Void, TransactionCommitFailedException> commitConfigurationDataPost(
+            final YangInstanceIdentifier path, final NormalizedNode<?, ?> payload) {
+        checkPreconditions();
+        return postDataViaTransaction(domDataBroker.newReadWriteTransaction(), CONFIGURATION, path, payload);
+    }
 
-        return dataService.readOperationalData(path);
+    public CheckedFuture<Void, TransactionCommitFailedException> commitConfigurationDataPost(
+            final DOMMountPoint mountPoint, final YangInstanceIdentifier path, final NormalizedNode<?, ?> payload) {
+        final Optional<DOMDataBroker> domDataBrokerService = mountPoint.getService(DOMDataBroker.class);
+        if (domDataBrokerService.isPresent()) {
+            return postDataViaTransaction(domDataBrokerService.get().newReadWriteTransaction(), CONFIGURATION, path,
+                    payload);
+        }
+        throw new RestconfDocumentedException("DOM data broker service isn't available for mount point.");
     }
 
-    public CompositeNode readOperationalDataBehindMountPoint(final MountInstance mountPoint,
+    // DELETE configuration
+    public CheckedFuture<Void, TransactionCommitFailedException> commitConfigurationDataDelete(
             final YangInstanceIdentifier path) {
-        this.checkPreconditions();
-
-        BrokerFacade.LOG.trace("Read Operational via Restconf: {}", path);
+        checkPreconditions();
+        return deleteDataViaTransaction(domDataBroker.newWriteOnlyTransaction(), CONFIGURATION, path);
+    }
 
-        return mountPoint.readOperationalData(path);
+    public CheckedFuture<Void, TransactionCommitFailedException> commitConfigurationDataDelete(
+            final DOMMountPoint mountPoint, final YangInstanceIdentifier path) {
+        final Optional<DOMDataBroker> domDataBrokerService = mountPoint.getService(DOMDataBroker.class);
+        if (domDataBrokerService.isPresent()) {
+            return deleteDataViaTransaction(domDataBrokerService.get().newWriteOnlyTransaction(), CONFIGURATION, path);
+        }
+        throw new RestconfDocumentedException("DOM data broker service isn't available for mount point.");
     }
 
+    // RPC
     public Future<RpcResult<CompositeNode>> invokeRpc(final QName type, final CompositeNode payload) {
         this.checkPreconditions();
 
         return context.rpc(type, payload);
     }
 
-    public Future<RpcResult<TransactionStatus>> commitConfigurationDataPut(final YangInstanceIdentifier path,
-            final CompositeNode payload) {
+    public void registerToListenDataChanges(final LogicalDatastoreType datastore, final DataChangeScope scope,
+            final ListenerAdapter listener) {
         this.checkPreconditions();
 
-        final DataModificationTransaction transaction = dataService.beginTransaction();
-        BrokerFacade.LOG.trace("Put Configuration via Restconf: {}", path);
-        transaction.putConfigurationData(path, payload);
-        return transaction.commit();
-    }
+        if (listener.isListening()) {
+            return;
+        }
 
-    public Future<RpcResult<TransactionStatus>> commitConfigurationDataPutBehindMountPoint(
-            final MountInstance mountPoint, final YangInstanceIdentifier path, final CompositeNode payload) {
-        this.checkPreconditions();
+        YangInstanceIdentifier path = listener.getPath();
+        final ListenerRegistration<DOMDataChangeListener> registration = domDataBroker.registerDataChangeListener(
+                datastore, path, listener, scope);
 
-        final DataModificationTransaction transaction = mountPoint.beginTransaction();
-        BrokerFacade.LOG.trace("Put Configuration via Restconf: {}", path);
-        transaction.putConfigurationData(path, payload);
-        return transaction.commit();
+        listener.setRegistration(registration);
     }
 
-    public Future<RpcResult<TransactionStatus>> commitConfigurationDataPost(final YangInstanceIdentifier path,
-            final CompositeNode payload) {
-        this.checkPreconditions();
-
-        final DataModificationTransaction transaction = dataService.beginTransaction();
-        /* check for available Node in Configuration DataStore by path */
-        CompositeNode availableNode = transaction.readConfigurationData(path);
-        if (availableNode != null) {
-            String errMsg = "Post Configuration via Restconf was not executed because data already exists";
-            BrokerFacade.LOG.warn((new StringBuilder(errMsg)).append(" : ").append(path).toString());
-
-            throw new RestconfDocumentedException("Data already exists for path: " + path, ErrorType.PROTOCOL,
-                    ErrorTag.DATA_EXISTS);
+    private NormalizedNode<?, ?> readDataViaTransaction(final DOMDataReadTransaction transaction,
+            LogicalDatastoreType datastore, YangInstanceIdentifier path) {
+        LOG.trace("Read " + datastore.name() + " via Restconf: {}", path);
+        final ListenableFuture<Optional<NormalizedNode<?, ?>>> listenableFuture = transaction.read(datastore, path);
+        if (listenableFuture != null) {
+            Optional<NormalizedNode<?, ?>> optional;
+            try {
+                LOG.debug("Reading result data from transaction.");
+                optional = listenableFuture.get();
+            } catch (InterruptedException | ExecutionException e) {
+                throw new RestconfDocumentedException("Problem to get data from transaction.", e.getCause());
+
+            }
+            if (optional != null) {
+                if (optional.isPresent()) {
+                    return optional.get();
+                }
+            }
         }
-        BrokerFacade.LOG.trace("Post Configuration via Restconf: {}", path);
-        transaction.putConfigurationData(path, payload);
-        return transaction.commit();
-    }
-
-    public Future<RpcResult<TransactionStatus>> commitConfigurationDataPostBehindMountPoint(
-            final MountInstance mountPoint, final YangInstanceIdentifier path, final CompositeNode payload) {
-        this.checkPreconditions();
-
-        final DataModificationTransaction transaction = mountPoint.beginTransaction();
-        /* check for available Node in Configuration DataStore by path */
-        CompositeNode availableNode = transaction.readConfigurationData(path);
-        if (availableNode != null) {
-            String errMsg = "Post Configuration via Restconf was not executed because data already exists";
-            BrokerFacade.LOG.warn((new StringBuilder(errMsg)).append(" : ").append(path).toString());
-
-            throw new RestconfDocumentedException("Data already exists for path: " + path, ErrorType.PROTOCOL,
-                    ErrorTag.DATA_EXISTS);
+        return null;
+    }
+
+    private CheckedFuture<Void, TransactionCommitFailedException> postDataViaTransaction(
+            final DOMDataReadWriteTransaction rWTransaction, final LogicalDatastoreType datastore,
+            final YangInstanceIdentifier path, final NormalizedNode<?, ?> payload) {
+        ListenableFuture<Optional<NormalizedNode<?, ?>>> futureDatastoreData = rWTransaction.read(datastore, path);
+        try {
+            final Optional<NormalizedNode<?, ?>> optionalDatastoreData = futureDatastoreData.get();
+            if (optionalDatastoreData.isPresent() && payload.equals(optionalDatastoreData.get())) {
+                String errMsg = "Post Configuration via Restconf was not executed because data already exists";
+                LOG.trace(errMsg + ":{}", path);
+                throw new RestconfDocumentedException("Data already exists for path: " + path, ErrorType.PROTOCOL,
+                        ErrorTag.DATA_EXISTS);
+            }
+        } catch (InterruptedException | ExecutionException e) {
+            LOG.trace("It wasn't possible to get data loaded from datastore at path " + path);
         }
-        BrokerFacade.LOG.trace("Post Configuration via Restconf: {}", path);
-        transaction.putConfigurationData(path, payload);
-        return transaction.commit();
-    }
-
-    public Future<RpcResult<TransactionStatus>> commitConfigurationDataDelete(final YangInstanceIdentifier path) {
-        this.checkPreconditions();
-        return deleteDataAtTarget(path, dataService.beginTransaction());
+        rWTransaction.merge(datastore, path, payload);
+        LOG.trace("Post " + datastore.name() + " via Restconf: {}", path);
+        return rWTransaction.submit();
     }
 
-    public Future<RpcResult<TransactionStatus>> commitConfigurationDataDeleteBehindMountPoint(
-            final MountInstance mountPoint, final YangInstanceIdentifier path) {
-        this.checkPreconditions();
-        return deleteDataAtTarget(path, mountPoint.beginTransaction());
+    private CheckedFuture<Void, TransactionCommitFailedException> putDataViaTransaction(
+            final DOMDataWriteTransaction writeTransaction, final LogicalDatastoreType datastore,
+            final YangInstanceIdentifier path, final NormalizedNode<?, ?> payload) {
+        LOG.trace("Put " + datastore.name() + " via Restconf: {}", path);
+        writeTransaction.put(datastore, path, payload);
+        return writeTransaction.submit();
     }
 
-    private Future<RpcResult<TransactionStatus>> deleteDataAtTarget(final YangInstanceIdentifier path,
-            final DataModificationTransaction transaction) {
-        LOG.info("Delete Configuration via Restconf: {}", path);
-        CompositeNode redDataAtPath = transaction.readConfigurationData(path);
-        if (redDataAtPath == null) {
-            return Futures.immediateFuture(RpcResultBuilder.<TransactionStatus>
-                                                    success(TransactionStatus.COMMITED).build());
-        }
-        transaction.removeConfigurationData(path);
-        return transaction.commit();
+    private CheckedFuture<Void, TransactionCommitFailedException> deleteDataViaTransaction(
+            final DOMDataWriteTransaction writeTransaction, final LogicalDatastoreType datastore,
+            YangInstanceIdentifier path) {
+        LOG.info("Delete " + datastore.name() + " via Restconf: {}", path);
+        writeTransaction.delete(datastore, path);
+        return writeTransaction.submit();
     }
 
-    public void registerToListenDataChanges(final ListenerAdapter listener) {
-        this.checkPreconditions();
-
-        if (listener.isListening()) {
-            return;
-        }
-
-        YangInstanceIdentifier path = listener.getPath();
-        final ListenerRegistration<DataChangeListener> registration = dataService.registerDataChangeListener(path,
-                listener);
-
-        listener.setRegistration(registration);
+    public void setDomDataBroker(DOMDataBroker domDataBroker) {
+        this.domDataBroker = domDataBroker;
     }
 }
index f8bcbe3c616ab7910f1d2346543f898c8548cdac..39f4eef657bd0d06d42c7dd7c6cbbb222a97c856 100644 (file)
@@ -9,6 +9,7 @@ package org.opendaylight.controller.sal.restconf.impl;
 
 import com.google.common.base.Function;
 import com.google.common.base.Objects;
+import com.google.common.base.Optional;
 import com.google.common.base.Preconditions;
 import com.google.common.base.Predicate;
 import com.google.common.base.Splitter;
@@ -17,7 +18,6 @@ import com.google.common.collect.BiMap;
 import com.google.common.collect.HashBiMap;
 import com.google.common.collect.ImmutableMap;
 import com.google.common.collect.Iterables;
-
 import java.io.UnsupportedEncodingException;
 import java.net.URI;
 import java.net.URLDecoder;
@@ -31,11 +31,9 @@ import java.util.List;
 import java.util.Map;
 import java.util.Set;
 import java.util.concurrent.atomic.AtomicReference;
-
 import javax.ws.rs.core.Response.Status;
-
-import org.opendaylight.controller.sal.core.api.mount.MountInstance;
-import org.opendaylight.controller.sal.core.api.mount.MountService;
+import org.opendaylight.controller.md.sal.dom.api.DOMMountPoint;
+import org.opendaylight.controller.md.sal.dom.api.DOMMountPointService;
 import org.opendaylight.controller.sal.rest.api.Draft02;
 import org.opendaylight.controller.sal.rest.impl.RestUtil;
 import org.opendaylight.controller.sal.restconf.impl.RestconfError.ErrorTag;
@@ -91,13 +89,13 @@ public class ControllerContext implements SchemaContextListener {
             new AtomicReference<>(Collections.<QName, RpcDefinition>emptyMap());
 
     private volatile SchemaContext globalSchema;
-    private volatile MountService mountService;
+    private volatile DOMMountPointService mountService;
 
     public void setGlobalSchema(final SchemaContext globalSchema) {
         this.globalSchema = globalSchema;
     }
 
-    public void setMountService(final MountService mountService) {
+    public void setMountService(final DOMMountPointService mountService) {
         this.mountService = mountService;
     }
 
@@ -207,7 +205,7 @@ public class ControllerContext implements SchemaContextListener {
         return this.getLatestModule(globalSchema, moduleName);
     }
 
-    public Module findModuleByName(final MountInstance mountPoint, final String moduleName) {
+    public Module findModuleByName(final DOMMountPoint mountPoint, final String moduleName) {
         Preconditions.checkArgument(moduleName != null && mountPoint != null);
 
         final SchemaContext mountPointSchema = mountPoint.getSchemaContext();
@@ -222,7 +220,7 @@ public class ControllerContext implements SchemaContextListener {
         return moduleSchemas == null ? null : this.filterLatestModule(moduleSchemas);
     }
 
-    public Module findModuleByNamespace(final MountInstance mountPoint, final URI namespace) {
+    public Module findModuleByNamespace(final DOMMountPoint mountPoint, final URI namespace) {
         Preconditions.checkArgument(namespace != null && mountPoint != null);
 
         final SchemaContext mountPointSchema = mountPoint.getSchemaContext();
@@ -237,7 +235,7 @@ public class ControllerContext implements SchemaContextListener {
         return globalSchema.findModuleByName(module.getLocalName(), module.getRevision());
     }
 
-    public Module findModuleByNameAndRevision(final MountInstance mountPoint, final QName module) {
+    public Module findModuleByNameAndRevision(final DOMMountPoint mountPoint, final QName module) {
         this.checkPreconditions();
         Preconditions.checkArgument(module != null && module.getLocalName() != null && module.getRevision() != null
                 && mountPoint != null);
@@ -306,7 +304,7 @@ public class ControllerContext implements SchemaContextListener {
         return moduleName;
     }
 
-    public String findModuleNameByNamespace(final MountInstance mountPoint, final URI namespace) {
+    public String findModuleNameByNamespace(final DOMMountPoint mountPoint, final URI namespace) {
         final Module module = this.findModuleByNamespace(mountPoint, namespace);
         return module == null ? null : module.getName();
     }
@@ -324,12 +322,12 @@ public class ControllerContext implements SchemaContextListener {
         return namespace;
     }
 
-    public URI findNamespaceByModuleName(final MountInstance mountPoint, final String moduleName) {
+    public URI findNamespaceByModuleName(final DOMMountPoint mountPoint, final String moduleName) {
         final Module module = this.findModuleByName(mountPoint, moduleName);
         return module == null ? null : module.getNamespace();
     }
 
-    public Set<Module> getAllModules(final MountInstance mountPoint) {
+    public Set<Module> getAllModules(final DOMMountPoint mountPoint) {
         this.checkPreconditions();
 
         SchemaContext schemaContext = mountPoint == null ? null : mountPoint.getSchemaContext();
@@ -363,7 +361,7 @@ public class ControllerContext implements SchemaContextListener {
         return builder.toString();
     }
 
-    public CharSequence toRestconfIdentifier(final MountInstance mountPoint, final QName qname) {
+    public CharSequence toRestconfIdentifier(final DOMMountPoint mountPoint, final QName qname) {
         if (mountPoint == null) {
             return null;
         }
@@ -525,7 +523,7 @@ public class ControllerContext implements SchemaContextListener {
     }
 
     private InstanceIdWithSchemaNode collectPathArguments(final InstanceIdentifierBuilder builder,
-            final List<String> strings, final DataNodeContainer parentNode, final MountInstance mountPoint,
+            final List<String> strings, final DataNodeContainer parentNode, final DOMMountPoint mountPoint,
             final boolean returnJustMountPoint) {
         Preconditions.<List<String>> checkNotNull(strings);
 
@@ -557,12 +555,13 @@ public class ControllerContext implements SchemaContextListener {
                 }
 
                 final YangInstanceIdentifier partialPath = builder.toInstance();
-                final MountInstance mount = mountService.getMountPoint(partialPath);
-                if (mount == null) {
+                final Optional<DOMMountPoint> mountOpt = mountService.getMountPoint(partialPath);
+                if (!mountOpt.isPresent()) {
                     LOG.debug("Instance identifier to missing mount point: {}", partialPath);
                     throw new RestconfDocumentedException("Mount point does not exist.", ErrorType.PROTOCOL,
                             ErrorTag.UNKNOWN_ELEMENT);
                 }
+                DOMMountPoint mount = mountOpt.get();
 
                 final SchemaContext mountPointSchema = mount.getSchemaContext();
                 if (mountPointSchema == null) {
@@ -764,7 +763,7 @@ public class ControllerContext implements SchemaContextListener {
     }
 
     private void addKeyValue(final HashMap<QName, Object> map, final DataSchemaNode node, final String uriValue,
-            final MountInstance mountPoint) {
+            final DOMMountPoint mountPoint) {
         Preconditions.<String> checkNotNull(uriValue);
         Preconditions.checkArgument((node instanceof LeafSchemaNode));
 
index 12c1ba66ecc3df3ad2d5c838a1ee916d85a21f5c..b58a6eeaea9393750dfacfc12f0355a5c6662310 100644 (file)
@@ -7,7 +7,7 @@
  */
 package org.opendaylight.controller.sal.restconf.impl;
 
-import org.opendaylight.controller.sal.core.api.mount.MountInstance;
+import org.opendaylight.controller.md.sal.dom.api.DOMMountPoint;
 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
 import org.opendaylight.yangtools.yang.model.api.DataSchemaNode;
 
@@ -15,10 +15,10 @@ public class InstanceIdWithSchemaNode {
 
     private final YangInstanceIdentifier instanceIdentifier;
     private final DataSchemaNode schemaNode;
-    private final MountInstance mountPoint;
+    private final DOMMountPoint mountPoint;
 
     public InstanceIdWithSchemaNode(YangInstanceIdentifier instanceIdentifier, DataSchemaNode schemaNode,
-            MountInstance mountPoint) {
+            DOMMountPoint mountPoint) {
         this.instanceIdentifier = instanceIdentifier;
         this.schemaNode = schemaNode;
         this.mountPoint = mountPoint;
@@ -32,7 +32,7 @@ public class InstanceIdWithSchemaNode {
         return schemaNode;
     }
 
-    public MountInstance getMountPoint() {
+    public DOMMountPoint getMountPoint() {
         return mountPoint;
     }
 
index ff90dd8439582969d8db755c2ae08f4e91129cc5..d61ccfdacf0e387fdd71e28a69b4b1bde6e99a0d 100644 (file)
@@ -12,7 +12,7 @@ import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
-import org.opendaylight.controller.sal.core.api.mount.MountInstance;
+import org.opendaylight.controller.md.sal.dom.api.DOMMountPoint;
 import org.opendaylight.controller.sal.rest.impl.RestUtil;
 import org.opendaylight.controller.sal.restconf.impl.IdentityValuesDTO.IdentityValue;
 import org.opendaylight.controller.sal.restconf.impl.IdentityValuesDTO.Predicate;
@@ -47,7 +47,7 @@ public class RestCodec {
     }
 
     public static final Codec<Object, Object> from(final TypeDefinition<?> typeDefinition,
-            final MountInstance mountPoint) {
+            final DOMMountPoint mountPoint) {
         return new ObjectCodec(typeDefinition, mountPoint);
     }
 
@@ -62,7 +62,7 @@ public class RestCodec {
 
         private final TypeDefinition<?> type;
 
-        private ObjectCodec(final TypeDefinition<?> typeDefinition, final MountInstance mountPoint) {
+        private ObjectCodec(final TypeDefinition<?> typeDefinition, final DOMMountPoint mountPoint) {
             type = RestUtil.resolveBaseTypeFrom(typeDefinition);
             if (type instanceof IdentityrefTypeDefinition) {
                 identityrefCodec = new IdentityrefCodecImpl(mountPoint);
@@ -158,9 +158,9 @@ public class RestCodec {
 
         private final Logger logger = LoggerFactory.getLogger(IdentityrefCodecImpl.class);
 
-        private final MountInstance mountPoint;
+        private final DOMMountPoint mountPoint;
 
-        public IdentityrefCodecImpl(final MountInstance mountPoint) {
+        public IdentityrefCodecImpl(final DOMMountPoint mountPoint) {
             this.mountPoint = mountPoint;
         }
 
@@ -200,9 +200,9 @@ public class RestCodec {
 
     public static class InstanceIdentifierCodecImpl implements InstanceIdentifierCodec<IdentityValuesDTO> {
         private final Logger logger = LoggerFactory.getLogger(InstanceIdentifierCodecImpl.class);
-        private final MountInstance mountPoint;
+        private final DOMMountPoint mountPoint;
 
-        public InstanceIdentifierCodecImpl(final MountInstance mountPoint) {
+        public InstanceIdentifierCodecImpl(final DOMMountPoint mountPoint) {
             this.mountPoint = mountPoint;
         }
 
@@ -318,7 +318,7 @@ public class RestCodec {
         }
     }
 
-    private static Module getModuleByNamespace(final String namespace, final MountInstance mountPoint) {
+    private static Module getModuleByNamespace(final String namespace, final DOMMountPoint mountPoint) {
         URI validNamespace = resolveValidNamespace(namespace, mountPoint);
 
         Module module = null;
@@ -334,7 +334,7 @@ public class RestCodec {
         return module;
     }
 
-    private static URI resolveValidNamespace(final String namespace, final MountInstance mountPoint) {
+    private static URI resolveValidNamespace(final String namespace, final DOMMountPoint mountPoint) {
         URI validNamespace;
         if (mountPoint != null) {
             validNamespace = ControllerContext.getInstance().findNamespaceByModuleName(mountPoint, namespace);
index 4c005c6ae5e9e109604a1890cd5ee0c5f81d264a..b68bee2f0c9cc30e04a7c6ae62288f6cf6f4bdb6 100644 (file)
@@ -24,17 +24,19 @@ import java.util.Collection;
 import java.util.Collections;
 import java.util.Date;
 import java.util.HashMap;
+import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
-import java.util.concurrent.Future;
 import javax.ws.rs.core.Response;
 import javax.ws.rs.core.Response.Status;
 import javax.ws.rs.core.UriBuilder;
 import javax.ws.rs.core.UriInfo;
 import org.apache.commons.lang3.StringUtils;
 import org.opendaylight.controller.md.sal.common.api.TransactionStatus;
-import org.opendaylight.controller.sal.core.api.mount.MountInstance;
+import org.opendaylight.controller.md.sal.common.api.data.AsyncDataBroker.DataChangeScope;
+import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
+import org.opendaylight.controller.md.sal.dom.api.DOMMountPoint;
 import org.opendaylight.controller.sal.rest.api.Draft02;
 import org.opendaylight.controller.sal.rest.api.RestconfService;
 import org.opendaylight.controller.sal.restconf.impl.RestconfError.ErrorTag;
@@ -47,16 +49,23 @@ import org.opendaylight.controller.sal.streams.listeners.Notificator;
 import org.opendaylight.controller.sal.streams.websockets.WebSocketServer;
 import org.opendaylight.yangtools.concepts.Codec;
 import org.opendaylight.yangtools.yang.common.QName;
+import org.opendaylight.yangtools.yang.common.QNameModule;
 import org.opendaylight.yangtools.yang.common.RpcError;
 import org.opendaylight.yangtools.yang.common.RpcResult;
 import org.opendaylight.yangtools.yang.data.api.CompositeNode;
+import org.opendaylight.yangtools.yang.data.api.MutableCompositeNode;
+import org.opendaylight.yangtools.yang.data.api.Node;
+import org.opendaylight.yangtools.yang.data.api.SimpleNode;
 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.InstanceIdentifierBuilder;
 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifierWithPredicates;
 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.PathArgument;
-import org.opendaylight.yangtools.yang.data.api.MutableCompositeNode;
-import org.opendaylight.yangtools.yang.data.api.Node;
-import org.opendaylight.yangtools.yang.data.api.SimpleNode;
+import org.opendaylight.yangtools.yang.data.api.schema.ContainerNode;
+import org.opendaylight.yangtools.yang.data.api.schema.MapEntryNode;
+import org.opendaylight.yangtools.yang.data.api.schema.MapNode;
+import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
+import org.opendaylight.yangtools.yang.data.composite.node.schema.cnsn.parser.CnSnToNormalizedNodeParserFactory;
+import org.opendaylight.yangtools.yang.data.composite.node.schema.cnsn.serializer.CnSnFromNormalizedNodeSerializerFactory;
 import org.opendaylight.yangtools.yang.data.impl.ImmutableCompositeNode;
 import org.opendaylight.yangtools.yang.data.impl.NodeFactory;
 import org.opendaylight.yangtools.yang.model.api.AnyXmlSchemaNode;
@@ -76,6 +85,8 @@ import org.opendaylight.yangtools.yang.model.api.type.IdentityrefTypeDefinition;
 import org.opendaylight.yangtools.yang.model.util.EmptyType;
 import org.opendaylight.yangtools.yang.parser.builder.impl.ContainerSchemaNodeBuilder;
 import org.opendaylight.yangtools.yang.parser.builder.impl.LeafSchemaNodeBuilder;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
 public class RestconfImpl implements RestconfService {
     private enum UriParameters {
@@ -96,6 +107,8 @@ public class RestconfImpl implements RestconfService {
 
     private final static RestconfImpl INSTANCE = new RestconfImpl();
 
+    private static final int NOTIFICATION_PORT = 8181;
+
     private static final int CHAR_NOT_FOUND = -1;
 
     private final static String MOUNT_POINT_MODULE_NAME = "ietf-netconf";
@@ -110,6 +123,30 @@ public class RestconfImpl implements RestconfService {
 
     private ControllerContext controllerContext;
 
+    private static final Logger LOG = LoggerFactory.getLogger(RestconfImpl.class);
+
+    private static final DataChangeScope DEFAULT_SCOPE = DataChangeScope.BASE;
+
+    private static final LogicalDatastoreType DEFAULT_DATASTORE = LogicalDatastoreType.CONFIGURATION;
+
+    private static final URI NAMESPACE_EVENT_SUBSCRIPTION_AUGMENT = URI.create("urn:sal:restconf:event:subscription");
+
+    private static final Date EVENT_SUBSCRIPTION_AUGMENT_REVISION;
+
+    private static final String DATASTORE_PARAM_NAME = "datastore";
+
+    private static final String SCOPE_PARAM_NAME = "scope";
+
+    static {
+        try {
+            EVENT_SUBSCRIPTION_AUGMENT_REVISION = new SimpleDateFormat("yyyy-MM-dd").parse("2014-07-08");
+        } catch (ParseException e) {
+            throw new RestconfDocumentedException(
+                    "It wasn't possible to convert revision date of sal-remote-augment to date", ErrorType.APPLICATION,
+                    ErrorTag.OPERATION_FAILED);
+        }
+    }
+
     public void setBroker(final BrokerFacade broker) {
         this.broker = broker;
     }
@@ -168,7 +205,7 @@ public class RestconfImpl implements RestconfService {
     @Override
     public StructuredData getModules(final String identifier, final UriInfo uriInfo) {
         Set<Module> modules = null;
-        MountInstance mountPoint = null;
+        DOMMountPoint mountPoint = null;
         if (identifier.contains(ControllerContext.MOUNT)) {
             InstanceIdWithSchemaNode mountPointIdentifier = this.controllerContext.toMountPointIdentifier(identifier);
             mountPoint = mountPointIdentifier.getMountPoint();
@@ -199,7 +236,7 @@ public class RestconfImpl implements RestconfService {
     public StructuredData getModule(final String identifier, final UriInfo uriInfo) {
         final QName moduleNameAndRevision = this.getModuleNameAndRevision(identifier);
         Module module = null;
-        MountInstance mountPoint = null;
+        DOMMountPoint mountPoint = null;
         if (identifier.contains(ControllerContext.MOUNT)) {
             InstanceIdWithSchemaNode mountPointIdentifier = this.controllerContext.toMountPointIdentifier(identifier);
             mountPoint = mountPointIdentifier.getMountPoint();
@@ -230,7 +267,7 @@ public class RestconfImpl implements RestconfService {
     @Override
     public StructuredData getOperations(final String identifier, final UriInfo uriInfo) {
         Set<Module> modules = null;
-        MountInstance mountPoint = null;
+        DOMMountPoint mountPoint = null;
         if (identifier.contains(ControllerContext.MOUNT)) {
             InstanceIdWithSchemaNode mountPointIdentifier = this.controllerContext.toMountPointIdentifier(identifier);
             mountPoint = mountPointIdentifier.getMountPoint();
@@ -245,7 +282,7 @@ public class RestconfImpl implements RestconfService {
     }
 
     private StructuredData operationsFromModulesToStructuredData(final Set<Module> modules,
-            final MountInstance mountPoint, boolean prettyPrint) {
+            final DOMMountPoint mountPoint, boolean prettyPrint) {
         final List<Node<?>> operationsAsData = new ArrayList<Node<?>>();
         Module restconfModule = this.getRestconfModule();
         final DataSchemaNode operationsSchemaNode = controllerContext.getRestconfModuleRestConfSchemaNode(
@@ -405,7 +442,7 @@ public class RestconfImpl implements RestconfService {
         return callRpc(rpc, payload, parsePrettyPrintParameter(uriInfo));
     }
 
-    private void validateInput(final DataSchemaNode inputSchema, final CompositeNode payload) {
+    private void validateInput(final DataSchemaNode inputSchema, final Node<?> payload) {
         if (inputSchema != null && payload == null) {
             // expected a non null payload
             throw new RestconfDocumentedException("Input is required.", ErrorType.PROTOCOL, ErrorTag.MALFORMED_MESSAGE);
@@ -416,6 +453,7 @@ public class RestconfImpl implements RestconfService {
         // else
         // {
         // TODO: Validate "mandatory" and "config" values here??? Or should those be
+        // those be
         // validate in a more central location inside MD-SAL core.
         // }
     }
@@ -436,7 +474,15 @@ public class RestconfImpl implements RestconfService {
         String streamName = null;
         if (!Iterables.isEmpty(pathIdentifier.getPathArguments())) {
             String fullRestconfIdentifier = this.controllerContext.toFullRestconfIdentifier(pathIdentifier);
-            streamName = Notificator.createStreamNameFromUri(fullRestconfIdentifier);
+
+            LogicalDatastoreType datastore = parseEnumTypeParameter(value, LogicalDatastoreType.class, DATASTORE_PARAM_NAME);
+            datastore = datastore == null ? DEFAULT_DATASTORE : datastore;
+
+            DataChangeScope scope = parseEnumTypeParameter(value, DataChangeScope.class, SCOPE_PARAM_NAME);
+            scope = scope == null ? DEFAULT_SCOPE : scope;
+
+            streamName = Notificator.createStreamNameFromUri(fullRestconfIdentifier + "/datastore=" + datastore
+                    + "/scope=" + scope);
         }
 
         if (Strings.isNullOrEmpty(streamName)) {
@@ -453,7 +499,7 @@ public class RestconfImpl implements RestconfService {
         final MutableCompositeNode responseData = NodeFactory.createMutableCompositeNode(rpc.getOutput().getQName(),
                 null, output, null, null);
 
-        if (!Notificator.existListenerFor(pathIdentifier)) {
+        if (!Notificator.existListenerFor(streamName)) {
             Notificator.createListener(pathIdentifier, streamName);
         }
 
@@ -470,7 +516,7 @@ public class RestconfImpl implements RestconfService {
 
     private RpcExecutor resolveIdentifierInInvokeRpc(final String identifier) {
         String identifierEncoded = null;
-        MountInstance mountPoint = null;
+        DOMMountPoint mountPoint = null;
         if (identifier.contains(ControllerContext.MOUNT)) {
             // mounted RPC call - look up mount instance.
             InstanceIdWithSchemaNode mountPointId = controllerContext.toMountPointIdentifier(identifier);
@@ -582,18 +628,20 @@ public class RestconfImpl implements RestconfService {
 
     @Override
     public StructuredData readConfigurationData(final String identifier, final UriInfo uriInfo) {
-        final InstanceIdWithSchemaNode iiWithData = this.controllerContext.toInstanceIdentifier(identifier);
-        CompositeNode data = null;
-        MountInstance mountPoint = iiWithData.getMountPoint();
+        final InstanceIdWithSchemaNode iiWithData = normalizeInstanceIdentifierWithSchemaNode(
+                this.controllerContext.toInstanceIdentifier(identifier), true);
+        DOMMountPoint mountPoint = iiWithData.getMountPoint();
+        NormalizedNode<?, ?> data = null;
         if (mountPoint != null) {
-            data = broker.readConfigurationDataBehindMountPoint(mountPoint, iiWithData.getInstanceIdentifier());
+            data = broker.readConfigurationData(mountPoint, iiWithData.getInstanceIdentifier());
         } else {
             data = broker.readConfigurationData(iiWithData.getInstanceIdentifier());
         }
+        CompositeNode compositeNode = datastoreNormalizedNodeToCompositeNode(data, iiWithData.getSchemaNode());
 
-        data = pruneDataAtDepth(data, parseDepthParameter(uriInfo));
+        compositeNode = pruneDataAtDepth(compositeNode, parseDepthParameter(uriInfo));
         boolean prettyPrintMode = parsePrettyPrintParameter(uriInfo);
-        return new StructuredData(data, iiWithData.getSchemaNode(), iiWithData.getMountPoint(), prettyPrintMode);
+        return new StructuredData(compositeNode, iiWithData.getSchemaNode(), iiWithData.getMountPoint(), prettyPrintMode);
     }
 
     @SuppressWarnings("unchecked")
@@ -640,18 +688,21 @@ public class RestconfImpl implements RestconfService {
 
     @Override
     public StructuredData readOperationalData(final String identifier, final UriInfo info) {
-        final InstanceIdWithSchemaNode iiWithData = this.controllerContext.toInstanceIdentifier(identifier);
-        CompositeNode data = null;
-        MountInstance mountPoint = iiWithData.getMountPoint();
+        final InstanceIdWithSchemaNode iiWithData = normalizeInstanceIdentifierWithSchemaNode(
+                this.controllerContext.toInstanceIdentifier(identifier), true);
+        NormalizedNode<?, ?> data = null;
+
+        DOMMountPoint mountPoint = iiWithData.getMountPoint();
         if (mountPoint != null) {
-            data = broker.readOperationalDataBehindMountPoint(mountPoint, iiWithData.getInstanceIdentifier());
+            data = broker.readOperationalData(mountPoint, iiWithData.getInstanceIdentifier());
         } else {
             data = broker.readOperationalData(iiWithData.getInstanceIdentifier());
         }
 
-        data = pruneDataAtDepth(data, parseDepthParameter(info));
-        boolean prettyPrintMode = parsePrettyPrintParameter(info);
-        return new StructuredData(data, iiWithData.getSchemaNode(), mountPoint, prettyPrintMode);
+        final CompositeNode compositeNode = datastoreNormalizedNodeToCompositeNode(data, iiWithData.getSchemaNode());
+        final CompositeNode prunedCompositeNode = pruneDataAtDepth(compositeNode, parseDepthParameter(info));
+        final boolean prettyPrintMode = parsePrettyPrintParameter(info);
+        return new StructuredData(prunedCompositeNode, iiWithData.getSchemaNode(), mountPoint,prettyPrintMode);
     }
 
     private boolean parsePrettyPrintParameter(UriInfo info) {
@@ -660,32 +711,31 @@ public class RestconfImpl implements RestconfService {
     }
 
     @Override
-    public Response updateConfigurationData(final String identifier, final CompositeNode payload) {
-        final InstanceIdWithSchemaNode iiWithData = this.controllerContext.toInstanceIdentifier(identifier);
+    public Response updateConfigurationData(final String identifier, final Node<?> payload) {
+        final InstanceIdWithSchemaNode iiWithData = normalizeInstanceIdentifierWithSchemaNode(this.controllerContext
+                .toInstanceIdentifier(identifier));
 
         validateInput(iiWithData.getSchemaNode(), payload);
 
-        MountInstance mountPoint = iiWithData.getMountPoint();
+        DOMMountPoint mountPoint = iiWithData.getMountPoint();
         final CompositeNode value = this.normalizeNode(payload, iiWithData.getSchemaNode(), mountPoint);
-        validateListKeysEqualityInPayloadAndUri(iiWithData, payload);
-        RpcResult<TransactionStatus> status = null;
+        validateListKeysEqualityInPayloadAndUri(iiWithData, value);
+        final NormalizedNode<?, ?> datastoreNormalizedNode = compositeNodeToDatastoreNormalizedNode(value,
+                iiWithData.getSchemaNode());
 
         try {
             if (mountPoint != null) {
-                status = broker.commitConfigurationDataPutBehindMountPoint(mountPoint,
-                        iiWithData.getInstanceIdentifier(), value).get();
+                broker.commitConfigurationDataPut(mountPoint, iiWithData.getInstanceIdentifier(),
+                        datastoreNormalizedNode).get();
             } else {
-                status = broker.commitConfigurationDataPut(iiWithData.getInstanceIdentifier(), value).get();
+                broker.commitConfigurationDataPut(iiWithData.getInstanceIdentifier(), datastoreNormalizedNode)
+                        .get();
             }
         } catch (Exception e) {
             throw new RestconfDocumentedException("Error updating data", e);
         }
 
-        if (status.getResult() == TransactionStatus.COMMITED) {
-            return Response.status(Status.OK).build();
-        }
-
-        return Response.status(Status.INTERNAL_SERVER_ERROR).build();
+        return Response.status(Status.OK).build();
     }
 
     /**
@@ -734,7 +784,7 @@ public class RestconfImpl implements RestconfService {
     }
 
     @Override
-    public Response createConfigurationData(final String identifier, final CompositeNode payload) {
+    public Response createConfigurationData(final String identifier, final Node<?> payload) {
         if (payload == null) {
             throw new RestconfDocumentedException("Input is required.", ErrorType.PROTOCOL, ErrorTag.MALFORMED_MESSAGE);
         }
@@ -765,8 +815,8 @@ public class RestconfImpl implements RestconfService {
             final InstanceIdWithSchemaNode incompleteInstIdWithData = this.controllerContext
                     .toInstanceIdentifier(identifier);
             final DataNodeContainer parentSchema = (DataNodeContainer) incompleteInstIdWithData.getSchemaNode();
-            MountInstance mountPoint = incompleteInstIdWithData.getMountPoint();
-            final Module module = this.findModule(mountPoint, payload);
+            DOMMountPoint mountPoint = incompleteInstIdWithData.getMountPoint();
+            final Module module = findModule(mountPoint, payload);
             if (module == null) {
                 throw new RestconfDocumentedException("Module was not found for \"" + payloadNS + "\"",
                         ErrorType.PROTOCOL, ErrorTag.UNKNOWN_ELEMENT);
@@ -777,38 +827,30 @@ public class RestconfImpl implements RestconfService {
                     parentSchema, payloadName, module.getNamespace());
             value = this.normalizeNode(payload, schemaNode, mountPoint);
 
-            iiWithData = this.addLastIdentifierFromData(incompleteInstIdWithData, value, schemaNode);
+            iiWithData = normalizeInstanceIdentifierWithSchemaNode(this.addLastIdentifierFromData(
+                    incompleteInstIdWithData, value, schemaNode));
         }
 
-        RpcResult<TransactionStatus> status = null;
-        MountInstance mountPoint = iiWithData.getMountPoint();
+        final NormalizedNode<?, ?> datastoreNormalizedData = compositeNodeToDatastoreNormalizedNode(value,
+                iiWithData.getSchemaNode());
+        DOMMountPoint mountPoint = iiWithData.getMountPoint();
         try {
             if (mountPoint != null) {
-                Future<RpcResult<TransactionStatus>> future = broker.commitConfigurationDataPostBehindMountPoint(
-                        mountPoint, iiWithData.getInstanceIdentifier(), value);
-                status = future == null ? null : future.get();
+                broker.commitConfigurationDataPost(mountPoint,
+                        iiWithData.getInstanceIdentifier(), datastoreNormalizedData);
             } else {
-                Future<RpcResult<TransactionStatus>> future = broker.commitConfigurationDataPost(
-                        iiWithData.getInstanceIdentifier(), value);
-                status = future == null ? null : future.get();
+                broker.commitConfigurationDataPost(
+                        iiWithData.getInstanceIdentifier(), datastoreNormalizedData);
             }
         } catch (Exception e) {
             throw new RestconfDocumentedException("Error creating data", e);
         }
 
-        if (status == null) {
-            return Response.status(Status.ACCEPTED).build();
-        }
-
-        if (status.getResult() == TransactionStatus.COMMITED) {
-            return Response.status(Status.NO_CONTENT).build();
-        }
-
-        return Response.status(Status.INTERNAL_SERVER_ERROR).build();
+        return Response.status(Status.NO_CONTENT).build();
     }
 
     @Override
-    public Response createConfigurationData(final CompositeNode payload) {
+    public Response createConfigurationData(final Node<?> payload) {
         if (payload == null) {
             throw new RestconfDocumentedException("Input is required.", ErrorType.PROTOCOL, ErrorTag.MALFORMED_MESSAGE);
         }
@@ -833,57 +875,56 @@ public class RestconfImpl implements RestconfService {
         final CompositeNode value = this.normalizeNode(payload, schemaNode, null);
         final InstanceIdWithSchemaNode iiWithData = this.addLastIdentifierFromData(null, value, schemaNode);
         RpcResult<TransactionStatus> status = null;
-        MountInstance mountPoint = iiWithData.getMountPoint();
+        final NormalizedNode<?, ?> datastoreNormalizedData = compositeNodeToDatastoreNormalizedNode(value, schemaNode);
+        DOMMountPoint mountPoint = iiWithData.getMountPoint();
 
         try {
             if (mountPoint != null) {
-                Future<RpcResult<TransactionStatus>> future = broker.commitConfigurationDataPostBehindMountPoint(
-                        mountPoint, iiWithData.getInstanceIdentifier(), value);
-                status = future == null ? null : future.get();
+                broker.commitConfigurationDataPost(mountPoint,
+                        iiWithData.getInstanceIdentifier(), datastoreNormalizedData);
             } else {
-                Future<RpcResult<TransactionStatus>> future = broker.commitConfigurationDataPost(
-                        iiWithData.getInstanceIdentifier(), value);
-                status = future == null ? null : future.get();
+                broker.commitConfigurationDataPost(
+                        iiWithData.getInstanceIdentifier(), datastoreNormalizedData);
             }
         } catch (Exception e) {
             throw new RestconfDocumentedException("Error creating data", e);
         }
 
-        if (status == null) {
-            return Response.status(Status.ACCEPTED).build();
-        }
-
-        if (status.getResult() == TransactionStatus.COMMITED) {
-            return Response.status(Status.NO_CONTENT).build();
-        }
-
-        return Response.status(Status.INTERNAL_SERVER_ERROR).build();
+        return Response.status(Status.NO_CONTENT).build();
     }
 
     @Override
     public Response deleteConfigurationData(final String identifier) {
-        final InstanceIdWithSchemaNode iiWithData = this.controllerContext.toInstanceIdentifier(identifier);
+        final InstanceIdWithSchemaNode iiWithData = normalizeInstanceIdentifierWithSchemaNode(this.controllerContext
+                .toInstanceIdentifier(identifier));
         RpcResult<TransactionStatus> status = null;
-        MountInstance mountPoint = iiWithData.getMountPoint();
+        DOMMountPoint mountPoint = iiWithData.getMountPoint();
 
         try {
             if (mountPoint != null) {
-                status = broker.commitConfigurationDataDeleteBehindMountPoint(mountPoint,
-                        iiWithData.getInstanceIdentifier()).get();
+                broker.commitConfigurationDataDelete(mountPoint, iiWithData.getInstanceIdentifier()).get();
             } else {
-                status = broker.commitConfigurationDataDelete(iiWithData.getInstanceIdentifier()).get();
+                broker.commitConfigurationDataDelete(iiWithData.getInstanceIdentifier()).get();
             }
         } catch (Exception e) {
             throw new RestconfDocumentedException("Error creating data", e);
         }
 
-        if (status.getResult() == TransactionStatus.COMMITED) {
-            return Response.status(Status.OK).build();
-        }
-
-        return Response.status(Status.INTERNAL_SERVER_ERROR).build();
+        return Response.status(Status.OK).build();
     }
 
+    /**
+     * Subscribes to some path in schema context (stream) to listen on changes
+     * on this stream.
+     *
+     * Additional parameters for subscribing to stream are loaded via rpc input
+     * parameters:
+     * <ul>
+     * <li>datastore</li> - default CONFIGURATION (other values of
+     * {@link LogicalDatastoreType} enum type)
+     * <li>scope</li> - default BASE (other values of {@link DataChangeScope})
+     * </ul>
+     */
     @Override
     public Response subscribeToStream(final String identifier, final UriInfo uriInfo) {
         final String streamName = Notificator.createStreamNameFromUri(identifier);
@@ -896,18 +937,100 @@ public class RestconfImpl implements RestconfService {
             throw new RestconfDocumentedException("Stream was not found.", ErrorType.PROTOCOL, ErrorTag.UNKNOWN_ELEMENT);
         }
 
-        broker.registerToListenDataChanges(listener);
+        Map<String, String> paramToValues = resolveValuesFromUri(identifier);
+        LogicalDatastoreType datastore = parserURIEnumParameter(LogicalDatastoreType.class,
+                paramToValues.get(DATASTORE_PARAM_NAME));
+        if (datastore == null) {
+            throw new RestconfDocumentedException("Stream name doesn't contains datastore value (pattern /datastore=)",
+                    ErrorType.APPLICATION, ErrorTag.MISSING_ATTRIBUTE);
+        }
+        DataChangeScope scope = parserURIEnumParameter(DataChangeScope.class, paramToValues.get(SCOPE_PARAM_NAME));
+        if (scope == null) {
+            throw new RestconfDocumentedException("Stream name doesn't contains datastore value (pattern /scope=)",
+                    ErrorType.APPLICATION, ErrorTag.MISSING_ATTRIBUTE);
+        }
+
+        broker.registerToListenDataChanges(datastore, scope, listener);
 
         final UriBuilder uriBuilder = uriInfo.getAbsolutePathBuilder();
-        UriBuilder port = uriBuilder.port(WebSocketServer.getInstance().getPort());
+        int notificationPort = NOTIFICATION_PORT;
+        try {
+            WebSocketServer webSocketServerInstance = WebSocketServer.getInstance();
+            notificationPort = webSocketServerInstance.getPort();
+        } catch (NullPointerException e) {
+            WebSocketServer.createInstance(NOTIFICATION_PORT);
+        }
+        UriBuilder port = uriBuilder.port(notificationPort);
         final URI uriToWebsocketServer = port.replacePath(streamName).build();
 
         return Response.status(Status.OK).location(uriToWebsocketServer).build();
     }
 
-    private Module findModule(final MountInstance mountPoint, final CompositeNode data) {
-        if (data instanceof CompositeNodeWrapper) {
-            return findModule(mountPoint, (CompositeNodeWrapper) data);
+    /**
+     * Load parameter for subscribing to stream from input composite node
+     *
+     * @param compNode
+     *            contains value
+     * @return enum object if its string value is equal to {@code paramName}. In
+     *         other cases null.
+     */
+    private <T> T parseEnumTypeParameter(final CompositeNode compNode, final Class<T> classDescriptor,
+            final String paramName) {
+        QNameModule salRemoteAugment = QNameModule.create(NAMESPACE_EVENT_SUBSCRIPTION_AUGMENT,
+                EVENT_SUBSCRIPTION_AUGMENT_REVISION);
+        SimpleNode<?> simpleNode = compNode.getFirstSimpleByName(QName.create(salRemoteAugment, paramName));
+        if (simpleNode == null) {
+            return null;
+        }
+        Object rawValue = simpleNode.getValue();
+        if (!(rawValue instanceof String)) {
+            return null;
+        }
+
+        return resolveAsEnum(classDescriptor, (String) rawValue);
+    }
+
+    /**
+     * Checks whether {@code value} is one of the string representation of
+     * enumeration {@code classDescriptor}
+     *
+     * @return enum object if string value of {@code classDescriptor}
+     *         enumeration is equal to {@code value}. Other cases null.
+     */
+    private <T> T parserURIEnumParameter(final Class<T> classDescriptor, final String value) {
+        if (Strings.isNullOrEmpty(value)) {
+            return null;
+        }
+        return resolveAsEnum(classDescriptor, value);
+    }
+
+    private <T> T resolveAsEnum(Class<T> classDescriptor, String value) {
+        T[] enumConstants = classDescriptor.getEnumConstants();
+        if (enumConstants != null) {
+            for (T enm : classDescriptor.getEnumConstants()) {
+                if (((Enum<?>) enm).name().equals(value)) {
+                    return enm;
+                }
+            }
+        }
+        return null;
+    }
+
+    private Map<String, String> resolveValuesFromUri(String uri) {
+        Map<String, String> result = new HashMap<>();
+        String[] tokens = uri.split("/");
+        for (int i = 1; i < tokens.length; i++) {
+            String[] parameterTokens = tokens[i].split("=");
+            if (parameterTokens.length == 2) {
+                result.put(parameterTokens[0], parameterTokens[1]);
+            }
+        }
+        return result;
+    }
+
+    private Module findModule(final DOMMountPoint mountPoint, final Node<?> data) {
+        if (data instanceof NodeWrapper) {
+            return findModule(mountPoint, (NodeWrapper<?>) data);
         } else if (data != null) {
             URI namespace = data.getNodeType().getNamespace();
             if (mountPoint != null) {
@@ -921,7 +1044,7 @@ public class RestconfImpl implements RestconfService {
         }
     }
 
-    private Module findModule(final MountInstance mountPoint, final CompositeNodeWrapper data) {
+    private Module findModule(final DOMMountPoint mountPoint, final NodeWrapper<?> data) {
         URI namespace = data.getNamespace();
         Preconditions.<URI> checkNotNull(namespace);
 
@@ -956,15 +1079,10 @@ public class RestconfImpl implements RestconfService {
             iiBuilder = YangInstanceIdentifier.builder(iiOriginal);
         }
 
-        if ((schemaOfData instanceof ListSchemaNode)) {
-            HashMap<QName, Object> keys = this.resolveKeysFromData(((ListSchemaNode) schemaOfData), data);
-            iiBuilder.nodeWithKey(schemaOfData.getQName(), keys);
-        } else {
-            iiBuilder.node(schemaOfData.getQName());
-        }
+        iiBuilder.node(schemaOfData.getQName());
 
         YangInstanceIdentifier instance = iiBuilder.toInstance();
-        MountInstance mountPoint = null;
+        DOMMountPoint mountPoint = null;
         if (identifierWithSchemaNode != null) {
             mountPoint = identifierWithSchemaNode.getMountPoint();
         }
@@ -1004,7 +1122,7 @@ public class RestconfImpl implements RestconfService {
         return identifier.endsWith(ControllerContext.MOUNT) || identifier.endsWith(ControllerContext.MOUNT + "/");
     }
 
-    private boolean representsMountPointRootData(final CompositeNode data) {
+    private boolean representsMountPointRootData(final Node<?> data) {
         URI namespace = this.namespace(data);
         return (SchemaContext.NAME.getNamespace().equals(namespace) /*
                                                                      * || MOUNT_POINT_MODULE_NAME .equals( namespace .
@@ -1022,8 +1140,7 @@ public class RestconfImpl implements RestconfService {
         return identifier + "/" + ControllerContext.MOUNT;
     }
 
-    private CompositeNode normalizeNode(final CompositeNode node, final DataSchemaNode schema,
-            final MountInstance mountPoint) {
+    private CompositeNode normalizeNode(final Node<?> node, final DataSchemaNode schema, final DOMMountPoint mountPoint) {
         if (schema == null) {
             QName nodeType = node == null ? null : node.getNodeType();
             String localName = nodeType == null ? null : nodeType.getLocalName();
@@ -1037,24 +1154,32 @@ public class RestconfImpl implements RestconfService {
                     ErrorType.PROTOCOL, ErrorTag.INVALID_VALUE);
         }
 
-        if ((node instanceof CompositeNodeWrapper)) {
-            boolean isChangeAllowed = ((CompositeNodeWrapper) node).isChangeAllowed();
+        if ((node instanceof NodeWrapper<?>)) {
+            NodeWrapper<?> nodeWrap = (NodeWrapper<?>) node;
+            boolean isChangeAllowed = ((NodeWrapper<?>) node).isChangeAllowed();
             if (isChangeAllowed) {
+                nodeWrap = topLevelElementAsCompositeNodeWrapper((NodeWrapper<?>) node, schema);
                 try {
-                    this.normalizeNode(((CompositeNodeWrapper) node), schema, null, mountPoint);
+                    this.normalizeNode(nodeWrap, schema, null, mountPoint);
                 } catch (IllegalArgumentException e) {
                     throw new RestconfDocumentedException(e.getMessage(), ErrorType.PROTOCOL, ErrorTag.INVALID_VALUE);
                 }
+                if (nodeWrap instanceof CompositeNodeWrapper) {
+                    return ((CompositeNodeWrapper) nodeWrap).unwrap();
+                }
             }
+        }
 
-            return ((CompositeNodeWrapper) node).unwrap();
+        if (node instanceof CompositeNode) {
+            return (CompositeNode) node;
         }
 
-        return node;
+        throw new RestconfDocumentedException("Top level element is not interpreted as composite node.",
+                ErrorType.APPLICATION, ErrorTag.INVALID_VALUE);
     }
 
     private void normalizeNode(final NodeWrapper<? extends Object> nodeBuilder, final DataSchemaNode schema,
-            final QName previousAugment, final MountInstance mountPoint) {
+            final QName previousAugment, final DOMMountPoint mountPoint) {
         if (schema == null) {
             throw new RestconfDocumentedException("Data has bad format.\n\"" + nodeBuilder.getLocalName()
                     + "\" does not exist in yang schema.", ErrorType.PROTOCOL, ErrorTag.INVALID_VALUE);
@@ -1111,7 +1236,7 @@ public class RestconfImpl implements RestconfService {
     }
 
     private void normalizeSimpleNode(final SimpleNodeWrapper simpleNode, final DataSchemaNode schema,
-            final MountInstance mountPoint) {
+            final DOMMountPoint mountPoint) {
         final Object value = simpleNode.getValue();
         Object inputValue = value;
         TypeDefinition<? extends Object> typeDefinition = this.typeDefinition(schema);
@@ -1133,7 +1258,7 @@ public class RestconfImpl implements RestconfService {
     }
 
     private void normalizeCompositeNode(final CompositeNodeWrapper compositeNodeBuilder,
-            final DataNodeContainer schema, final MountInstance mountPoint, final QName currentAugment) {
+            final DataNodeContainer schema, final DOMMountPoint mountPoint, final QName currentAugment) {
         final List<NodeWrapper<?>> children = compositeNodeBuilder.getValues();
         checkNodeMultiplicityAccordingToSchema(schema, children);
         for (final NodeWrapper<? extends Object> child : children) {
@@ -1214,7 +1339,7 @@ public class RestconfImpl implements RestconfService {
     }
 
     private QName normalizeNodeName(final NodeWrapper<? extends Object> nodeBuilder, final DataSchemaNode schema,
-            final QName previousAugment, final MountInstance mountPoint) {
+            final QName previousAugment, final DOMMountPoint mountPoint) {
         QName validQName = schema.getQName();
         QName currentAugment = previousAugment;
         if (schema.isAugmenting()) {
@@ -1248,9 +1373,9 @@ public class RestconfImpl implements RestconfService {
         return currentAugment;
     }
 
-    private URI namespace(final CompositeNode data) {
-        if (data instanceof CompositeNodeWrapper) {
-            return ((CompositeNodeWrapper) data).getNamespace();
+    private URI namespace(final Node<?> data) {
+        if (data instanceof NodeWrapper) {
+            return ((NodeWrapper<?>) data).getNamespace();
         } else if (data != null) {
             return data.getNodeType().getNamespace();
         } else {
@@ -1258,9 +1383,9 @@ public class RestconfImpl implements RestconfService {
         }
     }
 
-    private String localName(final CompositeNode data) {
-        if (data instanceof CompositeNodeWrapper) {
-            return ((CompositeNodeWrapper) data).getLocalName();
+    private String localName(final Node<?> data) {
+        if (data instanceof NodeWrapper) {
+            return ((NodeWrapper<?>) data).getLocalName();
         } else if (data != null) {
             return data.getNodeType().getLocalName();
         } else {
@@ -1268,9 +1393,9 @@ public class RestconfImpl implements RestconfService {
         }
     }
 
-    private String getName(final CompositeNode data) {
-        if (data instanceof CompositeNodeWrapper) {
-            return ((CompositeNodeWrapper) data).getLocalName();
+    private String getName(final Node<?> data) {
+        if (data instanceof NodeWrapper) {
+            return ((NodeWrapper<?>) data).getLocalName();
         } else if (data != null) {
             return data.getNodeType().getLocalName();
         } else {
@@ -1307,4 +1432,99 @@ public class RestconfImpl implements RestconfService {
             throw new IllegalArgumentException("Unhandled parameter types: " + Arrays.<Object> asList(node).toString());
         }
     }
+
+    private CompositeNode datastoreNormalizedNodeToCompositeNode(NormalizedNode<?, ?> dataNode, DataSchemaNode schema) {
+        Iterable<Node<?>> nodes = null;
+        if (dataNode == null) {
+            throw new RestconfDocumentedException(new RestconfError(ErrorType.APPLICATION, ErrorTag.DATA_MISSING,
+                    "No data was found."));
+        }
+        if (schema instanceof ContainerSchemaNode && dataNode instanceof ContainerNode) {
+            nodes = CnSnFromNormalizedNodeSerializerFactory.getInstance().getContainerNodeSerializer()
+                    .serialize((ContainerSchemaNode) schema, (ContainerNode) dataNode);
+        } else if (schema instanceof ListSchemaNode && dataNode instanceof MapNode) {
+            nodes = CnSnFromNormalizedNodeSerializerFactory.getInstance().getMapNodeSerializer()
+                    .serialize((ListSchemaNode) schema, (MapNode) dataNode);
+        } else if (schema instanceof ListSchemaNode && dataNode instanceof MapEntryNode) {
+            nodes = CnSnFromNormalizedNodeSerializerFactory.getInstance().getMapEntryNodeSerializer()
+                    .serialize((ListSchemaNode) schema, (MapEntryNode) dataNode);
+        }
+        if (nodes != null) {
+            if (nodes.iterator().hasNext()) {
+                Node<?> nodeOldStruct = nodes.iterator().next();
+                return (CompositeNode) nodeOldStruct;
+            } else {
+                LOG.error("The node " + dataNode.getNodeType() + " couldn't be transformed to compositenode.");
+            }
+        } else {
+            LOG.error("Top level node isn't of type Container or List schema node but "
+                    + schema.getClass().getSimpleName());
+        }
+
+        throw new RestconfDocumentedException(new RestconfError(ErrorType.APPLICATION, ErrorTag.INVALID_VALUE,
+                "It wasn't possible to correctly interpret data."));
+    }
+
+    private NormalizedNode<?, ?> compositeNodeToDatastoreNormalizedNode(CompositeNode compNode, DataSchemaNode schema) {
+        List<Node<?>> lst = new ArrayList<Node<?>>();
+        lst.add(compNode);
+        if (schema instanceof ContainerSchemaNode) {
+            return CnSnToNormalizedNodeParserFactory.getInstance().getContainerNodeParser()
+                    .parse(lst, (ContainerSchemaNode) schema);
+        } else if (schema instanceof ListSchemaNode) {
+            return CnSnToNormalizedNodeParserFactory.getInstance().getMapNodeParser()
+                    .parse(lst, (ListSchemaNode) schema);
+        }
+
+        LOG.error("Top level isn't of type container, list, leaf schema node but " + schema.getClass().getSimpleName());
+
+        throw new RestconfDocumentedException(new RestconfError(ErrorType.APPLICATION, ErrorTag.INVALID_VALUE,
+                "It wasn't possible to translate specified data to datastore readable form."));
+    }
+
+    private InstanceIdWithSchemaNode normalizeInstanceIdentifierWithSchemaNode(InstanceIdWithSchemaNode iiWithSchemaNode) {
+        return normalizeInstanceIdentifierWithSchemaNode(iiWithSchemaNode, false);
+    }
+
+    private InstanceIdWithSchemaNode normalizeInstanceIdentifierWithSchemaNode(
+            InstanceIdWithSchemaNode iiWithSchemaNode, boolean unwrapLastListNode) {
+        return new InstanceIdWithSchemaNode(instanceIdentifierToReadableFormForNormalizeNode(
+                iiWithSchemaNode.getInstanceIdentifier(), unwrapLastListNode), iiWithSchemaNode.getSchemaNode(),
+                iiWithSchemaNode.getMountPoint());
+    }
+
+    private YangInstanceIdentifier instanceIdentifierToReadableFormForNormalizeNode(YangInstanceIdentifier instIdentifier,
+            boolean unwrapLastListNode) {
+        Preconditions.checkNotNull(instIdentifier, "Instance identifier can't be null");
+        final List<PathArgument> result = new ArrayList<PathArgument>();
+        final Iterator<PathArgument> iter = instIdentifier.getPathArguments().iterator();
+        while (iter.hasNext()) {
+            final PathArgument pathArgument = iter.next();
+            if (pathArgument instanceof NodeIdentifierWithPredicates && (iter.hasNext() || unwrapLastListNode)) {
+                result.add(new YangInstanceIdentifier.NodeIdentifier(pathArgument.getNodeType()));
+            }
+            result.add(pathArgument);
+        }
+        return YangInstanceIdentifier.create(result);
+    }
+
+    private CompositeNodeWrapper topLevelElementAsCompositeNodeWrapper(final NodeWrapper<?> node,
+            final DataSchemaNode schemaNode) {
+        if (node instanceof CompositeNodeWrapper) {
+            return (CompositeNodeWrapper) node;
+        } else if (node instanceof SimpleNodeWrapper && isDataContainerNode(schemaNode)) {
+            final SimpleNodeWrapper simpleNodeWrapper = (SimpleNodeWrapper) node;
+            return new CompositeNodeWrapper(namespace(simpleNodeWrapper), localName(simpleNodeWrapper));
+        }
+
+        throw new RestconfDocumentedException(new RestconfError(ErrorType.APPLICATION, ErrorTag.INVALID_VALUE,
+                "Top level element has to be composite node or has to represent data container node."));
+    }
+
+    private boolean isDataContainerNode(final DataSchemaNode schemaNode) {
+        if (schemaNode instanceof ContainerSchemaNode || schemaNode instanceof ListSchemaNode) {
+            return true;
+        }
+        return false;
+    }
 }
index c745a8009deac75a70a7249626b07f56457d9243..29354349671943d2c3e67e16188c06ae9dd3bc55 100644 (file)
@@ -7,7 +7,7 @@
  */
 package org.opendaylight.controller.sal.restconf.impl;
 
-import org.opendaylight.controller.sal.core.api.mount.MountInstance;
+import org.opendaylight.controller.md.sal.dom.api.DOMMountPoint;
 import org.opendaylight.yangtools.yang.data.api.CompositeNode;
 import org.opendaylight.yangtools.yang.model.api.DataSchemaNode;
 
@@ -15,14 +15,14 @@ public class StructuredData {
 
     private final CompositeNode data;
     private final DataSchemaNode schema;
-    private final MountInstance mountPoint;
+    private final DOMMountPoint mountPoint;
     private final boolean prettyPrintMode;
 
-    public StructuredData(final CompositeNode data, final DataSchemaNode schema, final MountInstance mountPoint) {
+    public StructuredData(final CompositeNode data, final DataSchemaNode schema, final DOMMountPoint mountPoint) {
         this(data, schema, mountPoint, false);
     }
 
-    public StructuredData(final CompositeNode data, final DataSchemaNode schema, final MountInstance mountPoint,
+    public StructuredData(final CompositeNode data, final DataSchemaNode schema, final DOMMountPoint mountPoint,
             final boolean preattyPrintMode) {
         this.data = data;
         this.schema = schema;
@@ -38,7 +38,7 @@ public class StructuredData {
         return schema;
     }
 
-    public MountInstance getMountPoint() {
+    public DOMMountPoint getMountPoint() {
         return mountPoint;
     }
 
index 36502656c22834829deaaa73f01defce0be1885d..efb3e0a1d3924d914afe4dcc286ad783d94de8e0 100644 (file)
@@ -7,9 +7,12 @@
  */
 package org.opendaylight.controller.sal.restconf.rpc.impl;
 
+import com.google.common.base.Optional;
 import com.google.common.base.Preconditions;
 import java.util.concurrent.Future;
-import org.opendaylight.controller.sal.core.api.mount.MountInstance;
+import org.opendaylight.controller.md.sal.dom.api.DOMMountPoint;
+import org.opendaylight.controller.sal.core.api.RpcProvisionRegistry;
+import org.opendaylight.controller.sal.restconf.impl.RestconfDocumentedException;
 import org.opendaylight.yangtools.yang.common.RpcResult;
 import org.opendaylight.yangtools.yang.data.api.CompositeNode;
 import org.opendaylight.yangtools.yang.model.api.RpcDefinition;
@@ -21,9 +24,9 @@ import org.opendaylight.yangtools.yang.model.api.RpcDefinition;
  *
  */
 public class MountPointRpcExecutor extends AbstractRpcExecutor {
-    private final MountInstance mountPoint;
+    private final DOMMountPoint mountPoint;
 
-    public MountPointRpcExecutor(RpcDefinition rpcDef, MountInstance mountPoint) {
+    public MountPointRpcExecutor(RpcDefinition rpcDef, DOMMountPoint mountPoint) {
         super(rpcDef);
         this.mountPoint = mountPoint;
         Preconditions.checkNotNull(mountPoint, "MountInstance can not be null.");
@@ -31,6 +34,10 @@ public class MountPointRpcExecutor extends AbstractRpcExecutor {
 
     @Override
     protected Future<RpcResult<CompositeNode>> invokeRpcUnchecked(CompositeNode rpcRequest) {
-        return mountPoint.rpc(getRpcDefinition().getQName(), rpcRequest);
+        Optional<RpcProvisionRegistry> service = mountPoint.getService(RpcProvisionRegistry.class);
+        if (service.isPresent()) {
+            return service.get().invokeRpc(getRpcDefinition().getQName(), rpcRequest);
+        }
+        throw new RestconfDocumentedException("Rpc service is missing.");
     }
 }
\ No newline at end of file
index 2b7b0246e35ac2356ce90f87126d5e4f43076a2c..a6e02632ce6fd15eeb57127b5af34a772626a6c6 100644 (file)
@@ -38,8 +38,8 @@ import javax.xml.transform.TransformerException;
 import javax.xml.transform.TransformerFactory;
 import javax.xml.transform.dom.DOMSource;
 import javax.xml.transform.stream.StreamResult;
-import org.opendaylight.controller.md.sal.common.api.data.DataChangeEvent;
-import org.opendaylight.controller.sal.core.api.data.DataChangeListener;
+import org.opendaylight.controller.md.sal.common.api.data.AsyncDataChangeEvent;
+import org.opendaylight.controller.md.sal.dom.api.DOMDataChangeListener;
 import org.opendaylight.controller.sal.rest.impl.XmlMapper;
 import org.opendaylight.controller.sal.restconf.impl.ControllerContext;
 import org.opendaylight.yangtools.concepts.ListenerRegistration;
@@ -49,6 +49,7 @@ import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifierWithPredicates;
 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeWithValue;
 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.PathArgument;
+import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
 import org.opendaylight.yangtools.yang.model.api.DataNodeContainer;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -59,7 +60,7 @@ import org.w3c.dom.Node;
 /**
  * {@link ListenerAdapter} is responsible to track events, which occurred by changing data in data source.
  */
-public class ListenerAdapter implements DataChangeListener {
+public class ListenerAdapter implements DOMDataChangeListener {
 
     private static final Logger LOG = LoggerFactory.getLogger(ListenerAdapter.class);
     private static final DocumentBuilderFactory DBF = DocumentBuilderFactory.newInstance();
@@ -70,7 +71,7 @@ public class ListenerAdapter implements DataChangeListener {
     private final SimpleDateFormat rfc3339 = new SimpleDateFormat("yyyy-MM-dd'T'hh:mm:ssZ");
 
     private final YangInstanceIdentifier path;
-    private ListenerRegistration<DataChangeListener> registration;
+    private ListenerRegistration<DOMDataChangeListener> registration;
     private final String streamName;
     private Set<Channel> subscribers = new ConcurrentSet<>();
     private final EventBus eventBus;
@@ -95,10 +96,11 @@ public class ListenerAdapter implements DataChangeListener {
     }
 
     @Override
-    public void onDataChanged(final DataChangeEvent<YangInstanceIdentifier, CompositeNode> change) {
-        if (!change.getCreatedConfigurationData().isEmpty() || !change.getCreatedOperationalData().isEmpty()
-                || !change.getUpdatedConfigurationData().isEmpty() || !change.getUpdatedOperationalData().isEmpty()
-                || !change.getRemovedConfigurationData().isEmpty() || !change.getRemovedOperationalData().isEmpty()) {
+    public void onDataChanged(AsyncDataChangeEvent<YangInstanceIdentifier, NormalizedNode<?, ?>> change) {
+        // TODO Auto-generated method stub
+
+        if (!change.getCreatedData().isEmpty() || !change.getUpdatedData().isEmpty()
+                || !change.getRemovedPaths().isEmpty()) {
             String xml = prepareXmlFrom(change);
             Event event = new Event(EventType.NOTIFY);
             event.setData(xml);
@@ -216,7 +218,7 @@ public class ListenerAdapter implements DataChangeListener {
      *            DataChangeEvent
      * @return Data in printable form.
      */
-    private String prepareXmlFrom(final DataChangeEvent<YangInstanceIdentifier, CompositeNode> change) {
+    private String prepareXmlFrom(AsyncDataChangeEvent<YangInstanceIdentifier, NormalizedNode<?, ?>> change) {
         Document doc = createDocument();
         Element notificationElement = doc.createElementNS("urn:ietf:params:xml:ns:netconf:notification:1.0",
                 "notification");
@@ -262,7 +264,6 @@ public class ListenerAdapter implements DataChangeListener {
 
     /**
      * Creates {@link Document} document.
-     *
      * @return {@link Document} document.
      */
     private Document createDocument() {
@@ -287,23 +288,15 @@ public class ListenerAdapter implements DataChangeListener {
      */
     private void addValuesToDataChangedNotificationEventElement(final Document doc,
             final Element dataChangedNotificationEventElement,
-            final DataChangeEvent<YangInstanceIdentifier, CompositeNode> change) {
-        addValuesFromDataToElement(doc, change.getCreatedConfigurationData(), dataChangedNotificationEventElement,
-                Store.CONFIG, Operation.CREATED);
-        addValuesFromDataToElement(doc, change.getCreatedOperationalData(), dataChangedNotificationEventElement,
-                Store.OPERATION, Operation.CREATED);
-        if (change.getCreatedConfigurationData().isEmpty()) {
-            addValuesFromDataToElement(doc, change.getUpdatedConfigurationData(), dataChangedNotificationEventElement,
-                    Store.CONFIG, Operation.UPDATED);
-        }
-        if (change.getCreatedOperationalData().isEmpty()) {
-            addValuesFromDataToElement(doc, change.getUpdatedOperationalData(), dataChangedNotificationEventElement,
-                    Store.OPERATION, Operation.UPDATED);
+            AsyncDataChangeEvent<YangInstanceIdentifier, NormalizedNode<?, ?>> change) {
+        addValuesFromDataToElement(doc, change.getCreatedData().keySet(), dataChangedNotificationEventElement,
+                Operation.CREATED);
+        if (change.getCreatedData().isEmpty()) {
+            addValuesFromDataToElement(doc, change.getUpdatedData().keySet(), dataChangedNotificationEventElement,
+                    Operation.UPDATED);
         }
-        addValuesFromDataToElement(doc, change.getRemovedConfigurationData(), dataChangedNotificationEventElement,
-                Store.CONFIG, Operation.DELETED);
-        addValuesFromDataToElement(doc, change.getRemovedOperationalData(), dataChangedNotificationEventElement,
-                Store.OPERATION, Operation.DELETED);
+        addValuesFromDataToElement(doc, change.getRemovedPaths(), dataChangedNotificationEventElement,
+                Operation.DELETED);
     }
 
     /**
@@ -320,13 +313,13 @@ public class ListenerAdapter implements DataChangeListener {
      * @param operation
      *            {@link Operation}
      */
-    private void addValuesFromDataToElement(final Document doc, final Set<YangInstanceIdentifier> data,
-            final Element element, final Store store, final Operation operation) {
+    private void addValuesFromDataToElement(Document doc, Set<YangInstanceIdentifier> data, Element element,
+            Operation operation) {
         if (data == null || data.isEmpty()) {
             return;
         }
         for (YangInstanceIdentifier path : data) {
-            Node node = createDataChangeEventElement(doc, path, null, store, operation);
+            Node node = createDataChangeEventElement(doc, path, null, operation);
             element.appendChild(node);
         }
     }
@@ -345,13 +338,13 @@ public class ListenerAdapter implements DataChangeListener {
      * @param operation
      *            {@link Operation}
      */
-    private void addValuesFromDataToElement(final Document doc, final Map<YangInstanceIdentifier, CompositeNode> data,
-            final Element element, final Store store, final Operation operation) {
+    private void addValuesFromDataToElement(Document doc, Map<YangInstanceIdentifier, CompositeNode> data, Element element,
+            Operation operation) {
         if (data == null || data.isEmpty()) {
             return;
         }
         for (Entry<YangInstanceIdentifier, CompositeNode> entry : data.entrySet()) {
-            Node node = createDataChangeEventElement(doc, entry.getKey(), entry.getValue(), store, operation);
+            Node node = createDataChangeEventElement(doc, entry.getKey(), entry.getValue(), operation);
             element.appendChild(node);
         }
     }
@@ -371,17 +364,17 @@ public class ListenerAdapter implements DataChangeListener {
      *            {@link Operation}
      * @return {@link Node} node represented by changed event element.
      */
-    private Node createDataChangeEventElement(final Document doc, final YangInstanceIdentifier path,
-            final CompositeNode data, final Store store, final Operation operation) {
+    private Node createDataChangeEventElement(Document doc, YangInstanceIdentifier path, CompositeNode data,
+            Operation operation) {
         Element dataChangeEventElement = doc.createElement("data-change-event");
 
         Element pathElement = doc.createElement("path");
         addPathAsValueToElement(path, pathElement);
         dataChangeEventElement.appendChild(pathElement);
 
-        Element storeElement = doc.createElement("store");
-        storeElement.setTextContent(store.value);
-        dataChangeEventElement.appendChild(storeElement);
+        // Element storeElement = doc.createElement("store");
+        // storeElement.setTextContent(store.value);
+        // dataChangeEventElement.appendChild(storeElement);
 
         Element operationElement = doc.createElement("operation");
         operationElement.setTextContent(operation.value);
@@ -530,7 +523,7 @@ public class ListenerAdapter implements DataChangeListener {
      * @param registration
      *            ListenerRegistration<DataChangeListener>
      */
-    public void setRegistration(final ListenerRegistration<DataChangeListener> registration) {
+    public void setRegistration(final ListenerRegistration<DOMDataChangeListener> registration) {
         this.registration = registration;
     }
 
index 99bd8c5aafa88759847eda70c61d8d10c23923da..17565a6b8c082d314f5b4e90715be18ca3536a8c 100644 (file)
@@ -15,12 +15,12 @@ import java.util.concurrent.locks.ReentrantLock;
 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
 
 /**
- * {@link Notificator} is responsible to create, remove and find {@link ListenerAdapter} listener.
+ * {@link Notificator} is responsible to create, remove and find
+ * {@link ListenerAdapter} listener.
  */
 public class Notificator {
 
     private static Map<String, ListenerAdapter> listenersByStreamName = new ConcurrentHashMap<>();
-    private static Map<YangInstanceIdentifier, ListenerAdapter> listenersByInstanceIdentifier = new ConcurrentHashMap<>();
     private static final Lock lock = new ReentrantLock();
 
     private Notificator() {
@@ -44,26 +44,14 @@ public class Notificator {
         return listenersByStreamName.get(streamName);
     }
 
-    /**
-     * Gets {@link ListenerAdapter} listener specified by {@link YangInstanceIdentifier} path.
-     *
-     * @param path
-     *            Path to data in data repository.
-     * @return ListenerAdapter
-     */
-    public static ListenerAdapter getListenerFor(YangInstanceIdentifier path) {
-        return listenersByInstanceIdentifier.get(path);
-    }
-
     /**
      * Checks if the listener specified by {@link YangInstanceIdentifier} path exist.
      *
-     * @param path
-     *            Path to data in data repository.
+     * @param streamName
      * @return True if the listener exist, false otherwise.
      */
-    public static boolean existListenerFor(YangInstanceIdentifier path) {
-        return listenersByInstanceIdentifier.containsKey(path);
+    public static boolean existListenerFor(String streamName) {
+        return listenersByStreamName.containsKey(streamName);
     }
 
     /**
@@ -79,7 +67,6 @@ public class Notificator {
         ListenerAdapter listener = new ListenerAdapter(path, streamName);
         try {
             lock.lock();
-            listenersByInstanceIdentifier.put(path, listener);
             listenersByStreamName.put(streamName, listener);
         } finally {
             lock.unlock();
@@ -89,16 +76,6 @@ public class Notificator {
 
     /**
      * Looks for listener determined by {@link YangInstanceIdentifier} path and removes it.
-     *
-     * @param path
-     *            InstanceIdentifier
-     */
-    public static void removeListener(YangInstanceIdentifier path) {
-        ListenerAdapter listener = listenersByInstanceIdentifier.get(path);
-        deleteListener(listener);
-    }
-
-    /**
      * Creates String representation of stream name from URI. Removes slash from URI in start and end position.
      *
      * @param uri
@@ -123,7 +100,7 @@ public class Notificator {
      * Removes all listeners.
      */
     public static void removeAllListeners() {
-        for (ListenerAdapter listener : listenersByInstanceIdentifier.values()) {
+        for (ListenerAdapter listener : listenersByStreamName.values()) {
             try {
                 listener.close();
             } catch (Exception e) {
@@ -132,7 +109,6 @@ public class Notificator {
         try {
             lock.lock();
             listenersByStreamName = new ConcurrentHashMap<>();
-            listenersByInstanceIdentifier = new ConcurrentHashMap<>();
         } finally {
             lock.unlock();
         }
@@ -164,7 +140,6 @@ public class Notificator {
             }
             try {
                 lock.lock();
-                listenersByInstanceIdentifier.remove(listener.getPath());
                 listenersByStreamName.remove(listener.getStreamName());
             } finally {
                 lock.unlock();
diff --git a/opendaylight/md-sal/sal-rest-connector/src/main/yang/sal-remote-augment.yang b/opendaylight/md-sal/sal-rest-connector/src/main/yang/sal-remote-augment.yang
new file mode 100644 (file)
index 0000000..8393456
--- /dev/null
@@ -0,0 +1,31 @@
+module sal-remote-augment {
+
+    yang-version 1;
+    namespace "urn:sal:restconf:event:subscription";
+    prefix "salrmt-aug-ev-subscr";
+
+    import sal-remote {prefix salrmt; revision-date "2014-01-14";}
+
+    description
+        "Added input parameters to rpc create-data-change-event-subscription";
+
+    revision "2014-7-8" {
+    }
+
+    augment "/salrmt:create-data-change-event-subscription/salrmt:input" {
+        leaf datastore {
+            type enumeration {
+                enum OPERATIONAL;
+                enum CONFIGURATION;
+            }
+        }
+        leaf scope {
+            type enumeration {
+                enum BASE;
+                enum ONE;
+                enum SUBTREE;
+            }
+        }
+    }
+
+}
\ No newline at end of file
index 0f059f5024cdc7c70dc7042f488e9fa22c32da55..d9dc26d888acfb37a29a5d09b2b2245f163dd603 100644 (file)
@@ -35,6 +35,7 @@ import org.opendaylight.yangtools.yang.data.api.CompositeNode;
 import org.opendaylight.yangtools.yang.data.api.ModifyAction;
 import org.opendaylight.yangtools.yang.data.api.MutableCompositeNode;
 import org.opendaylight.yangtools.yang.data.api.MutableSimpleNode;
+import org.opendaylight.yangtools.yang.data.api.Node;
 import org.opendaylight.yangtools.yang.data.impl.NodeFactory;
 
 public class CnSnJsonBasicYangTypesTest extends YangAndXmlAndDataSchemaLoader {
@@ -67,12 +68,12 @@ public class CnSnJsonBasicYangTypesTest extends YangAndXmlAndDataSchemaLoader {
      */
     @Test
     public void xmlAndYangTypesWithJsonReaderTest() {
-        CompositeNode compositeNode = TestUtils.readInputToCnSn("/cnsn-to-json/simple-yang-types/xml/data.xml",
+        Node<?> node = TestUtils.readInputToCnSn("/cnsn-to-json/simple-yang-types/xml/data.xml",
                 XmlToCompositeNodeProvider.INSTANCE);
-        TestUtils.normalizeCompositeNode(compositeNode, modules, searchedModuleName + ":" + searchedDataSchemaName);
+        TestUtils.normalizeCompositeNode(node, modules, searchedModuleName + ":" + searchedDataSchemaName);
         String jsonOutput = null;
         try {
-            jsonOutput = TestUtils.writeCompNodeWithSchemaContextToOutput(compositeNode, modules, dataSchemaNode,
+            jsonOutput = TestUtils.writeCompNodeWithSchemaContextToOutput(node, modules, dataSchemaNode,
                     StructuredDataToJsonProvider.INSTANCE);
         } catch (WebApplicationException | IOException e) {
         }
index 0d0ce5cdd36908e458e50ac242ef356d4008287e..632d2490ee2623272d7aff1a944a48a6d4ce353d 100644 (file)
@@ -17,7 +17,8 @@ import org.opendaylight.controller.sal.rest.impl.StructuredDataToJsonProvider;
 import org.opendaylight.controller.sal.rest.impl.XmlToCompositeNodeProvider;
 import org.opendaylight.controller.sal.restconf.impl.test.TestUtils;
 import org.opendaylight.controller.sal.restconf.impl.test.YangAndXmlAndDataSchemaLoader;
-import org.opendaylight.yangtools.yang.data.api.CompositeNode;
+import org.opendaylight.yangtools.yang.data.api.Node;
+import org.opendaylight.yangtools.yang.data.impl.schema.builder.impl.valid.DataValidationException;
 
 public class CnSnJsonChoiceCaseTest extends YangAndXmlAndDataSchemaLoader {
 
@@ -31,7 +32,7 @@ public class CnSnJsonChoiceCaseTest extends YangAndXmlAndDataSchemaLoader {
      * return error because nodes has to be from one case below concrete choice.
      *
      */
-    @Test
+    @Test(expected=DataValidationException.class)
     public void nodeSchemasOnVariousChoiceCasePathTest() {
         testWrapper("/cnsn-to-json/choice/xml/data_various_path_err.xml", "choice-case-test:cont");
     }
@@ -42,7 +43,7 @@ public class CnSnJsonChoiceCaseTest extends YangAndXmlAndDataSchemaLoader {
      * choice.
      *
      */
-    @Test
+    @Test(expected=DataValidationException.class)
     public void nodeSchemasOnVariousChoiceCasePathAndMultipleChoicesTest() {
         testWrapper("/cnsn-to-json/choice/xml/data_more_choices_same_level_various_paths_err.xml",
                 "choice-case-test:cont");
@@ -116,10 +117,10 @@ public class CnSnJsonChoiceCaseTest extends YangAndXmlAndDataSchemaLoader {
     }
 
     private void testWrapper(String xmlPath, String pathToSchemaNode) {
-        CompositeNode compNode = TestUtils.readInputToCnSn(xmlPath, XmlToCompositeNodeProvider.INSTANCE);
-        TestUtils.normalizeCompositeNode(compNode, modules, pathToSchemaNode);
+        Node<?> node = TestUtils.readInputToCnSn(xmlPath, XmlToCompositeNodeProvider.INSTANCE);
+        TestUtils.normalizeCompositeNode(node, modules, pathToSchemaNode);
         try {
-            TestUtils.writeCompNodeWithSchemaContextToOutput(compNode, modules, dataSchemaNode,
+            TestUtils.writeCompNodeWithSchemaContextToOutput(node, modules, dataSchemaNode,
                     StructuredDataToJsonProvider.INSTANCE);
         } catch (WebApplicationException | IOException e) {
             // shouldn't end here
index 4b8b71440a7688334897bafc3c3117e8e2dfb937..11051cc73324009bee596c209e1a51968f3635f0 100644 (file)
@@ -27,7 +27,7 @@ import org.opendaylight.controller.sal.restconf.impl.RestconfDocumentedException
 import org.opendaylight.controller.sal.restconf.impl.RestconfError.ErrorTag;
 import org.opendaylight.controller.sal.restconf.impl.test.TestUtils;
 import org.opendaylight.controller.sal.restconf.impl.test.YangAndXmlAndDataSchemaLoader;
-import org.opendaylight.yangtools.yang.data.api.CompositeNode;
+import org.opendaylight.yangtools.yang.data.api.Node;
 
 public class CnSnToJsonBasicDataTypesTest extends YangAndXmlAndDataSchemaLoader {
 
@@ -189,12 +189,12 @@ public class CnSnToJsonBasicDataTypesTest extends YangAndXmlAndDataSchemaLoader
     @Test
     public void simpleYangDataTest() throws Exception {
 
-        CompositeNode compositeNode = TestUtils.readInputToCnSn("/cnsn-to-json/simple-data-types/xml/data.xml",
+        Node<?> node = TestUtils.readInputToCnSn("/cnsn-to-json/simple-data-types/xml/data.xml",
                 XmlToCompositeNodeProvider.INSTANCE);
 
-        TestUtils.normalizeCompositeNode(compositeNode, modules, "simple-data-types:cont");
+        TestUtils.normalizeCompositeNode(node, modules, "simple-data-types:cont");
 
-        String jsonOutput = TestUtils.writeCompNodeWithSchemaContextToOutput(compositeNode, modules, dataSchemaNode,
+        String jsonOutput = TestUtils.writeCompNodeWithSchemaContextToOutput(node, modules, dataSchemaNode,
                 StructuredDataToJsonProvider.INSTANCE);
 
         assertNotNull(jsonOutput);
@@ -303,10 +303,10 @@ public class CnSnToJsonBasicDataTypesTest extends YangAndXmlAndDataSchemaLoader
     public void testBadData() throws Exception {
 
         try {
-            CompositeNode compositeNode = TestUtils.readInputToCnSn("/cnsn-to-json/simple-data-types/xml/bad-data.xml",
+            Node<?> node = TestUtils.readInputToCnSn("/cnsn-to-json/simple-data-types/xml/bad-data.xml",
                     XmlToCompositeNodeProvider.INSTANCE);
 
-            TestUtils.normalizeCompositeNode(compositeNode, modules, "simple-data-types:cont");
+            TestUtils.normalizeCompositeNode(node, modules, "simple-data-types:cont");
             fail("Expected RestconfDocumentedException");
         } catch (RestconfDocumentedException e) {
             assertEquals("getErrorTag", ErrorTag.INVALID_VALUE, e.getErrors().get(0).getErrorTag());
index 50c834b1ffee46f96787d73ac47c9f6e49d6ffd4..3bd600dbf1a5b28335c0486add9145cef1cfda16 100644 (file)
@@ -21,7 +21,7 @@ import org.opendaylight.controller.sal.rest.impl.XmlToCompositeNodeProvider;
 import org.opendaylight.controller.sal.restconf.impl.test.TestUtils;
 import org.opendaylight.controller.sal.restconf.impl.test.YangAndXmlAndDataSchemaLoader;
 import org.opendaylight.yangtools.yang.common.QName;
-import org.opendaylight.yangtools.yang.data.api.CompositeNode;
+import org.opendaylight.yangtools.yang.data.api.Node;
 import org.opendaylight.yangtools.yang.model.api.ConstraintDefinition;
 import org.opendaylight.yangtools.yang.model.api.DataNodeContainer;
 import org.opendaylight.yangtools.yang.model.api.DataSchemaNode;
@@ -145,16 +145,15 @@ public class CnSnToJsonIncorrectTopLevelTest extends YangAndXmlAndDataSchemaLoad
     @Test
     public void incorrectTopLevelElementTest() {
 
-        CompositeNode compositeNode = TestUtils.readInputToCnSn("/cnsn-to-json/simple-data-types/xml/data.xml",
-                XmlToCompositeNodeProvider.INSTANCE);
+        Node<?> node = TestUtils.readInputToCnSn("/cnsn-to-json/simple-data-types/xml/data.xml", XmlToCompositeNodeProvider.INSTANCE);
         DataSchemaNode incorrectDataSchema = null;
         incorrectDataSchema = new IncorrectDataSchema();
 
-        TestUtils.normalizeCompositeNode(compositeNode, modules, "simple-data-types:cont");
+        TestUtils.normalizeCompositeNode(node, modules, "simple-data-types:cont");
 
         boolean exceptionRaised = false;
         try {
-            TestUtils.writeCompNodeWithSchemaContextToOutput(compositeNode, modules, incorrectDataSchema,
+            TestUtils.writeCompNodeWithSchemaContextToOutput(node, modules, incorrectDataSchema,
                     StructuredDataToJsonProvider.INSTANCE);
         } catch (UnsupportedDataTypeException e) {
             exceptionRaised = true;
index 6e41dcb57769b6fd633edb2bea9ea0ede1c9014a..b5d3528e95857cd95c9956522bf633f99edc6763 100644 (file)
@@ -20,7 +20,7 @@ import org.opendaylight.controller.sal.rest.impl.StructuredDataToJsonProvider;
 import org.opendaylight.controller.sal.rest.impl.XmlToCompositeNodeProvider;
 import org.opendaylight.controller.sal.restconf.impl.test.TestUtils;
 import org.opendaylight.controller.sal.restconf.impl.test.YangAndXmlAndDataSchemaLoader;
-import org.opendaylight.yangtools.yang.data.api.CompositeNode;
+import org.opendaylight.yangtools.yang.data.api.Node;
 
 /**
  *
@@ -95,9 +95,9 @@ public class CnSnToJsonLeafrefType extends YangAndXmlAndDataSchemaLoader {
 
     private String toJson(String xmlDataPath) {
         try {
-            CompositeNode compositeNode = TestUtils.readInputToCnSn(xmlDataPath, XmlToCompositeNodeProvider.INSTANCE);
-            TestUtils.normalizeCompositeNode(compositeNode, modules, searchedModuleName + ":" + searchedDataSchemaName);
-            return TestUtils.writeCompNodeWithSchemaContextToOutput(compositeNode, modules, dataSchemaNode,
+            Node<?> node = TestUtils.readInputToCnSn(xmlDataPath, XmlToCompositeNodeProvider.INSTANCE);
+            TestUtils.normalizeCompositeNode(node, modules, searchedModuleName + ":" + searchedDataSchemaName);
+            return TestUtils.writeCompNodeWithSchemaContextToOutput(node, modules, dataSchemaNode,
                     StructuredDataToJsonProvider.INSTANCE);
         } catch (WebApplicationException | IOException e) {
         }
index eb6a5b9e00f7c7af65d2398bd2e21e87f650fe9f..72b9ed93d469642886064641fabfb18284244052 100644 (file)
@@ -19,7 +19,7 @@ import org.opendaylight.controller.sal.rest.impl.StructuredDataToJsonProvider;
 import org.opendaylight.controller.sal.rest.impl.XmlToCompositeNodeProvider;
 import org.opendaylight.controller.sal.restconf.impl.test.TestUtils;
 import org.opendaylight.controller.sal.restconf.impl.test.YangAndXmlAndDataSchemaLoader;
-import org.opendaylight.yangtools.yang.data.api.CompositeNode;
+import org.opendaylight.yangtools.yang.data.api.Node;
 
 public class CnSnToJsonWithAugmentTest extends YangAndXmlAndDataSchemaLoader {
 
@@ -33,13 +33,13 @@ public class CnSnToJsonWithAugmentTest extends YangAndXmlAndDataSchemaLoader {
      */
     @Test
     public void augmentedElementsToJson() {
-        CompositeNode compositeNode = TestUtils.readInputToCnSn("/cnsn-to-json/augmentation/xml/data.xml",
+        Node<?> node = TestUtils.readInputToCnSn("/cnsn-to-json/augmentation/xml/data.xml",
                 XmlToCompositeNodeProvider.INSTANCE);
-        TestUtils.normalizeCompositeNode(compositeNode, modules, searchedModuleName + ":" + searchedDataSchemaName);
+        TestUtils.normalizeCompositeNode(node, modules, searchedModuleName + ":" + searchedDataSchemaName);
 
         String jsonOutput = null;
         try {
-            jsonOutput = TestUtils.writeCompNodeWithSchemaContextToOutput(compositeNode, modules, dataSchemaNode,
+            jsonOutput = TestUtils.writeCompNodeWithSchemaContextToOutput(node, modules, dataSchemaNode,
                     StructuredDataToJsonProvider.INSTANCE);
         } catch (WebApplicationException | IOException e) {
         }
index 4210944de71a6791ef7426533465f8cd9c900c5e..3adfee7f5bf3d44ff9f6a164d4765f0deab8671b 100644 (file)
@@ -13,12 +13,12 @@ import static org.mockito.Matchers.any;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.when;
 
+import com.google.common.util.concurrent.CheckedFuture;
 import java.io.FileNotFoundException;
 import java.net.URI;
 import java.util.List;
 import org.junit.Before;
 import org.junit.Test;
-import org.opendaylight.controller.md.sal.common.api.TransactionStatus;
 import org.opendaylight.controller.sal.restconf.impl.BrokerFacade;
 import org.opendaylight.controller.sal.restconf.impl.CompositeNodeWrapper;
 import org.opendaylight.controller.sal.restconf.impl.ControllerContext;
@@ -28,13 +28,10 @@ import org.opendaylight.controller.sal.restconf.impl.RestconfError.ErrorTag;
 import org.opendaylight.controller.sal.restconf.impl.RestconfError.ErrorType;
 import org.opendaylight.controller.sal.restconf.impl.RestconfImpl;
 import org.opendaylight.controller.sal.restconf.impl.SimpleNodeWrapper;
-import org.opendaylight.controller.sal.restconf.impl.test.DummyFuture;
-import org.opendaylight.controller.sal.restconf.impl.test.DummyFuture.Builder;
-import org.opendaylight.controller.sal.restconf.impl.test.DummyRpcResult;
 import org.opendaylight.controller.sal.restconf.impl.test.TestUtils;
 import org.opendaylight.yangtools.yang.common.QName;
-import org.opendaylight.yangtools.yang.data.api.CompositeNode;
 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
+import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
 import org.opendaylight.yangtools.yang.data.impl.ImmutableCompositeNode;
 import org.opendaylight.yangtools.yang.data.impl.util.CompositeNodeBuilder;
 import org.opendaylight.yangtools.yang.model.api.SchemaContext;
@@ -62,11 +59,8 @@ public class RestPutListDataTest {
         restconfImpl = RestconfImpl.getInstance();
         restconfImpl.setBroker(brokerFacade);
         restconfImpl.setControllerContext(controllerContext);
-        Builder<TransactionStatus> futureBuilder = new DummyFuture.Builder<TransactionStatus>();
-        futureBuilder.rpcResult(new DummyRpcResult.Builder<TransactionStatus>().result(TransactionStatus.COMMITED)
-                .build());
-        when(brokerFacade.commitConfigurationDataPut(any(YangInstanceIdentifier.class), any(CompositeNode.class)))
-                .thenReturn(futureBuilder.build());
+        when(brokerFacade.commitConfigurationDataPut(any(YangInstanceIdentifier.class), any(NormalizedNode.class)))
+                .thenReturn(mock(CheckedFuture.class));
     }
 
     /**
index 23b040a9a3846b6e273dedcb0fcb42e8c36ff5f4..cda635e84713a86f6fbe1485b00d78e83889e6a2 100644 (file)
@@ -31,15 +31,16 @@ public class JsonIdentityrefToCnSnTest extends YangAndXmlAndDataSchemaLoader {
 
     @Test
     public void jsonIdentityrefToCompositeNode() {
-        CompositeNode compositeNode = TestUtils.readInputToCnSn("/json-to-cnsn/identityref/json/data.json", false,
+        Node<?> node = TestUtils.readInputToCnSn("/json-to-cnsn/identityref/json/data.json", false,
                 JsonToCompositeNodeProvider.INSTANCE);
-        assertNotNull(compositeNode);
+        assertNotNull(node);
 
-        TestUtils.normalizeCompositeNode(compositeNode, modules, searchedModuleName + ":" + searchedDataSchemaName);
+        TestUtils.normalizeCompositeNode(node, modules, searchedModuleName + ":" + searchedDataSchemaName);
 
-        assertEquals("cont", compositeNode.getNodeType().getLocalName());
+        assertEquals("cont", node.getNodeType().getLocalName());
 
-        List<Node<?>> childs = compositeNode.getValue();
+        assert(node instanceof CompositeNode);
+        List<Node<?>> childs = ((CompositeNode)node).getValue();
         assertEquals(1, childs.size());
         Node<?> nd = childs.iterator().next();
         assertTrue(nd instanceof CompositeNode);
index 913e9f2d707bd310feb103313d53d5c8a83928df..59696bc534803935ab5c0c0126d0a43fc2c75fa5 100644 (file)
@@ -32,15 +32,16 @@ public class JsonLeafrefToCnSnTest extends YangAndXmlAndDataSchemaLoader {
      */
     @Test
     public void jsonIdentityrefToCompositeNode() {
-        CompositeNode compositeNode = TestUtils.readInputToCnSn("/json-to-cnsn/leafref/json/data.json", false,
+        Node<?> node = TestUtils.readInputToCnSn("/json-to-cnsn/leafref/json/data.json", false,
                 JsonToCompositeNodeProvider.INSTANCE);
-        assertNotNull(compositeNode);
-        TestUtils.normalizeCompositeNode(compositeNode, modules, searchedModuleName + ":" + searchedDataSchemaName);
+        assertNotNull(node);
+        TestUtils.normalizeCompositeNode(node, modules, searchedModuleName + ":" + searchedDataSchemaName);
 
-        assertEquals("cont", compositeNode.getNodeType().getLocalName());
+        assertEquals("cont", node.getNodeType().getLocalName());
 
         SimpleNode<?> lf2 = null;
-        for (Node<?> childNode : compositeNode.getValue()) {
+        assertTrue(node instanceof CompositeNode);
+        for (Node<?> childNode : ((CompositeNode) node).getValue()) {
             if (childNode instanceof SimpleNode) {
                 if (childNode.getNodeType().getLocalName().equals("lf2")) {
                     lf2 = (SimpleNode<?>) childNode;
index 7b71e42ab8ed669516c4e724231628c8d6bd4908..3699e4924fe25ca2c8a4b1399fe005376de3a86d 100644 (file)
@@ -11,6 +11,7 @@ import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertNotNull;
 import static org.junit.Assert.assertNull;
 import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
 
 import java.io.ByteArrayInputStream;
 import java.io.InputStream;
@@ -52,19 +53,21 @@ public class JsonToCnSnTest {
      */
     @Test
     public void multipleItemsInLeafList() {
-        CompositeNode compositeNode = TestUtils.readInputToCnSn("/json-to-cnsn/multiple-leaflist-items.json", true,
+        Node<?> node = TestUtils.readInputToCnSn("/json-to-cnsn/multiple-leaflist-items.json", true,
                 JsonToCompositeNodeProvider.INSTANCE);
-        assertNotNull(compositeNode);
+        assertNotNull(node);
+        assertTrue(node instanceof CompositeNode);
+        CompositeNode compositeNode = (CompositeNode)node;
         assertEquals(3, compositeNode.getValue().size());
 
         boolean lflst1_1 = false;
         boolean lflst1_2 = false;
         boolean lflst1_3 = false;
 
-        for (Node<?> node : compositeNode.getValue()) {
-            assertEquals("lflst1", node.getNodeType().getLocalName());
-            assertTrue(node instanceof SimpleNode<?>);
-            SimpleNode<?> simpleNode = (SimpleNode<?>) node;
+        for (Node<?> nd : compositeNode.getValue()) {
+            assertEquals("lflst1", nd.getNodeType().getLocalName());
+            assertTrue(nd instanceof SimpleNode<?>);
+            SimpleNode<?> simpleNode = (SimpleNode<?>) nd;
             if (simpleNode.getValue().equals("45")) {
                 lflst1_1 = true;
             } else if (simpleNode.getValue().equals("55")) {
@@ -86,9 +89,12 @@ public class JsonToCnSnTest {
      */
     @Test
     public void multipleItemsInListTest() {
-        CompositeNode compositeNode = TestUtils.readInputToCnSn("/json-to-cnsn/multiple-items-in-list.json", true,
+        Node<?> node = TestUtils.readInputToCnSn("/json-to-cnsn/multiple-items-in-list.json", true,
                 JsonToCompositeNodeProvider.INSTANCE);
 
+        assertTrue(node instanceof CompositeNode);
+        CompositeNode compositeNode = (CompositeNode)node;
+
         assertNotNull(compositeNode);
         assertEquals("lst", compositeNode.getNodeType().getLocalName());
 
@@ -97,9 +103,10 @@ public class JsonToCnSnTest {
 
     @Test
     public void nullArrayToSimpleNodeWithNullValueTest() {
-        CompositeNode compositeNode = TestUtils.readInputToCnSn("/json-to-cnsn/array-with-null.json", true,
+        Node<?> node = TestUtils.readInputToCnSn("/json-to-cnsn/array-with-null.json", true,
                 JsonToCompositeNodeProvider.INSTANCE);
-        assertNotNull(compositeNode);
+        assertTrue(node instanceof CompositeNode);
+        CompositeNode compositeNode = (CompositeNode)node;
         assertEquals("cont", compositeNode.getNodeType().getLocalName());
 
         assertNotNull(compositeNode.getValue());
@@ -163,10 +170,10 @@ public class JsonToCnSnTest {
      */
     @Test
     public void emptyDataReadTest() {
-        CompositeNode compositeNode = TestUtils.readInputToCnSn("/json-to-cnsn/empty-data.json", true,
+        Node<?> node = TestUtils.readInputToCnSn("/json-to-cnsn/empty-data.json", true,
                 JsonToCompositeNodeProvider.INSTANCE);
-
-        assertNotNull(compositeNode);
+        assertTrue(node instanceof CompositeNode);
+        CompositeNode compositeNode = (CompositeNode)node;
 
         assertEquals("cont", compositeNode.getNodeType().getLocalName());
         assertTrue(compositeNode instanceof CompositeNode);
@@ -189,9 +196,9 @@ public class JsonToCnSnTest {
     @Test
     public void testJsonBlankInput() throws Exception {
         InputStream inputStream = new ByteArrayInputStream("".getBytes());
-        CompositeNode compositeNode = JsonToCompositeNodeProvider.INSTANCE.readFrom(null, null, null, null, null,
-                inputStream);
-        assertNull(compositeNode);
+        Node<?> node =
+                JsonToCompositeNodeProvider.INSTANCE.readFrom(null, null, null, null, null, inputStream);
+        assertNull( node );
     }
 
     /**
@@ -202,9 +209,10 @@ public class JsonToCnSnTest {
     @Test
     public void notSupplyNamespaceIfAlreadySupplied() {
 
-        CompositeNode compositeNode = TestUtils.readInputToCnSn("/json-to-cnsn/simple-list.json", false,
+        Node<?> node = TestUtils.readInputToCnSn("/json-to-cnsn/simple-list.json", false,
                 JsonToCompositeNodeProvider.INSTANCE);
-        assertNotNull(compositeNode);
+        assertTrue(node instanceof CompositeNode);
+        CompositeNode compositeNode = (CompositeNode)node;
 
         // supplement namespaces according to first data schema -
         // "simple:data:types1"
@@ -223,15 +231,21 @@ public class JsonToCnSnTest {
         assertEquals("lst", compNode.getNodeType().getLocalName());
         verifyCompositeNode(compNode, "simple:list:yang1");
 
-        TestUtils.normalizeCompositeNode(compositeNode, modules2, "simple-list-yang2:lst");
+        try {
+            TestUtils.normalizeCompositeNode(compositeNode, modules2, "simple-list-yang2:lst");
+            fail("Conversion to normalized node shouldn't be successfull because of different namespaces");
+        } catch (IllegalStateException e) {
+        }
+//        veryfing has still meaning. despite exception, first phase where normalization of NodeWrappers is called passed successfuly.
         verifyCompositeNode(compNode, "simple:list:yang1");
     }
 
     @Test
     public void jsonIdentityrefToCompositeNode() {
-        CompositeNode compositeNode = TestUtils.readInputToCnSn("/json-to-cnsn/identityref/json/data.json", false,
+        Node<?> node = TestUtils.readInputToCnSn("/json-to-cnsn/identityref/json/data.json", false,
                 JsonToCompositeNodeProvider.INSTANCE);
-        assertNotNull(compositeNode);
+        assertTrue(node instanceof CompositeNode);
+        CompositeNode compositeNode = (CompositeNode)node;
 
         Set<Module> modules = TestUtils.loadModulesFrom("/json-to-cnsn/identityref");
         assertEquals(2, modules.size());
@@ -298,8 +312,9 @@ public class JsonToCnSnTest {
 
     private CompositeNode loadAndNormalizeData(final String jsonPath, final String yangPath,
             final String topLevelElementName, final String moduleName) {
-        CompositeNode compositeNode = TestUtils.readInputToCnSn(jsonPath, false, JsonToCompositeNodeProvider.INSTANCE);
-        assertNotNull(compositeNode);
+        Node<?> node = TestUtils.readInputToCnSn(jsonPath, false, JsonToCompositeNodeProvider.INSTANCE);
+        assertTrue(node instanceof CompositeNode);
+        CompositeNode compositeNode = (CompositeNode)node;
 
         Set<Module> modules = null;
         modules = TestUtils.loadModulesFrom(yangPath);
index 73f828c6466a886a2f5d7de7029c590389c5e662..e50c07e05aef735b1adb2568981f2354718a64af 100644 (file)
@@ -12,28 +12,34 @@ import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertNotNull;
 import static org.junit.Assert.assertSame;
 import static org.mockito.Matchers.any;
+import static org.mockito.Matchers.eq;
 import static org.mockito.Mockito.inOrder;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.verifyNoMoreInteractions;
 import static org.mockito.Mockito.when;
 
-import com.google.common.collect.ImmutableMap;
+import com.google.common.base.Optional;
+import com.google.common.util.concurrent.CheckedFuture;
 import com.google.common.util.concurrent.Futures;
-import java.util.Map;
+import com.google.common.util.concurrent.ListenableFuture;
 import java.util.concurrent.Future;
+import org.apache.commons.lang.StringEscapeUtils;
 import org.junit.Before;
 import org.junit.Test;
 import org.mockito.InOrder;
 import org.mockito.Mock;
 import org.mockito.MockitoAnnotations;
-import org.opendaylight.controller.md.sal.common.api.TransactionStatus;
+import org.opendaylight.controller.md.sal.common.api.data.AsyncDataBroker.DataChangeScope;
+import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
+import org.opendaylight.controller.md.sal.common.api.data.TransactionCommitFailedException;
+import org.opendaylight.controller.md.sal.dom.api.DOMDataBroker;
+import org.opendaylight.controller.md.sal.dom.api.DOMDataChangeListener;
+import org.opendaylight.controller.md.sal.dom.api.DOMDataReadOnlyTransaction;
+import org.opendaylight.controller.md.sal.dom.api.DOMDataReadWriteTransaction;
+import org.opendaylight.controller.md.sal.dom.api.DOMDataWriteTransaction;
+import org.opendaylight.controller.md.sal.dom.api.DOMMountPoint;
 import org.opendaylight.controller.sal.core.api.Broker.ConsumerSession;
-import org.opendaylight.controller.sal.core.api.data.DataBrokerService;
-import org.opendaylight.controller.sal.core.api.data.DataChangeListener;
-import org.opendaylight.controller.sal.core.api.data.DataModificationTransaction;
-import org.opendaylight.controller.sal.core.api.mount.MountInstance;
-import org.opendaylight.controller.sal.rest.impl.XmlToCompositeNodeProvider;
 import org.opendaylight.controller.sal.restconf.impl.BrokerFacade;
 import org.opendaylight.controller.sal.restconf.impl.RestconfDocumentedException;
 import org.opendaylight.controller.sal.restconf.impl.RestconfError;
@@ -44,7 +50,9 @@ import org.opendaylight.yangtools.yang.common.QName;
 import org.opendaylight.yangtools.yang.common.RpcResult;
 import org.opendaylight.yangtools.yang.data.api.CompositeNode;
 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
-import org.opendaylight.yangtools.yang.data.impl.ImmutableCompositeNode;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifier;
+import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
+import org.opendaylight.yangtools.yang.data.impl.schema.Builders;
 
 /**
  * Unit tests for BrokerFacade.
@@ -54,73 +62,83 @@ import org.opendaylight.yangtools.yang.data.impl.ImmutableCompositeNode;
 public class BrokerFacadeTest {
 
     @Mock
-    DataBrokerService dataBroker;
-
-    @Mock
-    DataModificationTransaction mockTransaction;
+    DOMDataBroker domDataBroker;
 
     @Mock
     ConsumerSession mockConsumerSession;
 
     @Mock
-    MountInstance mockMountInstance;
+    DOMMountPoint mockMountInstance;
 
     BrokerFacade brokerFacade = BrokerFacade.getInstance();
 
-    CompositeNode dataNode = TestUtils.readInputToCnSn("/parts/ietf-interfaces_interfaces.xml",
-            XmlToCompositeNodeProvider.INSTANCE);
+    CompositeNode dataNode;
+
+    NormalizedNode<?, ?> dummyNode = createDummyNode("dummy:namespace", "2014-07-01", "dummy local name");
+    ListenableFuture<Optional<NormalizedNode<?, ?>>> dummyNodeInFuture = wrapDummyNode(dummyNode);
 
     QName qname = QName.create("node");
 
     YangInstanceIdentifier instanceID = YangInstanceIdentifier.builder().node(qname).toInstance();
 
+    @Mock
+    DOMDataReadOnlyTransaction rTransaction;
+
+    @Mock
+    DOMDataWriteTransaction wTransaction;
+
+    @Mock
+    DOMDataReadWriteTransaction rwTransaction;
+
     @Before
     public void setUp() throws Exception {
         MockitoAnnotations.initMocks(this);
-
-        brokerFacade.setDataService(dataBroker);
+        // TODO it is started before every test method
+        brokerFacade.setDomDataBroker(domDataBroker);
         brokerFacade.setContext(mockConsumerSession);
-    }
-
-    @Test
-    public void testReadConfigurationData() {
-        when(dataBroker.readConfigurationData(instanceID)).thenReturn(dataNode);
+        when(domDataBroker.newReadOnlyTransaction()).thenReturn(rTransaction);
+        when(domDataBroker.newWriteOnlyTransaction()).thenReturn(wTransaction);
+        when(domDataBroker.newReadWriteTransaction()).thenReturn(rwTransaction);
 
-        CompositeNode actualNode = brokerFacade.readConfigurationData(instanceID);
+        dataNode = TestUtils.prepareCompositeNodeWithIetfInterfacesInterfacesData();
 
-        assertSame("readConfigurationData", dataNode, actualNode);
     }
 
-    @Test
-    public void testReadConfigurationDataBehindMountPoint() {
-        when(mockMountInstance.readConfigurationData(instanceID)).thenReturn(dataNode);
-
-        CompositeNode actualNode = brokerFacade.readConfigurationDataBehindMountPoint(mockMountInstance, instanceID);
+    private ListenableFuture<Optional<NormalizedNode<?, ?>>> wrapDummyNode(NormalizedNode<?, ?> dummyNode) {
+        return Futures.<Optional<NormalizedNode<?, ?>>> immediateFuture(Optional.<NormalizedNode<?, ?>> of(dummyNode));
+    }
 
-        assertSame("readConfigurationDataBehindMountPoint", dataNode, actualNode);
+    /**
+     * Value of this node shouldn't be important for testing purposes
+     */
+    private NormalizedNode<?, ?> createDummyNode(String namespace, String date, String localName) {
+        return Builders.containerBuilder()
+                .withNodeIdentifier(new NodeIdentifier(QName.create(namespace, date, localName))).build();
     }
 
     @Test
-    public void testReadOperationalData() {
-        when(dataBroker.readOperationalData(instanceID)).thenReturn(dataNode);
+    public void testReadConfigurationData() {
+        when(rTransaction.read(any(LogicalDatastoreType.class), any(YangInstanceIdentifier.class))).thenReturn(
+                dummyNodeInFuture);
 
-        CompositeNode actualNode = brokerFacade.readOperationalData(instanceID);
+        NormalizedNode<?, ?> actualNode = brokerFacade.readConfigurationData(instanceID);
 
-        assertSame("readOperationalData", dataNode, actualNode);
+        assertSame("readConfigurationData", dummyNode, actualNode);
     }
 
     @Test
-    public void testReadOperationalDataBehindMountPoint() {
-        when(mockMountInstance.readOperationalData(instanceID)).thenReturn(dataNode);
+    public void testReadOperationalData() {
+        when(rTransaction.read(any(LogicalDatastoreType.class), any(YangInstanceIdentifier.class))).thenReturn(
+                dummyNodeInFuture);
 
-        CompositeNode actualNode = brokerFacade.readOperationalDataBehindMountPoint(mockMountInstance, instanceID);
+        NormalizedNode<?, ?> actualNode = brokerFacade.readOperationalData(instanceID);
 
-        assertSame("readOperationalDataBehindMountPoint", dataNode, actualNode);
+        assertSame("readOperationalData", dummyNode, actualNode);
     }
 
     @Test(expected = RestconfDocumentedException.class)
     public void testReadOperationalDataWithNoDataBroker() {
-        brokerFacade.setDataService(null);
+        brokerFacade.setDomDataBroker(null);
 
         brokerFacade.readOperationalData(instanceID);
     }
@@ -148,109 +166,46 @@ public class BrokerFacadeTest {
 
     @Test
     public void testCommitConfigurationDataPut() {
-        Future<RpcResult<TransactionStatus>> expFuture = Futures.immediateFuture(null);
-
-        when(dataBroker.beginTransaction()).thenReturn(mockTransaction);
-        mockTransaction.putConfigurationData(instanceID, dataNode);
-        when(mockTransaction.commit()).thenReturn(expFuture);
+        CheckedFuture<Void, TransactionCommitFailedException> expFuture = mock(CheckedFuture.class);
 
-        Future<RpcResult<TransactionStatus>> actualFuture = brokerFacade.commitConfigurationDataPut(instanceID,
-                dataNode);
+        when(wTransaction.submit()).thenReturn(expFuture);
 
-        assertSame("invokeRpc", expFuture, actualFuture);
+        Future<Void> actualFuture = brokerFacade.commitConfigurationDataPut(instanceID, dummyNode);
 
-        InOrder inOrder = inOrder(dataBroker, mockTransaction);
-        inOrder.verify(dataBroker).beginTransaction();
-        inOrder.verify(mockTransaction).putConfigurationData(instanceID, dataNode);
-        inOrder.verify(mockTransaction).commit();
-    }
-
-    @Test
-    public void testCommitConfigurationDataPutBehindMountPoint() {
-        Future<RpcResult<TransactionStatus>> expFuture = Futures.immediateFuture(null);
-
-        when(mockMountInstance.beginTransaction()).thenReturn(mockTransaction);
-        mockTransaction.putConfigurationData(instanceID, dataNode);
-        when(mockTransaction.commit()).thenReturn(expFuture);
-
-        Future<RpcResult<TransactionStatus>> actualFuture = brokerFacade.commitConfigurationDataPutBehindMountPoint(
-                mockMountInstance, instanceID, dataNode);
-
-        assertSame("invokeRpc", expFuture, actualFuture);
+        assertSame("commitConfigurationDataPut", expFuture, actualFuture);
 
-        InOrder inOrder = inOrder(mockMountInstance, mockTransaction);
-        inOrder.verify(mockMountInstance).beginTransaction();
-        inOrder.verify(mockTransaction).putConfigurationData(instanceID, dataNode);
-        inOrder.verify(mockTransaction).commit();
+        InOrder inOrder = inOrder(domDataBroker, wTransaction);
+        inOrder.verify(domDataBroker).newWriteOnlyTransaction();
+        inOrder.verify(wTransaction).put(LogicalDatastoreType.CONFIGURATION, instanceID, dummyNode);
+        inOrder.verify(wTransaction).submit();
     }
 
     @Test
     public void testCommitConfigurationDataPost() {
-        Future<RpcResult<TransactionStatus>> expFuture = Futures.immediateFuture(null);
+        CheckedFuture<Void, TransactionCommitFailedException> expFuture = mock(CheckedFuture.class);
 
-        Map<YangInstanceIdentifier, CompositeNode> nodeMap = new ImmutableMap.Builder<YangInstanceIdentifier, CompositeNode>()
-                .put(instanceID, dataNode).build();
+        NormalizedNode<?, ?> dummyNode2 = createDummyNode("dummy:namespace2", "2014-07-01", "dummy local name2");
+        when(rwTransaction.read(eq(LogicalDatastoreType.CONFIGURATION), any(YangInstanceIdentifier.class))).thenReturn(
+                wrapDummyNode(dummyNode2));
+        when(rwTransaction.submit()).thenReturn(expFuture);
 
-        when(dataBroker.beginTransaction()).thenReturn(mockTransaction);
-        mockTransaction.putConfigurationData(instanceID, dataNode);
-        when(mockTransaction.getCreatedConfigurationData()).thenReturn(nodeMap);
-        when(mockTransaction.commit()).thenReturn(expFuture);
+        CheckedFuture<Void, TransactionCommitFailedException> actualFuture = brokerFacade.commitConfigurationDataPost(
+                instanceID, dummyNode);
 
-        Future<RpcResult<TransactionStatus>> actualFuture = brokerFacade.commitConfigurationDataPost(instanceID,
-                dataNode);
+        assertSame("commitConfigurationDataPost", expFuture, actualFuture);
 
-        assertSame("commitConfigurationDataPut", expFuture, actualFuture);
-
-        InOrder inOrder = inOrder(dataBroker, mockTransaction);
-        inOrder.verify(dataBroker).beginTransaction();
-        inOrder.verify(mockTransaction).putConfigurationData(instanceID, dataNode);
-        inOrder.verify(mockTransaction).commit();
+        InOrder inOrder = inOrder(domDataBroker, rwTransaction);
+        inOrder.verify(domDataBroker).newReadWriteTransaction();
+        inOrder.verify(rwTransaction).merge(LogicalDatastoreType.CONFIGURATION, instanceID, dummyNode);
+        inOrder.verify(rwTransaction).submit();
     }
 
     @Test(expected = RestconfDocumentedException.class)
     public void testCommitConfigurationDataPostAlreadyExists() {
-        when(dataBroker.beginTransaction()).thenReturn(mockTransaction);
-        mockTransaction.putConfigurationData(instanceID, dataNode);
-        when(mockTransaction.readConfigurationData(instanceID)).thenReturn(dataNode);
-        try {
-            brokerFacade.commitConfigurationDataPost(instanceID, dataNode);
-        } catch (RestconfDocumentedException e) {
-            assertEquals("getErrorTag", RestconfError.ErrorTag.DATA_EXISTS, e.getErrors().get(0).getErrorTag());
-            throw e;
-        }
-    }
-
-    @Test
-    public void testCommitConfigurationDataPostBehindMountPoint() {
-        Future<RpcResult<TransactionStatus>> expFuture = Futures.immediateFuture(null);
-
-        Map<YangInstanceIdentifier, CompositeNode> nodeMap = new ImmutableMap.Builder<YangInstanceIdentifier, CompositeNode>()
-                .put(instanceID, dataNode).build();
-
-        when(mockMountInstance.beginTransaction()).thenReturn(mockTransaction);
-        mockTransaction.putConfigurationData(instanceID, dataNode);
-        when(mockTransaction.getCreatedConfigurationData()).thenReturn(nodeMap);
-        when(mockTransaction.commit()).thenReturn(expFuture);
-
-        Future<RpcResult<TransactionStatus>> actualFuture = brokerFacade.commitConfigurationDataPostBehindMountPoint(
-                mockMountInstance, instanceID, dataNode);
-
-        assertSame("commitConfigurationDataPostBehindMountPoint", expFuture, actualFuture);
-
-        InOrder inOrder = inOrder(mockMountInstance, mockTransaction);
-        inOrder.verify(mockMountInstance).beginTransaction();
-        inOrder.verify(mockTransaction).putConfigurationData(instanceID, dataNode);
-        inOrder.verify(mockTransaction).commit();
-    }
-
-    @Test(expected = RestconfDocumentedException.class)
-    public void testCommitConfigurationDataPostBehindMountPointAlreadyExists() {
-
-        when(mockMountInstance.beginTransaction()).thenReturn(mockTransaction);
-        mockTransaction.putConfigurationData(instanceID, dataNode);
-        when(mockTransaction.readConfigurationData(instanceID)).thenReturn(dataNode);
+        when(rwTransaction.read(eq(LogicalDatastoreType.CONFIGURATION), any(YangInstanceIdentifier.class))).thenReturn(
+                dummyNodeInFuture);
         try {
-            brokerFacade.commitConfigurationDataPostBehindMountPoint(mockMountInstance, instanceID, dataNode);
+            brokerFacade.commitConfigurationDataPost(instanceID, dummyNode);
         } catch (RestconfDocumentedException e) {
             assertEquals("getErrorTag", RestconfError.ErrorTag.DATA_EXISTS, e.getErrors().get(0).getErrorTag());
             throw e;
@@ -259,43 +214,19 @@ public class BrokerFacadeTest {
 
     @Test
     public void testCommitConfigurationDataDelete() {
-        Future<RpcResult<TransactionStatus>> expFuture = Futures.immediateFuture(null);
+        CheckedFuture<Void, TransactionCommitFailedException> expFuture = mock(CheckedFuture.class);
 
-        when(dataBroker.beginTransaction()).thenReturn(mockTransaction);
-        when(mockTransaction.readConfigurationData(any(YangInstanceIdentifier.class))).thenReturn(
-                ImmutableCompositeNode.builder().toInstance());
-        mockTransaction.removeConfigurationData(instanceID);
-        when(mockTransaction.commit()).thenReturn(expFuture);
+        when(wTransaction.submit()).thenReturn(expFuture);
 
-        Future<RpcResult<TransactionStatus>> actualFuture = brokerFacade.commitConfigurationDataDelete(instanceID);
+        CheckedFuture<Void, TransactionCommitFailedException> actualFuture = brokerFacade
+                .commitConfigurationDataDelete(instanceID);
 
         assertSame("commitConfigurationDataDelete", expFuture, actualFuture);
 
-        InOrder inOrder = inOrder(dataBroker, mockTransaction);
-        inOrder.verify(dataBroker).beginTransaction();
-        inOrder.verify(mockTransaction).removeConfigurationData(instanceID);
-        inOrder.verify(mockTransaction).commit();
-    }
-
-    @Test
-    public void testCommitConfigurationDataDeleteBehindMountPoint() {
-        Future<RpcResult<TransactionStatus>> expFuture = Futures.immediateFuture(null);
-
-        when(mockMountInstance.beginTransaction()).thenReturn(mockTransaction);
-        when(mockTransaction.readConfigurationData(any(YangInstanceIdentifier.class))).thenReturn(
-                ImmutableCompositeNode.builder().toInstance());
-        mockTransaction.removeConfigurationData(instanceID);
-        when(mockTransaction.commit()).thenReturn(expFuture);
-
-        Future<RpcResult<TransactionStatus>> actualFuture = brokerFacade.commitConfigurationDataDeleteBehindMountPoint(
-                mockMountInstance, instanceID);
-
-        assertSame("commitConfigurationDataDeleteBehindMountPoint", expFuture, actualFuture);
-
-        InOrder inOrder = inOrder(mockMountInstance, mockTransaction);
-        inOrder.verify(mockMountInstance).beginTransaction();
-        inOrder.verify(mockTransaction).removeConfigurationData(instanceID);
-        inOrder.verify(mockTransaction).commit();
+        InOrder inOrder = inOrder(domDataBroker, wTransaction);
+        inOrder.verify(domDataBroker).newWriteOnlyTransaction();
+        inOrder.verify(wTransaction).delete(eq(LogicalDatastoreType.CONFIGURATION), any(YangInstanceIdentifier.class));
+        inOrder.verify(wTransaction).submit();
     }
 
     @SuppressWarnings("unchecked")
@@ -303,16 +234,23 @@ public class BrokerFacadeTest {
     public void testRegisterToListenDataChanges() {
         ListenerAdapter listener = Notificator.createListener(instanceID, "stream");
 
-        ListenerRegistration<DataChangeListener> mockRegistration = mock(ListenerRegistration.class);
-        when(dataBroker.registerDataChangeListener(instanceID, listener)).thenReturn(mockRegistration);
+        ListenerRegistration<DOMDataChangeListener> mockRegistration = mock(ListenerRegistration.class);
+
+        when(
+                domDataBroker.registerDataChangeListener(any(LogicalDatastoreType.class), eq(instanceID), eq(listener),
+                        eq(DataChangeScope.BASE))).thenReturn(mockRegistration);
 
-        brokerFacade.registerToListenDataChanges(listener);
+        brokerFacade.registerToListenDataChanges(LogicalDatastoreType.CONFIGURATION, DataChangeScope.BASE, listener);
 
-        verify(dataBroker).registerDataChangeListener(instanceID, listener);
+        verify(domDataBroker).registerDataChangeListener(LogicalDatastoreType.CONFIGURATION, instanceID, listener,
+                DataChangeScope.BASE);
 
         assertEquals("isListening", true, listener.isListening());
 
-        brokerFacade.registerToListenDataChanges(listener);
-        verifyNoMoreInteractions(dataBroker);
+        brokerFacade.registerToListenDataChanges(LogicalDatastoreType.CONFIGURATION, DataChangeScope.BASE, listener);
+        verifyNoMoreInteractions(domDataBroker);
+
+        String escapeXml = StringEscapeUtils.escapeXml("data might contain & or ! or % or ' ");
+        System.out.println(escapeXml);
     }
 }
index 9aab841546016a5cb09f669c168307b2aaf0f725..500baafab3476cba31ed159ec7b87c7cca66cdd5 100644 (file)
@@ -36,7 +36,8 @@ import javax.ws.rs.core.UriInfo;
 import org.junit.Before;
 import org.junit.BeforeClass;
 import org.junit.Test;
-import org.opendaylight.controller.sal.core.api.mount.MountInstance;
+import org.opendaylight.controller.md.sal.dom.api.DOMMountPoint;
+import org.opendaylight.controller.sal.core.api.RpcProvisionRegistry;
 import org.opendaylight.controller.sal.restconf.impl.BrokerFacade;
 import org.opendaylight.controller.sal.restconf.impl.ControllerContext;
 import org.opendaylight.controller.sal.restconf.impl.InstanceIdWithSchemaNode;
@@ -317,9 +318,10 @@ public class InvokeRpcMethodTest {
         RpcDefinition mockRpc = mock(RpcDefinition.class);
         when(mockRpc.getQName()).thenReturn(cancelToastQName);
 
-        MountInstance mockMountPoint = mock(MountInstance.class);
-        when(mockMountPoint.rpc(eq(cancelToastQName), any(CompositeNode.class))).thenReturn(mockListener);
-
+        DOMMountPoint mockMountPoint = mock(DOMMountPoint.class);
+        RpcProvisionRegistry mockedRpcProvisionRegistry = mock(RpcProvisionRegistry.class);
+        when(mockedRpcProvisionRegistry.invokeRpc(eq(cancelToastQName), any(CompositeNode.class))).thenReturn(mockListener);
+        when(mockMountPoint.getService(eq(RpcProvisionRegistry.class))).thenReturn(Optional.of(mockedRpcProvisionRegistry));
         when(mockMountPoint.getSchemaContext()).thenReturn(TestUtils.loadSchemaContext("/invoke-rpc"));
 
         InstanceIdWithSchemaNode mockedInstanceId = mock(InstanceIdWithSchemaNode.class);
index 5fbfc453523339500c46e5d751b7967db455c19d..478565f033df3a1c0a1b8e21cb1ce3fd4e5d9339 100644 (file)
@@ -21,7 +21,7 @@ import org.opendaylight.controller.sal.restconf.impl.RestconfDocumentedException
 import org.opendaylight.controller.sal.restconf.impl.RestconfError;
 import org.opendaylight.controller.sal.restconf.impl.RestconfError.ErrorTag;
 import org.opendaylight.controller.sal.restconf.impl.RestconfError.ErrorType;
-import org.opendaylight.yangtools.yang.data.api.CompositeNode;
+import org.opendaylight.yangtools.yang.data.api.Node;
 import org.opendaylight.yangtools.yang.model.api.Module;
 
 /**
@@ -57,16 +57,16 @@ public class MultipleEqualNamesForDataNodesTest {
     }
 
     private void multipleEqualNameDataNodeTest(String path, ErrorType errorType, ErrorTag errorTag,
-            MessageBodyReader<CompositeNode> messageBodyReader) {
+            MessageBodyReader<Node<?>> messageBodyReader) {
         try {
-            CompositeNode compositeNode = TestUtils.readInputToCnSn(path, false, messageBodyReader);
-            assertNotNull(compositeNode);
+            Node<?> node = TestUtils.readInputToCnSn(path, false, messageBodyReader);
+            assertNotNull(node);
 
             Set<Module> modules = null;
             modules = TestUtils.loadModulesFrom("/equal-data-node-names/yang");
             assertNotNull(modules);
 
-            TestUtils.normalizeCompositeNode(compositeNode, modules, "equal-data-node-names" + ":" + "cont");
+            TestUtils.normalizeCompositeNode(node, modules, "equal-data-node-names" + ":" + "cont");
             fail("Exception RestconfDocumentedException should be raised");
         } catch (RestconfDocumentedException e) {
             List<RestconfError> errors = e.getErrors();
index 66ced818175e2435cda90e41a854214277c6403b..8d5cac02048c4fd6043dc56208c6f6e9146cc91f 100644 (file)
@@ -10,13 +10,14 @@ package org.opendaylight.controller.sal.restconf.impl.test;
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertNotNull;
 import static org.mockito.Matchers.any;
+import static org.mockito.Mockito.doThrow;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.when;
 
+import com.google.common.util.concurrent.CheckedFuture;
 import java.io.FileNotFoundException;
 import java.io.UnsupportedEncodingException;
 import java.util.Set;
-import java.util.concurrent.Future;
 import javax.ws.rs.core.Application;
 import javax.ws.rs.core.MediaType;
 import javax.ws.rs.core.Response;
@@ -24,13 +25,12 @@ import org.glassfish.jersey.server.ResourceConfig;
 import org.glassfish.jersey.test.JerseyTest;
 import org.junit.BeforeClass;
 import org.junit.Test;
-import org.opendaylight.controller.md.sal.common.api.TransactionStatus;
 import org.opendaylight.controller.sal.rest.impl.StructuredDataToXmlProvider;
 import org.opendaylight.controller.sal.rest.impl.XmlToCompositeNodeProvider;
 import org.opendaylight.controller.sal.restconf.impl.BrokerFacade;
 import org.opendaylight.controller.sal.restconf.impl.ControllerContext;
+import org.opendaylight.controller.sal.restconf.impl.RestconfDocumentedException;
 import org.opendaylight.controller.sal.restconf.impl.RestconfImpl;
-import org.opendaylight.yangtools.yang.common.RpcResult;
 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
 import org.opendaylight.yangtools.yang.model.api.Module;
 import org.opendaylight.yangtools.yang.model.api.SchemaContext;
@@ -70,21 +70,14 @@ public class RestDeleteOperationTest extends JerseyTest {
     @Test
     public void deleteConfigStatusCodes() throws UnsupportedEncodingException {
         String uri = "/config/test-interface:interfaces";
-        Future<RpcResult<TransactionStatus>> dummyFuture = createFuture(TransactionStatus.COMMITED);
-        when(brokerFacade.commitConfigurationDataDelete(any(YangInstanceIdentifier.class))).thenReturn(dummyFuture);
+        when(brokerFacade.commitConfigurationDataDelete(any(YangInstanceIdentifier.class))).thenReturn(
+                mock(CheckedFuture.class));
         Response response = target(uri).request(MediaType.APPLICATION_XML).delete();
         assertEquals(200, response.getStatus());
 
-        dummyFuture = createFuture(TransactionStatus.FAILED);
-        when(brokerFacade.commitConfigurationDataDelete(any(YangInstanceIdentifier.class))).thenReturn(dummyFuture);
+        doThrow(RestconfDocumentedException.class).when(brokerFacade).commitConfigurationDataDelete(
+                any(YangInstanceIdentifier.class));
         response = target(uri).request(MediaType.APPLICATION_XML).delete();
         assertEquals(500, response.getStatus());
     }
-
-    private Future<RpcResult<TransactionStatus>> createFuture(TransactionStatus statusName) {
-        RpcResult<TransactionStatus> rpcResult = new DummyRpcResult.Builder<TransactionStatus>().result(statusName)
-                .build();
-        return new DummyFuture.Builder<TransactionStatus>().rpcResult(rpcResult).build();
-    }
-
 }
index ac660e32bce0f654e8801a56c723f6ec6736c80c..d4f69090819c152895eeb53b71bbfc9107fda511 100644 (file)
@@ -18,8 +18,10 @@ import static org.mockito.Matchers.eq;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.when;
 
+import com.google.common.base.Optional;
+import com.google.common.collect.Lists;
+import com.google.common.collect.Maps;
 import java.io.FileNotFoundException;
-import java.io.InputStream;
 import java.io.UnsupportedEncodingException;
 import java.net.URI;
 import java.net.URISyntaxException;
@@ -33,40 +35,46 @@ import java.util.Map;
 import java.util.Set;
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
-
 import javax.ws.rs.core.Application;
 import javax.ws.rs.core.MediaType;
 import javax.ws.rs.core.MultivaluedHashMap;
 import javax.ws.rs.core.MultivaluedMap;
 import javax.ws.rs.core.Response;
 import javax.ws.rs.core.UriInfo;
-
 import org.glassfish.jersey.server.ResourceConfig;
 import org.glassfish.jersey.test.JerseyTest;
 import org.junit.BeforeClass;
 import org.junit.Test;
 import org.mockito.invocation.InvocationOnMock;
 import org.mockito.stubbing.Answer;
-import org.opendaylight.controller.sal.core.api.mount.MountInstance;
-import org.opendaylight.controller.sal.core.api.mount.MountService;
+import org.opendaylight.controller.md.sal.dom.api.DOMMountPoint;
+import org.opendaylight.controller.md.sal.dom.api.DOMMountPointService;
 import org.opendaylight.controller.sal.rest.impl.JsonToCompositeNodeProvider;
 import org.opendaylight.controller.sal.rest.impl.RestconfDocumentedExceptionMapper;
 import org.opendaylight.controller.sal.rest.impl.StructuredDataToJsonProvider;
 import org.opendaylight.controller.sal.rest.impl.StructuredDataToXmlProvider;
 import org.opendaylight.controller.sal.rest.impl.XmlToCompositeNodeProvider;
 import org.opendaylight.controller.sal.restconf.impl.BrokerFacade;
-import org.opendaylight.controller.sal.restconf.impl.CompositeNodeWrapper;
 import org.opendaylight.controller.sal.restconf.impl.ControllerContext;
 import org.opendaylight.controller.sal.restconf.impl.RestconfDocumentedException;
 import org.opendaylight.controller.sal.restconf.impl.RestconfImpl;
-import org.opendaylight.controller.sal.restconf.impl.SimpleNodeWrapper;
 import org.opendaylight.yangtools.yang.common.QName;
 import org.opendaylight.yangtools.yang.data.api.CompositeNode;
 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.PathArgument;
-import org.opendaylight.yangtools.yang.data.api.Node;
+import org.opendaylight.yangtools.yang.data.api.schema.ContainerNode;
+import org.opendaylight.yangtools.yang.data.api.schema.MapEntryNode;
+import org.opendaylight.yangtools.yang.data.api.schema.MapNode;
+import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
 import org.opendaylight.yangtools.yang.data.impl.ImmutableCompositeNode;
+import org.opendaylight.yangtools.yang.data.impl.schema.Builders;
+import org.opendaylight.yangtools.yang.data.impl.schema.builder.api.CollectionNodeBuilder;
+import org.opendaylight.yangtools.yang.data.impl.schema.builder.impl.ImmutableLeafNodeBuilder;
+import org.opendaylight.yangtools.yang.data.impl.schema.builder.impl.ImmutableMapEntryNodeBuilder;
+import org.opendaylight.yangtools.yang.data.impl.schema.builder.impl.ImmutableMapNodeBuilder;
 import org.opendaylight.yangtools.yang.data.impl.util.CompositeNodeBuilder;
+import org.opendaylight.yangtools.yang.model.api.DataNodeContainer;
+import org.opendaylight.yangtools.yang.model.api.DataSchemaNode;
 import org.opendaylight.yangtools.yang.model.api.Module;
 import org.opendaylight.yangtools.yang.model.api.RpcDefinition;
 import org.opendaylight.yangtools.yang.model.api.SchemaContext;
@@ -74,9 +82,6 @@ import org.w3c.dom.Document;
 import org.w3c.dom.Element;
 import org.w3c.dom.NodeList;
 
-import com.google.common.collect.Lists;
-import com.google.common.collect.Maps;
-
 public class RestGetOperationTest extends JerseyTest {
 
     static class NodeData {
@@ -93,7 +98,7 @@ public class RestGetOperationTest extends JerseyTest {
     private static RestconfImpl restconfImpl;
     private static SchemaContext schemaContextYangsIetf;
     private static SchemaContext schemaContextTestModule;
-    private static CompositeNode answerFromGet;
+    private static NormalizedNode answerFromGet;
 
     private static SchemaContext schemaContextModules;
     private static SchemaContext schemaContextBehindMountPoint;
@@ -101,7 +106,7 @@ public class RestGetOperationTest extends JerseyTest {
     private static final String RESTCONF_NS = "urn:ietf:params:xml:ns:yang:ietf-restconf";
 
     @BeforeClass
-    public static void init() throws FileNotFoundException {
+    public static void init() throws FileNotFoundException, ParseException {
         schemaContextYangsIetf = TestUtils.loadSchemaContext("/full-versions/yangs");
         schemaContextTestModule = TestUtils.loadSchemaContext("/full-versions/test-module");
         ControllerContext controllerContext = ControllerContext.getInstance();
@@ -110,7 +115,7 @@ public class RestGetOperationTest extends JerseyTest {
         restconfImpl = RestconfImpl.getInstance();
         restconfImpl.setBroker(brokerFacade);
         restconfImpl.setControllerContext(controllerContext);
-        answerFromGet = prepareCompositeNodeWithIetfInterfacesInterfacesData();
+        answerFromGet = TestUtils.prepareNormalizedNodeWithIetfInterfacesInterfacesData();
 
         schemaContextModules = TestUtils.loadSchemaContext("/modules");
         schemaContextBehindMountPoint = TestUtils.loadSchemaContext("/modules/modules-behind-mount-point");
@@ -161,14 +166,13 @@ public class RestGetOperationTest extends JerseyTest {
      * MountPoint test. URI represents mount point.
      */
     @Test
-    public void getDataWithUrlMountPoint() throws UnsupportedEncodingException, URISyntaxException {
-        when(
-                brokerFacade.readConfigurationDataBehindMountPoint(any(MountInstance.class),
-                        any(YangInstanceIdentifier.class))).thenReturn(prepareCnDataForMountPointTest());
-        MountInstance mountInstance = mock(MountInstance.class);
+    public void getDataWithUrlMountPoint() throws UnsupportedEncodingException, URISyntaxException, ParseException {
+        when(brokerFacade.readConfigurationData(any(DOMMountPoint.class), any(YangInstanceIdentifier.class))).thenReturn(
+                prepareCnDataForMountPointTest(false));
+        DOMMountPoint mountInstance = mock(DOMMountPoint.class);
         when(mountInstance.getSchemaContext()).thenReturn(schemaContextTestModule);
-        MountService mockMountService = mock(MountService.class);
-        when(mockMountService.getMountPoint(any(YangInstanceIdentifier.class))).thenReturn(mountInstance);
+        DOMMountPointService mockMountService = mock(DOMMountPointService.class);
+        when(mockMountService.getMountPoint(any(YangInstanceIdentifier.class))).thenReturn(Optional.of(mountInstance));
 
         ControllerContext.getInstance().setMountService(mockMountService);
 
@@ -188,20 +192,18 @@ public class RestGetOperationTest extends JerseyTest {
      * {@link BrokerFacade#readConfigurationDataBehindMountPoint(MountInstance, YangInstanceIdentifier)} which is called in
      * method {@link RestconfImpl#readConfigurationData}
      *
-     *
      * @throws ParseException
      */
     @Test
     public void getDataWithSlashesBehindMountPoint() throws UnsupportedEncodingException, URISyntaxException,
             ParseException {
         YangInstanceIdentifier awaitedInstanceIdentifier = prepareInstanceIdentifierForList();
-        when(
-                brokerFacade.readConfigurationDataBehindMountPoint(any(MountInstance.class),
-                        eq(awaitedInstanceIdentifier))).thenReturn(prepareCnDataForMountPointTest());
-        MountInstance mountInstance = mock(MountInstance.class);
+        when(brokerFacade.readConfigurationData(any(DOMMountPoint.class), eq(awaitedInstanceIdentifier))).thenReturn(
+                prepareCnDataForSlashesBehindMountPointTest());
+        DOMMountPoint mountInstance = mock(DOMMountPoint.class);
         when(mountInstance.getSchemaContext()).thenReturn(schemaContextTestModule);
-        MountService mockMountService = mock(MountService.class);
-        when(mockMountService.getMountPoint(any(YangInstanceIdentifier.class))).thenReturn(mountInstance);
+        DOMMountPointService mockMountService = mock(DOMMountPointService.class);
+        when(mockMountService.getMountPoint(any(YangInstanceIdentifier.class))).thenReturn(Optional.of(mountInstance));
 
         ControllerContext.getInstance().setMountService(mockMountService);
 
@@ -219,24 +221,25 @@ public class RestGetOperationTest extends JerseyTest {
         QName qNameKeyList = QName.create(uri, revision, "lf11");
 
         parameters.add(new YangInstanceIdentifier.NodeIdentifier(qNameCont));
+        parameters.add(new YangInstanceIdentifier.NodeIdentifier(qNameList));
         parameters.add(new YangInstanceIdentifier.NodeIdentifierWithPredicates(qNameList, qNameKeyList,
                 "GigabitEthernet0/0/0/0"));
         return YangInstanceIdentifier.create(parameters);
     }
 
     @Test
-    public void getDataMountPointIntoHighestElement() throws UnsupportedEncodingException, URISyntaxException {
-        when(
-                brokerFacade.readConfigurationDataBehindMountPoint(any(MountInstance.class),
-                        any(YangInstanceIdentifier.class))).thenReturn(prepareCnDataForMountPointTest());
-        MountInstance mountInstance = mock(MountInstance.class);
+    public void getDataMountPointIntoHighestElement() throws UnsupportedEncodingException, URISyntaxException,
+            ParseException {
+        when(brokerFacade.readConfigurationData(any(DOMMountPoint.class), any(YangInstanceIdentifier.class))).thenReturn(
+                prepareCnDataForMountPointTest(true));
+        DOMMountPoint mountInstance = mock(DOMMountPoint.class);
         when(mountInstance.getSchemaContext()).thenReturn(schemaContextTestModule);
-        MountService mockMountService = mock(MountService.class);
-        when(mockMountService.getMountPoint(any(YangInstanceIdentifier.class))).thenReturn(mountInstance);
+        DOMMountPointService mockMountService = mock(DOMMountPointService.class);
+        when(mockMountService.getMountPoint(any(YangInstanceIdentifier.class))).thenReturn(Optional.of(mountInstance));
 
         ControllerContext.getInstance().setMountService(mockMountService);
 
-        String uri = "/config/ietf-interfaces:interfaces/interface/0/yang-ext:mount/";
+        String uri = "/config/ietf-interfaces:interfaces/interface/0/yang-ext:mount/test-module:cont";
         assertEquals(200, get(uri, MediaType.APPLICATION_XML));
     }
 
@@ -361,10 +364,10 @@ public class RestGetOperationTest extends JerseyTest {
         ControllerContext controllerContext = ControllerContext.getInstance();
         controllerContext.setGlobalSchema(schemaContextModules);
 
-        MountInstance mountInstance = mock(MountInstance.class);
+        DOMMountPoint mountInstance = mock(DOMMountPoint.class);
         when(mountInstance.getSchemaContext()).thenReturn(schemaContextBehindMountPoint);
-        MountService mockMountService = mock(MountService.class);
-        when(mockMountService.getMountPoint(any(YangInstanceIdentifier.class))).thenReturn(mountInstance);
+        DOMMountPointService mockMountService = mock(DOMMountPointService.class);
+        when(mockMountService.getMountPoint(any(YangInstanceIdentifier.class))).thenReturn(Optional.of(mountInstance));
 
         controllerContext.setMountService(mockMountService);
 
@@ -450,10 +453,10 @@ public class RestGetOperationTest extends JerseyTest {
         ControllerContext controllerContext = ControllerContext.getInstance();
         controllerContext.setGlobalSchema(schemaContextModules);
 
-        MountInstance mountInstance = mock(MountInstance.class);
+        DOMMountPoint mountInstance = mock(DOMMountPoint.class);
         when(mountInstance.getSchemaContext()).thenReturn(schemaContextBehindMountPoint);
-        MountService mockMountService = mock(MountService.class);
-        when(mockMountService.getMountPoint(any(YangInstanceIdentifier.class))).thenReturn(mountInstance);
+        DOMMountPointService mockMountService = mock(DOMMountPointService.class);
+        when(mockMountService.getMountPoint(any(YangInstanceIdentifier.class))).thenReturn(Optional.of(mountInstance));
 
         controllerContext.setMountService(mockMountService);
 
@@ -484,10 +487,10 @@ public class RestGetOperationTest extends JerseyTest {
         ControllerContext controllerContext = ControllerContext.getInstance();
         controllerContext.setGlobalSchema(schemaContextModules);
 
-        MountInstance mountInstance = mock(MountInstance.class);
+        DOMMountPoint mountInstance = mock(DOMMountPoint.class);
         when(mountInstance.getSchemaContext()).thenReturn(schemaContextBehindMountPoint);
-        MountService mockMountService = mock(MountService.class);
-        when(mockMountService.getMountPoint(any(YangInstanceIdentifier.class))).thenReturn(mountInstance);
+        DOMMountPointService mockMountService = mock(DOMMountPointService.class);
+        when(mockMountService.getMountPoint(any(YangInstanceIdentifier.class))).thenReturn(Optional.of(mountInstance));
 
         controllerContext.setMountService(mockMountService);
 
@@ -636,11 +639,30 @@ public class RestGetOperationTest extends JerseyTest {
         return target(uri).request(mediaType).get().getStatus();
     }
 
-    private CompositeNode prepareCnDataForMountPointTest() throws URISyntaxException {
-        CompositeNodeWrapper cont1 = new CompositeNodeWrapper(new URI("test:module"), "cont1");
-        SimpleNodeWrapper lf11 = new SimpleNodeWrapper(new URI("test:module"), "lf11", "lf11 value");
-        cont1.addValue(lf11);
-        return cont1.unwrap();
+    /**
+    container cont {
+        container cont1 {
+            leaf lf11 {
+                type string;
+            }
+    */
+    private NormalizedNode prepareCnDataForMountPointTest(boolean wrapToCont) throws URISyntaxException, ParseException {
+        String testModuleDate = "2014-01-09";
+        ContainerNode contChild = Builders
+                .containerBuilder()
+                .withNodeIdentifier(TestUtils.getNodeIdentifier("cont1", "test:module", testModuleDate))
+                .withChild(
+                        Builders.leafBuilder()
+                                .withNodeIdentifier(TestUtils.getNodeIdentifier("lf11", "test:module", testModuleDate))
+                                .withValue("lf11 value").build()).build();
+
+        if (wrapToCont) {
+            return Builders.containerBuilder()
+                    .withNodeIdentifier(TestUtils.getNodeIdentifier("cont", "test:module", testModuleDate))
+                    .withChild(contChild).build();
+        }
+        return contChild;
+
     }
 
     private void mockReadOperationalDataMethod() {
@@ -651,22 +673,20 @@ public class RestGetOperationTest extends JerseyTest {
         when(brokerFacade.readConfigurationData(any(YangInstanceIdentifier.class))).thenReturn(answerFromGet);
     }
 
-    private static CompositeNode prepareCompositeNodeWithIetfInterfacesInterfacesData() {
-        CompositeNode intface;
-        try {
-            intface = new CompositeNodeWrapper(new URI("interface"), "interface");
-            List<Node<?>> childs = new ArrayList<>();
-
-            childs.add(new SimpleNodeWrapper(new URI("name"), "name", "eth0"));
-            childs.add(new SimpleNodeWrapper(new URI("type"), "type", "ethernetCsmacd"));
-            childs.add(new SimpleNodeWrapper(new URI("enabled"), "enabled", Boolean.FALSE));
-            childs.add(new SimpleNodeWrapper(new URI("description"), "description", "some interface"));
-            intface.setValue(childs);
-            return intface;
-        } catch (URISyntaxException e) {
-        }
-
-        return null;
+    private NormalizedNode prepareCnDataForSlashesBehindMountPointTest() throws ParseException {
+        CollectionNodeBuilder<MapEntryNode, MapNode> lst1 = ImmutableMapNodeBuilder.create();
+        lst1.withNodeIdentifier(TestUtils.getNodeIdentifier("lst1", "test:module", "2014-01-09"));
+        lst1.withChild(ImmutableMapEntryNodeBuilder
+                .create()
+                .withNodeIdentifier(
+                        TestUtils.getNodeIdentifierPredicate("lst1", "test:module", "2014-01-09", "lf11",
+                                "GigabitEthernet0/0/0/0"))
+                .withChild(
+                        ImmutableLeafNodeBuilder.create()
+                                .withNodeIdentifier(TestUtils.getNodeIdentifier("lf11", "test:module", "2014-01-09"))
+                                .withValue("GigabitEthernet0/0/0/0").build()).build());
+
+        return lst1.build();
     }
 
     /**
@@ -682,6 +702,7 @@ public class RestGetOperationTest extends JerseyTest {
 
     private void getDataWithUriIncludeWhiteCharsParameter(final String target) throws UnsupportedEncodingException {
         mockReadConfigurationDataMethod();
+        mockReadOperationalDataMethod();
         String uri = "/" + target + "/ietf-interfaces:interfaces/interface/eth0";
         Response response = target(uri).queryParam("prettyPrint", "false").request("application/xml").get();
         String xmlData = response.readEntity(String.class);
@@ -726,7 +747,14 @@ public class RestGetOperationTest extends JerseyTest {
                         toSimpleNodeData(toNestedQName("depth3-leaf2"), "depth3-leaf2-value")),
                 toSimpleNodeData(toNestedQName("depth2-leaf1"), "depth2-leaf1-value")));
 
-        when(brokerFacade.readConfigurationData(any(YangInstanceIdentifier.class))).thenReturn(depth1Cont);
+        Module module = TestUtils.findModule(schemaContextModules.getModules(), "nested-module");
+        assertNotNull(module);
+
+        DataSchemaNode dataSchemaNode = TestUtils.resolveDataSchemaNode("depth1-cont", module);
+        assertNotNull(dataSchemaNode);
+
+        when(brokerFacade.readConfigurationData(any(YangInstanceIdentifier.class))).thenReturn(
+                TestUtils.compositeNodeToDatastoreNormalizedNode(depth1Cont, dataSchemaNode));
 
         // Test config with depth 1
 
@@ -852,7 +880,18 @@ public class RestGetOperationTest extends JerseyTest {
                         toSimpleNodeData(toNestedQName("depth4-leaf1"), "depth4-leaf1-value")),
                 toSimpleNodeData(toNestedQName("depth3-leaf1"), "depth3-leaf1-value")));
 
-        when(brokerFacade.readOperationalData(any(YangInstanceIdentifier.class))).thenReturn(depth2Cont1);
+        assertTrue(dataSchemaNode instanceof DataNodeContainer);
+        DataSchemaNode depth2cont1Schema = null;
+        for (DataSchemaNode childNode : ((DataNodeContainer) dataSchemaNode).getChildNodes()) {
+            if (childNode.getQName().getLocalName().equals("depth2-cont1")) {
+                depth2cont1Schema = childNode;
+                break;
+            }
+        }
+        assertNotNull(depth2Cont1);
+
+        when(brokerFacade.readOperationalData(any(YangInstanceIdentifier.class))).thenReturn(
+                TestUtils.compositeNodeToDatastoreNormalizedNode(depth2Cont1, depth2cont1Schema));
 
         response = target("/operational/nested-module:depth1-cont/depth2-cont1").queryParam("depth", "3")
                 .request("application/xml").get();
@@ -876,7 +915,7 @@ public class RestGetOperationTest extends JerseyTest {
         UriInfo mockInfo = mock(UriInfo.class);
         when(mockInfo.getQueryParameters(false)).thenAnswer(new Answer<MultivaluedMap<String, String>>() {
             @Override
-            public MultivaluedMap<String, String> answer(final InvocationOnMock invocation) {
+            public MultivaluedMap<String, String> answer(InvocationOnMock invocation) {
                 return paramMap;
             }
         });
@@ -901,8 +940,9 @@ public class RestGetOperationTest extends JerseyTest {
     }
 
     private void verifyXMLResponse(final Response response, final NodeData nodeData) {
-
-        Document doc = TestUtils.loadDocumentFrom((InputStream) response.getEntity());
+        Document doc = response.readEntity(Document.class);
+//        Document doc = TestUtils.loadDocumentFrom((InputStream) response.getEntity());
+//        System.out.println();
         assertNotNull("Could not parse XML document", doc);
 
         // System.out.println(TestUtils.getDocumentInPrintableForm( doc ));
@@ -913,11 +953,11 @@ public class RestGetOperationTest extends JerseyTest {
     @SuppressWarnings("unchecked")
     private void verifyContainerElement(final Element element, final NodeData nodeData) {
 
-        assertEquals("Element local name", nodeData.key, element.getNodeName());
+        assertEquals("Element local name", nodeData.key, element.getLocalName());
 
         NodeList childNodes = element.getChildNodes();
         if (nodeData.data == null) { // empty container
-            assertTrue("Expected no child elements for \"" + element.getNodeName() + "\"", childNodes.getLength() == 0);
+            assertTrue("Expected no child elements for \"" + element.getLocalName() + "\"", childNodes.getLength() == 0);
             return;
         }
 
@@ -933,21 +973,21 @@ public class RestGetOperationTest extends JerseyTest {
             }
 
             Element actualElement = (Element) actualChild;
-            NodeData expChild = expChildMap.remove(actualElement.getNodeName());
+            NodeData expChild = expChildMap.remove(actualElement.getLocalName());
             assertNotNull(
-                    "Unexpected child element for parent \"" + element.getNodeName() + "\": "
-                            + actualElement.getNodeName(), expChild);
+                    "Unexpected child element for parent \"" + element.getLocalName() + "\": "
+                            + actualElement.getLocalName(), expChild);
 
             if (expChild.data == null || expChild.data instanceof List) {
                 verifyContainerElement(actualElement, expChild);
             } else {
-                assertEquals("Text content for element: " + actualElement.getNodeName(), expChild.data,
+                assertEquals("Text content for element: " + actualElement.getLocalName(), expChild.data,
                         actualElement.getTextContent());
             }
         }
 
         if (!expChildMap.isEmpty()) {
-            fail("Missing elements for parent \"" + element.getNodeName() + "\": " + expChildMap.keySet());
+            fail("Missing elements for parent \"" + element.getLocalName() + "\": " + expChildMap.keySet());
         }
     }
 
@@ -990,4 +1030,5 @@ public class RestGetOperationTest extends JerseyTest {
     private NodeData toSimpleNodeData(final QName key, final Object value) {
         return new NodeData(key, value);
     }
+
 }
index 979b58b78a184aacc28ceb82f7bd44f7f3315100..97cd67d34b70095a1571c1384e4a0e46c61f155a 100644 (file)
@@ -9,12 +9,16 @@ package org.opendaylight.controller.sal.restconf.impl.test;
 
 import static org.junit.Assert.assertEquals;
 import static org.mockito.Matchers.any;
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.doThrow;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.times;
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
 import static org.opendaylight.controller.sal.restconf.impl.test.RestOperationUtils.XML;
 
+import com.google.common.base.Optional;
+import com.google.common.util.concurrent.CheckedFuture;
 import com.google.common.util.concurrent.Futures;
 import java.io.IOException;
 import java.io.InputStream;
@@ -27,7 +31,6 @@ import java.util.Collection;
 import java.util.Collections;
 import java.util.List;
 import java.util.Set;
-import java.util.concurrent.Future;
 import javax.ws.rs.client.Entity;
 import javax.ws.rs.core.Application;
 import javax.ws.rs.core.MediaType;
@@ -37,8 +40,8 @@ import org.junit.BeforeClass;
 import org.junit.Test;
 import org.mockito.ArgumentCaptor;
 import org.opendaylight.controller.md.sal.common.api.TransactionStatus;
-import org.opendaylight.controller.sal.core.api.mount.MountInstance;
-import org.opendaylight.controller.sal.core.api.mount.MountService;
+import org.opendaylight.controller.md.sal.dom.api.DOMMountPoint;
+import org.opendaylight.controller.md.sal.dom.api.DOMMountPointService;
 import org.opendaylight.controller.sal.rest.api.Draft02;
 import org.opendaylight.controller.sal.rest.impl.JsonToCompositeNodeProvider;
 import org.opendaylight.controller.sal.rest.impl.RestconfDocumentedExceptionMapper;
@@ -48,14 +51,16 @@ import org.opendaylight.controller.sal.rest.impl.XmlToCompositeNodeProvider;
 import org.opendaylight.controller.sal.restconf.impl.BrokerFacade;
 import org.opendaylight.controller.sal.restconf.impl.CompositeNodeWrapper;
 import org.opendaylight.controller.sal.restconf.impl.ControllerContext;
+import org.opendaylight.controller.sal.restconf.impl.RestconfDocumentedException;
 import org.opendaylight.controller.sal.restconf.impl.RestconfImpl;
 import org.opendaylight.yangtools.yang.common.QName;
 import org.opendaylight.yangtools.yang.common.RpcError;
-import org.opendaylight.yangtools.yang.common.RpcResultBuilder;
 import org.opendaylight.yangtools.yang.common.RpcError.ErrorType;
 import org.opendaylight.yangtools.yang.common.RpcResult;
+import org.opendaylight.yangtools.yang.common.RpcResultBuilder;
 import org.opendaylight.yangtools.yang.data.api.CompositeNode;
 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
+import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
 import org.opendaylight.yangtools.yang.model.api.Module;
 import org.opendaylight.yangtools.yang.model.api.SchemaContext;
 
@@ -77,7 +82,7 @@ public class RestPostOperationTest extends JerseyTest {
     private static SchemaContext schemaContextTestModule;
     private static SchemaContext schemaContext;
 
-    private static MountService mountService;
+    private static DOMMountPointService mountService;
 
     @BeforeClass
     public static void init() throws URISyntaxException, IOException {
@@ -124,10 +129,9 @@ public class RestPostOperationTest extends JerseyTest {
         assertEquals(500, post(uri, MediaType.APPLICATION_XML, xmlDataRpcInput));
 
         List<RpcError> rpcErrors = new ArrayList<>();
-        rpcErrors.add( RpcResultBuilder.newError( ErrorType.RPC, "tag1", "message1",
-                                                  "applicationTag1", "info1", null ) );
-        rpcErrors.add( RpcResultBuilder.newWarning( ErrorType.PROTOCOL, "tag2", "message2",
-                                                    "applicationTag2", "info2", null ) );
+        rpcErrors.add(RpcResultBuilder.newError(ErrorType.RPC, "tag1", "message1", "applicationTag1", "info1", null));
+        rpcErrors.add(RpcResultBuilder.newWarning(ErrorType.PROTOCOL, "tag2", "message2", "applicationTag2", "info2",
+                null));
         mockInvokeRpc(null, false, rpcErrors);
         assertEquals(500, post(uri, MediaType.APPLICATION_XML, xmlDataRpcInput));
 
@@ -138,28 +142,25 @@ public class RestPostOperationTest extends JerseyTest {
     @Test
     public void postConfigOnlyStatusCodes() throws UnsupportedEncodingException {
         controllerContext.setSchemas(schemaContextYangsIetf);
-        mockCommitConfigurationDataPostMethod(TransactionStatus.COMMITED);
         String uri = "/config";
+        mockCommitConfigurationDataPostMethod(true);
         assertEquals(204, post(uri, MediaType.APPLICATION_XML, xmlDataAbsolutePath));
 
-        mockCommitConfigurationDataPostMethod(null);
-        assertEquals(202, post(uri, MediaType.APPLICATION_XML, xmlDataAbsolutePath));
-
-        mockCommitConfigurationDataPostMethod(TransactionStatus.FAILED);
+        mockCommitConfigurationDataPostMethod(false);
         assertEquals(500, post(uri, MediaType.APPLICATION_XML, xmlDataAbsolutePath));
+
+        assertEquals(400, post(uri, MediaType.APPLICATION_XML, ""));
     }
 
     @Test
     public void postConfigStatusCodes() throws UnsupportedEncodingException {
         controllerContext.setSchemas(schemaContextYangsIetf);
-        mockCommitConfigurationDataPostMethod(TransactionStatus.COMMITED);
         String uri = "/config/ietf-interfaces:interfaces";
-        assertEquals(204, post(uri, MediaType.APPLICATION_XML, xmlDataInterfaceAbsolutePath));
 
-        mockCommitConfigurationDataPostMethod(null);
-        assertEquals(202, post(uri, MediaType.APPLICATION_XML, xmlDataInterfaceAbsolutePath));
+        mockCommitConfigurationDataPostMethod(true);
+        assertEquals(204, post(uri, MediaType.APPLICATION_XML, xmlDataInterfaceAbsolutePath));
 
-        mockCommitConfigurationDataPostMethod(TransactionStatus.FAILED);
+        mockCommitConfigurationDataPostMethod(false);
         assertEquals(500, post(uri, MediaType.APPLICATION_XML, xmlDataInterfaceAbsolutePath));
 
         assertEquals(400, post(uri, MediaType.APPLICATION_JSON, ""));
@@ -168,18 +169,14 @@ public class RestPostOperationTest extends JerseyTest {
     @Test
     public void postDataViaUrlMountPoint() throws UnsupportedEncodingException {
         controllerContext.setSchemas(schemaContextYangsIetf);
-        RpcResult<TransactionStatus> rpcResult = new DummyRpcResult.Builder<TransactionStatus>().result(
-                TransactionStatus.COMMITED).build();
-        Future<RpcResult<TransactionStatus>> dummyFuture = new DummyFuture.Builder<TransactionStatus>().rpcResult(
-                rpcResult).build();
         when(
-                brokerFacade.commitConfigurationDataPostBehindMountPoint(any(MountInstance.class),
-                        any(YangInstanceIdentifier.class), any(CompositeNode.class))).thenReturn(dummyFuture);
+                brokerFacade.commitConfigurationDataPost(any(DOMMountPoint.class), any(YangInstanceIdentifier.class),
+                        any(NormalizedNode.class))).thenReturn(mock(CheckedFuture.class));
 
-        MountInstance mountInstance = mock(MountInstance.class);
+        DOMMountPoint mountInstance = mock(DOMMountPoint.class);
         when(mountInstance.getSchemaContext()).thenReturn(schemaContextTestModule);
-        MountService mockMountService = mock(MountService.class);
-        when(mockMountService.getMountPoint(any(YangInstanceIdentifier.class))).thenReturn(mountInstance);
+        DOMMountPointService mockMountService = mock(DOMMountPointService.class);
+        when(mockMountService.getMountPoint(any(YangInstanceIdentifier.class))).thenReturn(Optional.of(mountInstance));
 
         ControllerContext.getInstance().setMountService(mockMountService);
 
@@ -207,18 +204,13 @@ public class RestPostOperationTest extends JerseyTest {
         mockInvokeRpc(result, sucessful, Collections.<RpcError> emptyList());
     }
 
-    private void mockCommitConfigurationDataPostMethod(TransactionStatus statusName) {
-        RpcResult<TransactionStatus> rpcResult = new DummyRpcResult.Builder<TransactionStatus>().result(statusName)
-                .build();
-        Future<RpcResult<TransactionStatus>> dummyFuture = null;
-        if (statusName != null) {
-            dummyFuture = new DummyFuture.Builder<TransactionStatus>().rpcResult(rpcResult).build();
+    private void mockCommitConfigurationDataPostMethod(final boolean succesfulComit) {
+        if (succesfulComit) {
+            doReturn(mock(CheckedFuture.class)).when(brokerFacade).commitConfigurationDataPost(any(YangInstanceIdentifier.class), any(NormalizedNode.class));
         } else {
-            dummyFuture = new DummyFuture.Builder<TransactionStatus>().build();
+            doThrow(RestconfDocumentedException.class).when(brokerFacade).commitConfigurationDataPost(
+                    any(YangInstanceIdentifier.class), any(NormalizedNode.class));
         }
-
-        when(brokerFacade.commitConfigurationDataPost(any(YangInstanceIdentifier.class), any(CompositeNode.class)))
-                .thenReturn(dummyFuture);
     }
 
     @Test
@@ -226,14 +218,12 @@ public class RestPostOperationTest extends JerseyTest {
         initMocking();
         RpcResult<TransactionStatus> rpcResult = new DummyRpcResult.Builder<TransactionStatus>().result(
                 TransactionStatus.COMMITED).build();
-        Future<RpcResult<TransactionStatus>> dummyFuture = new DummyFuture.Builder<TransactionStatus>().rpcResult(
-                rpcResult).build();
 
-        when(brokerFacade.commitConfigurationDataPost(any(YangInstanceIdentifier.class), any(CompositeNode.class)))
-                .thenReturn(dummyFuture);
+        when(brokerFacade.commitConfigurationDataPost(any(YangInstanceIdentifier.class), any(NormalizedNode.class)))
+                .thenReturn(mock(CheckedFuture.class));
 
         ArgumentCaptor<YangInstanceIdentifier> instanceIdCaptor = ArgumentCaptor.forClass(YangInstanceIdentifier.class);
-        ArgumentCaptor<CompositeNode> compNodeCaptor = ArgumentCaptor.forClass(CompositeNode.class);
+        ArgumentCaptor<NormalizedNode> compNodeCaptor = ArgumentCaptor.forClass(NormalizedNode.class);
 
         String URI_1 = "/config";
         assertEquals(204, post(URI_1, Draft02.MediaTypes.DATA + XML, xmlTestInterface));
@@ -253,20 +243,20 @@ public class RestPostOperationTest extends JerseyTest {
     public void createConfigurationDataNullTest() throws UnsupportedEncodingException {
         initMocking();
 
-        when(brokerFacade.commitConfigurationDataPost(any(YangInstanceIdentifier.class), any(CompositeNode.class)))
+        when(brokerFacade.commitConfigurationDataPost(any(YangInstanceIdentifier.class), any(NormalizedNode.class)))
                 .thenReturn(null);
 
         String URI_1 = "/config";
-        assertEquals(202, post(URI_1, Draft02.MediaTypes.DATA + XML, xmlTestInterface));
+        assertEquals(204, post(URI_1, Draft02.MediaTypes.DATA + XML, xmlTestInterface));
 
         String URI_2 = "/config/test-interface:interfaces";
-        assertEquals(202, post(URI_2, Draft02.MediaTypes.DATA + XML, xmlBlockData));
+        assertEquals(204, post(URI_2, Draft02.MediaTypes.DATA + XML, xmlBlockData));
     }
 
     private static void initMocking() {
         controllerContext = ControllerContext.getInstance();
         controllerContext.setSchemas(schemaContext);
-        mountService = mock(MountService.class);
+        mountService = mock(DOMMountPointService.class);
         controllerContext.setMountService(mountService);
         brokerFacade = mock(BrokerFacade.class);
         restconfImpl = RestconfImpl.getInstance();
index 5d837f42bd27dd58233aaed07546f1b2fb5e2f06..3284546dcbb32806563b2bb8b0959d7a3063a10d 100644 (file)
@@ -9,15 +9,18 @@ package org.opendaylight.controller.sal.restconf.impl.test;
 
 import static org.junit.Assert.assertEquals;
 import static org.mockito.Matchers.any;
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.doThrow;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.when;
 
+import com.google.common.base.Optional;
+import com.google.common.util.concurrent.CheckedFuture;
 import java.io.FileNotFoundException;
 import java.io.IOException;
 import java.io.InputStream;
 import java.io.UnsupportedEncodingException;
 import java.net.URISyntaxException;
-import java.util.concurrent.Future;
 import javax.ws.rs.client.Entity;
 import javax.ws.rs.core.Application;
 import javax.ws.rs.core.MediaType;
@@ -26,9 +29,9 @@ import org.glassfish.jersey.server.ResourceConfig;
 import org.glassfish.jersey.test.JerseyTest;
 import org.junit.BeforeClass;
 import org.junit.Test;
-import org.opendaylight.controller.md.sal.common.api.TransactionStatus;
-import org.opendaylight.controller.sal.core.api.mount.MountInstance;
-import org.opendaylight.controller.sal.core.api.mount.MountService;
+import org.opendaylight.controller.md.sal.common.api.data.TransactionCommitFailedException;
+import org.opendaylight.controller.md.sal.dom.api.DOMMountPoint;
+import org.opendaylight.controller.md.sal.dom.api.DOMMountPointService;
 import org.opendaylight.controller.sal.rest.impl.JsonToCompositeNodeProvider;
 import org.opendaylight.controller.sal.rest.impl.RestconfDocumentedExceptionMapper;
 import org.opendaylight.controller.sal.rest.impl.StructuredDataToJsonProvider;
@@ -36,10 +39,10 @@ import org.opendaylight.controller.sal.rest.impl.StructuredDataToXmlProvider;
 import org.opendaylight.controller.sal.rest.impl.XmlToCompositeNodeProvider;
 import org.opendaylight.controller.sal.restconf.impl.BrokerFacade;
 import org.opendaylight.controller.sal.restconf.impl.ControllerContext;
+import org.opendaylight.controller.sal.restconf.impl.RestconfDocumentedException;
 import org.opendaylight.controller.sal.restconf.impl.RestconfImpl;
-import org.opendaylight.yangtools.yang.common.RpcResult;
-import org.opendaylight.yangtools.yang.data.api.CompositeNode;
 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
+import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
 import org.opendaylight.yangtools.yang.model.api.SchemaContext;
 
 public class RestPutOperationTest extends JerseyTest {
@@ -96,10 +99,10 @@ public class RestPutOperationTest extends JerseyTest {
     @Test
     public void putConfigStatusCodes() throws UnsupportedEncodingException {
         String uri = "/config/ietf-interfaces:interfaces/interface/eth0";
-        mockCommitConfigurationDataPutMethod(TransactionStatus.COMMITED);
+        mockCommitConfigurationDataPutMethod(true);
         assertEquals(200, put(uri, MediaType.APPLICATION_XML, xmlData));
 
-        mockCommitConfigurationDataPutMethod(TransactionStatus.FAILED);
+        mockCommitConfigurationDataPutMethod(false);
         assertEquals(500, put(uri, MediaType.APPLICATION_XML, xmlData));
 
         assertEquals(400, put(uri, MediaType.APPLICATION_JSON, ""));
@@ -117,18 +120,16 @@ public class RestPutOperationTest extends JerseyTest {
     public void testRpcResultCommitedToStatusCodesWithMountPoint() throws UnsupportedEncodingException,
             FileNotFoundException, URISyntaxException {
 
-        RpcResult<TransactionStatus> rpcResult = new DummyRpcResult.Builder<TransactionStatus>().result(
-                TransactionStatus.COMMITED).build();
-        Future<RpcResult<TransactionStatus>> dummyFuture = new DummyFuture.Builder<TransactionStatus>().rpcResult(
-                rpcResult).build();
+        CheckedFuture<Void, TransactionCommitFailedException> dummyFuture = mock(CheckedFuture.class);
+
         when(
-                brokerFacade.commitConfigurationDataPutBehindMountPoint(any(MountInstance.class),
-                        any(YangInstanceIdentifier.class), any(CompositeNode.class))).thenReturn(dummyFuture);
+                brokerFacade.commitConfigurationDataPut(any(DOMMountPoint.class), any(YangInstanceIdentifier.class),
+                        any(NormalizedNode.class))).thenReturn(dummyFuture);
 
-        MountInstance mountInstance = mock(MountInstance.class);
+        DOMMountPoint mountInstance = mock(DOMMountPoint.class);
         when(mountInstance.getSchemaContext()).thenReturn(schemaContextTestModule);
-        MountService mockMountService = mock(MountService.class);
-        when(mockMountService.getMountPoint(any(YangInstanceIdentifier.class))).thenReturn(mountInstance);
+        DOMMountPointService mockMountService = mock(DOMMountPointService.class);
+        when(mockMountService.getMountPoint(any(YangInstanceIdentifier.class))).thenReturn(Optional.of(mountInstance));
 
         ControllerContext.getInstance().setMountService(mockMountService);
 
@@ -141,18 +142,15 @@ public class RestPutOperationTest extends JerseyTest {
 
     @Test
     public void putDataMountPointIntoHighestElement() throws UnsupportedEncodingException, URISyntaxException {
-        RpcResult<TransactionStatus> rpcResult = new DummyRpcResult.Builder<TransactionStatus>().result(
-                TransactionStatus.COMMITED).build();
-        Future<RpcResult<TransactionStatus>> dummyFuture = new DummyFuture.Builder<TransactionStatus>().rpcResult(
-                rpcResult).build();
+        CheckedFuture<Void, TransactionCommitFailedException> dummyFuture = mock(CheckedFuture.class);
         when(
-                brokerFacade.commitConfigurationDataPutBehindMountPoint(any(MountInstance.class),
-                        any(YangInstanceIdentifier.class), any(CompositeNode.class))).thenReturn(dummyFuture);
+                brokerFacade.commitConfigurationDataPut(any(DOMMountPoint.class), any(YangInstanceIdentifier.class),
+                        any(NormalizedNode.class))).thenReturn(dummyFuture);
 
-        MountInstance mountInstance = mock(MountInstance.class);
+        DOMMountPoint mountInstance = mock(DOMMountPoint.class);
         when(mountInstance.getSchemaContext()).thenReturn(schemaContextTestModule);
-        MountService mockMountService = mock(MountService.class);
-        when(mockMountService.getMountPoint(any(YangInstanceIdentifier.class))).thenReturn(mountInstance);
+        DOMMountPointService mockMountService = mock(DOMMountPointService.class);
+        when(mockMountService.getMountPoint(any(YangInstanceIdentifier.class))).thenReturn(Optional.of(mountInstance));
 
         ControllerContext.getInstance().setMountService(mockMountService);
 
@@ -164,13 +162,14 @@ public class RestPutOperationTest extends JerseyTest {
         return target(uri).request(mediaType).put(Entity.entity(data, mediaType)).getStatus();
     }
 
-    private void mockCommitConfigurationDataPutMethod(TransactionStatus statusName) {
-        RpcResult<TransactionStatus> rpcResult = new DummyRpcResult.Builder<TransactionStatus>().result(statusName)
-                .build();
-        Future<RpcResult<TransactionStatus>> dummyFuture = new DummyFuture.Builder<TransactionStatus>().rpcResult(
-                rpcResult).build();
-        when(brokerFacade.commitConfigurationDataPut(any(YangInstanceIdentifier.class), any(CompositeNode.class)))
-                .thenReturn(dummyFuture);
+    private void mockCommitConfigurationDataPutMethod(final boolean noErrors) {
+        if (noErrors) {
+            doReturn(mock(CheckedFuture.class)).when(brokerFacade).commitConfigurationDataPut(
+                    any(YangInstanceIdentifier.class), any(NormalizedNode.class));
+        } else {
+            doThrow(RestconfDocumentedException.class).when(brokerFacade).commitConfigurationDataPut(
+                    any(YangInstanceIdentifier.class), any(NormalizedNode.class));
+        }
     }
 
 }
index 236712b45499a70df1b1e69b7c19e3d094dc561b..906695b3aab9fbad4c7b38fc2fd30db95c7d2037 100644 (file)
@@ -15,16 +15,16 @@ import static org.mockito.Mockito.spy;
 import static org.mockito.Mockito.when;
 
 import java.io.FileNotFoundException;
+import java.text.ParseException;
 import java.util.Set;
 import org.junit.Before;
 import org.junit.BeforeClass;
 import org.junit.Test;
-import org.opendaylight.controller.sal.rest.impl.XmlToCompositeNodeProvider;
 import org.opendaylight.controller.sal.restconf.impl.BrokerFacade;
 import org.opendaylight.controller.sal.restconf.impl.ControllerContext;
 import org.opendaylight.controller.sal.restconf.impl.RestconfImpl;
-import org.opendaylight.yangtools.yang.data.api.CompositeNode;
 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
+import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
 import org.opendaylight.yangtools.yang.model.api.Module;
 import org.opendaylight.yangtools.yang.model.api.SchemaContext;
 
@@ -54,12 +54,12 @@ public class RestconfImplTest {
     }
 
     @Test
-    public void testExample() throws FileNotFoundException {
-        CompositeNode loadedCompositeNode = TestUtils.readInputToCnSn("/parts/ietf-interfaces_interfaces.xml",
-                XmlToCompositeNodeProvider.INSTANCE);
+    public void testExample() throws FileNotFoundException, ParseException {
+        NormalizedNode normalizedNodeData = TestUtils.prepareNormalizedNodeWithIetfInterfacesInterfacesData();
         BrokerFacade brokerFacade = mock(BrokerFacade.class);
-        when(brokerFacade.readOperationalData(any(YangInstanceIdentifier.class))).thenReturn(loadedCompositeNode);
-        assertEquals(loadedCompositeNode, brokerFacade.readOperationalData(null));
+        when(brokerFacade.readOperationalData(any(YangInstanceIdentifier.class))).thenReturn(normalizedNodeData);
+        assertEquals(normalizedNodeData,
+                brokerFacade.readOperationalData(null));
     }
 
 }
index 67d98f6b558db0a0915928ff869d2a0f123a5b45..562cac0bcf523a74a62163116105a9fff7d47c8d 100644 (file)
@@ -14,6 +14,7 @@ import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.when;
 
 import com.google.common.base.Preconditions;
+import com.google.common.util.concurrent.CheckedFuture;
 import java.io.BufferedReader;
 import java.io.ByteArrayOutputStream;
 import java.io.File;
@@ -25,8 +26,12 @@ import java.io.OutputStreamWriter;
 import java.net.URI;
 import java.net.URISyntaxException;
 import java.sql.Date;
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
 import java.util.ArrayList;
+import java.util.HashMap;
 import java.util.List;
+import java.util.Map;
 import java.util.Set;
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
@@ -42,20 +47,37 @@ import javax.xml.transform.TransformerException;
 import javax.xml.transform.TransformerFactory;
 import javax.xml.transform.dom.DOMSource;
 import javax.xml.transform.stream.StreamResult;
-import org.opendaylight.controller.md.sal.common.api.TransactionStatus;
 import org.opendaylight.controller.sal.restconf.impl.BrokerFacade;
 import org.opendaylight.controller.sal.restconf.impl.CompositeNodeWrapper;
 import org.opendaylight.controller.sal.restconf.impl.ControllerContext;
 import org.opendaylight.controller.sal.restconf.impl.NodeWrapper;
+import org.opendaylight.controller.sal.restconf.impl.RestconfDocumentedException;
+import org.opendaylight.controller.sal.restconf.impl.RestconfError;
+import org.opendaylight.controller.sal.restconf.impl.RestconfError.ErrorTag;
+import org.opendaylight.controller.sal.restconf.impl.RestconfError.ErrorType;
 import org.opendaylight.controller.sal.restconf.impl.RestconfImpl;
 import org.opendaylight.controller.sal.restconf.impl.StructuredData;
 import org.opendaylight.yangtools.yang.common.QName;
 import org.opendaylight.yangtools.yang.data.api.CompositeNode;
+import org.opendaylight.yangtools.yang.data.api.Node;
 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
+import org.opendaylight.yangtools.yang.data.api.schema.MapEntryNode;
+import org.opendaylight.yangtools.yang.data.api.schema.MapNode;
+import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
+import org.opendaylight.yangtools.yang.data.composite.node.schema.cnsn.parser.CnSnToNormalizedNodeParserFactory;
+import org.opendaylight.yangtools.yang.data.impl.ImmutableCompositeNode;
+import org.opendaylight.yangtools.yang.data.impl.schema.builder.api.CollectionNodeBuilder;
+import org.opendaylight.yangtools.yang.data.impl.schema.builder.api.DataContainerNodeAttrBuilder;
+import org.opendaylight.yangtools.yang.data.impl.schema.builder.impl.ImmutableLeafNodeBuilder;
+import org.opendaylight.yangtools.yang.data.impl.schema.builder.impl.ImmutableMapEntryNodeBuilder;
+import org.opendaylight.yangtools.yang.data.impl.schema.builder.impl.ImmutableMapNodeBuilder;
+import org.opendaylight.yangtools.yang.data.impl.util.CompositeNodeBuilder;
+import org.opendaylight.yangtools.yang.model.api.ContainerSchemaNode;
 import org.opendaylight.yangtools.yang.model.api.DataSchemaNode;
+import org.opendaylight.yangtools.yang.model.api.ListSchemaNode;
 import org.opendaylight.yangtools.yang.model.api.Module;
 import org.opendaylight.yangtools.yang.model.api.SchemaContext;
-import org.opendaylight.yangtools.yang.model.parser.api.YangModelParser;
+import org.opendaylight.yangtools.yang.model.parser.api.YangContextParser;
 import org.opendaylight.yangtools.yang.parser.impl.YangParserImpl;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -66,7 +88,7 @@ public final class TestUtils {
 
     private static final Logger LOG = LoggerFactory.getLogger(TestUtils.class);
 
-    private final static YangModelParser parser = new YangParserImpl();
+    private final static YangContextParser parser = new YangParserImpl();
 
     private static Set<Module> loadModules(String resourceDirectory) throws FileNotFoundException {
         final File testDir = new File(resourceDirectory);
@@ -151,12 +173,12 @@ public final class TestUtils {
      * {@code dataSchemaNode}. The method {@link RestconfImpl#createConfigurationData createConfigurationData} is used
      * because it contains calling of method {code normalizeNode}
      */
-    public static void normalizeCompositeNode(CompositeNode compositeNode, Set<Module> modules, String schemaNodePath) {
+    public static void normalizeCompositeNode(Node<?> node, Set<Module> modules, String schemaNodePath) {
         RestconfImpl restconf = RestconfImpl.getInstance();
         ControllerContext.getInstance().setSchemas(TestUtils.loadSchemaContext(modules));
 
         prepareMocksForRestconf(modules, restconf);
-        restconf.updateConfigurationData(schemaNodePath, compositeNode);
+        restconf.updateConfigurationData(schemaNodePath, node);
     }
 
     /**
@@ -229,33 +251,30 @@ public final class TestUtils {
 
         controllerContext.setSchemas(TestUtils.loadSchemaContext(modules));
 
-        when(mockedBrokerFacade.commitConfigurationDataPut(any(YangInstanceIdentifier.class), any(CompositeNode.class)))
-                .thenReturn(
-                        new DummyFuture.Builder().rpcResult(
-                                new DummyRpcResult.Builder<TransactionStatus>().result(TransactionStatus.COMMITED)
-                                        .build()).build());
+        when(mockedBrokerFacade.commitConfigurationDataPut(any(YangInstanceIdentifier.class), any(NormalizedNode.class)))
+                .thenReturn(mock(CheckedFuture.class));
 
         restconf.setControllerContext(controllerContext);
         restconf.setBroker(mockedBrokerFacade);
     }
 
-    public static CompositeNode readInputToCnSn(String path, boolean dummyNamespaces,
-            MessageBodyReader<CompositeNode> reader) throws WebApplicationException {
+    public static Node<?> readInputToCnSn(String path, boolean dummyNamespaces,
+            MessageBodyReader<Node<?>> reader) throws WebApplicationException {
 
         InputStream inputStream = TestUtils.class.getResourceAsStream(path);
         try {
-            CompositeNode compositeNode = reader.readFrom(null, null, null, null, null, inputStream);
-            assertTrue(compositeNode instanceof CompositeNodeWrapper);
+            final Node<?> node = reader.readFrom(null, null, null, null, null, inputStream);
+            assertTrue(node instanceof CompositeNodeWrapper);
             if (dummyNamespaces) {
                 try {
-                    TestUtils.addDummyNamespaceToAllNodes((CompositeNodeWrapper) compositeNode);
-                    return ((CompositeNodeWrapper) compositeNode).unwrap();
+                    TestUtils.addDummyNamespaceToAllNodes((CompositeNodeWrapper) node);
+                    return ((CompositeNodeWrapper) node).unwrap();
                 } catch (URISyntaxException e) {
                     LOG.error(e.getMessage());
                     assertTrue(e.getMessage(), false);
                 }
             }
-            return compositeNode;
+            return node;
         } catch (IOException e) {
             LOG.error(e.getMessage());
             assertTrue(e.getMessage(), false);
@@ -263,21 +282,33 @@ public final class TestUtils {
         return null;
     }
 
-    public static CompositeNode readInputToCnSn(String path, MessageBodyReader<CompositeNode> reader) {
+//    public static Node<?> readInputToCnSnNew(String path, MessageBodyReader<Node<?>> reader) throws WebApplicationException {
+//        InputStream inputStream = TestUtils.class.getResourceAsStream(path);
+//        try {
+//            return reader.readFrom(null, null, null, null, null, inputStream);
+//        } catch (IOException e) {
+//            LOG.error(e.getMessage());
+//            assertTrue(e.getMessage(), false);
+//        }
+//        return null;
+//    }
+
+    public static Node<?> readInputToCnSn(String path, MessageBodyReader<Node<?>> reader) {
         return readInputToCnSn(path, false, reader);
     }
 
-    public static String writeCompNodeWithSchemaContextToOutput(CompositeNode compositeNode, Set<Module> modules,
+    public static String writeCompNodeWithSchemaContextToOutput(Node<?> node, Set<Module> modules,
             DataSchemaNode dataSchemaNode, MessageBodyWriter<StructuredData> messageBodyWriter) throws IOException,
             WebApplicationException {
 
         assertNotNull(dataSchemaNode);
-        assertNotNull("Composite node can't be null", compositeNode);
+        assertNotNull("Composite node can't be null", node);
         ByteArrayOutputStream byteArrayOS = new ByteArrayOutputStream();
 
         ControllerContext.getInstance().setSchemas(loadSchemaContext(modules));
 
-        messageBodyWriter.writeTo(new StructuredData(compositeNode, dataSchemaNode, null), null, null, null, null,
+        assertTrue(node instanceof CompositeNode);
+        messageBodyWriter.writeTo(new StructuredData((CompositeNode)node, dataSchemaNode, null), null, null, null, null,
                 null, byteArrayOS);
 
         return byteArrayOS.toString();
@@ -312,4 +343,96 @@ public final class TestUtils {
         Matcher matcher = pattern.matcher(jsonOutput);
         return matcher.matches();
     }
+
+    public static NormalizedNode compositeNodeToDatastoreNormalizedNode(final CompositeNode compositeNode,
+            final DataSchemaNode schema) {
+        List<Node<?>> lst = new ArrayList<Node<?>>();
+        lst.add(compositeNode);
+        if (schema instanceof ContainerSchemaNode) {
+            return CnSnToNormalizedNodeParserFactory.getInstance().getContainerNodeParser()
+                    .parse(lst, (ContainerSchemaNode) schema);
+        } else if (schema instanceof ListSchemaNode) {
+            return CnSnToNormalizedNodeParserFactory.getInstance().getMapNodeParser()
+                    .parse(lst, (ListSchemaNode) schema);
+        }
+
+        LOG.error("Top level isn't of type container, list, leaf schema node but " + schema.getClass().getSimpleName());
+
+        throw new RestconfDocumentedException(new RestconfError(ErrorType.APPLICATION, ErrorTag.INVALID_VALUE,
+                "It wasn't possible to translate specified data to datastore readable form."));
+    }
+
+    public static YangInstanceIdentifier.NodeIdentifier getNodeIdentifier(String localName, String namespace,
+            String revision) throws ParseException {
+        return new YangInstanceIdentifier.NodeIdentifier(QName.create(namespace, revision, localName));
+    }
+
+    public static YangInstanceIdentifier.NodeIdentifierWithPredicates getNodeIdentifierPredicate(String localName,
+            String namespace, String revision, Map<String, Object> keys) throws ParseException {
+        Map<QName, Object> predicate = new HashMap<>();
+        for (String key : keys.keySet()) {
+            predicate.put(QName.create(namespace, revision, key), keys.get(key));
+        }
+
+        return new YangInstanceIdentifier.NodeIdentifierWithPredicates(
+
+        QName.create(namespace, revision, localName), predicate);
+    }
+
+    public static YangInstanceIdentifier.NodeIdentifierWithPredicates getNodeIdentifierPredicate(String localName,
+            String namespace, String revision, String... keysAndValues) throws ParseException {
+        java.util.Date date = new SimpleDateFormat("yyyy-MM-dd").parse(revision);
+        if (keysAndValues.length % 2 != 0) {
+            new IllegalArgumentException("number of keys argument have to be divisible by 2 (map)");
+        }
+        Map<QName, Object> predicate = new HashMap<>();
+
+        int i = 0;
+        while (i < keysAndValues.length) {
+            predicate.put(QName.create(namespace, revision, keysAndValues[i++]), keysAndValues[i++]);
+        }
+
+        return new YangInstanceIdentifier.NodeIdentifierWithPredicates(QName.create(namespace, revision, localName),
+                predicate);
+    }
+
+    public static CompositeNode prepareCompositeNodeWithIetfInterfacesInterfacesData() {
+        CompositeNodeBuilder<ImmutableCompositeNode> interfaceBuilder = ImmutableCompositeNode.builder();
+        interfaceBuilder.addLeaf(buildQName("name", "dummy", "2014-07-29"), "eth0");
+        interfaceBuilder.addLeaf(buildQName("type", "dummy", "2014-07-29"), "ethernetCsmacd");
+        interfaceBuilder.addLeaf(buildQName("enabled", "dummy", "2014-07-29"), "false");
+        interfaceBuilder.addLeaf(buildQName("description", "dummy", "2014-07-29"), "some interface");
+        return interfaceBuilder.toInstance();
+    }
+
+    static NormalizedNode prepareNormalizedNodeWithIetfInterfacesInterfacesData() throws ParseException {
+        String ietfInterfacesDate = "2013-07-04";
+        CollectionNodeBuilder<MapEntryNode, MapNode> intface = ImmutableMapNodeBuilder.create();
+        String namespace = "urn:ietf:params:xml:ns:yang:ietf-interfaces";
+        intface.withNodeIdentifier(getNodeIdentifier("interface", namespace, ietfInterfacesDate));
+        DataContainerNodeAttrBuilder<YangInstanceIdentifier.NodeIdentifierWithPredicates, MapEntryNode> mapEntryNode = ImmutableMapEntryNodeBuilder.create();
+
+        Map<String, Object> predicates = new HashMap<>();
+        predicates.put("name", "eth0");
+
+        mapEntryNode.withNodeIdentifier(getNodeIdentifierPredicate("interface", namespace, ietfInterfacesDate,
+                predicates));
+        mapEntryNode
+                .withChild(new ImmutableLeafNodeBuilder<String>()
+                        .withNodeIdentifier(getNodeIdentifier("name", namespace, ietfInterfacesDate)).withValue("eth0")
+                        .build());
+        mapEntryNode.withChild(new ImmutableLeafNodeBuilder<String>()
+                .withNodeIdentifier(getNodeIdentifier("type", namespace, ietfInterfacesDate))
+                .withValue("ethernetCsmacd").build());
+        mapEntryNode.withChild(new ImmutableLeafNodeBuilder<Boolean>()
+                .withNodeIdentifier(getNodeIdentifier("enabled", namespace, ietfInterfacesDate))
+                .withValue(Boolean.FALSE).build());
+        mapEntryNode.withChild(new ImmutableLeafNodeBuilder<String>()
+                .withNodeIdentifier(getNodeIdentifier("description", namespace, ietfInterfacesDate))
+                .withValue("some interface").build());
+
+        intface.withChild(mapEntryNode.build());
+
+        return intface.build();
+    }
 }
diff --git a/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/test/URIParametersParsing.java b/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/test/URIParametersParsing.java
new file mode 100644 (file)
index 0000000..3c954f8
--- /dev/null
@@ -0,0 +1,101 @@
+/*
+ * 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.test;
+
+import static org.junit.Assert.assertNotNull;
+import static org.mockito.Matchers.eq;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+import java.io.FileNotFoundException;
+import javax.ws.rs.core.MultivaluedMap;
+import javax.ws.rs.core.UriBuilder;
+import javax.ws.rs.core.UriInfo;
+import org.junit.Before;
+import org.junit.Test;
+import org.opendaylight.controller.md.sal.common.api.data.AsyncDataBroker.DataChangeScope;
+import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
+import org.opendaylight.controller.sal.restconf.impl.BrokerFacade;
+import org.opendaylight.controller.sal.restconf.impl.ControllerContext;
+import org.opendaylight.controller.sal.restconf.impl.RestconfImpl;
+import org.opendaylight.controller.sal.streams.listeners.ListenerAdapter;
+import org.opendaylight.controller.sal.streams.listeners.Notificator;
+import org.opendaylight.yangtools.yang.common.QName;
+import org.opendaylight.yangtools.yang.data.api.CompositeNode;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.InstanceIdentifierBuilder;
+import org.opendaylight.yangtools.yang.data.impl.ImmutableCompositeNode;
+import org.opendaylight.yangtools.yang.data.impl.util.CompositeNodeBuilder;
+
+public class URIParametersParsing {
+
+    private RestconfImpl restconf;
+    private BrokerFacade mockedBrokerFacade;
+
+    @Before
+    public void init() throws FileNotFoundException {
+        restconf = RestconfImpl.getInstance();
+        mockedBrokerFacade = mock(BrokerFacade.class);
+        ControllerContext controllerContext = ControllerContext.getInstance();
+        controllerContext.setSchemas(TestUtils.loadSchemaContext("/datastore-and-scope-specification"));
+        restconf.setControllerContext(controllerContext);
+        restconf.setBroker(mockedBrokerFacade);
+    }
+
+    @Test
+    public void resolveURIParametersConcreteValues() {
+        resolveURIParameters("OPERATIONAL", "SUBTREE", LogicalDatastoreType.OPERATIONAL, DataChangeScope.SUBTREE);
+    }
+
+    @Test
+    public void resolveURIParametersDefaultValues() {
+        resolveURIParameters(null, null, LogicalDatastoreType.CONFIGURATION, DataChangeScope.BASE);
+    }
+
+    private void resolveURIParameters(final String datastore, final String scope,
+            final LogicalDatastoreType datastoreExpected, final DataChangeScope scopeExpected) {
+
+        InstanceIdentifierBuilder iiBuilder = YangInstanceIdentifier.builder();
+        iiBuilder.node(QName.create("dummyStreamName"));
+
+        final String datastoreValue = datastore == null ? "CONFIGURATION" : datastore;
+        final String scopeValue = scope == null ? "BASE" : scope + "";
+        Notificator.createListener(iiBuilder.build(), "dummyStreamName/datastore=" + datastoreValue + "/scope="
+                + scopeValue);
+
+        UriInfo mockedUriInfo = mock(UriInfo.class);
+        MultivaluedMap<String, String> mockedMultivaluedMap = mock(MultivaluedMap.class);
+        when(mockedMultivaluedMap.getFirst(eq("datastore"))).thenReturn(datastoreValue);
+        when(mockedMultivaluedMap.getFirst(eq("scope"))).thenReturn(scopeValue);
+
+        when(mockedUriInfo.getQueryParameters(eq(false))).thenReturn(mockedMultivaluedMap);
+
+         UriBuilder uriBuilder = UriBuilder.fromUri("www.whatever.com");
+         when(mockedUriInfo.getAbsolutePathBuilder()).thenReturn(uriBuilder);
+
+        restconf.invokeRpc("sal-remote:create-data-change-event-subscription", prepareRpcNode(datastore, scope),
+                mockedUriInfo);
+
+        ListenerAdapter listener = Notificator.getListenerFor("opendaylight-inventory:nodes/datastore="
+                + datastoreValue + "/scope=" + scopeValue);
+        assertNotNull(listener);
+
+    }
+
+    private CompositeNode prepareRpcNode(final String datastore, final String scope) {
+        CompositeNodeBuilder<ImmutableCompositeNode> inputBuilder = ImmutableCompositeNode.builder();
+        inputBuilder.setQName(QName.create("urn:opendaylight:params:xml:ns:yang:controller:md:sal:remote",
+                "2014-01-14", "input"));
+        inputBuilder.addLeaf(
+                QName.create("urn:opendaylight:params:xml:ns:yang:controller:md:sal:remote", "2014-01-14", "path"),
+                YangInstanceIdentifier.builder().node(QName.create("urn:opendaylight:inventory", "2013-08-19", "nodes")).build());
+        inputBuilder.addLeaf(QName.create("urn:sal:restconf:event:subscription", "2014-7-8", "datastore"), datastore);
+        inputBuilder.addLeaf(QName.create("urn:sal:restconf:event:subscription", "2014-7-8", "scope"), scope);
+        return inputBuilder.toInstance();
+    }
+}
index 655aba267fb5574a94e352fcedd3e4727c923a73..ed871bb52727895c5cdf69dd80e0caa2433cacef 100644 (file)
@@ -14,6 +14,7 @@ import static org.mockito.Matchers.any;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.when;
 
+import com.google.common.base.Optional;
 import com.google.common.collect.Iterables;
 import java.io.FileNotFoundException;
 import java.util.Set;
@@ -21,8 +22,8 @@ import org.junit.BeforeClass;
 import org.junit.Rule;
 import org.junit.Test;
 import org.junit.rules.ExpectedException;
-import org.opendaylight.controller.sal.core.api.mount.MountInstance;
-import org.opendaylight.controller.sal.core.api.mount.MountService;
+import org.opendaylight.controller.md.sal.dom.api.DOMMountPoint;
+import org.opendaylight.controller.md.sal.dom.api.DOMMountPointService;
 import org.opendaylight.controller.sal.restconf.impl.BrokerFacade;
 import org.opendaylight.controller.sal.restconf.impl.ControllerContext;
 import org.opendaylight.controller.sal.restconf.impl.InstanceIdWithSchemaNode;
@@ -153,7 +154,7 @@ public class URITest {
     }
 
     public void initMountService(final boolean withSchema) {
-        MountService mountService = mock(MountService.class);
+        DOMMountPointService mountService = mock(DOMMountPointService.class);
         controllerContext.setMountService(mountService);
         BrokerFacade brokerFacade = mock(BrokerFacade.class);
         RestconfImpl restconfImpl = RestconfImpl.getInstance();
@@ -162,12 +163,12 @@ public class URITest {
 
         Set<Module> modules2 = TestUtils.loadModulesFrom("/test-config-data/yang2");
         SchemaContext schemaContext2 = TestUtils.loadSchemaContext(modules2);
-        MountInstance mountInstance = mock(MountInstance.class);
+        DOMMountPoint mountInstance = mock(DOMMountPoint.class);
         if (withSchema) {
             when(mountInstance.getSchemaContext()).thenReturn(schemaContext2);
         } else {
             when(mountInstance.getSchemaContext()).thenReturn(null);
         }
-        when(mountService.getMountPoint(any(YangInstanceIdentifier.class))).thenReturn(mountInstance);
+        when(mountService.getMountPoint(any(YangInstanceIdentifier.class))).thenReturn(Optional.of(mountInstance));
     }
 }
index f4e869f99f49ebf42e482ca0c67f88dff0a6c285..23e868c8b2d738e040081603234a86038146f593 100644 (file)
@@ -26,6 +26,7 @@ import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifierWithPredicates;
 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeWithValue;
 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.PathArgument;
+import org.opendaylight.yangtools.yang.data.api.Node;
 import org.opendaylight.yangtools.yang.data.api.SimpleNode;
 
 public class XmlAndJsonToCnSnInstanceIdentifierTest extends YangAndXmlAndDataSchemaLoader {
@@ -37,32 +38,44 @@ public class XmlAndJsonToCnSnInstanceIdentifierTest extends YangAndXmlAndDataSch
 
     @Test
     public void loadXmlToCnSn() throws WebApplicationException, IOException, URISyntaxException {
-        CompositeNode cnSn = TestUtils.readInputToCnSn("/instanceidentifier/xml/xmldata.xml",
+        Node<?> node = TestUtils.readInputToCnSn("/instanceidentifier/xml/xmldata.xml",
                 XmlToCompositeNodeProvider.INSTANCE);
+
+        assertTrue(node instanceof CompositeNode);
+        CompositeNode cnSn = (CompositeNode)node;
         TestUtils.normalizeCompositeNode(cnSn, modules, schemaNodePath);
         verifyListPredicate(cnSn);
     }
 
     @Test
     public void loadXmlLeafListToCnSn() throws WebApplicationException, IOException, URISyntaxException {
-        CompositeNode cnSn = TestUtils.readInputToCnSn("/instanceidentifier/xml/xmldata_leaf_list.xml",
+        Node<?> node = TestUtils.readInputToCnSn("/instanceidentifier/xml/xmldata_leaf_list.xml",
                 XmlToCompositeNodeProvider.INSTANCE);
+
+        assertTrue(node instanceof CompositeNode);
+        CompositeNode cnSn = (CompositeNode)node;
         TestUtils.normalizeCompositeNode(cnSn, modules, schemaNodePath);
         verifyLeafListPredicate(cnSn);
     }
 
     @Test
     public void loadJsonToCnSn() throws WebApplicationException, IOException, URISyntaxException {
-        CompositeNode cnSn = TestUtils.readInputToCnSn("/instanceidentifier/json/jsondata.json",
+        Node<?> node = TestUtils.readInputToCnSn("/instanceidentifier/json/jsondata.json",
                 JsonToCompositeNodeProvider.INSTANCE);
+
+        assertTrue(node instanceof CompositeNode);
+        CompositeNode cnSn = (CompositeNode)node;
         TestUtils.normalizeCompositeNode(cnSn, modules, schemaNodePath);
         verifyListPredicate(cnSn);
     }
 
     @Test
     public void loadJsonLeafListToCnSn() throws WebApplicationException, IOException, URISyntaxException {
-        CompositeNode cnSn = TestUtils.readInputToCnSn("/instanceidentifier/json/jsondata_leaf_list.json",
+        Node<?> node = TestUtils.readInputToCnSn("/instanceidentifier/json/jsondata_leaf_list.json",
                 JsonToCompositeNodeProvider.INSTANCE);
+        assertTrue(node instanceof CompositeNode);
+        CompositeNode cnSn = (CompositeNode)node;
+
         TestUtils.normalizeCompositeNode(cnSn, modules, schemaNodePath);
         verifyLeafListPredicate(cnSn);
     }
index 483d90da0d220fc1054929d01008afabb5871175..1c8e53e69ff5091d9a9013947d09cb6381d5723a 100644 (file)
@@ -8,6 +8,7 @@
 package org.opendaylight.controller.sal.restconf.impl.test;
 
 import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
 
 import java.io.IOException;
 import java.net.URISyntaxException;
@@ -29,15 +30,22 @@ public class XmlAndJsonToCnSnLeafRefTest extends YangAndXmlAndDataSchemaLoader {
 
     @Test
     public void loadXmlToCnSn() throws WebApplicationException, IOException, URISyntaxException {
-        CompositeNode cnSn = TestUtils.readInputToCnSn("/leafref/xml/xmldata.xml", XmlToCompositeNodeProvider.INSTANCE);
+        Node<?> node = TestUtils.readInputToCnSn("/leafref/xml/xmldata.xml", XmlToCompositeNodeProvider.INSTANCE);
+
+        assertTrue(node instanceof CompositeNode);
+        CompositeNode cnSn = (CompositeNode)node;
+
         TestUtils.normalizeCompositeNode(cnSn, modules, schemaNodePath);
         verifyContPredicate(cnSn, "/ns:cont/ns:lf1", "/cont/lf1", "/ns:cont/ns:lf1", "../lf1");
     }
 
     @Test
     public void loadJsonToCnSn() throws WebApplicationException, IOException, URISyntaxException {
-        CompositeNode cnSn = TestUtils.readInputToCnSn("/leafref/json/jsondata.json",
+        Node<?> node = TestUtils.readInputToCnSn("/leafref/json/jsondata.json",
                 JsonToCompositeNodeProvider.INSTANCE);
+        assertTrue(node instanceof CompositeNode);
+        CompositeNode cnSn = (CompositeNode)node;
+
         TestUtils.normalizeCompositeNode(cnSn, modules, schemaNodePath);
         verifyContPredicate(cnSn, "/leafref-module:cont/leafref-module:lf1", "/leafref-module:cont/leafref-module:lf1",
                 "/referenced-module:cont/referenced-module:lf1", "/leafref-module:cont/leafref-module:lf1");
index 70f0f050dc9fdea84f186537eafbcad6779d7e53..121a3865bd01343533924435aa981f865586e53e 100644 (file)
@@ -32,6 +32,9 @@ import org.opendaylight.controller.sal.restconf.impl.ControllerContext;
 import org.opendaylight.controller.sal.restconf.impl.RestconfImpl;
 import org.opendaylight.controller.sal.restconf.impl.test.TestUtils;
 import org.opendaylight.yangtools.yang.model.api.SchemaContext;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
 
 public class RestStream extends JerseyTest {
 
@@ -68,17 +71,20 @@ public class RestStream extends JerseyTest {
     public void testCallRpcCallGet() throws UnsupportedEncodingException, InterruptedException {
         String uri = "/operations/sal-remote:create-data-change-event-subscription";
         Response responseWithStreamName = post(uri, MediaType.APPLICATION_XML, getRpcInput());
-        String xmlResponse = responseWithStreamName.readEntity(String.class);
+        Document xmlResponse = responseWithStreamName.readEntity(Document.class);
         assertNotNull(xmlResponse);
-        assertTrue(xmlResponse
-                .contains("<stream-name>ietf-interfaces:interfaces/ietf-interfaces:interface/eth0</stream-name>"));
+        Element outputElement = xmlResponse.getDocumentElement();
+        assertEquals("output",outputElement.getLocalName());
 
-        uri = "/streams/stream/ietf-interfaces:interfaces/ietf-interfaces:interface/eth0";
+        Node streamNameElement = outputElement.getFirstChild();
+        assertEquals("stream-name",streamNameElement.getLocalName());
+        assertEquals("ietf-interfaces:interfaces/ietf-interfaces:interface/eth0/datastore=CONFIGURATION/scope=BASE",streamNameElement.getTextContent());
+
+        uri = "/streams/stream/ietf-interfaces:interfaces/ietf-interfaces:interface/eth0/datastore=CONFIGURATION/scope=BASE";
         Response responseWithRedirectionUri = get(uri, MediaType.APPLICATION_XML);
         final URI websocketServerUri = responseWithRedirectionUri.getLocation();
         assertNotNull(websocketServerUri);
-        assertEquals(websocketServerUri.toString(),
-                "http://localhost:8181/ietf-interfaces:interfaces/ietf-interfaces:interface/eth0");
+        assertTrue(websocketServerUri.toString().matches(".*http://localhost:[\\d]+/ietf-interfaces:interfaces/ietf-interfaces:interface/eth0.*"));
     }
 
     private Response post(String uri, String mediaType, String data) {
index 5a5a621d930b68fc240140f76b086a0d57bc0a3c..e992e1214e9b44af05bf76bc0091afc623d11613 100644 (file)
@@ -8,12 +8,14 @@
 package org.opendaylight.controller.sal.restconf.impl.xml.to.cnsn.test;
 
 import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
 
 import java.util.Set;
 import org.junit.Test;
 import org.opendaylight.controller.sal.rest.impl.XmlToCompositeNodeProvider;
 import org.opendaylight.controller.sal.restconf.impl.test.TestUtils;
 import org.opendaylight.yangtools.yang.data.api.CompositeNode;
+import org.opendaylight.yangtools.yang.data.api.Node;
 import org.opendaylight.yangtools.yang.model.api.Module;
 
 public class XmlAugmentedElementToCnSnTest {
@@ -25,12 +27,15 @@ public class XmlAugmentedElementToCnSnTest {
     }
 
     private void loadAndNormalizeData(String xmlPath, String yangPath, String topLevelElementName, String moduleName) {
-        CompositeNode compNode = TestUtils.readInputToCnSn(xmlPath, false, XmlToCompositeNodeProvider.INSTANCE);
-        assertNotNull(compNode);
+        Node<?> node = TestUtils.readInputToCnSn(xmlPath, false,
+                XmlToCompositeNodeProvider.INSTANCE);
+        assertTrue(node instanceof CompositeNode);
+        CompositeNode cnSn = (CompositeNode)node;
+
         Set<Module> modules = TestUtils.loadModulesFrom(yangPath);
 
         assertNotNull(modules);
-        TestUtils.normalizeCompositeNode(compNode, modules, topLevelElementName + ":" + moduleName);
+        TestUtils.normalizeCompositeNode(cnSn, modules, topLevelElementName + ":" + moduleName);
     }
 
 }
index 6c11bc1861995879818ce31b3d6d75696c2decf7..1c62b7fbdb8e9013a38cd124d1df4e1c481bf3e5 100644 (file)
@@ -33,8 +33,11 @@ public class XmlLeafrefToCnSnTest {
      */
     @Test
     public void testXmlDataContainer() {
-        CompositeNode compNode = TestUtils.readInputToCnSn("/xml-to-cnsn/data-container.xml", false,
+        Node<?> node = TestUtils.readInputToCnSn("/xml-to-cnsn/data-container.xml", false,
                 XmlToCompositeNodeProvider.INSTANCE);
+        assertTrue(node instanceof CompositeNode);
+        CompositeNode compNode = (CompositeNode)node;
+
         assertNotNull(compNode);
         Set<Module> modules = TestUtils.loadModulesFrom("/xml-to-cnsn/data-container-yang");
 
@@ -76,9 +79,11 @@ public class XmlLeafrefToCnSnTest {
 
     @Test
     public void testXmlDataList() {
-        CompositeNode compNode = TestUtils.readInputToCnSn("/xml-to-cnsn/data-list.xml", false,
+        Node<?> node = TestUtils.readInputToCnSn("/xml-to-cnsn/data-list.xml", false,
                 XmlToCompositeNodeProvider.INSTANCE);
-        assertNotNull(compNode);
+        assertTrue(node instanceof CompositeNode);
+        CompositeNode compNode = (CompositeNode)node;
+
 
         Set<Module> modules = TestUtils.loadModulesFrom("/xml-to-cnsn/data-list-yang");
         assertNotNull(modules);
@@ -93,22 +98,22 @@ public class XmlLeafrefToCnSnTest {
         CompositeNode lst1_1 = null;
         CompositeNode lst1_2 = null;
         int loopCount = 0;
-        for (Node<?> node : compNode.getValue()) {
-            if (node.getNodeType().getLocalName().equals("lf1")) {
-                assertEquals(nameSpaceList, node.getNodeType().getNamespace().toString());
-                assertTrue(node instanceof SimpleNode<?>);
-                assertEquals("lf1", node.getValue());
+        for (Node<?> nd : compNode.getValue()) {
+            if (nd.getNodeType().getLocalName().equals("lf1")) {
+                assertEquals(nameSpaceList, nd.getNodeType().getNamespace().toString());
+                assertTrue(nd instanceof SimpleNode<?>);
+                assertEquals("lf1", nd.getValue());
             } else {
-                assertTrue(node instanceof CompositeNode);
+                assertTrue(nd instanceof CompositeNode);
                 switch (loopCount++) {
                 case 0:
-                    lst1_1 = (CompositeNode) node;
+                    lst1_1 = (CompositeNode) nd;
                     break;
                 case 1:
-                    lst1_2 = (CompositeNode) node;
+                    lst1_2 = (CompositeNode) nd;
                     break;
                 }
-                assertEquals(nameSpaceCont, node.getNodeType().getNamespace().toString());
+                assertEquals(nameSpaceCont, nd.getNodeType().getNamespace().toString());
             }
         }
         // lst1_1
@@ -118,15 +123,15 @@ public class XmlLeafrefToCnSnTest {
         // lst1_2
         SimpleNode<?> lflst11 = null;
         CompositeNode cont11 = null;
-        for (Node<?> node : lst1_2.getValue()) {
-            String nodeName = node.getNodeType().getLocalName();
+        for (Node<?> nd : lst1_2.getValue()) {
+            String nodeName = nd.getNodeType().getLocalName();
             if (nodeName.equals("lflst11")) {
-                assertTrue(node instanceof SimpleNode<?>);
-                lflst11 = (SimpleNode<?>) node;
+                assertTrue(nd instanceof SimpleNode<?>);
+                lflst11 = (SimpleNode<?>) nd;
 
             } else if (nodeName.equals("cont11")) {
-                assertTrue(node instanceof CompositeNode);
-                cont11 = (CompositeNode) node;
+                assertTrue(nd instanceof CompositeNode);
+                cont11 = (CompositeNode) nd;
             }
             assertEquals(nameSpaceCont, compNode.getNodeType().getNamespace().toString());
         }
@@ -144,32 +149,35 @@ public class XmlLeafrefToCnSnTest {
 
     @Test
     public void testXmlEmptyData() {
-        CompositeNode compNode = TestUtils.readInputToCnSn("/xml-to-cnsn/empty-data.xml", true,
+        Node<?> node = TestUtils.readInputToCnSn("/xml-to-cnsn/empty-data.xml", true,
                 XmlToCompositeNodeProvider.INSTANCE);
+        assertTrue(node instanceof CompositeNode);
+        CompositeNode compNode = (CompositeNode)node;
+
         assertEquals("cont", compNode.getNodeType().getLocalName());
         SimpleNode<?> lf1 = null;
         SimpleNode<?> lflst1_1 = null;
         SimpleNode<?> lflst1_2 = null;
         CompositeNode lst1 = null;
         int lflst1Count = 0;
-        for (Node<?> node : compNode.getValue()) {
-            if (node.getNodeType().getLocalName().equals("lf1")) {
-                assertTrue(node instanceof SimpleNode<?>);
-                lf1 = (SimpleNode<?>) node;
-            } else if (node.getNodeType().getLocalName().equals("lflst1")) {
-                assertTrue(node instanceof SimpleNode<?>);
+        for (Node<?> nd : compNode.getValue()) {
+            if (nd.getNodeType().getLocalName().equals("lf1")) {
+                assertTrue(nd instanceof SimpleNode<?>);
+                lf1 = (SimpleNode<?>) nd;
+            } else if (nd.getNodeType().getLocalName().equals("lflst1")) {
+                assertTrue(nd instanceof SimpleNode<?>);
 
                 switch (lflst1Count++) {
                 case 0:
-                    lflst1_1 = (SimpleNode<?>) node;
+                    lflst1_1 = (SimpleNode<?>) nd;
                     break;
                 case 1:
-                    lflst1_2 = (SimpleNode<?>) node;
+                    lflst1_2 = (SimpleNode<?>) nd;
                     break;
                 }
-            } else if (node.getNodeType().getLocalName().equals("lst1")) {
-                assertTrue(node instanceof CompositeNode);
-                lst1 = (CompositeNode) node;
+            } else if (nd.getNodeType().getLocalName().equals("lst1")) {
+                assertTrue(nd instanceof CompositeNode);
+                lst1 = (CompositeNode) nd;
             }
         }
 
@@ -317,8 +325,10 @@ public class XmlLeafrefToCnSnTest {
 
     private void testIdentityrefToCnSn(final String xmlPath, final String yangPath, final String moduleName,
             final String schemaName, final int moduleCount, final String resultLocalName, final String resultNamespace) {
-        CompositeNode compositeNode = TestUtils.readInputToCnSn(xmlPath, false, XmlToCompositeNodeProvider.INSTANCE);
-        assertNotNull(compositeNode);
+        Node<?> node = TestUtils.readInputToCnSn(xmlPath, false, XmlToCompositeNodeProvider.INSTANCE);
+        assertTrue(node instanceof CompositeNode);
+        CompositeNode compositeNode = (CompositeNode)node;
+
 
         Set<Module> modules = TestUtils.loadModulesFrom(yangPath);
         assertEquals(moduleCount, modules.size());
index e2621d635bc3dab04629beffcb15c3d111b9eb21..d0af29e913fa633381c176ff1796a2fbd3f41c29 100644 (file)
@@ -32,9 +32,12 @@ public class XmlToCnSnTest extends YangAndXmlAndDataSchemaLoader {
 
     @Test
     public void testXmlLeafrefToCnSn() {
-        CompositeNode compositeNode = TestUtils.readInputToCnSn("/xml-to-cnsn/leafref/xml/data.xml", false,
+        Node<?> node = TestUtils.readInputToCnSn("/xml-to-cnsn/leafref/xml/data.xml", false,
                 XmlToCompositeNodeProvider.INSTANCE);
-        assertNotNull(compositeNode);
+        assertTrue(node instanceof CompositeNode);
+        CompositeNode compositeNode = (CompositeNode)node;
+
+
         assertNotNull(dataSchemaNode);
         TestUtils.normalizeCompositeNode(compositeNode, modules, schemaNodePath);
 
@@ -58,10 +61,10 @@ public class XmlToCnSnTest extends YangAndXmlAndDataSchemaLoader {
     @Test
     public void testXmlBlankInput() throws Exception {
         InputStream inputStream = new ByteArrayInputStream("".getBytes());
-        CompositeNode compositeNode = XmlToCompositeNodeProvider.INSTANCE.readFrom(null, null, null, null, null,
-                inputStream);
+        Node<?> node =
+                XmlToCompositeNodeProvider.INSTANCE.readFrom(null, null, null, null, null, inputStream);
 
-        assertNull(compositeNode);
+        assertNull( node );
     }
 
     @Test
@@ -72,10 +75,10 @@ public class XmlToCnSnTest extends YangAndXmlAndDataSchemaLoader {
                 return false;
             }
         };
-        CompositeNode compositeNode = XmlToCompositeNodeProvider.INSTANCE.readFrom(null, null, null, null, null,
-                inputStream);
+        Node<?> node =
+                XmlToCompositeNodeProvider.INSTANCE.readFrom(null, null, null, null, null, inputStream);
 
-        assertNull(compositeNode);
+        assertNull( node );
     }
 
 }
diff --git a/opendaylight/md-sal/sal-rest-connector/src/test/resources/datastore-and-scope-specification/opendaylight-inventory.yang b/opendaylight/md-sal/sal-rest-connector/src/test/resources/datastore-and-scope-specification/opendaylight-inventory.yang
new file mode 100644 (file)
index 0000000..e4247be
--- /dev/null
@@ -0,0 +1,19 @@
+module opendaylight-inventory {
+    namespace "urn:opendaylight:inventory";
+    prefix inv;
+
+    revision "2013-08-19" {
+        description "Initial revision of Inventory model";
+    }
+    
+    
+    container nodes {
+        list node {
+            key "id";
+            leaf id {
+                type string;
+            }
+        }
+    }
+
+}
diff --git a/opendaylight/md-sal/sal-rest-connector/src/test/resources/datastore-and-scope-specification/sal-remote-augment.yang b/opendaylight/md-sal/sal-rest-connector/src/test/resources/datastore-and-scope-specification/sal-remote-augment.yang
new file mode 100644 (file)
index 0000000..8393456
--- /dev/null
@@ -0,0 +1,31 @@
+module sal-remote-augment {
+
+    yang-version 1;
+    namespace "urn:sal:restconf:event:subscription";
+    prefix "salrmt-aug-ev-subscr";
+
+    import sal-remote {prefix salrmt; revision-date "2014-01-14";}
+
+    description
+        "Added input parameters to rpc create-data-change-event-subscription";
+
+    revision "2014-7-8" {
+    }
+
+    augment "/salrmt:create-data-change-event-subscription/salrmt:input" {
+        leaf datastore {
+            type enumeration {
+                enum OPERATIONAL;
+                enum CONFIGURATION;
+            }
+        }
+        leaf scope {
+            type enumeration {
+                enum BASE;
+                enum ONE;
+                enum SUBTREE;
+            }
+        }
+    }
+
+}
\ No newline at end of file
diff --git a/opendaylight/md-sal/sal-rest-connector/src/test/resources/datastore-and-scope-specification/sal-remote@2014-01-14.yang b/opendaylight/md-sal/sal-rest-connector/src/test/resources/datastore-and-scope-specification/sal-remote@2014-01-14.yang
new file mode 100644 (file)
index 0000000..d12e252
--- /dev/null
@@ -0,0 +1,98 @@
+module sal-remote {
+
+       yang-version 1;
+    namespace "urn:opendaylight:params:xml:ns:yang:controller:md:sal:remote";
+    prefix "sal-remote";
+    
+
+    organization "Cisco Systems, Inc.";
+    contact "Martin Bobak <mbobak@cisco.com>";
+
+    description
+          "This module contains the definition of methods related to
+           sal remote model.
+
+           Copyright (c)2013 Cisco Systems, Inc. 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";
+
+    revision "2014-01-14" {
+        description
+            "Initial revision";
+    }
+
+
+     typedef q-name {
+       type string;
+       reference
+         "http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/#QName";
+     }
+
+    rpc create-data-change-event-subscription {
+        input {
+            leaf path {
+                type instance-identifier;
+                description "Subtree path. ";
+            }
+         }
+         output {
+            leaf stream-name {
+                type string;
+                description "Notification stream name.";
+            }
+         }
+    }
+
+    notification data-changed-notification {
+        description "Data change notification.";
+        list data-change-event {
+            key path;
+            leaf path {
+                type instance-identifier;
+            }
+            leaf store {
+                type enumeration {
+                    enum config;
+                    enum operation;
+                }
+            }
+            leaf operation {
+                type enumeration {
+                    enum created;
+                    enum updated;
+                    enum deleted;
+                }
+            }
+            anyxml data{
+                description "DataObject ";
+            }
+         }
+    }
+
+    rpc create-notification-stream {
+        input {
+            leaf-list notifications {
+                type q-name;
+                description "Notification QNames";
+            }
+         }
+        output {
+            leaf notification-stream-identifier {
+                type string;
+                description "Unique notification stream identifier, in which notifications will be propagated";
+            }
+        }
+    }
+
+    rpc begin-transaction{
+        output{
+            anyxml data-modification-transaction{
+                description "DataModificationTransaction xml";
+            }
+        }
+    }
+
+}
\ No newline at end of file