Bug 4883 - implement query parameter - filter
[netconf.git] / restconf / sal-rest-connector / src / main / java / org / opendaylight / restconf / restful / services / impl / RestconfDataServiceImpl.java
index a6187f5fa39f022513afaddf85a232315791db74..b15a00aa8683d5a5b1c8a57dff0bef4377b45ff0 100644 (file)
@@ -9,17 +9,25 @@ package org.opendaylight.restconf.restful.services.impl;
 
 import com.google.common.base.Optional;
 import com.google.common.base.Preconditions;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+import java.util.TimeZone;
+import javax.annotation.Nonnull;
 import javax.ws.rs.core.Response;
 import javax.ws.rs.core.UriInfo;
 import org.opendaylight.controller.md.sal.dom.api.DOMDataBroker;
-import org.opendaylight.controller.md.sal.dom.api.DOMDataReadWriteTransaction;
 import org.opendaylight.controller.md.sal.dom.api.DOMMountPoint;
+import org.opendaylight.controller.md.sal.dom.api.DOMTransactionChain;
 import org.opendaylight.netconf.sal.restconf.impl.InstanceIdentifierContext;
 import org.opendaylight.netconf.sal.restconf.impl.NormalizedNodeContext;
 import org.opendaylight.netconf.sal.restconf.impl.PATCHContext;
 import org.opendaylight.netconf.sal.restconf.impl.PATCHStatusContext;
 import org.opendaylight.netconf.sal.restconf.impl.RestconfDocumentedException;
+import org.opendaylight.netconf.sal.restconf.impl.RestconfError;
+import org.opendaylight.netconf.sal.restconf.impl.WriterParameters;
+import org.opendaylight.restconf.RestConnectorProvider;
 import org.opendaylight.restconf.common.references.SchemaContextRef;
+import org.opendaylight.restconf.handlers.DOMMountPointServiceHandler;
 import org.opendaylight.restconf.handlers.SchemaContextHandler;
 import org.opendaylight.restconf.handlers.TransactionChainHandler;
 import org.opendaylight.restconf.restful.services.api.RestconfDataService;
