Introduce ReadTransaction.exists() 67/77767/3
authorRobert Varga <robert.varga@pantheon.tech>
Wed, 14 Nov 2018 09:11:44 +0000 (10:11 +0100)
committerStephen Kitt <skitt@redhat.com>
Wed, 14 Nov 2018 15:47:21 +0000 (15:47 +0000)
This method exists in the DOM API, but for some reason it was left
out if the Binding API. Introduce it as default methods riding on
the read() method and override them in all known implementations,
so the request is efficiently routed.

JIRA: MDSAL-389
Change-Id: Id56332d6f720396305ac68e40554e62fd17c34fb
Signed-off-by: Robert Varga <robert.varga@pantheon.tech>
opendaylight/md-sal/sal-binding-api/src/main/java/org/opendaylight/controller/md/sal/binding/api/ForwardingReadOnlyTransaction.java
opendaylight/md-sal/sal-binding-api/src/main/java/org/opendaylight/controller/md/sal/binding/api/ForwardingReadWriteTransaction.java
opendaylight/md-sal/sal-binding-api/src/main/java/org/opendaylight/controller/md/sal/binding/api/ReadTransaction.java
opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/md/sal/binding/impl/AbstractForwardedTransaction.java
opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/md/sal/binding/impl/BindingDOMReadTransactionAdapter.java
opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/md/sal/binding/impl/BindingDOMReadWriteTransactionAdapter.java

index a8fad515607fb00d99dbb32760dbe2c7bbef67f4..a71c08a1c0c59316dae123b8662327eb20a0d6e6 100644 (file)
@@ -24,7 +24,7 @@ public class ForwardingReadOnlyTransaction extends ForwardingObject implements R
 
     private final ReadOnlyTransaction delegate;
 
 
     private final ReadOnlyTransaction delegate;
 
-    protected ForwardingReadOnlyTransaction(ReadOnlyTransaction delegate) {
+    protected ForwardingReadOnlyTransaction(final ReadOnlyTransaction delegate) {
         this.delegate = delegate;
     }
 
         this.delegate = delegate;
     }
 
@@ -34,11 +34,17 @@ public class ForwardingReadOnlyTransaction extends ForwardingObject implements R
     }
 
     @Override
     }
 
     @Override
-    public <T extends DataObject> CheckedFuture<Optional<T>, ReadFailedException> read(LogicalDatastoreType store,
-            InstanceIdentifier<T> path) {
+    public <T extends DataObject> CheckedFuture<Optional<T>, ReadFailedException> read(final LogicalDatastoreType store,
+            final InstanceIdentifier<T> path) {
         return delegate.read(store, path);
     }
 
         return delegate.read(store, path);
     }
 
+    @Override
+    public CheckedFuture<Boolean, ReadFailedException> exists(final LogicalDatastoreType store,
+            final InstanceIdentifier<?> path) {
+        return delegate.exists(store, path);
+    }
+
     @Override
     public Object getIdentifier() {
         return delegate.getIdentifier();
     @Override
     public Object getIdentifier() {
         return delegate.getIdentifier();
index 641e77bb7242deeec2e79ce17cd21236974d9a72..3e8dfe7e579d628f8735fca9ae8c86cd21b6b78d 100644 (file)
@@ -26,7 +26,7 @@ public class ForwardingReadWriteTransaction extends ForwardingObject implements
 
     private final ReadWriteTransaction delegate;
 
 
     private final ReadWriteTransaction delegate;
 
-    protected ForwardingReadWriteTransaction(ReadWriteTransaction delegate) {
+    protected ForwardingReadWriteTransaction(final ReadWriteTransaction delegate) {
         this.delegate = delegate;
     }
 
         this.delegate = delegate;
     }
 
@@ -36,22 +36,29 @@ public class ForwardingReadWriteTransaction extends ForwardingObject implements
     }
 
     @Override
     }
 
     @Override
-    public <T extends DataObject> void put(LogicalDatastoreType store, InstanceIdentifier<T> path, T data) {
+    public <T extends DataObject> void put(final LogicalDatastoreType store, final InstanceIdentifier<T> path,
+            final T data) {
         delegate.put(store, path, data);
     }
 
     @Override
         delegate.put(store, path, data);
     }
 
     @Override
-    public <T extends DataObject> void put(LogicalDatastoreType store, InstanceIdentifier<T> path, T data,
-            boolean createMissingParents) {
+    public <T extends DataObject> void put(final LogicalDatastoreType store, final InstanceIdentifier<T> path,
+            final T data, final boolean createMissingParents) {
         delegate.put(store, path, data, createMissingParents);
     }
 
     @Override
         delegate.put(store, path, data, createMissingParents);
     }
 
     @Override
