Bind RestconfStrategy to EffectiveModelContext 72/107872/2
authorRobert Varga <robert.varga@pantheon.tech>
Thu, 14 Sep 2023 14:59:31 +0000 (16:59 +0200)
committerRobert Varga <robert.varga@pantheon.tech>
Thu, 14 Sep 2023 16:27:34 +0000 (18:27 +0200)
We are passing around EffectiveModelContext like there's no tomorrow.
Let us just bind it to a RestconfStrategy instance.

This allows us to simplify methods all over the place, reducing
cognitive load while navigating them.

JIRA: NETCONF-773
Change-Id: Ibaeb7b865c894c6eaadf65de11147b912534cf93
Signed-off-by: Robert Varga <robert.varga@pantheon.tech>
12 files changed:
restconf/restconf-nb/src/main/java/org/opendaylight/restconf/nb/rfc8040/rests/services/impl/ResourceRequest.java
restconf/restconf-nb/src/main/java/org/opendaylight/restconf/nb/rfc8040/rests/services/impl/RestconfDataServiceImpl.java
restconf/restconf-nb/src/main/java/org/opendaylight/restconf/nb/rfc8040/rests/transactions/MdsalRestconfStrategy.java
restconf/restconf-nb/src/main/java/org/opendaylight/restconf/nb/rfc8040/rests/transactions/MdsalRestconfTransaction.java
restconf/restconf-nb/src/main/java/org/opendaylight/restconf/nb/rfc8040/rests/transactions/NetconfRestconfStrategy.java
restconf/restconf-nb/src/main/java/org/opendaylight/restconf/nb/rfc8040/rests/transactions/NetconfRestconfTransaction.java
restconf/restconf-nb/src/main/java/org/opendaylight/restconf/nb/rfc8040/rests/transactions/RestconfStrategy.java
restconf/restconf-nb/src/main/java/org/opendaylight/restconf/nb/rfc8040/rests/transactions/RestconfTransaction.java
restconf/restconf-nb/src/test/java/org/opendaylight/restconf/nb/rfc8040/rests/services/impl/RestconfDataServiceImplTest.java
restconf/restconf-nb/src/test/java/org/opendaylight/restconf/nb/rfc8040/rests/transactions/AbstractRestconfStrategyTest.java
restconf/restconf-nb/src/test/java/org/opendaylight/restconf/nb/rfc8040/rests/transactions/MdsalRestconfStrategyTest.java
restconf/restconf-nb/src/test/java/org/opendaylight/restconf/nb/rfc8040/rests/transactions/NetconfRestconfStrategyTest.java

index 786682fdd96db0a919f26d507f7882d823ad634b..7e71ebd3d0eba5be2a81342af1cfe3469d5b3e68 100644 (file)
@@ -13,19 +13,16 @@ import org.eclipse.jdt.annotation.NonNull;
 import org.opendaylight.restconf.nb.rfc8040.rests.transactions.RestconfStrategy;
 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
 import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