@@ -45,38 +53,71 @@ public class RestconfDataServiceImpl implements RestconfDataService {
 
     private final SchemaContextHandler schemaContextHandler;
     private final TransactionChainHandler transactionChainHandler;
+    private final DOMMountPointServiceHandler mountPointServiceHandler;
 
     public RestconfDataServiceImpl(final SchemaContextHandler schemaContextHandler,
-            final TransactionChainHandler transactionChainHandler) {
+                                   final TransactionChainHandler transactionChainHandler,
+                                   final DOMMountPointServiceHandler mountPointServiceHandler) {
         this.schemaContextHandler = schemaContextHandler;
         this.transactionChainHandler = transactionChainHandler;
+        this.mountPointServiceHandler = mountPointServiceHandler;
     }
 
     @Override
-    public NormalizedNodeContext readData(final String identifier, final UriInfo uriInfo) {
-        Preconditions.checkNotNull(identifier);
+    public Response readData(final UriInfo uriInfo) {
+        return readData(null, uriInfo);
+    }
+
+    @Override
+    public Response readData(final String identifier, final UriInfo uriInfo) {
         final SchemaContextRef schemaContextRef = new SchemaContextRef(this.schemaContextHandler.get());
+        final InstanceIdentifierContext<?> instanceIdentifier = ParserIdentifier.toInstanceIdentifier(
+                identifier, schemaContextRef.get(), Optional.of(this.mountPointServiceHandler.get()));
 
-        final InstanceIdentifierContext<?> instanceIdentifier = ParserIdentifier.toInstanceIdentifier(identifier, schemaContextRef.get());
-        final DOMMountPoint mountPoint = instanceIdentifier.getMountPoint();
-        final String value = uriInfo.getQueryParameters().getFirst(RestconfDataServiceConstant.CONTENT);
+        final WriterParameters parameters = ReadDataTransactionUtil.parseUriParameters(
+                instanceIdentifier, uriInfo);
 
-        DOMDataReadWriteTransaction transaction = null;
+        final DOMMountPoint mountPoint = instanceIdentifier.getMountPoint();
+        final DOMTransactionChain transactionChain;
         if (mountPoint == null) {
-            transaction = this.transactionChainHandler.get().newReadWriteTransaction();
+            transactionChain = this.transactionChainHandler.get();
         } else {
-            transaction = transactionOfMountPoint(mountPoint);
+            transactionChain = transactionChainOfMountPoint(mountPoint);
         }
-        final TransactionVarsWrapper transactionNode = new TransactionVarsWrapper(instanceIdentifier, mountPoint,
-                transaction);
-        final NormalizedNode<?, ?> node = ReadDataTransactionUtil.readData(value, transactionNode);
 
-        return new NormalizedNodeContext(instanceIdentifier, node);
+        final TransactionVarsWrapper transactionNode = new TransactionVarsWrapper(
+                instanceIdentifier, mountPoint, transactionChain);
+        final NormalizedNode<?, ?> node = ReadDataTransactionUtil.readData(parameters.getContent(), transactionNode);
+        if (node == null) {
+            throw new RestconfDocumentedException(
+                    "Request could not be completed because the relevant data model content does not exist",
+                    RestconfError.ErrorType.PROTOCOL,
+                    RestconfError.ErrorTag.DATA_MISSING);
+        }
+        final SimpleDateFormat dateFormatGmt = new SimpleDateFormat("yyyy-MMM-dd HH:mm:ss");
+        dateFormatGmt.setTimeZone(TimeZone.getTimeZone("GMT"));
+        final String etag = '"' + node.getNodeType().getModule().getFormattedRevision()
+                + node.getNodeType().getLocalName() + '"';
+        final Response resp;
+
+        if ((parameters.getContent().equals(RestconfDataServiceConstant.ReadData.ALL))
+                    || parameters.getContent().equals(RestconfDataServiceConstant.ReadData.CONFIG)) {
+            resp = Response.status(200)
+                    .entity(new NormalizedNodeContext(instanceIdentifier, node, parameters))
+                    .header("ETag", etag)
+                    .header("Last-Modified", dateFormatGmt.format(new Date()))
+                    .build();
+        } else {
+            resp = Response.status(200)
+                    .entity(new NormalizedNodeContext(instanceIdentifier, node, parameters))
+                    .build();
+        }
+
+        return resp;
     }
 
     @Override
     public Response putData(final String identifier, final NormalizedNodeContext payload) {
-        Preconditions.checkNotNull(identifier);
         Preconditions.checkNotNull(payload);
 
         final InstanceIdentifierContext<? extends SchemaNode> iid = payload
@@ -87,18 +128,18 @@ public class RestconfDataServiceImpl implements RestconfDataService {
         PutDataTransactionUtil.validateListKeysEqualityInPayloadAndUri(payload);
 
         final DOMMountPoint mountPoint = payload.getInstanceIdentifierContext().getMountPoint();
-        DOMDataReadWriteTransaction transaction = null;
-        SchemaContextRef ref = null;
+        final DOMTransactionChain transactionChain;
+        final SchemaContextRef ref;
         if (mountPoint == null) {
-            transaction = this.transactionChainHandler.get().newReadWriteTransaction();
+            transactionChain = this.transactionChainHandler.get();
             ref = new SchemaContextRef(this.schemaContextHandler.get());
         } else {
-            transaction = transactionOfMountPoint(mountPoint);
+            transactionChain = transactionChainOfMountPoint(mountPoint);
             ref = new SchemaContextRef(mountPoint.getSchemaContext());
         }
 
         final TransactionVarsWrapper transactionNode = new TransactionVarsWrapper(
-                payload.getInstanceIdentifierContext(), mountPoint, transaction);
+                payload.getInstanceIdentifierContext(), mountPoint, transactionChain);
         return PutDataTransactionUtil.putData(payload, ref, transactionNode);
     }
 
@@ -112,42 +153,41 @@ public class RestconfDataServiceImpl implements RestconfDataService {
         Preconditions.checkNotNull(payload);
 
         final DOMMountPoint mountPoint = payload.getInstanceIdentifierContext().getMountPoint();
-        DOMDataReadWriteTransaction transaction = null;
-        SchemaContextRef ref = null;
+        final DOMTransactionChain transactionChain;
+        final SchemaContextRef ref;
         if (mountPoint == null) {
-            transaction = this.transactionChainHandler.get().newReadWriteTransaction();
+            transactionChain = this.transactionChainHandler.get();
             ref = new SchemaContextRef(this.schemaContextHandler.get());
         } else {
-            transaction = transactionOfMountPoint(mountPoint);
+            transactionChain = transactionChainOfMountPoint(mountPoint);
             ref = new SchemaContextRef(mountPoint.getSchemaContext());
         }
         final TransactionVarsWrapper transactionNode = new TransactionVarsWrapper(
-                payload.getInstanceIdentifierContext(), mountPoint, transaction);
+                payload.getInstanceIdentifierContext(), mountPoint, transactionChain);
         return PostDataTransactionUtil.postData(uriInfo, payload, transactionNode, ref);
     }
 
     @Override
     public Response deleteData(final String identifier) {
         final SchemaContextRef schemaContextRef = new SchemaContextRef(this.schemaContextHandler.get());
-        final InstanceIdentifierContext<?> instanceIdentifier = ParserIdentifier.toInstanceIdentifier(identifier,
-                schemaContextRef.get());
+        final InstanceIdentifierContext<?> instanceIdentifier = ParserIdentifier.toInstanceIdentifier(
+                identifier, schemaContextRef.get(), Optional.of(this.mountPointServiceHandler.get()));
 
         final DOMMountPoint mountPoint = instanceIdentifier.getMountPoint();
-        final DOMDataReadWriteTransaction transaction;
+        final DOMTransactionChain transactionChain;
         if (mountPoint == null) {
-            transaction = this.transactionChainHandler.get().newReadWriteTransaction();
+            transactionChain = this.transactionChainHandler.get();
         } else {
-            transaction = transactionOfMountPoint(mountPoint);
+            transactionChain = transactionChainOfMountPoint(mountPoint);
         }
 
         final TransactionVarsWrapper transactionNode = new TransactionVarsWrapper(instanceIdentifier, mountPoint,
-                transaction);
+                transactionChain);
         return DeleteDataTransactionUtil.deleteData(transactionNode);
     }
 
     @Override
     public PATCHStatusContext patchData(final String identifier, final PATCHContext context, final UriInfo uriInfo) {
-        Preconditions.checkNotNull(identifier);
         return patchData(context, uriInfo);
     }
 
