From 1e2d66e6bbd8a3f8d2ada231e781cb607ad8c867 Mon Sep 17 00:00:00 2001 From: Robert Varga Date: Tue, 12 Sep 2023 01:03:48 +0200 Subject: [PATCH] Optimize RestconfStrategy.postData() The implementation is now tightly bound to a RestconfStrategy, which allows us to check invariants before we embark on modifying the datastore. JIRA: NETCONF-1126 Change-Id: Iec2bec456e248a2d557ed6190719043226dfade2 Signed-off-by: Robert Varga --- .../restconf/nb/rfc8040/WriteDataParams.java | 10 -- .../rests/transactions/RestconfStrategy.java | 101 +++++++++--------- 2 files changed, 51 insertions(+), 60 deletions(-) diff --git a/restconf/restconf-nb/src/main/java/org/opendaylight/restconf/nb/rfc8040/WriteDataParams.java b/restconf/restconf-nb/src/main/java/org/opendaylight/restconf/nb/rfc8040/WriteDataParams.java index 6e5b56c309..c6fbb5e1fd 100644 --- a/restconf/restconf-nb/src/main/java/org/opendaylight/restconf/nb/rfc8040/WriteDataParams.java +++ b/restconf/restconf-nb/src/main/java/org/opendaylight/restconf/nb/rfc8040/WriteDataParams.java @@ -7,9 +7,6 @@ */ package org.opendaylight.restconf.nb.rfc8040; -import static com.google.common.base.Verify.verifyNotNull; - -import com.google.common.annotations.Beta; import com.google.common.base.MoreObjects; import org.eclipse.jdt.annotation.NonNull; import org.eclipse.jdt.annotation.Nullable; @@ -71,13 +68,6 @@ public final class WriteDataParams implements Immutable { return point; } - @Beta - @Deprecated(forRemoval = true) - // FIXME: it seems callers' structure should be able to cater with just point() and insert() - public @NonNull PointParam getPoint() { - return verifyNotNull(point); - } - @Override public String toString() { final var helper = MoreObjects.toStringHelper(this).omitNullValues(); diff --git a/restconf/restconf-nb/src/main/java/org/opendaylight/restconf/nb/rfc8040/rests/transactions/RestconfStrategy.java b/restconf/restconf-nb/src/main/java/org/opendaylight/restconf/nb/rfc8040/rests/transactions/RestconfStrategy.java index 196a1e8099..a6f0913144 100644 --- a/restconf/restconf-nb/src/main/java/org/opendaylight/restconf/nb/rfc8040/rests/transactions/RestconfStrategy.java +++ b/restconf/restconf-nb/src/main/java/org/opendaylight/restconf/nb/rfc8040/rests/transactions/RestconfStrategy.java @@ -204,7 +204,7 @@ public abstract class RestconfStrategy { if (insert != null) { final var parentPath = path.coerceParent(); checkListAndOrderedType(context, parentPath); - commitFuture = insertAndCommit(path, data, insert, params.point(), parentPath, context); + commitFuture = insertAndCommitPut(path, data, insert, params.point(), parentPath, context); } else { commitFuture = replaceAndCommit(prepareWriteExecution(), path, data, context); } @@ -213,7 +213,7 @@ public abstract class RestconfStrategy { return exists ? CreateOrReplaceResult.REPLACED : CreateOrReplaceResult.CREATED; } - private ListenableFuture insertAndCommit(final YangInstanceIdentifier path, + private ListenableFuture insertAndCommitPut(final YangInstanceIdentifier path, final NormalizedNode data, final @NonNull InsertParam insert, final @Nullable PointParam point, final YangInstanceIdentifier parentPath, final EffectiveModelContext context) { final var tx = prepareWriteExecution(); @@ -308,71 +308,73 @@ public abstract class RestconfStrategy { /** * Check mount point and prepare variables for post data. * - * @param path path - * @param data data - * @param schemaContext reference to actual {@link EffectiveModelContext} - * @param params {@link WriteDataParams} + * @param path path + * @param data data + * @param context reference to actual {@link EffectiveModelContext} + * @param params {@link WriteDataParams} */ public final void postData(final YangInstanceIdentifier path, final NormalizedNode data, - final EffectiveModelContext schemaContext, final WriteDataParams params) { - TransactionUtil.syncCommit(submitData(path, data, schemaContext, params), "POST", path); - } - - private ListenableFuture submitData(final YangInstanceIdentifier path, - final NormalizedNode data, final EffectiveModelContext schemaContext, final WriteDataParams params) { - final var transaction = prepareWriteExecution(); + final EffectiveModelContext context, final WriteDataParams params) { final var insert = params.insert(); - if (insert == null) { - return makePost(path, data, schemaContext, transaction); + final ListenableFuture future; + if (insert != null) { + final var parentPath = path.coerceParent(); + checkListAndOrderedType(context, parentPath); + future = insertAndCommitPost(path, data, insert, params.point(), parentPath, context); + } else { + future = createAndCommit(prepareWriteExecution(), path, data, context); } + TransactionUtil.syncCommit(future, "POST", path); + } - final var parentPath = path.coerceParent(); - checkListAndOrderedType(schemaContext, parentPath); - final var grandParentPath = parentPath.coerceParent(); + private ListenableFuture insertAndCommitPost(final YangInstanceIdentifier path, + final NormalizedNode data, final @NonNull InsertParam insert, final @Nullable PointParam point, + final YangInstanceIdentifier parent, final EffectiveModelContext context) { + final var grandParent = parent.coerceParent(); + final var tx = prepareWriteExecution(); return switch (insert) { case FIRST -> { - final var readData = transaction.readList(grandParentPath); + final var readData = tx.readList(grandParent); if (readData == null || readData.isEmpty()) { - transaction.replace(path, data, schemaContext); + tx.replace(path, data, context); } else { checkItemDoesNotExists(exists(path), path); - transaction.remove(grandParentPath); - transaction.replace(path, data, schemaContext); - transaction.replace(grandParentPath, readData, schemaContext); + tx.remove(grandParent); + tx.replace(path, data, context); + tx.replace(grandParent, readData, context); } - yield transaction.commit(); + yield tx.commit(); } - case LAST -> makePost(path, data, schemaContext, transaction); + case LAST -> createAndCommit(tx, path, data, context); case BEFORE -> { - final var readData = transaction.readList(grandParentPath); + final var readData = tx.readList(grandParent); if (readData == null || readData.isEmpty()) { - transaction.replace(path, data, schemaContext); + tx.replace(path, data, context); } else { checkItemDoesNotExists(exists(path), path); - insertWithPointPost(path, data, schemaContext, params.getPoint(), readData, true, transaction); + insertWithPointPost(tx, path, data, verifyNotNull(point), readData, grandParent, true, context); } - yield transaction.commit(); + yield tx.commit(); } case AFTER -> { - final var readData = transaction.readList(grandParentPath); + final var readData = tx.readList(grandParent); if (readData == null || readData.isEmpty()) { - transaction.replace(path, data, schemaContext); + tx.replace(path, data, context); } else { checkItemDoesNotExists(exists(path), path); - insertWithPointPost(path, data, schemaContext, params.getPoint(), readData, false, transaction); + insertWithPointPost(tx, path, data, verifyNotNull(point), readData, grandParent, false, context); } - yield transaction.commit(); + yield tx.commit(); } }; } - private static void insertWithPointPost(final YangInstanceIdentifier path, final NormalizedNode data, - final EffectiveModelContext schemaContext, final PointParam point, - final NormalizedNodeContainer readList, final boolean before, final RestconfTransaction transaction) { - final YangInstanceIdentifier parent = path.coerceParent().coerceParent(); - transaction.remove(parent); - final var pointArg = YangInstanceIdentifierDeserializer.create(schemaContext, point.value()).path + private static 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) { + tx.remove(grandParentPath); + final var pointArg = YangInstanceIdentifierDeserializer.create(context, point.value()).path .getLastPathArgument(); int lastItemPosition = 0; for (var nodeChild : readList.body()) { @@ -385,30 +387,29 @@ public abstract class RestconfStrategy { lastItemPosition++; } int lastInsertedPosition = 0; - final var emptySubtree = ImmutableNodes.fromInstanceId(schemaContext, parent); - transaction.merge(YangInstanceIdentifier.of(emptySubtree.name()), emptySubtree); + final var emptySubtree = ImmutableNodes.fromInstanceId(context, grandParentPath); + tx.merge(YangInstanceIdentifier.of(emptySubtree.name()), emptySubtree); for (var nodeChild : readList.body()) { if (lastInsertedPosition == lastItemPosition) { - transaction.replace(path, data, schemaContext); + tx.replace(path, data, context); } - final YangInstanceIdentifier childPath = parent.node(nodeChild.name()); - transaction.replace(childPath, nodeChild, schemaContext); + final YangInstanceIdentifier childPath = grandParentPath.node(nodeChild.name()); + tx.replace(childPath, nodeChild, context); lastInsertedPosition++; } } - private static ListenableFuture makePost(final YangInstanceIdentifier path, - final NormalizedNode data, final EffectiveModelContext schemaContext, - final RestconfTransaction transaction) { + private static ListenableFuture createAndCommit(final RestconfTransaction tx, + final YangInstanceIdentifier path, final NormalizedNode data, final EffectiveModelContext context) { try { - transaction.create(path, data, schemaContext); + tx.create(path, data, context); } catch (RestconfDocumentedException e) { // close transaction if any and pass exception further - transaction.cancel(); + tx.cancel(); throw e; } - return transaction.commit(); + return tx.commit(); } /** -- 2.36.6