-    public <T extends DataObject> CheckedFuture<Optional<T>, ReadFailedException> read(LogicalDatastoreType store,
-            InstanceIdentifier<T> path) {
+    public <T extends DataObject> CheckedFuture<Optional<T>, ReadFailedException> read(final LogicalDatastoreType store,
+            final InstanceIdentifier<T> path) {
         return delegate.read(store, path);
     }
 
         return delegate.read(store, path);
     }
 
+    @Override
+    public CheckedFuture<Boolean, ReadFailedException> exists(final LogicalDatastoreType store,
+            final InstanceIdentifier<?> path) {
+        return delegate.exists(store, path);
+    }
+
     @Override
     public Object getIdentifier() {
         return delegate.getIdentifier();
     @Override
     public Object getIdentifier() {
         return delegate.getIdentifier();
@@ -63,13 +70,14 @@ public class ForwardingReadWriteTransaction extends ForwardingObject implements
     }
 
     @Override
     }
 
     @Override
-    public <T extends DataObject> void merge(LogicalDatastoreType store, InstanceIdentifier<T> path, T data) {
+    public <T extends DataObject> void merge(final LogicalDatastoreType store, final InstanceIdentifier<T> path,
+            final T data) {
         delegate.merge(store, path, data);
     }
 
     @Override
         delegate.merge(store, path, data);
     }
 
     @Override
-    public <T extends DataObject> void merge(LogicalDatastoreType store, InstanceIdentifier<T> path, T data,
-            boolean createMissingParents) {
+    public <T extends DataObject> void merge(final LogicalDatastoreType store, final InstanceIdentifier<T> path,
+            final T data, final boolean createMissingParents) {
         delegate.merge(store, path, data, createMissingParents);
     }
 
         delegate.merge(store, path, data, createMissingParents);
     }
 
@@ -79,7 +87,7 @@ public class ForwardingReadWriteTransaction extends ForwardingObject implements
     }
 
     @Override
     }
 
     @Override
-    public void delete(LogicalDatastoreType store, InstanceIdentifier<?> path) {
+    public void delete(final LogicalDatastoreType store, final InstanceIdentifier<?> path) {
         delegate.delete(store, path);
     }
 }
         delegate.delete(store, path);
     }
 }
index 21bcf23cd468a4f09570a6d8d4c40fb8699bfae2..01f525487a923d9b9fc59a5606be89b6ecaabb7f 100644 (file)
@@ -9,6 +9,9 @@ package org.opendaylight.controller.md.sal.binding.api;
 
 import com.google.common.base.Optional;
 import com.google.common.util.concurrent.CheckedFuture;
 
 import com.google.common.base.Optional;
 import com.google.common.util.concurrent.CheckedFuture;
+import com.google.common.util.concurrent.Futures;
+import com.google.common.util.concurrent.MoreExecutors;
+import org.opendaylight.controller.md.sal.common.api.MappingCheckedFuture;
 import org.opendaylight.controller.md.sal.common.api.data.AsyncReadTransaction;
 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
 import org.opendaylight.controller.md.sal.common.api.data.ReadFailedException;
 import org.opendaylight.controller.md.sal.common.api.data.AsyncReadTransaction;
 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
 import org.opendaylight.controller.md.sal.common.api.data.ReadFailedException;
@@ -45,6 +48,38 @@ public interface ReadTransaction extends AsyncReadTransaction<InstanceIdentifier
      *         {@link ReadFailedException} or an exception derived from ReadFailedException.</li>
      *         </ul>
      */
      *         {@link ReadFailedException} or an exception derived from ReadFailedException.</li>
      *         </ul>
      */
-    <T extends DataObject> CheckedFuture<Optional<T>,ReadFailedException> read(
+    <T extends DataObject> CheckedFuture<Optional<T>, ReadFailedException> read(
             LogicalDatastoreType store, InstanceIdentifier<T> path);
             LogicalDatastoreType store, InstanceIdentifier<T> path);
