Rename netconf.api.ModifyAction to EffectiveOperation
[netconf.git] / netconf / sal-netconf-connector / src / main / java / org / opendaylight / netconf / sal / connect / netconf / sal / AbstractNetconfDataTreeService.java
index 6e10f11adae98dfdc5ae86486b08dead647d66b3..aa910cd39e6eef667b75ebc2aaacc33465e90b31 100644 (file)
@@ -15,7 +15,6 @@ import com.google.common.util.concurrent.FutureCallback;
 import com.google.common.util.concurrent.Futures;
 import com.google.common.util.concurrent.ListenableFuture;
 import com.google.common.util.concurrent.MoreExecutors;
-import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
 import java.util.Collection;
 import java.util.List;
 import java.util.Optional;
@@ -23,27 +22,28 @@ import org.eclipse.jdt.annotation.NonNull;
 import org.eclipse.jdt.annotation.Nullable;
 import org.opendaylight.mdsal.common.api.LogicalDatastoreType;
 import org.opendaylight.mdsal.dom.api.DOMRpcResult;
-import org.opendaylight.mdsal.dom.api.DOMRpcService;
 import org.opendaylight.mdsal.dom.spi.DefaultDOMRpcResult;
-import org.opendaylight.netconf.api.ModifyAction;
+import org.opendaylight.netconf.api.EffectiveOperation;
 import org.opendaylight.netconf.dom.api.NetconfDataTreeService;
+import org.opendaylight.netconf.sal.connect.api.RemoteDeviceServices.Rpcs;
 import org.opendaylight.netconf.sal.connect.netconf.listener.NetconfSessionPreferences;
 import org.opendaylight.netconf.sal.connect.netconf.util.NetconfBaseOps;
 import org.opendaylight.netconf.sal.connect.netconf.util.NetconfRpcFutureCallback;
 import org.opendaylight.netconf.sal.connect.util.RemoteDeviceId;
 import org.opendaylight.yangtools.rfc8528.data.api.MountPointContext;
+import org.opendaylight.yangtools.yang.common.ErrorSeverity;
 import org.opendaylight.yangtools.yang.common.RpcError;