-import org.opendaylight.yangtools.yang.model.api.EffectiveModelContext;
 
 /**
  * A request to a resource identified by the URL path.
  */
 record ResourceRequest(
         @NonNull RestconfStrategy strategy,
-        @NonNull EffectiveModelContext modelContext,
         @NonNull YangInstanceIdentifier path,
         @NonNull NormalizedNode data) {
     ResourceRequest {
         requireNonNull(strategy);
-        requireNonNull(modelContext);
         requireNonNull(path);
         requireNonNull(data);
     }
index 64e983eca6056854d49bc9e4bd17587e9b784bb8..63cfbb0ca42806f4a7eceffb2353bde4563aabe4 100644 (file)
@@ -21,6 +21,8 @@ import com.google.common.util.concurrent.Futures;
 import com.google.common.util.concurrent.MoreExecutors;
 import java.io.IOException;
 import java.io.InputStream;
+import java.lang.invoke.MethodHandles;
+import java.lang.invoke.VarHandle;
 import java.net.URI;
 import java.time.Clock;
 import java.time.LocalDateTime;
@@ -116,23 +118,34 @@ import org.slf4j.LoggerFactory;
 public final class RestconfDataServiceImpl {
     private static final Logger LOG = LoggerFactory.getLogger(RestconfDataServiceImpl.class);
     private static final DateTimeFormatter FORMATTER = DateTimeFormatter.ofPattern("yyyy-MMM-dd HH:mm:ss");
+    private static final VarHandle LOCAL_STRATEGY;
+
+    static {
+        try {
+            LOCAL_STRATEGY = MethodHandles.lookup()
+                .findVarHandle(RestconfDataServiceImpl.class, "localStrategy", RestconfStrategy.class);
+        } catch (NoSuchFieldException | IllegalAccessException e) {
+            throw new ExceptionInInitializerError(e);
+        }
+    }
 
     private final RestconfStreamsSubscriptionService delegRestconfSubscrService;
     private final DatabindProvider databindProvider;
-    private final MdsalRestconfStrategy restconfStrategy;
     private final DOMMountPointService mountPointService;
     private final SubscribeToStreamUtil streamUtils;
     private final DOMActionService actionService;
     private final DOMDataBroker dataBroker;
     private final ListenersBroker listenersBroker = ListenersBroker.getInstance();
 
+    @SuppressWarnings("unused")
+    private volatile RestconfStrategy localStrategy;
+
     public RestconfDataServiceImpl(final DatabindProvider databindProvider,
             final DOMDataBroker dataBroker, final DOMMountPointService  mountPointService,
             final RestconfStreamsSubscriptionService delegRestconfSubscrService,
             final DOMActionService actionService, final StreamsConfiguration configuration) {
         this.databindProvider = requireNonNull(databindProvider);
         this.dataBroker = requireNonNull(dataBroker);
-        restconfStrategy = new MdsalRestconfStrategy(dataBroker);
         this.mountPointService = requireNonNull(mountPointService);
         this.delegRestconfSubscrService = requireNonNull(delegRestconfSubscrService);
         this.actionService = requireNonNull(actionService);
@@ -192,14 +205,15 @@ public final class RestconfDataServiceImpl {
 
         final var queryParams = QueryParams.newQueryParameters(readParams, instanceIdentifier);
         final var fieldPaths = queryParams.fieldPaths();
-        final var strategy = getRestconfStrategy(mountPoint);
+        // FIXME:the model context should be coming from instanceIdentifier!
+        final var strategy = getRestconfStrategy(schemaContextRef, mountPoint);
         final NormalizedNode node;
         if (fieldPaths != null && !fieldPaths.isEmpty()) {
             node = strategy.readData(readParams.content(), instanceIdentifier.getInstanceIdentifier(),
-                readParams.withDefaults(), instanceIdentifier.getSchemaContext(), fieldPaths);
+                readParams.withDefaults(), fieldPaths);
         } else {
             node = strategy.readData(readParams.content(), instanceIdentifier.getInstanceIdentifier(),
-                readParams.withDefaults(), instanceIdentifier.getSchemaContext());
+                readParams.withDefaults());
         }
 
         // FIXME: this is utter craziness, refactor it properly!
@@ -371,7 +385,7 @@ public final class RestconfDataServiceImpl {
         final var req = bindResourceRequest(identifier, body);
 
         return switch (
-            req.strategy().putData(req.path(), req.data(), req.modelContext(), insert)) {
+            req.strategy().putData(req.path(), req.data(), insert)) {
             // Note: no Location header, as it matches the request path
             case CREATED -> Response.status(Status.CREATED).build();
             case REPLACED -> Response.noContent().build();
@@ -485,8 +499,8 @@ public final class RestconfDataServiceImpl {
     private Response postData(final Inference inference, final YangInstanceIdentifier parentPath, final ChildBody body,
             final UriInfo uriInfo, final @Nullable DOMMountPoint mountPoint) {
         final var insert = QueryParams.parseInsert(uriInfo);
-        final var strategy = getRestconfStrategy(mountPoint);
-        final var context = inference.getEffectiveModelContext();
+        final var modelContext = inference.getEffectiveModelContext();
+        final var strategy = getRestconfStrategy(modelContext, mountPoint);
         var path = parentPath;
         final var payload = body.toPayload(path, inference);
         final var data = payload.body();
@@ -495,8 +509,8 @@ public final class RestconfDataServiceImpl {
             path = path.node(arg);
         }
 
-        strategy.postData(path, data, context, insert);
-        return Response.created(resolveLocation(uriInfo, path, context, data)).build();
+        strategy.postData(path, data, insert);
+        return Response.created(resolveLocation(uriInfo, path, modelContext, data)).build();
     }
 
     /**
@@ -532,7 +546,8 @@ public final class RestconfDataServiceImpl {
             @Suspended final AsyncResponse ar) {
         final var instanceIdentifier = ParserIdentifier.toInstanceIdentifier(identifier,
             databindProvider.currentContext().modelContext(), mountPointService);
-        final var strategy = getRestconfStrategy(instanceIdentifier.getMountPoint());
+        final var strategy = getRestconfStrategy(instanceIdentifier.getSchemaContext(),
+            instanceIdentifier.getMountPoint());
 
         Futures.addCallback(strategy.delete(instanceIdentifier.getInstanceIdentifier()), new FutureCallback<>() {
             @Override
@@ -639,7 +654,7 @@ public final class RestconfDataServiceImpl {
      */
     private void plainPatchData(final @Nullable String identifier, final ResourceBody body, final AsyncResponse ar) {
         final var req = bindResourceRequest(identifier, body);
-        final var future = req.strategy().merge(req.path(), req.data(), req.modelContext());
+        final var future = req.strategy().merge(req.path(), req.data());
 
         Futures.addCallback(future, new FutureCallback<>() {
             @Override
@@ -662,7 +677,7 @@ public final class RestconfDataServiceImpl {
         final var path = context.getInstanceIdentifier();
         final var data = body.toNormalizedNode(path, inference, context.getSchemaNode());
 
-        return new ResourceRequest(getRestconfStrategy(context.getMountPoint()), inference.getEffectiveModelContext(),
+        return new ResourceRequest(getRestconfStrategy(inference.getEffectiveModelContext(), context.getMountPoint()),
             path, data);
     }
 
@@ -764,9 +779,9 @@ public final class RestconfDataServiceImpl {
 
 
     @VisibleForTesting
-    @NonNull PatchStatusContext yangPatchData(final @NonNull EffectiveModelContext context,
+    @NonNull PatchStatusContext yangPatchData(final @NonNull EffectiveModelContext modelContext,
             final @NonNull PatchContext patch, final @Nullable DOMMountPoint mountPoint) {
-        return getRestconfStrategy(mountPoint).patchData(patch, context);
+        return getRestconfStrategy(modelContext, mountPoint).patchData(patch);
     }
 
     private static @NonNull PatchContext parsePatchBody(final @NonNull EffectiveModelContext context,
@@ -781,16 +796,31 @@ public final class RestconfDataServiceImpl {
     }
 
     @VisibleForTesting
-    RestconfStrategy getRestconfStrategy(final DOMMountPoint mountPoint) {
+    @NonNull RestconfStrategy getRestconfStrategy(final EffectiveModelContext modelContext,
+            final @Nullable DOMMountPoint mountPoint) {
         if (mountPoint == null) {
-            return restconfStrategy;
+            return localStrategy(modelContext);
+        }
+
+        final var ret = RestconfStrategy.forMountPoint(modelContext, mountPoint);
+        if (ret == null) {
+            final var mountId = mountPoint.getIdentifier();
+            LOG.warn("Mount point {} does not expose a suitable access interface", mountId);
+            throw new RestconfDocumentedException("Could not find a supported access interface in mount point "
+                + mountId);
+        }
+        return ret;
+    }
+
+    private @NonNull RestconfStrategy localStrategy(final EffectiveModelContext modelContext) {
+        final var local = (RestconfStrategy) LOCAL_STRATEGY.getAcquire(this);
+        if (local != null && modelContext.equals(local.modelContext())) {
+            return local;
         }
 
-        return RestconfStrategy.forMountPoint(mountPoint).orElseThrow(() -> {
-            LOG.warn("Mount point {} does not expose a suitable access interface", mountPoint.getIdentifier());
-            return new RestconfDocumentedException("Could not find a supported access interface in mount point "
-                + mountPoint.getIdentifier());
-        });
+        final var created = new MdsalRestconfStrategy(modelContext, dataBroker);
+        LOCAL_STRATEGY.setRelease(this, created);
+        return created;
     }
 
     /**
index 43c85a192ccefe703f324458ae44c1606d800d80..30aca2def9da2ac7bf386a2cafd1f80265396cb2 100644 (file)
@@ -28,6 +28,7 @@ import org.opendaylight.yangtools.yang.common.ErrorTag;
 import org.opendaylight.yangtools.yang.common.ErrorType;
 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
 import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
+import org.opendaylight.yangtools.yang.model.api.EffectiveModelContext;
 
 /**
  * Implementation of RESTCONF operations using {@link DOMTransactionChain} and related concepts.
@@ -38,13 +39,14 @@ import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
 public final class MdsalRestconfStrategy extends RestconfStrategy {
     private final DOMDataBroker dataBroker;
 
-    public MdsalRestconfStrategy(final DOMDataBroker dataBroker) {
+    public MdsalRestconfStrategy(final EffectiveModelContext modelContext, final DOMDataBroker dataBroker) {
+        super(modelContext);
         this.dataBroker = requireNonNull(dataBroker);
     }
 
     @Override
     RestconfTransaction prepareWriteExecution() {
-        return new MdsalRestconfTransaction(dataBroker);
+        return new MdsalRestconfTransaction(modelContext(), dataBroker);
     }
 
     @Override
index 78961c8f6c07670847827552b5ce17d5a84b53e8..66dfd8dc0c5dc3b9ca32de86ec8894e415e6e355 100644 (file)
@@ -37,7 +37,8 @@ final class MdsalRestconfTransaction extends RestconfTransaction {
 
     private DOMDataTreeReadWriteTransaction rwTx;
 
-    MdsalRestconfTransaction(final DOMDataBroker dataBroker) {
+    MdsalRestconfTransaction(final EffectiveModelContext modelContext, final DOMDataBroker dataBroker) {
+        super(modelContext);
         rwTx = dataBroker.newReadWriteTransaction();
     }
 
@@ -71,11 +72,11 @@ final class MdsalRestconfTransaction extends RestconfTransaction {
     }
 
     @Override
-    void createImpl(final YangInstanceIdentifier path, final NormalizedNode data, final EffectiveModelContext context) {
+    void createImpl(final YangInstanceIdentifier path, final NormalizedNode data) {
         if (data instanceof MapNode || data instanceof LeafSetNode) {
-            final var emptySubTree = ImmutableNodes.fromInstanceId(context, path);
+            final var emptySubTree = ImmutableNodes.fromInstanceId(modelContext, path);
             merge(YangInstanceIdentifier.of(emptySubTree.name()), emptySubTree);
-            ensureParentsByMerge(path, context);
+            ensureParentsByMerge(path);
 
             final var children = ((DistinctNodeContainer<?, ?>) data).body();
             final var check = BatchedExistenceCheck.start(verifyNotNull(rwTx), CONFIGURATION, path, children);
@@ -88,25 +89,24 @@ final class MdsalRestconfTransaction extends RestconfTransaction {
             checkExistence(path, check);
         } else {
             RestconfStrategy.checkItemDoesNotExists(verifyNotNull(rwTx).exists(CONFIGURATION, path), path);
-            ensureParentsByMerge(path, context);
+            ensureParentsByMerge(path);
             verifyNotNull(rwTx).put(CONFIGURATION, path, data);
         }
     }
 
     @Override
-    void replaceImpl(final YangInstanceIdentifier path, final NormalizedNode data,
-            final EffectiveModelContext context) {
+    void replaceImpl(final YangInstanceIdentifier path, final NormalizedNode data) {
         if (data instanceof MapNode || data instanceof LeafSetNode) {
-            final var emptySubtree = ImmutableNodes.fromInstanceId(context, path);
+            final var emptySubtree = ImmutableNodes.fromInstanceId(modelContext, path);
             merge(YangInstanceIdentifier.of(emptySubtree.name()), emptySubtree);
-            ensureParentsByMerge(path, context);
+            ensureParentsByMerge(path);
 
             for (var child : ((NormalizedNodeContainer<?>) data).body()) {
                 final var childPath = path.node(child.name());
                 verifyNotNull(rwTx).put(CONFIGURATION, childPath, child);
             }
         } else {
-            ensureParentsByMerge(path, context);
+            ensureParentsByMerge(path);
             verifyNotNull(rwTx).put(CONFIGURATION, path, data);
         }
     }
index d8714cd310d78ef60b00860688f63b9a15e92599..60fd463c04336dbcf9885a5d396391a627deff57 100644 (file)
@@ -24,6 +24,7 @@ import org.opendaylight.restconf.common.errors.SettableRestconfFuture;
 import org.opendaylight.yangtools.yang.common.Empty;
 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
 import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
+import org.opendaylight.yangtools.yang.model.api.EffectiveModelContext;
 
 /**
  * Implementation of RESTCONF operations on top of a raw NETCONF backend.
@@ -33,7 +34,9 @@ import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
 public final class NetconfRestconfStrategy extends RestconfStrategy {
     private final NetconfDataTreeService netconfService;
 
-    public NetconfRestconfStrategy(final NetconfDataTreeService netconfService) {
+    public NetconfRestconfStrategy(final EffectiveModelContext modelContext,
+            final NetconfDataTreeService netconfService) {
+        super(modelContext);
         this.netconfService = requireNonNull(netconfService);
     }
 
@@ -56,7 +59,7 @@ public final class NetconfRestconfStrategy extends RestconfStrategy {
 
     @Override
     RestconfTransaction prepareWriteExecution() {
-        return new NetconfRestconfTransaction(netconfService);
+        return new NetconfRestconfTransaction(modelContext(), netconfService);
     }
 
     @Override
index e0ed5bf6f79c5f807573295618075ce4688abd8c..7d2284a7b71607bc514834277ebe1a39ca6de65f 100644 (file)
@@ -54,8 +54,10 @@ final class NetconfRestconfTransaction extends RestconfTransaction {
 
     private volatile boolean isLocked = false;
 
-    NetconfRestconfTransaction(final NetconfDataTreeService netconfService) {
+    NetconfRestconfTransaction(final EffectiveModelContext modelContext, final NetconfDataTreeService netconfService) {
+        super(modelContext);
         this.netconfService = requireNonNull(netconfService);
+
         final var lockResult = netconfService.lock();
         Futures.addCallback(lockResult, new FutureCallback<DOMRpcResult>() {
             @Override
@@ -96,9 +98,9 @@ final class NetconfRestconfTransaction extends RestconfTransaction {
     }
 
     @Override
-    void createImpl(final YangInstanceIdentifier path, final NormalizedNode data, final EffectiveModelContext context) {
+    void createImpl(final YangInstanceIdentifier path, final NormalizedNode data) {
         if (data instanceof MapNode || data instanceof LeafSetNode) {
-            final var emptySubTree = ImmutableNodes.fromInstanceId(context, path);
+            final var emptySubTree = ImmutableNodes.fromInstanceId(modelContext, path);
             merge(YangInstanceIdentifier.of(emptySubTree.name()), emptySubTree);
 
             for (var child : ((NormalizedNodeContainer<?>) data).body()) {
@@ -111,10 +113,9 @@ final class NetconfRestconfTransaction extends RestconfTransaction {
     }
 
     @Override
-    void replaceImpl(final YangInstanceIdentifier path, final NormalizedNode data,
-            final EffectiveModelContext context) {
+    void replaceImpl(final YangInstanceIdentifier path, final NormalizedNode data) {
         if (data instanceof MapNode || data instanceof LeafSetNode) {
-            final var emptySubTree = ImmutableNodes.fromInstanceId(context, path);
+            final var emptySubTree = ImmutableNodes.fromInstanceId(modelContext, path);
             merge(YangInstanceIdentifier.of(emptySubTree.name()), emptySubTree);
 
             for (var child : ((NormalizedNodeContainer<?>) data).body()) {
index 2717aa9790bdecc830c8b28bd75e8df75dc63ae8..c08764a1f4edf017f0a28bc61029630d39f26e09 100644 (file)
@@ -110,25 +110,35 @@ public abstract class RestconfStrategy {
 
     private static final Logger LOG = LoggerFactory.getLogger(RestconfStrategy.class);
 
-    RestconfStrategy() {
-        // Hidden on purpose
+    private final @NonNull EffectiveModelContext modelContext;
+
+    RestconfStrategy(final EffectiveModelContext modelContext) {
+        this.modelContext = requireNonNull(modelContext);
     }
 
     /**
      * Look up the appropriate strategy for a particular mount point.
      *
+     * @param modelContext {@link EffectiveModelContext} of target mount point
      * @param mountPoint Target mount point
      * @return A strategy, or null if the mount point does not expose a supported interface
-     * @throws NullPointerException if {@code mountPoint} is null
+     * @throws NullPointerException if any argument is {@code null}
      */
-    public static Optional<RestconfStrategy> forMountPoint(final DOMMountPoint mountPoint) {
-        final Optional<RestconfStrategy> netconf = mountPoint.getService(NetconfDataTreeService.class)
-            .map(NetconfRestconfStrategy::new);
-        if (netconf.isPresent()) {
-            return netconf;
+    public static @Nullable RestconfStrategy forMountPoint(final EffectiveModelContext modelContext,
+            final DOMMountPoint mountPoint) {
+        final var netconfService = mountPoint.getService(NetconfDataTreeService.class);
+        if (netconfService.isPresent()) {
+            return new NetconfRestconfStrategy(modelContext, netconfService.orElseThrow());
+        }
+        final var dataBroker = mountPoint.getService(DOMDataBroker.class);
+        if (dataBroker.isPresent()) {
+            return new MdsalRestconfStrategy(modelContext, dataBroker.orElseThrow());
         }
+        return null;
+    }
 
-        return mountPoint.getService(DOMDataBroker.class).map(MdsalRestconfStrategy::new);
+    public final @NonNull EffectiveModelContext modelContext() {
+        return modelContext;
     }
 
     /**
@@ -146,8 +156,7 @@ public abstract class RestconfStrategy {
      * @param path the data object path
      * @return a ListenableFuture containing the result of the read
      */
-    abstract ListenableFuture<Optional<NormalizedNode>> read(LogicalDatastoreType store,
-        YangInstanceIdentifier path);
+    abstract ListenableFuture<Optional<NormalizedNode>> read(LogicalDatastoreType store, YangInstanceIdentifier path);
 
     /**
      * Read data selected using fields from the datastore.
@@ -157,8 +166,8 @@ public abstract class RestconfStrategy {
      * @param fields paths to selected fields relative to parent path
      * @return a ListenableFuture containing the result of the read
      */
-    abstract ListenableFuture<Optional<NormalizedNode>> read(LogicalDatastoreType store,
-            YangInstanceIdentifier path, List<YangInstanceIdentifier> fields);
+    abstract ListenableFuture<Optional<NormalizedNode>> read(LogicalDatastoreType store, YangInstanceIdentifier path,
+        List<YangInstanceIdentifier> fields);
 
     /**
      * Check if data already exists in the configuration datastore.
@@ -192,23 +201,20 @@ public abstract class RestconfStrategy {
      *
      * @param path Path to merge
      * @param data Data to merge
-     * @param context Corresponding EffectiveModelContext
      * @return A {@link RestconfFuture}
      * @throws NullPointerException if any argument is {@code null}
      */
-    public final @NonNull RestconfFuture<Empty> merge(final YangInstanceIdentifier path, final NormalizedNode data,
-            final EffectiveModelContext context) {
+    public final @NonNull RestconfFuture<Empty> merge(final YangInstanceIdentifier path, final NormalizedNode data) {
         final var ret = new SettableRestconfFuture<Empty>();
-        merge(ret, requireNonNull(path), requireNonNull(data), requireNonNull(context));
+        merge(ret, requireNonNull(path), requireNonNull(data));
         return ret;
     }
 
-    private void merge(final @NonNull SettableRestconfFuture<Empty> future,
-            final @NonNull YangInstanceIdentifier path, final @NonNull NormalizedNode data,
-            final @NonNull EffectiveModelContext context) {
+    private void merge(final @NonNull SettableRestconfFuture<Empty> future, final @NonNull YangInstanceIdentifier path,
+            final @NonNull NormalizedNode data) {
         final var tx = prepareWriteExecution();
         // FIXME: this method should be further specialized to eliminate this call -- it is only needed for MD-SAL
-        tx.ensureParentsByMerge(path, context);
+        tx.ensureParentsByMerge(path);
         tx.merge(path, data);
         Futures.addCallback(tx.commit(), new FutureCallback<CommitInfo>() {
             @Override
@@ -228,21 +234,20 @@ public abstract class RestconfStrategy {
      *
      * @param path    path of data
      * @param data    data
-     * @param context reference to {@link EffectiveModelContext}
      * @param insert  {@link Insert}
      * @return A {@link CreateOrReplaceResult}
      */
-    public @NonNull CreateOrReplaceResult putData(final YangInstanceIdentifier path, final NormalizedNode data,
-            final EffectiveModelContext context, final @Nullable Insert insert) {
+    public final @NonNull CreateOrReplaceResult putData(final YangInstanceIdentifier path, final NormalizedNode data,
+            final @Nullable Insert insert) {
         final var exists = TransactionUtil.syncAccess(exists(path), path);
 
         final ListenableFuture<? extends CommitInfo> commitFuture;
         if (insert != null) {
             final var parentPath = path.coerceParent();
-            checkListAndOrderedType(context, parentPath);
-            commitFuture = insertAndCommitPut(path, data, insert, parentPath, context);
+            checkListAndOrderedType(parentPath);
+            commitFuture = insertAndCommitPut(path, data, insert, parentPath);
         } else {
-            commitFuture = replaceAndCommit(prepareWriteExecution(), path, data, context);
+            commitFuture = replaceAndCommit(prepareWriteExecution(), path, data);
         }
 
         TransactionUtil.syncCommit(commitFuture, "PUT", path);
@@ -250,46 +255,46 @@ public abstract class RestconfStrategy {
     }
 
     private ListenableFuture<? extends CommitInfo> insertAndCommitPut(final YangInstanceIdentifier path,
-            final NormalizedNode data, final @NonNull Insert insert, final YangInstanceIdentifier parentPath,
-            final EffectiveModelContext context) {
+            final NormalizedNode data, final @NonNull Insert insert, final YangInstanceIdentifier parentPath) {
         final var tx = prepareWriteExecution();
 
         return switch (insert.insert()) {
             case FIRST -> {
                 final var readData = tx.readList(parentPath);
                 if (readData == null || readData.isEmpty()) {
-                    yield replaceAndCommit(tx, path, data, context);
+                    yield replaceAndCommit(tx, path, data);
                 }
                 tx.remove(parentPath);
-                tx.replace(path, data, context);
-                tx.replace(parentPath, readData, context);
+                tx.replace(path, data);
+                tx.replace(parentPath, readData);
                 yield tx.commit();
             }
-            case LAST -> replaceAndCommit(tx, path, data, context);
+            case LAST -> replaceAndCommit(tx, path, data);
             case BEFORE -> {
                 final var readData = tx.readList(parentPath);
                 if (readData == null || readData.isEmpty()) {
-                    yield replaceAndCommit(tx, path, data, context);
+                    yield replaceAndCommit(tx, path, data);
                 }
-                insertWithPointPut(tx, path, data, verifyNotNull(insert.point()), readData, true, context);
+                insertWithPointPut(tx, path, data, verifyNotNull(insert.point()), readData, true);
                 yield tx.commit();
             }
             case AFTER -> {
                 final var readData = tx.readList(parentPath);
                 if (readData == null || readData.isEmpty()) {
-                    yield replaceAndCommit(tx, path, data, context);
+                    yield replaceAndCommit(tx, path, data);
                 }
-                insertWithPointPut(tx, path, data, verifyNotNull(insert.point()), readData, false, context);
+                insertWithPointPut(tx, path, data, verifyNotNull(insert.point()), readData, false);
                 yield tx.commit();
             }
         };
     }
 
-    private static void insertWithPointPut(final RestconfTransaction tx, final YangInstanceIdentifier path,
+    private void insertWithPointPut(final RestconfTransaction tx, final YangInstanceIdentifier path,
             final NormalizedNode data, final @NonNull PointParam point, final NormalizedNodeContainer<?> readList,
-            final boolean before, final EffectiveModelContext context) {
+            final boolean before) {
         tx.remove(path.getParent());
-        final var pointArg = YangInstanceIdentifierDeserializer.create(context, point.value()).path
+        // FIXME: this should have happened sooner
+        final var pointArg = YangInstanceIdentifierDeserializer.create(modelContext, point.value()).path
             .getLastPathArgument();
         int lastItemPosition = 0;
         for (var nodeChild : readList.body()) {
@@ -302,27 +307,28 @@ public abstract class RestconfStrategy {
             lastItemPosition++;
         }
         int lastInsertedPosition = 0;
-        final var emptySubtree = ImmutableNodes.fromInstanceId(context, path.getParent());
+        final var emptySubtree = ImmutableNodes.fromInstanceId(modelContext, path.getParent());
         tx.merge(YangInstanceIdentifier.of(emptySubtree.name()), emptySubtree);
         for (var nodeChild : readList.body()) {
             if (lastInsertedPosition == lastItemPosition) {
-                tx.replace(path, data, context);
+                tx.replace(path, data);
             }
             final var childPath = path.coerceParent().node(nodeChild.name());
-            tx.replace(childPath, nodeChild, context);
+            tx.replace(childPath, nodeChild);
             lastInsertedPosition++;
         }
     }
 
     private static ListenableFuture<? extends CommitInfo> replaceAndCommit(final RestconfTransaction tx,
-            final YangInstanceIdentifier path, final NormalizedNode data, final EffectiveModelContext context) {
-        tx.replace(path, data, context);
+            final YangInstanceIdentifier path, final NormalizedNode data) {
+        tx.replace(path, data);
         return tx.commit();
     }
 
-    private static DataSchemaNode checkListAndOrderedType(final EffectiveModelContext ctx,
-            final YangInstanceIdentifier path) {
-        final var dataSchemaNode = DataSchemaContextTree.from(ctx).findChild(path).orElseThrow().dataSchemaNode();
+    private DataSchemaNode checkListAndOrderedType(final YangInstanceIdentifier path) {
+        // FIXME: we have this available in InstanceIdentifierContext
+        final var dataSchemaNode = DataSchemaContextTree.from(modelContext).findChild(path).orElseThrow()
+            .dataSchemaNode();
 
         final String message;
         if (dataSchemaNode instanceof ListSchemaNode listSchema) {
@@ -346,25 +352,23 @@ public abstract class RestconfStrategy {
      *
      * @param path    path
      * @param data    data
-     * @param context reference to actual {@link EffectiveModelContext}
      * @param insert  {@link Insert}
      */
     public final void postData(final YangInstanceIdentifier path, final NormalizedNode data,
-            final EffectiveModelContext context, final @Nullable Insert insert) {
+            final @Nullable Insert insert) {
         final ListenableFuture<? extends CommitInfo> future;
         if (insert != null) {
             final var parentPath = path.coerceParent();
-            checkListAndOrderedType(context, parentPath);
-            future = insertAndCommitPost(path, data, insert, parentPath, context);
+            checkListAndOrderedType(parentPath);
+            future = insertAndCommitPost(path, data, insert, parentPath);
         } else {
-            future = createAndCommit(prepareWriteExecution(), path, data, context);
+            future = createAndCommit(prepareWriteExecution(), path, data);
         }
         TransactionUtil.syncCommit(future, "POST", path);
     }
 
     private ListenableFuture<? extends CommitInfo> insertAndCommitPost(final YangInstanceIdentifier path,
-            final NormalizedNode data, final @NonNull Insert insert, final YangInstanceIdentifier parent,
-            final EffectiveModelContext context) {
+            final NormalizedNode data, final @NonNull Insert insert, final YangInstanceIdentifier parent) {
         final var grandParent = parent.coerceParent();
         final var tx = prepareWriteExecution();
 
@@ -372,35 +376,33 @@ public abstract class RestconfStrategy {
             case FIRST -> {
                 final var readData = tx.readList(grandParent);
                 if (readData == null || readData.isEmpty()) {
-                    tx.replace(path, data, context);
+                    tx.replace(path, data);
                 } else {
                     checkItemDoesNotExists(exists(path), path);
                     tx.remove(grandParent);
-                    tx.replace(path, data, context);
-                    tx.replace(grandParent, readData, context);
+                    tx.replace(path, data);
+                    tx.replace(grandParent, readData);
                 }
                 yield tx.commit();
             }
-            case LAST -> createAndCommit(tx, path, data, context);
+            case LAST -> createAndCommit(tx, path, data);
             case BEFORE -> {
                 final var readData = tx.readList(grandParent);
                 if (readData == null || readData.isEmpty()) {
-                    tx.replace(path, data, context);
+                    tx.replace(path, data);
                 } else {
                     checkItemDoesNotExists(exists(path), path);
-                    insertWithPointPost(tx, path, data, verifyNotNull(insert.point()), readData, grandParent, true,
-                        context);
+                    insertWithPointPost(tx, path, data, verifyNotNull(insert.point()), readData, grandParent, true);
                 }
                 yield tx.commit();
             }
             case AFTER -> {
                 final var readData = tx.readList(grandParent);
                 if (readData == null || readData.isEmpty()) {
-                    tx.replace(path, data, context);
+                    tx.replace(path, data);
                 } else {
                     checkItemDoesNotExists(exists(path), path);
-                    insertWithPointPost(tx, path, data, verifyNotNull(insert.point()), readData, grandParent, false,
-                        context);
+                    insertWithPointPost(tx, path, data, verifyNotNull(insert.point()), readData, grandParent, false);
                 }
                 yield tx.commit();
             }
@@ -410,11 +412,10 @@ public abstract class RestconfStrategy {
     /**
      * Process edit operations of one {@link PatchContext}.
      *
-     * @param patch    Patch context to be processed
-     * @param context  Global schema context
+     * @param patch Patch context to be processed
      * @return {@link PatchStatusContext}
      */
-    public final @NonNull PatchStatusContext patchData(final PatchContext patch, final EffectiveModelContext context) {
+    public final @NonNull PatchStatusContext patchData(final PatchContext patch) {
         final var editCollection = new ArrayList<PatchStatusEntity>();
         final var tx = prepareWriteExecution();
 
@@ -427,7 +428,7 @@ public abstract class RestconfStrategy {
                 switch (patchEntity.getOperation()) {
                     case Create:
                         try {
-                            tx.create(targetNode, patchEntity.getNode(), context);
+                            tx.create(targetNode, patchEntity.getNode());
                             editCollection.add(new PatchStatusEntity(editId, true, null));
                         } catch (RestconfDocumentedException e) {
                             editCollection.add(new PatchStatusEntity(editId, false, e.getErrors()));
@@ -445,7 +446,7 @@ public abstract class RestconfStrategy {
                         break;
                     case Merge:
                         try {
-                            tx.ensureParentsByMerge(targetNode, context);
+                            tx.ensureParentsByMerge(targetNode);
                             tx.merge(targetNode, patchEntity.getNode());
                             editCollection.add(new PatchStatusEntity(editId, true, null));
                         } catch (RestconfDocumentedException e) {
@@ -455,7 +456,7 @@ public abstract class RestconfStrategy {
                         break;
                     case Replace:
                         try {
-                            tx.replace(targetNode, patchEntity.getNode(), context);
+                            tx.replace(targetNode, patchEntity.getNode());
                             editCollection.add(new PatchStatusEntity(editId, true, null));
                         } catch (RestconfDocumentedException e) {
                             editCollection.add(new PatchStatusEntity(editId, false, e.getErrors()));
@@ -490,21 +491,22 @@ public abstract class RestconfStrategy {
                 TransactionUtil.syncCommit(tx.commit(), "PATCH", null);
             } catch (RestconfDocumentedException e) {
                 // if errors occurred during transaction commit then patch failed and global errors are reported
-                return new PatchStatusContext(context, patchId, List.copyOf(editCollection), false, e.getErrors());
+                return new PatchStatusContext(modelContext, patchId, List.copyOf(editCollection), false, e.getErrors());
             }
 
-            return new PatchStatusContext(context, patchId, List.copyOf(editCollection), true, null);
+            return new PatchStatusContext(modelContext, patchId, List.copyOf(editCollection), true, null);
         } else {
             tx.cancel();
-            return new PatchStatusContext(context, patchId, List.copyOf(editCollection), false, null);
+            return new PatchStatusContext(modelContext, patchId, List.copyOf(editCollection), false, null);
         }
     }
 
-    private static void insertWithPointPost(final RestconfTransaction tx, final YangInstanceIdentifier path,
+    private void insertWithPointPost(final RestconfTransaction tx, final YangInstanceIdentifier path,
             final NormalizedNode data, final PointParam point, final NormalizedNodeContainer<?> readList,
-            final YangInstanceIdentifier grandParentPath, final boolean before, final EffectiveModelContext context) {
+            final YangInstanceIdentifier grandParentPath, final boolean before) {
         tx.remove(grandParentPath);
-        final var pointArg = YangInstanceIdentifierDeserializer.create(context, point.value()).path
+        // FIXME: this should have happened sooner
+        final var pointArg = YangInstanceIdentifierDeserializer.create(modelContext, point.value()).path
             .getLastPathArgument();
         int lastItemPosition = 0;
         for (var nodeChild : readList.body()) {
@@ -517,22 +519,22 @@ public abstract class RestconfStrategy {
             lastItemPosition++;
         }
         int lastInsertedPosition = 0;
-        final var emptySubtree = ImmutableNodes.fromInstanceId(context, grandParentPath);
+        final var emptySubtree = ImmutableNodes.fromInstanceId(modelContext, grandParentPath);
         tx.merge(YangInstanceIdentifier.of(emptySubtree.name()), emptySubtree);
         for (var nodeChild : readList.body()) {
             if (lastInsertedPosition == lastItemPosition) {
-                tx.replace(path, data, context);
+                tx.replace(path, data);
             }
             final YangInstanceIdentifier childPath = grandParentPath.node(nodeChild.name());
-            tx.replace(childPath, nodeChild, context);
+            tx.replace(childPath, nodeChild);
             lastInsertedPosition++;
         }
     }
 
     private static ListenableFuture<? extends CommitInfo> createAndCommit(final RestconfTransaction tx,
-            final YangInstanceIdentifier path, final NormalizedNode data, final EffectiveModelContext context) {
+            final YangInstanceIdentifier path, final NormalizedNode data) {
         try {
-            tx.create(path, data, context);
+            tx.create(path, data);
         } catch (RestconfDocumentedException e) {
             // close transaction if any and pass exception further
             tx.cancel();
@@ -562,15 +564,13 @@ public abstract class RestconfStrategy {
      * Read specific type of data from data store via transaction. Close {@link DOMTransactionChain} if any
      * inside of object {@link RestconfStrategy} provided as a parameter.
      *
-     * @param content        type of data to read (config, state, all)
-     * @param path           the path to read
-     * @param defaultsMode   value of with-defaults parameter
-     * @param ctx            schema context
+     * @param content      type of data to read (config, state, all)
+     * @param path         the path to read
+     * @param defaultsMode value of with-defaults parameter
      * @return {@link NormalizedNode}
      */
     public @Nullable NormalizedNode readData(final @NonNull ContentParam content,
-            final @NonNull YangInstanceIdentifier path, final WithDefaultsParam defaultsMode,
-            final EffectiveModelContext ctx) {
+            final @NonNull YangInstanceIdentifier path, final WithDefaultsParam defaultsMode) {
         return switch (content) {
             case ALL -> {
                 // PREPARE STATE DATA NODE
@@ -579,11 +579,12 @@ public abstract class RestconfStrategy {
                 final var configDataNode = readDataViaTransaction(LogicalDatastoreType.CONFIGURATION, path);
 
                 yield mergeConfigAndSTateDataIfNeeded(stateDataNode, defaultsMode == null ? configDataNode
-                    : prepareDataByParamWithDef(configDataNode, path, defaultsMode.mode(), ctx));
+                    : prepareDataByParamWithDef(configDataNode, path, defaultsMode.mode()));
             }
             case CONFIG -> {
                 final var read = readDataViaTransaction(LogicalDatastoreType.CONFIGURATION, path);
-                yield defaultsMode == null ? read : prepareDataByParamWithDef(read, path, defaultsMode.mode(), ctx);
+                yield defaultsMode == null ? read
+                    : prepareDataByParamWithDef(read, path, defaultsMode.mode());
             }
             case NONCONFIG -> readDataViaTransaction(LogicalDatastoreType.OPERATIONAL, path);
         };
@@ -593,16 +594,15 @@ public abstract class RestconfStrategy {
      * Read specific type of data from data store via transaction with specified subtrees that should only be read.
      * Close {@link DOMTransactionChain} inside of object {@link RestconfStrategy} provided as a parameter.
      *
-     * @param content        type of data to read (config, state, all)
-     * @param path           the parent path to read
-     * @param withDefa       value of with-defaults parameter
-     * @param ctx            schema context
-     * @param fields         paths to selected subtrees which should be read, relative to to the parent path
+     * @param content  type of data to read (config, state, all)
+     * @param path     the parent path to read
+     * @param withDefa value of with-defaults parameter
+     * @param fields   paths to selected subtrees which should be read, relative to to the parent path
      * @return {@link NormalizedNode}
      */
     public @Nullable NormalizedNode readData(final @NonNull ContentParam content,
             final @NonNull YangInstanceIdentifier path, final @Nullable WithDefaultsParam withDefa,
-            final @NonNull EffectiveModelContext ctx, final @NonNull List<YangInstanceIdentifier> fields) {
+            final @NonNull List<YangInstanceIdentifier> fields) {
         return switch (content) {
             case ALL -> {
                 // PREPARE STATE DATA NODE
@@ -611,11 +611,11 @@ public abstract class RestconfStrategy {
                 final var configDataNode = readDataViaTransaction(LogicalDatastoreType.CONFIGURATION, path, fields);
 
                 yield mergeConfigAndSTateDataIfNeeded(stateDataNode, withDefa == null ? configDataNode
-                    : prepareDataByParamWithDef(configDataNode, path, withDefa.mode(), ctx));
+                    : prepareDataByParamWithDef(configDataNode, path, withDefa.mode()));
             }
             case CONFIG -> {
                 final var read = readDataViaTransaction(LogicalDatastoreType.CONFIGURATION, path, fields);
-                yield withDefa == null ? read : prepareDataByParamWithDef(read, path, withDefa.mode(), ctx);
+                yield withDefa == null ? read : prepareDataByParamWithDef(read, path, withDefa.mode());
             }
             case NONCONFIG -> readDataViaTransaction(LogicalDatastoreType.OPERATIONAL, path, fields);
         };
@@ -642,8 +642,8 @@ public abstract class RestconfStrategy {
         return TransactionUtil.syncAccess(read(store, path, fields), path).orElse(null);
     }
 
-    private static NormalizedNode prepareDataByParamWithDef(final NormalizedNode readData,
-            final YangInstanceIdentifier path, final WithDefaultsMode defaultsMode, final EffectiveModelContext ctx) {
+    private NormalizedNode prepareDataByParamWithDef(final NormalizedNode readData, final YangInstanceIdentifier path,
+            final WithDefaultsMode defaultsMode) {
         final boolean trim = switch (defaultsMode) {
             case Trim -> true;
             case Explicit -> false;
@@ -651,7 +651,8 @@ public abstract class RestconfStrategy {
                 "Unsupported with-defaults value " + defaultsMode.getName());
         };
 
-        final var ctxNode = DataSchemaContextTree.from(ctx).findChild(path).orElseThrow();
+        // FIXME: we have this readily available in InstanceIdentifierContext
+        final var ctxNode = DataSchemaContextTree.from(modelContext).findChild(path).orElseThrow();
         if (readData instanceof ContainerNode container) {
             final var builder = Builders.containerBuilder().withNodeIdentifier(container.name());
             buildCont(builder, container.body(), ctxNode, trim);
@@ -999,5 +1000,4 @@ public abstract class RestconfStrategy {
         configMap.entrySet().stream().filter(x -> stateMap.containsKey(x.getKey())).forEach(
             y -> builder.addChild((T) prepareData(y.getValue(), stateMap.get(y.getKey()))));
     }
-
 }
index 8eddae84c5f3b4e9d3bb394d0480e07db16bab1e..510958bff350245c291c5e6d6f8847a94476b73e 100644 (file)
@@ -22,7 +22,6 @@ import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
 import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNodeContainer;
 import org.opendaylight.yangtools.yang.data.impl.schema.ImmutableNodes;
 import org.opendaylight.yangtools.yang.model.api.EffectiveModelContext;
-import org.opendaylight.yangtools.yang.model.api.SchemaContext;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -34,8 +33,10 @@ import org.slf4j.LoggerFactory;
 abstract class RestconfTransaction {
     private static final Logger LOG = LoggerFactory.getLogger(RestconfTransaction.class);
 
-    RestconfTransaction() {
-        // Hidden on purpose
+    final @NonNull EffectiveModelContext modelContext;
+
+    RestconfTransaction(final EffectiveModelContext modelContext) {
+        this.modelContext = requireNonNull(modelContext);
     }
 
     /**
@@ -94,35 +95,28 @@ abstract class RestconfTransaction {
      *
      * @param path    the data object path
      * @param data    the data object to be merged to the specified path
-     * @param context static view of compiled yang files
      */
-    final void create(final YangInstanceIdentifier path, final NormalizedNode data,
-            final EffectiveModelContext context) {
+    final void create(final YangInstanceIdentifier path, final NormalizedNode data) {
         LOG.trace("Create {}", path);
         LOG.trace(Markers.confidential(), "Create as {}", data.prettyTree());
-        createImpl(requireNonNull(path), data, requireNonNull(context));
+        createImpl(requireNonNull(path), data);
     }
 
-    abstract void createImpl(@NonNull YangInstanceIdentifier path, @NonNull NormalizedNode data,
-        @NonNull EffectiveModelContext context);
+    abstract void createImpl(@NonNull YangInstanceIdentifier path, @NonNull NormalizedNode data);
 
     /**
      * Replace a piece of data at the specified path.
      *
      * @param path    the data object path
      * @param data    the data object to be merged to the specified path
-     * @param context static view of compiled yang files
      */
-    final void replace(final YangInstanceIdentifier path, final NormalizedNode data,
-            final EffectiveModelContext context) {
+    final void replace(final YangInstanceIdentifier path, final NormalizedNode data) {
         LOG.trace("Replace {}", path);
         LOG.trace(Markers.confidential(), "Replace with {}", data.prettyTree());
-        replaceImpl(requireNonNull(path), data, requireNonNull(context));
+        replaceImpl(requireNonNull(path), data);
     }
 
-    abstract void replaceImpl(@NonNull YangInstanceIdentifier path, @NonNull NormalizedNode data,
-        @NonNull EffectiveModelContext context);
-
+    abstract void replaceImpl(@NonNull YangInstanceIdentifier path, @NonNull NormalizedNode data);
 
     final @Nullable NormalizedNodeContainer<?> readList(final YangInstanceIdentifier path) {
         return (NormalizedNodeContainer<?>) TransactionUtil.syncAccess(read(path), path).orElse(null);
@@ -134,11 +128,10 @@ abstract class RestconfTransaction {
      * Merge parents of data.
      *
      * @param path    path of data
-     * @param context {@link SchemaContext}
      */
     // FIXME: this method should only be invoked in MdsalRestconfStrategy, and even then only if we are crossing
     //        an implicit list.
-    final void ensureParentsByMerge(final YangInstanceIdentifier path, final EffectiveModelContext context) {
+    final void ensureParentsByMerge(final YangInstanceIdentifier path) {
         final var normalizedPathWithoutChildArgs = new ArrayList<PathArgument>();
         YangInstanceIdentifier rootNormalizedPath = null;
 
@@ -160,6 +153,6 @@ abstract class RestconfTransaction {
         }
 
         merge(rootNormalizedPath,
-            ImmutableNodes.fromInstanceId(context, YangInstanceIdentifier.of(normalizedPathWithoutChildArgs)));
+            ImmutableNodes.fromInstanceId(modelContext, YangInstanceIdentifier.of(normalizedPathWithoutChildArgs)));
     }
 }
index 69e12d2ed4a7bd227827151f4374451c3b83dba9..38f831dc13abc969ecae0abac3d800d713bcea19 100644 (file)
@@ -64,7 +64,6 @@ import org.opendaylight.restconf.nb.rfc8040.legacy.NormalizedNodePayload;
 import org.opendaylight.restconf.nb.rfc8040.rests.services.api.RestconfStreamsSubscriptionService;
 import org.opendaylight.restconf.nb.rfc8040.rests.transactions.MdsalRestconfStrategy;
 import org.opendaylight.restconf.nb.rfc8040.rests.transactions.NetconfRestconfStrategy;
-import org.opendaylight.restconf.nb.rfc8040.rests.transactions.RestconfStrategy;
 import org.opendaylight.restconf.nb.rfc8040.streams.StreamsConfiguration;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.patch.rev170222.yang.patch.yang.patch.Edit.Operation;
 import org.opendaylight.yangtools.yang.common.ErrorTag;
@@ -470,11 +469,11 @@ public class RestconfDataServiceImplTest extends AbstractJukeboxTest {
 
     @Test
     public void testGetRestconfStrategy() {
-        RestconfStrategy restconfStrategy = dataService.getRestconfStrategy(mountPoint);
+        var restconfStrategy = dataService.getRestconfStrategy(JUKEBOX_SCHEMA, mountPoint);
         assertTrue(restconfStrategy instanceof MdsalRestconfStrategy);
 
         doReturn(Optional.of(netconfService)).when(mountPoint).getService(NetconfDataTreeService.class);
-        restconfStrategy = dataService.getRestconfStrategy(mountPoint);
+        restconfStrategy = dataService.getRestconfStrategy(JUKEBOX_SCHEMA, mountPoint);
         assertTrue(restconfStrategy instanceof NetconfRestconfStrategy);
     }
 }
index 3f6c2fed96dba890d3c28a60890d2f7a21e89fd9..4826c7eed85ba80975011726505df1c1f0cadb5a 100644 (file)
@@ -208,7 +208,7 @@ abstract class AbstractRestconfStrategyTest extends AbstractJukeboxTest {
         new NodeIdentifier(QName.create("ns", "2016-02-28", "container"));
 
     @Mock
-    private EffectiveModelContext mockSchemaContext;
+    EffectiveModelContext mockSchemaContext;
     @Mock
     private UriInfo uriInfo;
 
@@ -242,7 +242,7 @@ abstract class AbstractRestconfStrategyTest extends AbstractJukeboxTest {
 
     @Test
     public final void testPostContainerData() {
-        testPostContainerDataStrategy().postData(JUKEBOX_IID, EMPTY_JUKEBOX, JUKEBOX_SCHEMA, null);
+        testPostContainerDataStrategy().postData(JUKEBOX_IID, EMPTY_JUKEBOX, null);
     }
 
     abstract @NonNull RestconfStrategy testPostContainerDataStrategy();
@@ -250,7 +250,7 @@ abstract class AbstractRestconfStrategyTest extends AbstractJukeboxTest {
     @Test
     public final void testPostListData() {
         testPostListDataStrategy(BAND_ENTRY, PLAYLIST_IID.node(BAND_ENTRY.name())).postData(PLAYLIST_IID, PLAYLIST,
-            JUKEBOX_SCHEMA, null);
+            null);
     }
 
     abstract @NonNull RestconfStrategy testPostListDataStrategy(MapEntryNode entryNode, YangInstanceIdentifier node);
@@ -260,7 +260,7 @@ abstract class AbstractRestconfStrategyTest extends AbstractJukeboxTest {
         final var domException = new DOMException((short) 414, "Post request failed");
 
         RestconfDocumentedException ex = assertThrows(RestconfDocumentedException.class,
-            () -> testPostDataFailStrategy(domException).postData(JUKEBOX_IID, EMPTY_JUKEBOX, JUKEBOX_SCHEMA, null));
+            () -> testPostDataFailStrategy(domException).postData(JUKEBOX_IID, EMPTY_JUKEBOX, null));
         assertEquals(1, ex.getErrors().size());
         assertThat(ex.getErrors().get(0).getErrorInfo(), containsString(domException.getMessage()));
     }
@@ -269,21 +269,21 @@ abstract class AbstractRestconfStrategyTest extends AbstractJukeboxTest {
 
     @Test
     public final void testPatchContainerData() {
-        testPatchContainerDataStrategy().merge(JUKEBOX_IID, EMPTY_JUKEBOX, JUKEBOX_SCHEMA).getOrThrow();
+        testPatchContainerDataStrategy().merge(JUKEBOX_IID, EMPTY_JUKEBOX).getOrThrow();
     }
 
     abstract @NonNull RestconfStrategy testPatchContainerDataStrategy();
 
     @Test
     public final void testPatchLeafData() {
-        testPatchLeafDataStrategy().merge(GAP_IID, GAP_LEAF, JUKEBOX_SCHEMA).getOrThrow();
+        testPatchLeafDataStrategy().merge(GAP_IID, GAP_LEAF).getOrThrow();
     }
 
     abstract @NonNull RestconfStrategy testPatchLeafDataStrategy();
 
     @Test
     public final void testPatchListData() {
-        testPatchListDataStrategy().merge(JUKEBOX_IID, JUKEBOX_WITH_PLAYLIST, JUKEBOX_SCHEMA).getOrThrow();
+        testPatchListDataStrategy().merge(JUKEBOX_IID, JUKEBOX_WITH_PLAYLIST).getOrThrow();
     }
 
     abstract @NonNull RestconfStrategy testPatchListDataStrategy();
@@ -329,7 +329,7 @@ abstract class AbstractRestconfStrategyTest extends AbstractJukeboxTest {
     @Test
     public final void testDeleteNonexistentData() {
         final var patchStatusContext = deleteNonexistentDataTestStrategy().patchData(new PatchContext("patchD",
-            List.of(new PatchEntity("edit", Operation.Delete, CREATE_AND_DELETE_TARGET))), JUKEBOX_SCHEMA);
+            List.of(new PatchEntity("edit", Operation.Delete, CREATE_AND_DELETE_TARGET))));
         assertFalse(patchStatusContext.ok());
     }
 
@@ -461,13 +461,13 @@ abstract class AbstractRestconfStrategyTest extends AbstractJukeboxTest {
      * @param strategy       {@link RestconfStrategy} - wrapper for variables
      * @return {@link NormalizedNode}
      */
-    private @Nullable NormalizedNode readData(final @NonNull ContentParam content,
+    private static @Nullable NormalizedNode readData(final @NonNull ContentParam content,
             final YangInstanceIdentifier path, final @NonNull RestconfStrategy strategy) {
-        return strategy.readData(content, path, null, mockSchemaContext);
+        return strategy.readData(content, path, null);
     }
 
     private static void patch(final PatchContext patchContext, final RestconfStrategy strategy, final boolean failed) {
-        final var patchStatusContext = strategy.patchData(patchContext, JUKEBOX_SCHEMA);
+        final var patchStatusContext = strategy.patchData(patchContext);
         for (var entity : patchStatusContext.editCollection()) {
             if (failed) {
                 assertTrue("Edit " + entity.getEditId() + " failed", entity.isOk());
index 2ccf2bee20e746325fbc7049b99762f52a033885..945f2ff6701e39ee63394845de6745a37d6cac65 100644 (file)
@@ -77,7 +77,7 @@ public final class MdsalRestconfStrategyTest extends AbstractRestconfStrategyTes
         // assert that data to delete exists
         when(readWrite.exists(LogicalDatastoreType.CONFIGURATION, YangInstanceIdentifier.of()))
             .thenReturn(immediateTrueFluentFuture());
-        return new MdsalRestconfStrategy(mockDataBroker);
+        return new MdsalRestconfStrategy(JUKEBOX_SCHEMA, mockDataBroker);
     }
 
     @Override
@@ -85,7 +85,7 @@ public final class MdsalRestconfStrategyTest extends AbstractRestconfStrategyTes
         // assert that data to delete does NOT exist
         when(readWrite.exists(LogicalDatastoreType.CONFIGURATION, YangInstanceIdentifier.of()))
             .thenReturn(immediateFalseFluentFuture());
-        return new MdsalRestconfStrategy(mockDataBroker);
+        return new MdsalRestconfStrategy(JUKEBOX_SCHEMA, mockDataBroker);
     }
 
     @Override
@@ -93,7 +93,7 @@ public final class MdsalRestconfStrategyTest extends AbstractRestconfStrategyTes
         doReturn(immediateFalseFluentFuture()).when(readWrite).exists(LogicalDatastoreType.CONFIGURATION, node);
         doNothing().when(readWrite).put(LogicalDatastoreType.CONFIGURATION, node, entryNode);
         doReturn(CommitInfo.emptyFluentFuture()).when(readWrite).commit();
-        return new MdsalRestconfStrategy(mockDataBroker);
+        return new MdsalRestconfStrategy(JUKEBOX_SCHEMA, mockDataBroker);
     }
 
     @Override
@@ -101,7 +101,7 @@ public final class MdsalRestconfStrategyTest extends AbstractRestconfStrategyTes
         doReturn(immediateFalseFluentFuture()).when(readWrite).exists(LogicalDatastoreType.CONFIGURATION, JUKEBOX_IID);
         doReturn(immediateFailedFluentFuture(domException)).when(readWrite).commit();
         doNothing().when(readWrite).put(LogicalDatastoreType.CONFIGURATION, JUKEBOX_IID, EMPTY_JUKEBOX);
-        return new MdsalRestconfStrategy(mockDataBroker);
+        return new MdsalRestconfStrategy(JUKEBOX_SCHEMA, mockDataBroker);
     }
 
     @Test
@@ -112,7 +112,7 @@ public final class MdsalRestconfStrategyTest extends AbstractRestconfStrategyTes
         doNothing().when(readWrite).put(LogicalDatastoreType.CONFIGURATION, JUKEBOX_IID, EMPTY_JUKEBOX);
         doReturn(CommitInfo.emptyFluentFuture()).when(readWrite).commit();
 
-        new MdsalRestconfStrategy(mockDataBroker).putData(JUKEBOX_IID, EMPTY_JUKEBOX, JUKEBOX_SCHEMA, null);
+        new MdsalRestconfStrategy(JUKEBOX_SCHEMA, mockDataBroker).putData(JUKEBOX_IID, EMPTY_JUKEBOX, null);
         verify(read).exists(LogicalDatastoreType.CONFIGURATION, JUKEBOX_IID);
         verify(readWrite).put(LogicalDatastoreType.CONFIGURATION, JUKEBOX_IID, EMPTY_JUKEBOX);
     }
@@ -125,7 +125,7 @@ public final class MdsalRestconfStrategyTest extends AbstractRestconfStrategyTes
         doNothing().when(readWrite).put(LogicalDatastoreType.CONFIGURATION, GAP_IID, GAP_LEAF);
         doReturn(CommitInfo.emptyFluentFuture()).when(readWrite).commit();
 
-        new MdsalRestconfStrategy(mockDataBroker).putData(GAP_IID, GAP_LEAF, JUKEBOX_SCHEMA, null);
+        new MdsalRestconfStrategy(JUKEBOX_SCHEMA, mockDataBroker).putData(GAP_IID, GAP_LEAF, null);
         verify(read).exists(LogicalDatastoreType.CONFIGURATION, GAP_IID);
         verify(readWrite).put(LogicalDatastoreType.CONFIGURATION, GAP_IID, GAP_LEAF);
     }
@@ -140,7 +140,7 @@ public final class MdsalRestconfStrategyTest extends AbstractRestconfStrategyTes
         doNothing().when(readWrite).put(LogicalDatastoreType.CONFIGURATION, JUKEBOX_IID, JUKEBOX_WITH_BANDS);
         doReturn(CommitInfo.emptyFluentFuture()).when(readWrite).commit();
 
-        new MdsalRestconfStrategy(mockDataBroker).putData(JUKEBOX_IID, JUKEBOX_WITH_BANDS, JUKEBOX_SCHEMA, null);
+        new MdsalRestconfStrategy(JUKEBOX_SCHEMA, mockDataBroker).putData(JUKEBOX_IID, JUKEBOX_WITH_BANDS, null);
         verify(read).exists(LogicalDatastoreType.CONFIGURATION, JUKEBOX_IID);
         verify(readWrite).put(LogicalDatastoreType.CONFIGURATION, JUKEBOX_IID, JUKEBOX_WITH_BANDS);
     }
@@ -150,33 +150,33 @@ public final class MdsalRestconfStrategyTest extends AbstractRestconfStrategyTes
         doReturn(immediateFalseFluentFuture()).when(readWrite).exists(LogicalDatastoreType.CONFIGURATION, JUKEBOX_IID);
         doNothing().when(readWrite).put(LogicalDatastoreType.CONFIGURATION, JUKEBOX_IID, EMPTY_JUKEBOX);
         doReturn(CommitInfo.emptyFluentFuture()).when(readWrite).commit();
-        return new MdsalRestconfStrategy(mockDataBroker);
+        return new MdsalRestconfStrategy(JUKEBOX_SCHEMA, mockDataBroker);
     }
 
     @Override
     RestconfStrategy testPatchContainerDataStrategy() {
         doReturn(readWrite).when(mockDataBroker).newReadWriteTransaction();
         doReturn(CommitInfo.emptyFluentFuture()).when(readWrite).commit();
-        return new MdsalRestconfStrategy(mockDataBroker);
+        return new MdsalRestconfStrategy(JUKEBOX_SCHEMA, mockDataBroker);
     }
 
     @Override
     RestconfStrategy testPatchLeafDataStrategy() {
         doReturn(readWrite).when(mockDataBroker).newReadWriteTransaction();
         doReturn(CommitInfo.emptyFluentFuture()).when(readWrite).commit();
-        return new MdsalRestconfStrategy(mockDataBroker);
+        return new MdsalRestconfStrategy(JUKEBOX_SCHEMA, mockDataBroker);
     }
 
     @Override
     RestconfStrategy testPatchListDataStrategy() {
         doReturn(readWrite).when(mockDataBroker).newReadWriteTransaction();
         doReturn(CommitInfo.emptyFluentFuture()).when(readWrite).commit();
-        return new MdsalRestconfStrategy(mockDataBroker);
+        return new MdsalRestconfStrategy(JUKEBOX_SCHEMA, mockDataBroker);
     }
 
     @Override
     RestconfStrategy testPatchDataReplaceMergeAndRemoveStrategy() {
-        return new MdsalRestconfStrategy(mockDataBroker);
+        return new MdsalRestconfStrategy(JUKEBOX_SCHEMA, mockDataBroker);
     }
 
     @Override
@@ -184,19 +184,19 @@ public final class MdsalRestconfStrategyTest extends AbstractRestconfStrategyTes
         doReturn(immediateFalseFluentFuture()).when(readWrite).exists(LogicalDatastoreType.CONFIGURATION, PLAYER_IID);
         doReturn(immediateTrueFluentFuture()).when(readWrite).exists(LogicalDatastoreType.CONFIGURATION,
             CREATE_AND_DELETE_TARGET);
-        return new MdsalRestconfStrategy(mockDataBroker);
+        return new MdsalRestconfStrategy(JUKEBOX_SCHEMA, mockDataBroker);
     }
 
     @Override
     RestconfStrategy testPatchMergePutContainerStrategy() {
-        return new MdsalRestconfStrategy(mockDataBroker);
+        return new MdsalRestconfStrategy(JUKEBOX_SCHEMA, mockDataBroker);
     }
 
     @Override
     RestconfStrategy deleteNonexistentDataTestStrategy() {
         doReturn(immediateFalseFluentFuture()).when(readWrite).exists(LogicalDatastoreType.CONFIGURATION,
             CREATE_AND_DELETE_TARGET);
-        return new MdsalRestconfStrategy(mockDataBroker);
+        return new MdsalRestconfStrategy(JUKEBOX_SCHEMA, mockDataBroker);
     }
 
     @Override
@@ -215,7 +215,7 @@ public final class MdsalRestconfStrategyTest extends AbstractRestconfStrategyTes
         doReturn(read).when(mockDataBroker).newReadOnlyTransaction();
         doReturn(immediateFluentFuture(Optional.of(DATA_3))).when(read)
             .read(LogicalDatastoreType.CONFIGURATION, PATH);
-        return new MdsalRestconfStrategy(mockDataBroker);
+        return new MdsalRestconfStrategy(mockSchemaContext, mockDataBroker);
     }
 
     @Override
@@ -225,7 +225,7 @@ public final class MdsalRestconfStrategyTest extends AbstractRestconfStrategyTes
             .read(LogicalDatastoreType.CONFIGURATION, PATH);
         doReturn(immediateFluentFuture(Optional.empty())).when(read)
             .read(LogicalDatastoreType.OPERATIONAL, PATH);
-        return new MdsalRestconfStrategy(mockDataBroker);
+        return new MdsalRestconfStrategy(mockSchemaContext, mockDataBroker);
     }
 
     @Override
@@ -235,7 +235,7 @@ public final class MdsalRestconfStrategyTest extends AbstractRestconfStrategyTes
             .read(LogicalDatastoreType.OPERATIONAL, PATH_2);
         doReturn(immediateFluentFuture(Optional.empty())).when(read)
             .read(LogicalDatastoreType.CONFIGURATION, PATH_2);
-        return new MdsalRestconfStrategy(mockDataBroker);
+        return new MdsalRestconfStrategy(mockSchemaContext, mockDataBroker);
     }
 
     @Override
@@ -243,7 +243,7 @@ public final class MdsalRestconfStrategyTest extends AbstractRestconfStrategyTes
         doReturn(read).when(mockDataBroker).newReadOnlyTransaction();
         doReturn(immediateFluentFuture(Optional.of(DATA_2))).when(read)
             .read(LogicalDatastoreType.OPERATIONAL, PATH_2);
-        return new MdsalRestconfStrategy(mockDataBroker);
+        return new MdsalRestconfStrategy(mockSchemaContext, mockDataBroker);
     }
 
     @Override
@@ -253,7 +253,7 @@ public final class MdsalRestconfStrategyTest extends AbstractRestconfStrategyTes
             .read(LogicalDatastoreType.CONFIGURATION, PATH);
         doReturn(immediateFluentFuture(Optional.of(DATA_4))).when(read)
             .read(LogicalDatastoreType.OPERATIONAL, PATH);
-        return new MdsalRestconfStrategy(mockDataBroker);
+        return new MdsalRestconfStrategy(mockSchemaContext, mockDataBroker);
     }
 
     @Override
@@ -263,7 +263,7 @@ public final class MdsalRestconfStrategyTest extends AbstractRestconfStrategyTes
             .read(LogicalDatastoreType.CONFIGURATION, PATH);
         doReturn(immediateFluentFuture(Optional.of(DATA_4))).when(read)
             .read(LogicalDatastoreType.OPERATIONAL, PATH);
-        return new MdsalRestconfStrategy(mockDataBroker);
+        return new MdsalRestconfStrategy(mockSchemaContext, mockDataBroker);
     }
 
     @Override
@@ -273,7 +273,7 @@ public final class MdsalRestconfStrategyTest extends AbstractRestconfStrategyTes
             .read(LogicalDatastoreType.OPERATIONAL, PATH_3);
         doReturn(immediateFluentFuture(Optional.of(LIST_DATA_2))).when(read)
             .read(LogicalDatastoreType.CONFIGURATION, PATH_3);
-        return new MdsalRestconfStrategy(mockDataBroker);
+        return new MdsalRestconfStrategy(mockSchemaContext, mockDataBroker);
     }
 
     @Override
@@ -283,7 +283,7 @@ public final class MdsalRestconfStrategyTest extends AbstractRestconfStrategyTes
             .read(LogicalDatastoreType.OPERATIONAL, PATH_3);
         doReturn(immediateFluentFuture(Optional.of(ORDERED_MAP_NODE_2))).when(read)
             .read(LogicalDatastoreType.CONFIGURATION, PATH_3);
-        return new MdsalRestconfStrategy(mockDataBroker);
+        return new MdsalRestconfStrategy(mockSchemaContext, mockDataBroker);
     }
 
     @Override
@@ -293,7 +293,7 @@ public final class MdsalRestconfStrategyTest extends AbstractRestconfStrategyTes
             .read(LogicalDatastoreType.OPERATIONAL, PATH_3);
         doReturn(immediateFluentFuture(Optional.of(UNKEYED_LIST_NODE_2))).when(read)
             .read(LogicalDatastoreType.CONFIGURATION, PATH_3);
-        return new MdsalRestconfStrategy(mockDataBroker);
+        return new MdsalRestconfStrategy(mockSchemaContext, mockDataBroker);
     }
 
     @Override
@@ -303,7 +303,7 @@ public final class MdsalRestconfStrategyTest extends AbstractRestconfStrategyTes
             .read(LogicalDatastoreType.OPERATIONAL, LEAF_SET_NODE_PATH);
         doReturn(immediateFluentFuture(Optional.of(LEAF_SET_NODE_2))).when(read)
             .read(LogicalDatastoreType.CONFIGURATION, LEAF_SET_NODE_PATH);
-        return new MdsalRestconfStrategy(mockDataBroker);
+        return new MdsalRestconfStrategy(mockSchemaContext, mockDataBroker);
     }
 
     @Override
@@ -313,14 +313,14 @@ public final class MdsalRestconfStrategyTest extends AbstractRestconfStrategyTes
             .read(LogicalDatastoreType.OPERATIONAL, LEAF_SET_NODE_PATH);
         doReturn(immediateFluentFuture(Optional.of(ORDERED_LEAF_SET_NODE_2))).when(read)
             .read(LogicalDatastoreType.CONFIGURATION, LEAF_SET_NODE_PATH);
-        return new MdsalRestconfStrategy(mockDataBroker);
+        return new MdsalRestconfStrategy(mockSchemaContext, mockDataBroker);
     }
 
     @Override
     RestconfStrategy readDataWrongPathOrNoContentTestStrategy() {
         doReturn(read).when(mockDataBroker).newReadOnlyTransaction();
         doReturn(immediateFluentFuture(Optional.empty())).when(read).read(LogicalDatastoreType.CONFIGURATION, PATH_2);
-        return new MdsalRestconfStrategy(mockDataBroker);
+        return new MdsalRestconfStrategy(mockSchemaContext, mockDataBroker);
     }
 
     @Test
@@ -336,8 +336,8 @@ public final class MdsalRestconfStrategyTest extends AbstractRestconfStrategyTes
         doReturn(immediateFluentFuture(Optional.of(data))).when(read)
                 .read(LogicalDatastoreType.OPERATIONAL, path);
 
-        assertEquals(data, new MdsalRestconfStrategy(mockDataBroker).readData(ContentParam.ALL, path,
-            WithDefaultsParam.TRIM, MODULES_SCHEMA));
+        assertEquals(data, new MdsalRestconfStrategy(MODULES_SCHEMA, mockDataBroker).readData(ContentParam.ALL, path,
+            WithDefaultsParam.TRIM));
     }
 
     @Test
@@ -367,8 +367,8 @@ public final class MdsalRestconfStrategyTest extends AbstractRestconfStrategyTes
         doReturn(immediateFluentFuture(Optional.of(data))).when(read)
                 .read(LogicalDatastoreType.OPERATIONAL, path);
 
-        assertEquals(data, new MdsalRestconfStrategy(mockDataBroker).readData(ContentParam.ALL, path,
-            WithDefaultsParam.TRIM, MODULES_SCHEMA));
+        assertEquals(data, new MdsalRestconfStrategy(MODULES_SCHEMA, mockDataBroker).readData(ContentParam.ALL, path,
+            WithDefaultsParam.TRIM));
     }
 
     @Test
@@ -391,7 +391,7 @@ public final class MdsalRestconfStrategyTest extends AbstractRestconfStrategyTes
         doReturn(immediateFluentFuture(Optional.of(content))).when(read)
                 .read(LogicalDatastoreType.OPERATIONAL, path);
 
-        assertEquals(content, new MdsalRestconfStrategy(mockDataBroker).readData(ContentParam.ALL, path,
-            WithDefaultsParam.TRIM, MODULES_SCHEMA));
+        assertEquals(content, new MdsalRestconfStrategy(MODULES_SCHEMA, mockDataBroker).readData(ContentParam.ALL, path,
+            WithDefaultsParam.TRIM));
     }
 }
index 37f331e46aeaa946169b739f2dbcce36f6899bde..380273e63520e3b7078c771bb8a6a8c0f54067ad 100644 (file)
@@ -55,7 +55,7 @@ public final class NetconfRestconfStrategyTest extends AbstractRestconfStrategyT
 
     @Override
     RestconfStrategy testDeleteDataStrategy() {
-        return new NetconfRestconfStrategy(netconfService);
+        return new NetconfRestconfStrategy(JUKEBOX_SCHEMA, netconfService);
     }
 
     @Override
@@ -63,7 +63,7 @@ public final class NetconfRestconfStrategyTest extends AbstractRestconfStrategyT
         doReturn(Futures.immediateFailedFuture(new TransactionCommitFailedException(
             "Commit of transaction " + this + " failed", new NetconfDocumentedException("id",
                 ErrorType.RPC, ErrorTag.DATA_MISSING, ErrorSeverity.ERROR)))).when(netconfService).commit();
-        return new NetconfRestconfStrategy(netconfService);
+        return new NetconfRestconfStrategy(JUKEBOX_SCHEMA, netconfService);
     }
 
     @Override
@@ -71,33 +71,35 @@ public final class NetconfRestconfStrategyTest extends AbstractRestconfStrategyT
         doReturn(Futures.immediateFuture(new DefaultDOMRpcResult())).when(netconfService).commit();
         doReturn(Futures.immediateFuture(new DefaultDOMRpcResult())).when(netconfService)
             .create(LogicalDatastoreType.CONFIGURATION, JUKEBOX_IID, EMPTY_JUKEBOX, Optional.empty());
-        return new NetconfRestconfStrategy(netconfService);
+        return new NetconfRestconfStrategy(JUKEBOX_SCHEMA, netconfService);
     }
 
     @Override
     RestconfStrategy testPostListDataStrategy(final MapEntryNode entryNode, final YangInstanceIdentifier node) {
         doReturn(Futures.immediateFuture(new DefaultDOMRpcResult())).when(netconfService)
+            // FIXME: exact match
             .merge(any(), any(), any(), any());
         doReturn(Futures.immediateFuture(new DefaultDOMRpcResult())).when(netconfService).commit();
         doReturn(Futures.immediateFuture(new DefaultDOMRpcResult())).when(netconfService).create(
             LogicalDatastoreType.CONFIGURATION, node, entryNode, Optional.empty());
-        return new NetconfRestconfStrategy(netconfService);
+        return new NetconfRestconfStrategy(JUKEBOX_SCHEMA, netconfService);
     }
 
     @Override
     RestconfStrategy testPostDataFailStrategy(final DOMException domException) {
         doReturn(immediateFailedFluentFuture(domException)).when(netconfService)
+            // FIXME: exact match
             .create(any(), any(), any(), any());
         doReturn(Futures.immediateFuture(new DefaultDOMRpcResult())).when(netconfService).discardChanges();
         doReturn(Futures.immediateFuture(new DefaultDOMRpcResult())).when(netconfService).unlock();
-        return new NetconfRestconfStrategy(netconfService);
+        return new NetconfRestconfStrategy(JUKEBOX_SCHEMA, netconfService);
     }
 
     @Override
     RestconfStrategy testPatchContainerDataStrategy() {
         doReturn(Futures.immediateFuture(new DefaultDOMRpcResult())).when(netconfService).merge(any(), any(),any(),
             any());
-        return new NetconfRestconfStrategy(netconfService);
+        return new NetconfRestconfStrategy(JUKEBOX_SCHEMA, netconfService);
     }
 
     @Override
@@ -105,7 +107,7 @@ public final class NetconfRestconfStrategyTest extends AbstractRestconfStrategyT
         doReturn(Futures.immediateFuture(new DefaultDOMRpcResult())).when(netconfService)
             .merge(any(), any(), any(), any());
         doReturn(Futures.immediateFuture(new DefaultDOMRpcResult())).when(netconfService).commit();
-        return new NetconfRestconfStrategy(netconfService);
+        return new NetconfRestconfStrategy(JUKEBOX_SCHEMA, netconfService);
     }
 
     @Override
@@ -113,7 +115,7 @@ public final class NetconfRestconfStrategyTest extends AbstractRestconfStrategyT
         doReturn(Futures.immediateFuture(new DefaultDOMRpcResult())).when(netconfService).commit();
         doReturn(Futures.immediateFuture(new DefaultDOMRpcResult())).when(netconfService)
             .merge(any(), any(),any(),any());
-        return new NetconfRestconfStrategy(netconfService);
+        return new NetconfRestconfStrategy(JUKEBOX_SCHEMA, netconfService);
     }
 
     @Test
@@ -123,7 +125,7 @@ public final class NetconfRestconfStrategyTest extends AbstractRestconfStrategyT
         doReturn(Futures.immediateFuture(new DefaultDOMRpcResult())).when(netconfService)
             .replace(LogicalDatastoreType.CONFIGURATION, JUKEBOX_IID, EMPTY_JUKEBOX, Optional.empty());
 
-        new NetconfRestconfStrategy(netconfService).putData(JUKEBOX_IID, EMPTY_JUKEBOX, JUKEBOX_SCHEMA, null);
+        new NetconfRestconfStrategy(JUKEBOX_SCHEMA, netconfService).putData(JUKEBOX_IID, EMPTY_JUKEBOX, null);
         verify(netconfService).lock();
         verify(netconfService).getConfig(JUKEBOX_IID);
         verify(netconfService).replace(LogicalDatastoreType.CONFIGURATION, JUKEBOX_IID, EMPTY_JUKEBOX,
@@ -138,7 +140,7 @@ public final class NetconfRestconfStrategyTest extends AbstractRestconfStrategyT
         doReturn(Futures.immediateFuture(new DefaultDOMRpcResult())).when(netconfService)
             .replace(LogicalDatastoreType.CONFIGURATION, JUKEBOX_IID, EMPTY_JUKEBOX, Optional.empty());
 
-        new NetconfRestconfStrategy(netconfService).putData(JUKEBOX_IID, EMPTY_JUKEBOX, JUKEBOX_SCHEMA, null);
+        new NetconfRestconfStrategy(JUKEBOX_SCHEMA, netconfService).putData(JUKEBOX_IID, EMPTY_JUKEBOX, null);
         verify(netconfService).getConfig(JUKEBOX_IID);
         verify(netconfService).replace(LogicalDatastoreType.CONFIGURATION, JUKEBOX_IID, EMPTY_JUKEBOX,
             Optional.empty());
@@ -151,7 +153,7 @@ public final class NetconfRestconfStrategyTest extends AbstractRestconfStrategyT
         doReturn(Futures.immediateFuture(new DefaultDOMRpcResult())).when(netconfService)
             .replace(LogicalDatastoreType.CONFIGURATION, GAP_IID, GAP_LEAF, Optional.empty());
 
-        new NetconfRestconfStrategy(netconfService).putData(GAP_IID, GAP_LEAF, JUKEBOX_SCHEMA, null);
+        new NetconfRestconfStrategy(JUKEBOX_SCHEMA, netconfService).putData(GAP_IID, GAP_LEAF, null);
         verify(netconfService).getConfig(GAP_IID);
         verify(netconfService).replace(LogicalDatastoreType.CONFIGURATION, GAP_IID, GAP_LEAF, Optional.empty());
     }
@@ -164,7 +166,7 @@ public final class NetconfRestconfStrategyTest extends AbstractRestconfStrategyT
         doReturn(Futures.immediateFuture(new DefaultDOMRpcResult())).when(netconfService)
             .replace(LogicalDatastoreType.CONFIGURATION, GAP_IID, GAP_LEAF, Optional.empty());
 
-        new NetconfRestconfStrategy(netconfService).putData(GAP_IID, GAP_LEAF, JUKEBOX_SCHEMA, null);
+        new NetconfRestconfStrategy(JUKEBOX_SCHEMA, netconfService).putData(GAP_IID, GAP_LEAF, null);
         verify(netconfService).getConfig(GAP_IID);
         verify(netconfService).replace(LogicalDatastoreType.CONFIGURATION, GAP_IID, GAP_LEAF, Optional.empty());
     }
@@ -176,7 +178,7 @@ public final class NetconfRestconfStrategyTest extends AbstractRestconfStrategyT
         doReturn(Futures.immediateFuture(new DefaultDOMRpcResult())).when(netconfService)
             .replace(LogicalDatastoreType.CONFIGURATION, JUKEBOX_IID, JUKEBOX_WITH_BANDS, Optional.empty());
 
-        new NetconfRestconfStrategy(netconfService).putData(JUKEBOX_IID, JUKEBOX_WITH_BANDS, JUKEBOX_SCHEMA, null);
+        new NetconfRestconfStrategy(JUKEBOX_SCHEMA, netconfService).putData(JUKEBOX_IID, JUKEBOX_WITH_BANDS, null);
         verify(netconfService).getConfig(JUKEBOX_IID);
         verify(netconfService).replace(LogicalDatastoreType.CONFIGURATION, JUKEBOX_IID, JUKEBOX_WITH_BANDS,
             Optional.empty());
@@ -190,7 +192,7 @@ public final class NetconfRestconfStrategyTest extends AbstractRestconfStrategyT
         doReturn(Futures.immediateFuture(new DefaultDOMRpcResult())).when(netconfService)
             .replace(LogicalDatastoreType.CONFIGURATION, JUKEBOX_IID, JUKEBOX_WITH_BANDS, Optional.empty());
 
-        new NetconfRestconfStrategy(netconfService).putData(JUKEBOX_IID, JUKEBOX_WITH_BANDS, JUKEBOX_SCHEMA, null);
+        new NetconfRestconfStrategy(JUKEBOX_SCHEMA, netconfService).putData(JUKEBOX_IID, JUKEBOX_WITH_BANDS, null);
         verify(netconfService).getConfig(JUKEBOX_IID);
         verify(netconfService).replace(LogicalDatastoreType.CONFIGURATION, JUKEBOX_IID, JUKEBOX_WITH_BANDS,
             Optional.empty());
@@ -201,8 +203,9 @@ public final class NetconfRestconfStrategyTest extends AbstractRestconfStrategyT
         doReturn(Futures.immediateFuture(new DefaultDOMRpcResult())).when(netconfService)
             .remove(LogicalDatastoreType.CONFIGURATION, ARTIST_IID);
         doReturn(Futures.immediateFuture(new DefaultDOMRpcResult())).when(netconfService)
+            // FIXME: exact match
             .replace(any(), any(), any(), any());
-        return new NetconfRestconfStrategy(netconfService);
+        return new NetconfRestconfStrategy(JUKEBOX_SCHEMA, netconfService);
     }
 
     @Override
@@ -211,12 +214,12 @@ public final class NetconfRestconfStrategyTest extends AbstractRestconfStrategyT
             .create(LogicalDatastoreType.CONFIGURATION, PLAYER_IID, EMPTY_JUKEBOX, Optional.empty());
         doReturn(Futures.immediateFuture(new DefaultDOMRpcResult())).when(netconfService)
             .delete(LogicalDatastoreType.CONFIGURATION, CREATE_AND_DELETE_TARGET);
-        return new NetconfRestconfStrategy(netconfService);
+        return new NetconfRestconfStrategy(JUKEBOX_SCHEMA, netconfService);
     }
 
     @Override
     RestconfStrategy testPatchMergePutContainerStrategy() {
-        return new NetconfRestconfStrategy(netconfService);
+        return new NetconfRestconfStrategy(JUKEBOX_SCHEMA, netconfService);
     }
 
     @Override
@@ -227,7 +230,7 @@ public final class NetconfRestconfStrategyTest extends AbstractRestconfStrategyT
             .when(netconfService).commit();
         doReturn(Futures.immediateFuture(new DefaultDOMRpcResult())).when(netconfService)
             .delete(LogicalDatastoreType.CONFIGURATION, CREATE_AND_DELETE_TARGET);
-        return new NetconfRestconfStrategy(netconfService);
+        return new NetconfRestconfStrategy(JUKEBOX_SCHEMA, netconfService);
     }
 
     @Override
@@ -242,62 +245,62 @@ public final class NetconfRestconfStrategyTest extends AbstractRestconfStrategyT
     @Override
     RestconfStrategy readDataConfigTestStrategy() {
         doReturn(immediateFluentFuture(Optional.of(DATA_3))).when(netconfService).getConfig(PATH);
-        return new NetconfRestconfStrategy(netconfService);
+        return new NetconfRestconfStrategy(mockSchemaContext, netconfService);
     }
 
     @Override
     RestconfStrategy readAllHavingOnlyConfigTestStrategy() {
         doReturn(immediateFluentFuture(Optional.of(DATA_3))).when(netconfService).getConfig(PATH);
         doReturn(immediateFluentFuture(Optional.empty())).when(netconfService).get(PATH);
-        return new NetconfRestconfStrategy(netconfService);
+        return new NetconfRestconfStrategy(mockSchemaContext, netconfService);
     }
 
     @Override
     RestconfStrategy readAllHavingOnlyNonConfigTestStrategy() {
         doReturn(immediateFluentFuture(Optional.of(DATA_2))).when(netconfService).get(PATH_2);
         doReturn(immediateFluentFuture(Optional.empty())).when(netconfService).getConfig(PATH_2);
-        return new NetconfRestconfStrategy(netconfService);
+        return new NetconfRestconfStrategy(mockSchemaContext, netconfService);
     }
 
     @Override
     RestconfStrategy readDataNonConfigTestStrategy() {
         doReturn(immediateFluentFuture(Optional.of(DATA_2))).when(netconfService).get(PATH_2);
-        return new NetconfRestconfStrategy(netconfService);
+        return new NetconfRestconfStrategy(mockSchemaContext, netconfService);
     }
 
     @Override
     RestconfStrategy readContainerDataAllTestStrategy() {
         doReturn(immediateFluentFuture(Optional.of(DATA_3))).when(netconfService).getConfig(PATH);
         doReturn(immediateFluentFuture(Optional.of(DATA_4))).when(netconfService).get(PATH);
-        return new NetconfRestconfStrategy(netconfService);
+        return new NetconfRestconfStrategy(mockSchemaContext, netconfService);
     }
 
     @Override
     RestconfStrategy readContainerDataConfigNoValueOfContentTestStrategy() {
         doReturn(immediateFluentFuture(Optional.of(DATA_3))).when(netconfService).getConfig(PATH);
         doReturn(immediateFluentFuture(Optional.of(DATA_4))).when(netconfService).get(PATH);
-        return new NetconfRestconfStrategy(netconfService);
+        return new NetconfRestconfStrategy(mockSchemaContext, netconfService);
     }
 
     @Override
     RestconfStrategy readListDataAllTestStrategy() {
         doReturn(immediateFluentFuture(Optional.of(LIST_DATA))).when(netconfService).get(PATH_3);
         doReturn(immediateFluentFuture(Optional.of(LIST_DATA_2))).when(netconfService).getConfig(PATH_3);
-        return new NetconfRestconfStrategy(netconfService);
+        return new NetconfRestconfStrategy(mockSchemaContext, netconfService);
     }
 
     @Override
     RestconfStrategy readOrderedListDataAllTestStrategy() {
         doReturn(immediateFluentFuture(Optional.of(ORDERED_MAP_NODE_1))).when(netconfService).get(PATH_3);
         doReturn(immediateFluentFuture(Optional.of(ORDERED_MAP_NODE_2))).when(netconfService).getConfig(PATH_3);
-        return new NetconfRestconfStrategy(netconfService);
+        return new NetconfRestconfStrategy(mockSchemaContext, netconfService);
     }
 
     @Override
     RestconfStrategy readUnkeyedListDataAllTestStrategy() {
         doReturn(immediateFluentFuture(Optional.of(UNKEYED_LIST_NODE_1))).when(netconfService).get(PATH_3);
         doReturn(immediateFluentFuture(Optional.of(UNKEYED_LIST_NODE_2))).when(netconfService).getConfig(PATH_3);
-        return new NetconfRestconfStrategy(netconfService);
+        return new NetconfRestconfStrategy(mockSchemaContext, netconfService);
     }
 
     @Override
@@ -306,7 +309,7 @@ public final class NetconfRestconfStrategyTest extends AbstractRestconfStrategyT
             .get(LEAF_SET_NODE_PATH);
         doReturn(immediateFluentFuture(Optional.of(LEAF_SET_NODE_2))).when(netconfService)
             .getConfig(LEAF_SET_NODE_PATH);
-        return new NetconfRestconfStrategy(netconfService);
+        return new NetconfRestconfStrategy(mockSchemaContext, netconfService);
     }
 
     @Override
@@ -315,12 +318,12 @@ public final class NetconfRestconfStrategyTest extends AbstractRestconfStrategyT
             .get(LEAF_SET_NODE_PATH);
         doReturn(immediateFluentFuture(Optional.of(ORDERED_LEAF_SET_NODE_2))).when(netconfService)
             .getConfig(LEAF_SET_NODE_PATH);
-        return new NetconfRestconfStrategy(netconfService);
+        return new NetconfRestconfStrategy(mockSchemaContext, netconfService);
     }
 
     @Override
     RestconfStrategy readDataWrongPathOrNoContentTestStrategy() {
         doReturn(immediateFluentFuture(Optional.empty())).when(netconfService).getConfig(PATH_2);
-        return new NetconfRestconfStrategy(netconfService);
+        return new NetconfRestconfStrategy(mockSchemaContext, netconfService);
     }
 }