+
+    /**
+     * Checks if data is available in the logical data store located at provided path.
+     *
+     * <p>
+     * Note: a successful result from this method makes no guarantee that a subsequent call to {@link #read}
+     * will succeed. It is possible that the data resides in a data store on a remote node and, if that
+     * node goes down or a network failure occurs, a subsequent read would fail. Another scenario is if
+     * the data is deleted in between the calls to <code>exists</code> and <code>read</code>
+     *
+     * <p>
+     * Default implementation delegates to {@link #read(LogicalDatastoreType, InstanceIdentifier)}, implementations
+     * are advised to provide a more efficient override.
+     *
+     * @param store
+     *            Logical data store from which read should occur.
+     * @param path
+     *            Path which uniquely identifies subtree which client want to
+     *            check existence of
+     * @return a CheckFuture containing the result of the check.
+     *         <ul>
+     *         <li>If the data at the supplied path exists, the Future returns a Boolean
+     *         whose value is true, false otherwise</li>
+     *         <li>If checking for the data fails, the Future will fail with a
+     *         {@link ReadFailedException} or an exception derived from ReadFailedException.</li>
+     *         </ul>
+     */
+    default CheckedFuture<Boolean, ReadFailedException> exists(final LogicalDatastoreType store,
+            final InstanceIdentifier<?> path) {
+        return MappingCheckedFuture.create(Futures.transform(read(store, path), Optional::isPresent,
+            MoreExecutors.directExecutor()), ReadFailedException.MAPPER);
+    }
 }
 }
index fe8c75864ed7c7cbface6893a7e3e397c049e1bf..24b7ff03cee1557869508a0345e88f066485cd2b 100644 (file)
@@ -57,7 +57,7 @@ abstract class AbstractForwardedTransaction<T extends AsyncTransaction<YangInsta
         return codec;
     }
 
         return codec;
     }
 
-    protected final <D extends DataObject> CheckedFuture<Optional<D>,ReadFailedException> doRead(
+    protected final <D extends DataObject> CheckedFuture<Optional<D>, ReadFailedException> doRead(
             final DOMDataReadTransaction readTx, final LogicalDatastoreType store,
             final InstanceIdentifier<D> path) {
         Preconditions.checkArgument(!path.isWildcarded(), "Invalid read of wildcarded path %s", path);
             final DOMDataReadTransaction readTx, final LogicalDatastoreType store,
             final InstanceIdentifier<D> path) {
         Preconditions.checkArgument(!path.isWildcarded(), "Invalid read of wildcarded path %s", path);
@@ -68,4 +68,13 @@ abstract class AbstractForwardedTransaction<T extends AsyncTransaction<YangInsta
                 MoreExecutors.directExecutor()),
             ReadFailedException.MAPPER);
     }
                 MoreExecutors.directExecutor()),
             ReadFailedException.MAPPER);
     }
+
+    protected final CheckedFuture<Boolean, ReadFailedException> doExists(
+            final DOMDataReadTransaction readTx, final LogicalDatastoreType store,
+            final InstanceIdentifier<?> path) {
+        Preconditions.checkArgument(!path.isWildcarded(), "Invalid read of wildcarded path %s", path);
+
+        return MappingCheckedFuture.create(readTx.exists(store, codec.toYangInstanceIdentifierBlocking(path)),
+            ReadFailedException.MAPPER);
+    }
 }
 }
index 1d6932237bb16f34d84ac6fc5eb0ee6e22ed3a52..7a8414ce796973908d7babc4f172cfc2465c2d92 100644 (file)
@@ -25,11 +25,17 @@ class BindingDOMReadTransactionAdapter extends AbstractForwardedTransaction<DOMD
     }
 
     @Override
     }
 
     @Override
-    public <T extends DataObject> CheckedFuture<Optional<T>,ReadFailedException> read(
+    public <T extends DataObject> CheckedFuture<Optional<T>, ReadFailedException> read(
             final LogicalDatastoreType store, final InstanceIdentifier<T> path) {
         return doRead(getDelegate(),store, path);
     }
 
             final LogicalDatastoreType store, final InstanceIdentifier<T> path) {
         return doRead(getDelegate(),store, path);
     }
 
+    @Override
+    public CheckedFuture<Boolean, ReadFailedException> exists(final LogicalDatastoreType store,
+            final InstanceIdentifier<?> path) {
+        return doExists(getDelegate(), store, path);
+    }
+
     @Override
     public void close() {
         getDelegate().close();
     @Override
     public void close() {
         getDelegate().close();
index bebed4df8508ebd689d1b9b407887b711362e9de..d3764fbce6f76639342090678ac4c08aa09a0e0e 100644 (file)
@@ -29,4 +29,10 @@ class BindingDOMReadWriteTransactionAdapter extends
             final LogicalDatastoreType store, final InstanceIdentifier<T> path) {
         return doRead(getDelegate(), store, path);
     }
             final LogicalDatastoreType store, final InstanceIdentifier<T> path) {
         return doRead(getDelegate(), store, path);
     }
+
+    @Override
+    public CheckedFuture<Boolean, ReadFailedException> exists(final LogicalDatastoreType store,
+            final InstanceIdentifier<?> path) {
+        return doExists(getDelegate(), store, path);
+    }
 }
 }