-import org.opendaylight.yangtools.yang.common.RpcError.ErrorSeverity;
 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
 import org.opendaylight.yangtools.yang.data.api.schema.DataContainerChild;
 import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-public abstract class AbstractNetconfDataTreeService implements NetconfDataTreeService {
+public abstract sealed class AbstractNetconfDataTreeService implements NetconfDataTreeService {
     private static final class Candidate extends AbstractNetconfDataTreeService {
-        Candidate(final RemoteDeviceId id, final NetconfBaseOps netconfOps, final boolean rollbackSupport) {
-            super(id, netconfOps, rollbackSupport);
+        Candidate(final RemoteDeviceId id, final NetconfBaseOps netconfOps, final boolean rollbackSupport,
+                final boolean lockDatastore) {
+            super(id, netconfOps, rollbackSupport, lockDatastore);
         }
 
         /**
@@ -66,8 +66,8 @@ public abstract class AbstractNetconfDataTreeService implements NetconfDataTreeS
         }
 
         @Override
-        ListenableFuture<? extends DOMRpcResult> editConfig(final DataContainerChild<?, ?> editStructure,
-                final ModifyAction defaultOperation) {
+        ListenableFuture<? extends DOMRpcResult> editConfig(final DataContainerChild editStructure,
+                final EffectiveOperation defaultOperation) {
             final NetconfRpcFutureCallback callback = new NetconfRpcFutureCallback("Edit candidate", id);
             return defaultOperation == null ? netconfOps.editConfigCandidate(callback, editStructure, rollbackSupport)
                 : netconfOps.editConfigCandidate(callback, editStructure, defaultOperation, rollbackSupport);
@@ -75,8 +75,9 @@ public abstract class AbstractNetconfDataTreeService implements NetconfDataTreeS
     }
 
     private static final class Running extends AbstractNetconfDataTreeService {
-        Running(final RemoteDeviceId id, final NetconfBaseOps netconfOps, final boolean rollbackSupport) {
-            super(id, netconfOps, rollbackSupport);
+        Running(final RemoteDeviceId id, final NetconfBaseOps netconfOps, final boolean rollbackSupport,
+                final boolean lockDatastore) {
+            super(id, netconfOps, rollbackSupport, lockDatastore);
         }
 
         @Override
@@ -85,6 +86,12 @@ public abstract class AbstractNetconfDataTreeService implements NetconfDataTreeS
             return RPC_SUCCESS;
         }
 
+        @Override
+        public ListenableFuture<DOMRpcResult> commit() {
+            // No candidate, hence we commit immediately
+            return RPC_SUCCESS;
+        }
+
         @Override
         ListenableFuture<? extends DOMRpcResult> lockSingle() {
             return netconfOps.lockRunning(new NetconfRpcFutureCallback("Lock running", id));
@@ -96,8 +103,8 @@ public abstract class AbstractNetconfDataTreeService implements NetconfDataTreeS
         }
 
         @Override
-        ListenableFuture<? extends DOMRpcResult> editConfig(final DataContainerChild<?, ?> editStructure,
-                final ModifyAction defaultOperation) {
+        ListenableFuture<? extends DOMRpcResult> editConfig(final DataContainerChild editStructure,
+                final EffectiveOperation defaultOperation) {
             final NetconfRpcFutureCallback callback = new NetconfRpcFutureCallback("Edit running", id);
             return defaultOperation == null ? netconfOps.editConfigRunning(callback, editStructure, rollbackSupport)
                 : netconfOps.editConfigRunning(callback, editStructure, defaultOperation, rollbackSupport);
@@ -109,10 +116,10 @@ public abstract class AbstractNetconfDataTreeService implements NetconfDataTreeS
         private final Running running;
 
         CandidateWithRunning(final RemoteDeviceId id, final NetconfBaseOps netconfOps,
-                final boolean rollbackSupport) {
-            super(id, netconfOps, rollbackSupport);
-            candidate = new Candidate(id, netconfOps, rollbackSupport);
-            running = new Running(id, netconfOps, rollbackSupport);
+                final boolean rollbackSupport, final boolean lockDatastore) {
+            super(id, netconfOps, rollbackSupport, lockDatastore);
+            candidate = new Candidate(id, netconfOps, rollbackSupport, lockDatastore);
+            running = new Running(id, netconfOps, rollbackSupport, lockDatastore);
         }
 
         @Override
@@ -136,11 +143,10 @@ public abstract class AbstractNetconfDataTreeService implements NetconfDataTreeS
         }
 
         @Override
-        ListenableFuture<? extends DOMRpcResult> editConfig(final DataContainerChild<?, ?> editStructure,
-                final ModifyAction defaultOperation) {
+        ListenableFuture<? extends DOMRpcResult> editConfig(final DataContainerChild editStructure,
+                final EffectiveOperation defaultOperation) {
             return candidate.editConfig(editStructure, defaultOperation);
         }
-
     }
 
     private static final Logger LOG = LoggerFactory.getLogger(AbstractNetconfDataTreeService.class);
@@ -151,29 +157,29 @@ public abstract class AbstractNetconfDataTreeService implements NetconfDataTreeS
     final NetconfBaseOps netconfOps;
     final boolean rollbackSupport;
 
-    // FIXME: what do we do with locks acquired before this got flipped?
-    private volatile boolean isLockAllowed = true;
+    private final boolean lockDatastore;
 
     AbstractNetconfDataTreeService(final RemoteDeviceId id, final NetconfBaseOps netconfOps,
-            final boolean rollbackSupport) {
+            final boolean rollbackSupport, final boolean lockDatastore) {
         this.id = requireNonNull(id);
         this.netconfOps = requireNonNull(netconfOps);
         this.rollbackSupport = rollbackSupport;
+        this.lockDatastore = lockDatastore;
     }
 
     public static @NonNull AbstractNetconfDataTreeService of(final RemoteDeviceId id,
-            final MountPointContext mountContext, final DOMRpcService rpc,
-            final NetconfSessionPreferences netconfSessionPreferences) {
-        final NetconfBaseOps netconfOps = new NetconfBaseOps(rpc, mountContext);
-        final boolean rollbackSupport = netconfSessionPreferences.isRollbackSupported();
+            final MountPointContext mountContext, final Rpcs rpcs,
+            final NetconfSessionPreferences sessionPreferences, final boolean lockDatastore) {
+        final var netconfOps = new NetconfBaseOps(rpcs, mountContext);
+        final boolean rollbackSupport = sessionPreferences.isRollbackSupported();
 
         // Examine preferences and decide which implementation to use
-        if (netconfSessionPreferences.isCandidateSupported()) {
-            return netconfSessionPreferences.isRunningWritable()
-                ? new CandidateWithRunning(id, netconfOps, rollbackSupport)
-                    : new Candidate(id, netconfOps, rollbackSupport);
-        } else if (netconfSessionPreferences.isRunningWritable()) {
-            return new Running(id, netconfOps, rollbackSupport);
+        if (sessionPreferences.isCandidateSupported()) {
+            return sessionPreferences.isRunningWritable()
+                ? new CandidateWithRunning(id, netconfOps, rollbackSupport, lockDatastore)
+                    : new Candidate(id, netconfOps, rollbackSupport, lockDatastore);
+        } else if (sessionPreferences.isRunningWritable()) {
+            return new Running(id, netconfOps, rollbackSupport, lockDatastore);
         } else {
             throw new IllegalArgumentException("Device " + id.getName() + " has advertised neither :writable-running "
                 + "nor :candidate capability. Failed to establish session, as at least one of these must be "
@@ -183,16 +189,16 @@ public abstract class AbstractNetconfDataTreeService implements NetconfDataTreeS
 
     @Override
     public synchronized ListenableFuture<DOMRpcResult> lock() {
-        if (!isLockAllowed) {
+        if (!lockDatastore) {
             LOG.trace("Lock is not allowed by device configuration, ignoring lock results: {}", id);
             return RPC_SUCCESS;
         }
 
         final ListenableFuture<DOMRpcResult> result = mergeFutures(lockImpl());
-        Futures.addCallback(result, new FutureCallback<DOMRpcResult>() {
+        Futures.addCallback(result, new FutureCallback<>() {
             @Override
             public void onSuccess(final DOMRpcResult result) {
-                final var errors = result.getErrors();
+                final var errors = result.errors();
                 if (errors.isEmpty()) {
                     LOG.debug("{}: Lock successful.", id);
                     return;
@@ -222,17 +228,16 @@ public abstract class AbstractNetconfDataTreeService implements NetconfDataTreeS
 
     @Override
     public synchronized ListenableFuture<DOMRpcResult> unlock() {
-        // FIXME: deal with lock with lifecycle?
-        if (!isLockAllowed) {
+        if (!lockDatastore) {
             LOG.trace("Unlock is not allowed: {}", id);
             return RPC_SUCCESS;
         }
 
         final ListenableFuture<DOMRpcResult> result = mergeFutures(unlockImpl());
-        Futures.addCallback(result, new FutureCallback<DOMRpcResult>() {
+        Futures.addCallback(result, new FutureCallback<>() {
             @Override
             public void onSuccess(final DOMRpcResult result) {
-                final var errors = result.getErrors();
+                final var errors = result.errors();
                 if (errors.isEmpty()) {
                     LOG.debug("{}: Unlock successful.", id);
                     return;
@@ -256,24 +261,24 @@ public abstract class AbstractNetconfDataTreeService implements NetconfDataTreeS
     abstract List<ListenableFuture<? extends DOMRpcResult>> unlockImpl();
 
     @Override
-    public ListenableFuture<Optional<NormalizedNode<?, ?>>> get(final YangInstanceIdentifier path) {
+    public ListenableFuture<Optional<NormalizedNode>> get(final YangInstanceIdentifier path) {
         return netconfOps.getData(new NetconfRpcFutureCallback("Data read", id), Optional.ofNullable(path));
     }
 
     @Override
-    public ListenableFuture<Optional<NormalizedNode<?, ?>>> get(final YangInstanceIdentifier path,
+    public ListenableFuture<Optional<NormalizedNode>> get(final YangInstanceIdentifier path,
             final List<YangInstanceIdentifier> fields) {
         return netconfOps.getData(new NetconfRpcFutureCallback("Data read", id), Optional.ofNullable(path), fields);
     }
 
     @Override
-    public ListenableFuture<Optional<NormalizedNode<?, ?>>> getConfig(final YangInstanceIdentifier path) {
+    public ListenableFuture<Optional<NormalizedNode>> getConfig(final YangInstanceIdentifier path) {
         return netconfOps.getConfigRunningData(new NetconfRpcFutureCallback("Data read", id),
             Optional.ofNullable(path));
     }
 
     @Override
-    public ListenableFuture<Optional<NormalizedNode<?, ?>>> getConfig(final YangInstanceIdentifier path,
+    public ListenableFuture<Optional<NormalizedNode>> getConfig(final YangInstanceIdentifier path,
             final List<YangInstanceIdentifier> fields) {
         return netconfOps.getConfigRunningData(new NetconfRpcFutureCallback("Data read", id),
             Optional.ofNullable(path), fields);
@@ -281,46 +286,49 @@ public abstract class AbstractNetconfDataTreeService implements NetconfDataTreeS
 
     @Override
     public synchronized ListenableFuture<? extends DOMRpcResult> merge(final LogicalDatastoreType store,
-            final YangInstanceIdentifier path, final NormalizedNode<?, ?> data,
-            final Optional<ModifyAction> defaultOperation) {
+            final YangInstanceIdentifier path, final NormalizedNode data,
+            final Optional<EffectiveOperation> defaultOperation) {
         checkEditable(store);
         return editConfig(
-            netconfOps.createEditConfigStrcture(Optional.ofNullable(data), Optional.of(ModifyAction.MERGE), path),
+            netconfOps.createEditConfigStructure(Optional.ofNullable(data), Optional.of(EffectiveOperation.MERGE),
+                path),
             defaultOperation.orElse(null));
     }
 
     @Override
     public synchronized ListenableFuture<? extends DOMRpcResult> replace(final LogicalDatastoreType store,
-            final YangInstanceIdentifier path, final NormalizedNode<?, ?> data,
-            final Optional<ModifyAction> defaultOperation) {
+            final YangInstanceIdentifier path, final NormalizedNode data,
+            final Optional<EffectiveOperation> defaultOperation) {
         checkEditable(store);
         return editConfig(
-            netconfOps.createEditConfigStrcture(Optional.ofNullable(data), Optional.of(ModifyAction.REPLACE), path),
+            netconfOps.createEditConfigStructure(Optional.ofNullable(data), Optional.of(EffectiveOperation.REPLACE),
+                path),
             defaultOperation.orElse(null));
     }
 
     @Override
     public synchronized ListenableFuture<? extends DOMRpcResult> create(final LogicalDatastoreType store,
-            final YangInstanceIdentifier path, final NormalizedNode<?, ?> data,
-            final Optional<ModifyAction> defaultOperation) {
+            final YangInstanceIdentifier path, final NormalizedNode data,
+            final Optional<EffectiveOperation> defaultOperation) {
         checkEditable(store);
         return editConfig(
-            netconfOps.createEditConfigStrcture(Optional.ofNullable(data), Optional.of(ModifyAction.CREATE), path),
+            netconfOps.createEditConfigStructure(Optional.ofNullable(data), Optional.of(EffectiveOperation.CREATE),
+                path),
             defaultOperation.orElse(null));
     }
 
     @Override
     public synchronized ListenableFuture<? extends DOMRpcResult> delete(final LogicalDatastoreType store,
             final YangInstanceIdentifier path) {
-        return editConfig(netconfOps.createEditConfigStrcture(Optional.empty(), Optional.of(ModifyAction.DELETE), path),
-            null);
+        return editConfig(netconfOps.createEditConfigStructure(Optional.empty(),
+                Optional.of(EffectiveOperation.DELETE), path), null);
     }
 
     @Override
     public synchronized ListenableFuture<? extends DOMRpcResult> remove(final LogicalDatastoreType store,
             final YangInstanceIdentifier path) {
-        return editConfig(netconfOps.createEditConfigStrcture(Optional.empty(), Optional.of(ModifyAction.REMOVE), path),
-            null);
+        return editConfig(netconfOps.createEditConfigStructure(Optional.empty(),
+                Optional.of(EffectiveOperation.REMOVE), path), null);
     }
 
     @Override
@@ -333,12 +341,8 @@ public abstract class AbstractNetconfDataTreeService implements NetconfDataTreeS
         return id;
     }
 
-    final void setLockAllowed(final boolean isLockAllowedOrig) {
-        this.isLockAllowed = isLockAllowedOrig;
-    }
-
-    abstract ListenableFuture<? extends DOMRpcResult> editConfig(DataContainerChild<?, ?> editStructure,
-        @Nullable ModifyAction defaultOperation);
+    abstract ListenableFuture<? extends DOMRpcResult> editConfig(DataContainerChild editStructure,
+        @Nullable EffectiveOperation defaultOperation);
 
     private static void checkEditable(final LogicalDatastoreType store) {
         checkArgument(store == LogicalDatastoreType.CONFIGURATION, "Can only edit configuration data, not %s", store);
@@ -355,14 +359,12 @@ public abstract class AbstractNetconfDataTreeService implements NetconfDataTreeS
 
             final var builder = ImmutableList.<RpcError>builder();
             for (ListenableFuture<? extends DOMRpcResult> future : futures) {
-                builder.addAll(Futures.getDone(future).getErrors());
+                builder.addAll(Futures.getDone(future).errors());
             }
             return new DefaultDOMRpcResult(null, builder.build());
         }, MoreExecutors.directExecutor());
     }
 
-    @SuppressFBWarnings(value = "UPM_UNCALLED_PRIVATE_METHOD",
-        justification = "https://github.com/spotbugs/spotbugs/issues/811")
     private static boolean allWarnings(final Collection<? extends @NonNull RpcError> errors) {
         return errors.stream().allMatch(error -> error.getSeverity() == ErrorSeverity.WARNING);
     }