@@ -156,32 +196,32 @@ public class RestconfDataServiceImpl implements RestconfDataService {
         Preconditions.checkNotNull(context);
         final DOMMountPoint mountPoint = context.getInstanceIdentifierContext().getMountPoint();
 
-        final DOMDataReadWriteTransaction transaction;
+        final DOMTransactionChain transactionChain;
         final SchemaContextRef ref;
         if (mountPoint == null) {
-            transaction = this.transactionChainHandler.get().newReadWriteTransaction();
+            transactionChain = this.transactionChainHandler.get();
             ref = new SchemaContextRef(this.schemaContextHandler.get());
         } else {
-            transaction = transactionOfMountPoint(mountPoint);
+            transactionChain = transactionChainOfMountPoint(mountPoint);
             ref = new SchemaContextRef(mountPoint.getSchemaContext());
         }
 
         final TransactionVarsWrapper transactionNode = new TransactionVarsWrapper(
-                context.getInstanceIdentifierContext(), mountPoint, transaction);
+                context.getInstanceIdentifierContext(), mountPoint, transactionChain);
 
         return PatchDataTransactionUtil.patchData(context, transactionNode, ref);
     }
 
     /**
-     * Prepare transaction to read data of mount point, if these data are
-     * present.
+     * Prepare transaction chain to access data of mount point
      * @param mountPoint
-     * @return {@link DOMDataReadWriteTransaction}
+     *            - mount point reference
+     * @return {@link DOMTransactionChain}
      */
-    private static DOMDataReadWriteTransaction transactionOfMountPoint(final DOMMountPoint mountPoint) {
+    private static DOMTransactionChain transactionChainOfMountPoint(@Nonnull final DOMMountPoint mountPoint) {
         final Optional<DOMDataBroker> domDataBrokerService = mountPoint.getService(DOMDataBroker.class);
         if (domDataBrokerService.isPresent()) {
-            return domDataBrokerService.get().newReadWriteTransaction();
+            return domDataBrokerService.get().createTransactionChain(RestConnectorProvider.transactionListener);
         } else {
             final String errMsg = "DOM data broker service isn't available for mount point "
                     + mountPoint.getIdentifier();