import javax.ws.rs.core.Response.Status;
import org.opendaylight.mdsal.common.api.CommitInfo;
import org.opendaylight.mdsal.common.api.LogicalDatastoreType;
-import org.opendaylight.mdsal.dom.api.DOMDataTreeReadWriteTransaction;
-import org.opendaylight.mdsal.dom.api.DOMDataTreeWriteTransaction;
import org.opendaylight.mdsal.dom.api.DOMTransactionChain;
import org.opendaylight.restconf.common.context.InstanceIdentifierContext;
import org.opendaylight.restconf.common.context.NormalizedNodeContext;
import org.opendaylight.restconf.common.errors.RestconfError;
import org.opendaylight.restconf.common.errors.RestconfError.ErrorTag;
import org.opendaylight.restconf.common.errors.RestconfError.ErrorType;
-import org.opendaylight.restconf.nb.rfc8040.handlers.TransactionChainHandler;
-import org.opendaylight.restconf.nb.rfc8040.references.SchemaContextRef;
-import org.opendaylight.restconf.nb.rfc8040.rests.transactions.TransactionVarsWrapper;
+import org.opendaylight.restconf.nb.rfc8040.rests.transactions.RestconfStrategy;
import org.opendaylight.restconf.nb.rfc8040.utils.parser.ParserIdentifier;
import org.opendaylight.yangtools.yang.common.QName;
import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
import org.opendaylight.yangtools.yang.data.util.DataSchemaContextNode;
import org.opendaylight.yangtools.yang.data.util.DataSchemaContextTree;
import org.opendaylight.yangtools.yang.model.api.DataSchemaNode;
+import org.opendaylight.yangtools.yang.model.api.EffectiveModelContext;
import org.opendaylight.yangtools.yang.model.api.LeafListSchemaNode;
import org.opendaylight.yangtools.yang.model.api.ListSchemaNode;
import org.opendaylight.yangtools.yang.model.api.SchemaContext;
public final class PutDataTransactionUtil {
private PutDataTransactionUtil() {
-
}
/**
* Valid input data with {@link SchemaNode}.
*
- * @param schemaNode
- * {@link SchemaNode}
- * @param payload
- * input data
+ * @param schemaNode {@link SchemaNode}
+ * @param payload input data
*/
public static void validInputData(final SchemaNode schemaNode, final NormalizedNodeContext payload) {
if (schemaNode != null && payload.getData() == null) {
/**
* Valid top level node name.
*
- * @param path
- * path of node
- * @param payload
- * data
+ * @param path path of node
+ * @param payload data
*/
public static void validTopLevelNodeName(final YangInstanceIdentifier path, final NormalizedNodeContext payload) {
final String payloadName = payload.getData().getNodeType().getLocalName();
* Validates whether keys in {@code payload} are equal to values of keys in
* {@code iiWithData} for list schema node.
*
- * @throws RestconfDocumentedException
- * if key values or key count in payload and URI isn't equal
+ * @throws RestconfDocumentedException if key values or key count in payload and URI isn't equal
*/
public static void validateListKeysEqualityInPayloadAndUri(final NormalizedNodeContext payload) {
final InstanceIdentifierContext<?> iiWithData = payload.getInstanceIdentifierContext();
}
private static void isEqualUriAndPayloadKeyValues(final Map<QName, Object> uriKeyValues, final MapEntryNode payload,
- final List<QName> keyDefinitions) {
+ final List<QName> keyDefinitions) {
final Map<QName, Object> mutableCopyUriKeyValues = new HashMap<>(uriKeyValues);
for (final QName keyDefinition : keyDefinitions) {
final Object uriKeyValue = RestconfDocumentedException.throwIfNull(
- mutableCopyUriKeyValues.remove(keyDefinition), ErrorType.PROTOCOL, ErrorTag.DATA_MISSING,
- "Missing key %s in URI.", keyDefinition);
+ mutableCopyUriKeyValues.remove(keyDefinition), ErrorType.PROTOCOL, ErrorTag.DATA_MISSING,
+ "Missing key %s in URI.", keyDefinition);
final Object dataKeyValue = payload.getIdentifier().getValue(keyDefinition);
}
/**
- * Check mount point and prepare variables for put data to DS. Close {@link DOMTransactionChain} inside of object
- * {@link TransactionVarsWrapper} provided as a parameter.
+ * Check mount point and prepare variables for put data to DS. Close {@link DOMTransactionChain} if any
+ * inside of object {@link RestconfStrategy} provided as a parameter if any.
*
- * @param payload
- * data to put
- * @param schemaCtxRef
- * reference to {@link SchemaContext}
- * @param transactionNode
- * wrapper of variables for transaction
- * @param point
- * query parameter
- * @param insert
- * query parameter
+ * @param payload data to put
+ * @param schemaContext reference to {@link EffectiveModelContext}
+ * @param strategy object that perform the actual DS operations
+ * @param point query parameter
+ * @param insert query parameter
* @return {@link Response}
*/
- public static Response putData(final NormalizedNodeContext payload, final SchemaContextRef schemaCtxRef,
- final TransactionVarsWrapper transactionNode, final String insert, final String point) {
+ public static Response putData(final NormalizedNodeContext payload, final EffectiveModelContext schemaContext,
+ final RestconfStrategy strategy, final String insert, final String point) {
final YangInstanceIdentifier path = payload.getInstanceIdentifierContext().getInstanceIdentifier();
- final SchemaContext schemaContext = schemaCtxRef.get();
-
- final DOMDataTreeReadWriteTransaction readWriteTransaction =
- transactionNode.getTransactionChain().newReadWriteTransaction();
- final FluentFuture<Boolean> existsFuture = readWriteTransaction.exists(LogicalDatastoreType.CONFIGURATION,
- path);
+ strategy.prepareReadWriteExecution();
+ final FluentFuture<Boolean> existsFuture = strategy.exists(LogicalDatastoreType.CONFIGURATION, path);
final FutureDataFactory<Boolean> existsResponse = new FutureDataFactory<>();
FutureCallbackTx.addCallback(existsFuture, RestconfDataServiceConstant.PutData.PUT_TX_TYPE, existsResponse);
final ResponseFactory responseFactory =
new ResponseFactory(existsResponse.result ? Status.NO_CONTENT : Status.CREATED);
- final FluentFuture<? extends CommitInfo> submitData = submitData(path, schemaContext,
- transactionNode.getTransactionChainHandler(), readWriteTransaction, payload.getData(), insert, point);
- //This method will close transactionChain
+ final FluentFuture<? extends CommitInfo> submitData = submitData(path, schemaContext, strategy,
+ payload.getData(), insert, point, existsResponse.result);
+ //This method will close transactionChain if any
FutureCallbackTx.addCallback(submitData, RestconfDataServiceConstant.PutData.PUT_TX_TYPE, responseFactory,
- transactionNode.getTransactionChain());
+ strategy.getTransactionChain());
return responseFactory.build();
}
/**
* Put data to DS.
*
- * @param path
- * path of data
- * @param schemaContext
- * {@link SchemaContext}
- * @param transactionChainHandler
- * write transaction
- * @param data
- * data
- * @param point
- * query parameter
- * @param insert
- * query parameter
+ * @param path path of data
+ * @param schemaContext {@link SchemaContext}
+ * @param strategy object that perform the actual DS operations
+ * @param data data
+ * @param point query parameter
+ * @param insert query parameter
* @return {@link FluentFuture}
*/
- private static FluentFuture<? extends CommitInfo> submitData(final YangInstanceIdentifier path,
- final SchemaContext schemaContext, final TransactionChainHandler transactionChainHandler,
- final DOMDataTreeReadWriteTransaction readWriteTransaction,
- final NormalizedNode<?, ?> data, final String insert, final String point) {
+ private static FluentFuture<? extends CommitInfo> submitData(
+ final YangInstanceIdentifier path,
+ final EffectiveModelContext schemaContext,
+ final RestconfStrategy strategy,
+ final NormalizedNode<?, ?> data, final String insert, final String point, final boolean exists) {
if (insert == null) {
- return makePut(path, schemaContext, readWriteTransaction, data);
+ return makePut(path, schemaContext, strategy, data, exists);
}
final DataSchemaNode schemaNode = checkListAndOrderedType(schemaContext, path);
switch (insert) {
case "first":
if (schemaNode instanceof ListSchemaNode) {
- final NormalizedNode<?, ?> readData =
- readList(path, schemaContext, transactionChainHandler, schemaNode);
+ final NormalizedNode<?, ?> readData = readList(path, schemaContext, strategy, schemaNode);
final OrderedMapNode readList = (OrderedMapNode) readData;
if (readList == null || readList.getValue().isEmpty()) {
- return makePut(path, schemaContext, readWriteTransaction, data);
+ return makePut(path, schemaContext, strategy, data, exists);
} else {
- readWriteTransaction.delete(LogicalDatastoreType.CONFIGURATION, path.getParent());
- simplePut(LogicalDatastoreType.CONFIGURATION, path, readWriteTransaction,
- schemaContext, data);
- listPut(LogicalDatastoreType.CONFIGURATION, path.getParent(), readWriteTransaction,
- schemaContext, readList);
- return readWriteTransaction.commit();
+ strategy.delete(LogicalDatastoreType.CONFIGURATION, path.getParent());
+ simplePut(LogicalDatastoreType.CONFIGURATION, path, strategy, schemaContext, data, exists);
+ listPut(LogicalDatastoreType.CONFIGURATION, path.getParent(), strategy,
+ schemaContext, readList, exists);
+ return strategy.commit();
}
} else {
- final NormalizedNode<?, ?> readData =
- readList(path, schemaContext, transactionChainHandler, schemaNode);
+ final NormalizedNode<?, ?> readData = readList(path, schemaContext, strategy, schemaNode);
final OrderedLeafSetNode<?> readLeafList = (OrderedLeafSetNode<?>) readData;
if (readLeafList == null || readLeafList.getValue().isEmpty()) {
- return makePut(path, schemaContext, readWriteTransaction, data);
+ return makePut(path, schemaContext, strategy, data, exists);
} else {
- readWriteTransaction.delete(LogicalDatastoreType.CONFIGURATION, path.getParent());
- simplePut(LogicalDatastoreType.CONFIGURATION, path, readWriteTransaction,
- schemaContext, data);
- listPut(LogicalDatastoreType.CONFIGURATION, path.getParent(), readWriteTransaction,
- schemaContext, readLeafList);
- return readWriteTransaction.commit();
+ strategy.delete(LogicalDatastoreType.CONFIGURATION, path.getParent());
+ simplePut(LogicalDatastoreType.CONFIGURATION, path, strategy,
+ schemaContext, data, exists);
+ listPut(LogicalDatastoreType.CONFIGURATION, path.getParent(), strategy,
+ schemaContext, readLeafList, exists);
+ return strategy.commit();
}
}
case "last":
- return makePut(path, schemaContext, readWriteTransaction, data);
+ return makePut(path, schemaContext, strategy, data, exists);
case "before":
if (schemaNode instanceof ListSchemaNode) {
- final NormalizedNode<?, ?> readData =
- readList(path, schemaContext, transactionChainHandler, schemaNode);
+ final NormalizedNode<?, ?> readData = readList(path, schemaContext, strategy, schemaNode);
final OrderedMapNode readList = (OrderedMapNode) readData;
if (readList == null || readList.getValue().isEmpty()) {
- return makePut(path, schemaContext, readWriteTransaction, data);
+ return makePut(path, schemaContext, strategy, data, exists);
} else {
- insertWithPointListPut(readWriteTransaction, LogicalDatastoreType.CONFIGURATION, path,
- data, schemaContext, point, readList, true);
- return readWriteTransaction.commit();
+ insertWithPointListPut(strategy, LogicalDatastoreType.CONFIGURATION, path,
+ data, schemaContext, point, readList, true, exists);
+ return strategy.commit();
}
} else {
- final NormalizedNode<?, ?> readData =
- readList(path, schemaContext, transactionChainHandler, schemaNode);
+ final NormalizedNode<?, ?> readData = readList(path, schemaContext, strategy, schemaNode);
final OrderedLeafSetNode<?> readLeafList = (OrderedLeafSetNode<?>) readData;
if (readLeafList == null || readLeafList.getValue().isEmpty()) {
- return makePut(path, schemaContext, readWriteTransaction, data);
+ return makePut(path, schemaContext, strategy, data, exists);
} else {
- insertWithPointLeafListPut(readWriteTransaction, LogicalDatastoreType.CONFIGURATION,
- path, data, schemaContext, point, readLeafList, true);
- return readWriteTransaction.commit();
+ insertWithPointLeafListPut(strategy, LogicalDatastoreType.CONFIGURATION,
+ path, data, schemaContext, point, readLeafList, true, exists);
+ return strategy.commit();
}
}
case "after":
if (schemaNode instanceof ListSchemaNode) {
- final NormalizedNode<?, ?> readData =
- readList(path, schemaContext, transactionChainHandler, schemaNode);
+ final NormalizedNode<?, ?> readData = readList(path, schemaContext, strategy, schemaNode);
final OrderedMapNode readList = (OrderedMapNode) readData;
if (readList == null || readList.getValue().isEmpty()) {
- return makePut(path, schemaContext, readWriteTransaction, data);
+ return makePut(path, schemaContext, strategy, data, exists);
} else {
- insertWithPointListPut(readWriteTransaction, LogicalDatastoreType.CONFIGURATION,
- path, data, schemaContext, point, readList, false);
- return readWriteTransaction.commit();
+ insertWithPointListPut(strategy, LogicalDatastoreType.CONFIGURATION,
+ path, data, schemaContext, point, readList, false, exists);
+ return strategy.commit();
}
} else {
- final NormalizedNode<?, ?> readData =
- readList(path, schemaContext, transactionChainHandler, schemaNode);
+ final NormalizedNode<?, ?> readData = readList(path, schemaContext, strategy, schemaNode);
final OrderedLeafSetNode<?> readLeafList = (OrderedLeafSetNode<?>) readData;
if (readLeafList == null || readLeafList.getValue().isEmpty()) {
- return makePut(path, schemaContext, readWriteTransaction, data);
+ return makePut(path, schemaContext, strategy, data, exists);
} else {
- insertWithPointLeafListPut(readWriteTransaction, LogicalDatastoreType.CONFIGURATION,
- path, data, schemaContext, point, readLeafList, true);
- return readWriteTransaction.commit();
+ insertWithPointLeafListPut(strategy, LogicalDatastoreType.CONFIGURATION,
+ path, data, schemaContext, point, readLeafList, true, exists);
+ return strategy.commit();
}
}
default:
}
}
- public static NormalizedNode<?, ?> readList(final YangInstanceIdentifier path, final SchemaContext schemaContext,
- final TransactionChainHandler transactionChainHandler, final DataSchemaNode schemaNode) {
+ public static NormalizedNode<?, ?> readList(final YangInstanceIdentifier path,
+ final EffectiveModelContext schemaContext,
+ final RestconfStrategy strategy,
+ final DataSchemaNode schemaNode) {
final InstanceIdentifierContext<?> iid = new InstanceIdentifierContext<SchemaNode>(
path.getParent(), schemaNode, null, schemaContext);
- final TransactionVarsWrapper transactionNode = new TransactionVarsWrapper(iid, null, transactionChainHandler);
- final NormalizedNode<?, ?> readData = ReadDataTransactionUtil
- .readData(RestconfDataServiceConstant.ReadData.CONFIG, transactionNode, schemaContext);
- return readData;
+ final RestconfStrategy restconfStrategy = strategy.buildStrategy(iid);
+ return ReadDataTransactionUtil.readData(
+ RestconfDataServiceConstant.ReadData.CONFIG, restconfStrategy, schemaContext);
}
- private static void insertWithPointLeafListPut(final DOMDataTreeReadWriteTransaction rwTransaction,
- final LogicalDatastoreType datastore, final YangInstanceIdentifier path,
- final NormalizedNode<?, ?> data, final SchemaContext schemaContext, final String point,
- final OrderedLeafSetNode<?> readLeafList, final boolean before) {
- rwTransaction.delete(datastore, path.getParent());
+ private static void insertWithPointLeafListPut(final RestconfStrategy strategy,
+ final LogicalDatastoreType datastore,
+ final YangInstanceIdentifier path,
+ final NormalizedNode<?, ?> data,
+ final EffectiveModelContext schemaContext, final String point,
+ final OrderedLeafSetNode<?> readLeafList, final boolean before,
+ final boolean exists) {
+ strategy.delete(datastore, path.getParent());
final InstanceIdentifierContext<?> instanceIdentifier =
ParserIdentifier.toInstanceIdentifier(point, schemaContext, Optional.empty());
int lastItemPosition = 0;
}
int lastInsertedPosition = 0;
final NormalizedNode<?, ?> emptySubtree = ImmutableNodes.fromInstanceId(schemaContext, path.getParent());
- rwTransaction.merge(datastore, YangInstanceIdentifier.create(emptySubtree.getIdentifier()), emptySubtree);
+ strategy.merge(datastore, YangInstanceIdentifier.create(emptySubtree.getIdentifier()), emptySubtree);
for (final LeafSetEntryNode<?> nodeChild : readLeafList.getValue()) {
if (lastInsertedPosition == lastItemPosition) {
- simplePut(datastore, path, rwTransaction, schemaContext, data);
+ simplePut(datastore, path, strategy, schemaContext, data, exists);
}
final YangInstanceIdentifier childPath = path.getParent().node(nodeChild.getIdentifier());
- rwTransaction.put(datastore, childPath, nodeChild);
+ if (exists) {
+ strategy.replace(datastore, childPath, nodeChild);
+ } else {
+ strategy.create(datastore, childPath, nodeChild);
+ }
lastInsertedPosition++;
}
}
- private static void insertWithPointListPut(final DOMDataTreeReadWriteTransaction writeTx,
- final LogicalDatastoreType datastore, final YangInstanceIdentifier path,
- final NormalizedNode<?, ?> data, final SchemaContext schemaContext, final String point,
- final OrderedMapNode readList, final boolean before) {
- writeTx.delete(datastore, path.getParent());
+ private static void insertWithPointListPut(final RestconfStrategy strategy,
+ final LogicalDatastoreType datastore, final YangInstanceIdentifier path,
+ final NormalizedNode<?, ?> data,
+ final EffectiveModelContext schemaContext, final String point,
+ final OrderedMapNode readList, final boolean before,
+ final boolean exists) {
+ strategy.delete(datastore, path.getParent());
final InstanceIdentifierContext<?> instanceIdentifier =
ParserIdentifier.toInstanceIdentifier(point, schemaContext, Optional.empty());
int lastItemPosition = 0;
}
int lastInsertedPosition = 0;
final NormalizedNode<?, ?> emptySubtree = ImmutableNodes.fromInstanceId(schemaContext, path.getParent());
- writeTx.merge(datastore, YangInstanceIdentifier.create(emptySubtree.getIdentifier()), emptySubtree);
+ strategy.merge(datastore, YangInstanceIdentifier.create(emptySubtree.getIdentifier()), emptySubtree);
for (final MapEntryNode mapEntryNode : readList.getValue()) {
if (lastInsertedPosition == lastItemPosition) {
- simplePut(datastore, path, writeTx, schemaContext, data);
+ simplePut(datastore, path, strategy, schemaContext, data, exists);
}
final YangInstanceIdentifier childPath = path.getParent().node(mapEntryNode.getIdentifier());
- writeTx.put(datastore, childPath, mapEntryNode);
+ if (exists) {
+ strategy.replace(datastore, childPath, mapEntryNode);
+ } else {
+ strategy.create(datastore, childPath, mapEntryNode);
+ }
lastInsertedPosition++;
}
}
private static void listPut(final LogicalDatastoreType datastore, final YangInstanceIdentifier path,
- final DOMDataTreeWriteTransaction writeTx, final SchemaContext schemaContext,
- final OrderedLeafSetNode<?> payload) {
+ final RestconfStrategy strategy, final SchemaContext schemaContext,
+ final OrderedLeafSetNode<?> payload, final boolean exists) {
final NormalizedNode<?, ?> emptySubtree = ImmutableNodes.fromInstanceId(schemaContext, path);
- writeTx.merge(datastore, YangInstanceIdentifier.create(emptySubtree.getIdentifier()), emptySubtree);
- TransactionUtil.ensureParentsByMerge(path, schemaContext, writeTx);
+ strategy.merge(datastore, YangInstanceIdentifier.create(emptySubtree.getIdentifier()), emptySubtree);
+ TransactionUtil.ensureParentsByMerge(path, schemaContext, strategy);
for (final LeafSetEntryNode<?> child : ((LeafSetNode<?>) payload).getValue()) {
final YangInstanceIdentifier childPath = path.node(child.getIdentifier());
- writeTx.put(datastore, childPath, child);
+ if (exists) {
+ strategy.replace(datastore, childPath, child);
+ } else {
+ strategy.create(datastore, childPath, child);
+ }
}
}
private static void listPut(final LogicalDatastoreType datastore, final YangInstanceIdentifier path,
- final DOMDataTreeWriteTransaction writeTx, final SchemaContext schemaContext,
- final OrderedMapNode payload) {
+ final RestconfStrategy strategy, final SchemaContext schemaContext,
+ final OrderedMapNode payload, final boolean exists) {
final NormalizedNode<?, ?> emptySubtree = ImmutableNodes.fromInstanceId(schemaContext, path);
- writeTx.merge(datastore, YangInstanceIdentifier.create(emptySubtree.getIdentifier()), emptySubtree);
- TransactionUtil.ensureParentsByMerge(path, schemaContext, writeTx);
+ strategy.merge(datastore, YangInstanceIdentifier.create(emptySubtree.getIdentifier()), emptySubtree);
+ TransactionUtil.ensureParentsByMerge(path, schemaContext, strategy);
for (final MapEntryNode child : payload.getValue()) {
final YangInstanceIdentifier childPath = path.node(child.getIdentifier());
- writeTx.put(datastore, childPath, child);
+ if (exists) {
+ strategy.replace(datastore, childPath, child);
+ } else {
+ strategy.create(datastore, childPath, child);
+ }
}
}
private static void simplePut(final LogicalDatastoreType configuration, final YangInstanceIdentifier path,
- final DOMDataTreeWriteTransaction writeTx, final SchemaContext schemaContext,
- final NormalizedNode<?, ?> data) {
- TransactionUtil.ensureParentsByMerge(path, schemaContext, writeTx);
- writeTx.put(LogicalDatastoreType.CONFIGURATION, path, data);
+ final RestconfStrategy strategy, final SchemaContext schemaContext,
+ final NormalizedNode<?, ?> data, final boolean exists) {
+ TransactionUtil.ensureParentsByMerge(path, schemaContext, strategy);
+ if (exists) {
+ strategy.replace(LogicalDatastoreType.CONFIGURATION, path, data);
+ } else {
+ strategy.create(LogicalDatastoreType.CONFIGURATION, path, data);
+ }
}
private static FluentFuture<? extends CommitInfo> makePut(final YangInstanceIdentifier path,
- final SchemaContext schemaContext, final DOMDataTreeWriteTransaction writeTx,
- final NormalizedNode<?, ?> data) {
- TransactionUtil.ensureParentsByMerge(path, schemaContext, writeTx);
- writeTx.put(LogicalDatastoreType.CONFIGURATION, path, data);
- return writeTx.commit();
+ final SchemaContext schemaContext,
+ final RestconfStrategy strategy,
+ final NormalizedNode<?, ?> data,
+ final boolean exists) {
+ TransactionUtil.ensureParentsByMerge(path, schemaContext, strategy);
+ if (exists) {
+ strategy.replace(LogicalDatastoreType.CONFIGURATION, path, data);
+ } else {
+ strategy.create(LogicalDatastoreType.CONFIGURATION, path, data);
+ }
+ return strategy.commit();
}
public static DataSchemaNode checkListAndOrderedType(final SchemaContext ctx, final YangInstanceIdentifier path) {