X-Git-Url: https://git.opendaylight.org/gerrit/gitweb?a=blobdiff_plain;f=restconf%2Frestconf-nb-rfc8040%2Fsrc%2Fmain%2Fjava%2Forg%2Fopendaylight%2Frestconf%2Fnb%2Frfc8040%2Frests%2Futils%2FPutDataTransactionUtil.java;h=b9f20b79df08a9d84b039ff5f36132ad5b4597c9;hb=14bd5e7ef6421c109248f4e750be330cb0337287;hp=200605da4b626b77fd72c811bd14ad019aeb4064;hpb=bb0a5647411830d544b19fb79c35b7e563d12079;p=netconf.git diff --git a/restconf/restconf-nb-rfc8040/src/main/java/org/opendaylight/restconf/nb/rfc8040/rests/utils/PutDataTransactionUtil.java b/restconf/restconf-nb-rfc8040/src/main/java/org/opendaylight/restconf/nb/rfc8040/rests/utils/PutDataTransactionUtil.java index 200605da4b..b9f20b79df 100644 --- a/restconf/restconf-nb-rfc8040/src/main/java/org/opendaylight/restconf/nb/rfc8040/rests/utils/PutDataTransactionUtil.java +++ b/restconf/restconf-nb-rfc8040/src/main/java/org/opendaylight/restconf/nb/rfc8040/rests/utils/PutDataTransactionUtil.java @@ -7,27 +7,23 @@ */ package org.opendaylight.restconf.nb.rfc8040.rests.utils; -import com.google.common.base.Optional; -import com.google.common.collect.Maps; -import com.google.common.util.concurrent.CheckedFuture; +import com.google.common.util.concurrent.FluentFuture; +import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.Optional; import javax.ws.rs.core.Response; import javax.ws.rs.core.Response.Status; -import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType; -import org.opendaylight.controller.md.sal.common.api.data.ReadFailedException; -import org.opendaylight.controller.md.sal.common.api.data.TransactionCommitFailedException; -import org.opendaylight.controller.md.sal.dom.api.DOMDataReadWriteTransaction; -import org.opendaylight.controller.md.sal.dom.api.DOMDataWriteTransaction; +import org.opendaylight.mdsal.common.api.CommitInfo; +import org.opendaylight.mdsal.common.api.LogicalDatastoreType; +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.RestconfDocumentedException; +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.common.validation.RestconfValidationUtils; -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; @@ -43,6 +39,7 @@ import org.opendaylight.yangtools.yang.data.impl.schema.ImmutableNodes; 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; @@ -55,16 +52,13 @@ import org.opendaylight.yangtools.yang.model.api.SchemaNode; 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) { @@ -77,10 +71,8 @@ public final class PutDataTransactionUtil { /** * 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(); @@ -104,8 +96,7 @@ public final class PutDataTransactionUtil { * 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(); @@ -115,22 +106,21 @@ public final class PutDataTransactionUtil { if (schemaNode instanceof ListSchemaNode) { final List keyDefinitions = ((ListSchemaNode) schemaNode).getKeyDefinition(); if (lastPathArgument instanceof NodeIdentifierWithPredicates && data instanceof MapEntryNode) { - final Map uriKeyValues = ((NodeIdentifierWithPredicates) lastPathArgument) - .getKeyValues(); + final Map uriKeyValues = ((NodeIdentifierWithPredicates) lastPathArgument).asMap(); isEqualUriAndPayloadKeyValues(uriKeyValues, (MapEntryNode) data, keyDefinitions); } } } private static void isEqualUriAndPayloadKeyValues(final Map uriKeyValues, final MapEntryNode payload, - final List keyDefinitions) { - final Map mutableCopyUriKeyValues = Maps.newHashMap(uriKeyValues); + final List keyDefinitions) { + final Map mutableCopyUriKeyValues = new HashMap<>(uriKeyValues); for (final QName keyDefinition : keyDefinitions) { - final Object uriKeyValue = mutableCopyUriKeyValues.remove(keyDefinition); - RestconfValidationUtils.checkDocumentedError(uriKeyValue != null, ErrorType.PROTOCOL, ErrorTag.DATA_MISSING, - "Missing key " + keyDefinition + " in URI."); + final Object uriKeyValue = RestconfDocumentedException.throwIfNull( + mutableCopyUriKeyValues.remove(keyDefinition), ErrorType.PROTOCOL, ErrorTag.DATA_MISSING, + "Missing key %s in URI.", keyDefinition); - final Object dataKeyValue = payload.getIdentifier().getKeyValues().get(keyDefinition); + final Object dataKeyValue = payload.getIdentifier().getValue(keyDefinition); if (!uriKeyValue.equals(dataKeyValue)) { final String errMsg = "The value '" + uriKeyValue + "' for key '" + keyDefinition.getLocalName() @@ -142,175 +132,161 @@ public final class PutDataTransactionUtil { } /** - * Check mount point and prepare variables for put data to DS. + * 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 - * @return {@link CheckedFuture} + * @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 DOMDataReadWriteTransaction readWriteTransaction = - transactionNode.getTransactionChain().newReadWriteTransaction(); - final CheckedFuture existsFuture = - readWriteTransaction.exists(LogicalDatastoreType.CONFIGURATION, path); + strategy.prepareReadWriteExecution(); + final FluentFuture existsFuture = strategy.exists(LogicalDatastoreType.CONFIGURATION, path); final FutureDataFactory 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 CheckedFuture submitData = submitData(path, schemaContext, - transactionNode.getTransactionChainHandler(), readWriteTransaction, payload.getData(), insert, point); - FutureCallbackTx.addCallback(submitData, RestconfDataServiceConstant.PutData.PUT_TX_TYPE, responseFactory); + final FluentFuture 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, + 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 - * @return {@link CheckedFuture} + * @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 CheckedFuture submitData(final YangInstanceIdentifier path, - final SchemaContext schemaContext, final TransactionChainHandler transactionChainHandler, - final DOMDataReadWriteTransaction readWriteTransaction, - final NormalizedNode data, final String insert, final String point) { + private static FluentFuture 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); - } else { - final DataSchemaNode schemaNode = checkListAndOrderedType(schemaContext, path); - switch (insert) { - case "first": - if (schemaNode instanceof ListSchemaNode) { - final NormalizedNode readData = - readList(path, schemaContext, transactionChainHandler, schemaNode); - final OrderedMapNode readList = (OrderedMapNode) readData; - if (readList == null || readList.getValue().isEmpty()) { - return makePut(path, schemaContext, readWriteTransaction, data); - } else { - readWriteTransaction.delete(LogicalDatastoreType.CONFIGURATION, path.getParent()); - simplePut(LogicalDatastoreType.CONFIGURATION, path, readWriteTransaction, - schemaContext, data); - listPut(LogicalDatastoreType.CONFIGURATION, path.getParent(), readWriteTransaction, - schemaContext, readList); - return readWriteTransaction.submit(); - } + 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, strategy, schemaNode); + final OrderedMapNode readList = (OrderedMapNode) readData; + if (readList == null || readList.getValue().isEmpty()) { + return makePut(path, schemaContext, strategy, data, exists); } else { - final NormalizedNode readData = - readList(path, schemaContext, transactionChainHandler, schemaNode); + 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, strategy, schemaNode); - final OrderedLeafSetNode readLeafList = (OrderedLeafSetNode) readData; - if (readLeafList == null || readLeafList.getValue().isEmpty()) { - return makePut(path, schemaContext, readWriteTransaction, data); - } else { - readWriteTransaction.delete(LogicalDatastoreType.CONFIGURATION, path.getParent()); - simplePut(LogicalDatastoreType.CONFIGURATION, path, readWriteTransaction, - schemaContext, data); - listPut(LogicalDatastoreType.CONFIGURATION, path.getParent(), readWriteTransaction, - schemaContext, readLeafList); - return readWriteTransaction.submit(); - } + final OrderedLeafSetNode readLeafList = (OrderedLeafSetNode) readData; + if (readLeafList == null || readLeafList.getValue().isEmpty()) { + return makePut(path, schemaContext, strategy, data, exists); + } else { + 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); - case "before": - if (schemaNode instanceof ListSchemaNode) { - final NormalizedNode readData = - readList(path, schemaContext, transactionChainHandler, schemaNode); - final OrderedMapNode readList = (OrderedMapNode) readData; - if (readList == null || readList.getValue().isEmpty()) { - return makePut(path, schemaContext, readWriteTransaction, data); - } else { - insertWithPointListPut(readWriteTransaction, LogicalDatastoreType.CONFIGURATION, path, - data, schemaContext, point, readList, true); - return readWriteTransaction.submit(); - } + } + case "last": + return makePut(path, schemaContext, strategy, data, exists); + case "before": + if (schemaNode instanceof ListSchemaNode) { + final NormalizedNode readData = readList(path, schemaContext, strategy, schemaNode); + final OrderedMapNode readList = (OrderedMapNode) readData; + if (readList == null || readList.getValue().isEmpty()) { + return makePut(path, schemaContext, strategy, data, exists); } else { - final NormalizedNode readData = - readList(path, schemaContext, transactionChainHandler, schemaNode); + insertWithPointListPut(strategy, LogicalDatastoreType.CONFIGURATION, path, + data, schemaContext, point, readList, true, exists); + return strategy.commit(); + } + } else { + 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); - } else { - insertWithPointLeafListPut(readWriteTransaction, LogicalDatastoreType.CONFIGURATION, - path, data, schemaContext, point, readLeafList, true); - return readWriteTransaction.submit(); - } + final OrderedLeafSetNode readLeafList = (OrderedLeafSetNode) readData; + if (readLeafList == null || readLeafList.getValue().isEmpty()) { + return makePut(path, schemaContext, strategy, data, exists); + } else { + 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 OrderedMapNode readList = (OrderedMapNode) readData; - if (readList == null || readList.getValue().isEmpty()) { - return makePut(path, schemaContext, readWriteTransaction, data); - } else { - insertWithPointListPut(readWriteTransaction, LogicalDatastoreType.CONFIGURATION, - path, data, schemaContext, point, readList, false); - return readWriteTransaction.submit(); - } + } + case "after": + if (schemaNode instanceof ListSchemaNode) { + final NormalizedNode readData = readList(path, schemaContext, strategy, schemaNode); + final OrderedMapNode readList = (OrderedMapNode) readData; + if (readList == null || readList.getValue().isEmpty()) { + return makePut(path, schemaContext, strategy, data, exists); } else { - final NormalizedNode readData = - readList(path, schemaContext, transactionChainHandler, schemaNode); + insertWithPointListPut(strategy, LogicalDatastoreType.CONFIGURATION, + path, data, schemaContext, point, readList, false, exists); + return strategy.commit(); + } + } else { + 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); - } else { - insertWithPointLeafListPut(readWriteTransaction, LogicalDatastoreType.CONFIGURATION, - path, data, schemaContext, point, readLeafList, true); - return readWriteTransaction.submit(); - } + final OrderedLeafSetNode readLeafList = (OrderedLeafSetNode) readData; + if (readLeafList == null || readLeafList.getValue().isEmpty()) { + return makePut(path, schemaContext, strategy, data, exists); + } else { + insertWithPointLeafListPut(strategy, LogicalDatastoreType.CONFIGURATION, + path, data, schemaContext, point, readLeafList, true, exists); + return strategy.commit(); } - default: - throw new RestconfDocumentedException( - "Used bad value of insert parameter. Possible values are first, last, before or after, " - + "but was: " + insert); - } + } + default: + throw new RestconfDocumentedException( + "Used bad value of insert parameter. Possible values are first, last, before or after, " + + "but was: " + insert, RestconfError.ErrorType.PROTOCOL, ErrorTag.BAD_ATTRIBUTE); } } - 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( 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 DOMDataReadWriteTransaction 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.absent()); + ParserIdentifier.toInstanceIdentifier(point, schemaContext, Optional.empty()); int lastItemPosition = 0; for (final LeafSetEntryNode nodeChild : readLeafList.getValue()) { if (nodeChild.getIdentifier().equals(instanceIdentifier.getInstanceIdentifier().getLastPathArgument())) { @@ -323,24 +299,30 @@ public final class PutDataTransactionUtil { } 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 DOMDataReadWriteTransaction 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.absent()); + ParserIdentifier.toInstanceIdentifier(point, schemaContext, Optional.empty()); int lastItemPosition = 0; for (final MapEntryNode mapEntryNode : readList.getValue()) { if (mapEntryNode.getIdentifier().equals(instanceIdentifier.getInstanceIdentifier().getLastPathArgument())) { @@ -353,53 +335,76 @@ public final class PutDataTransactionUtil { } 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 DOMDataReadWriteTransaction 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 DOMDataReadWriteTransaction 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 DOMDataReadWriteTransaction 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 CheckedFuture makePut(final YangInstanceIdentifier path, - final SchemaContext schemaContext, final DOMDataWriteTransaction writeTx, final NormalizedNode data) { - TransactionUtil.ensureParentsByMerge(path, schemaContext, writeTx); - writeTx.put(LogicalDatastoreType.CONFIGURATION, path, data); - return writeTx.submit(); + private static FluentFuture makePut(final YangInstanceIdentifier path, + 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) { @@ -409,17 +414,20 @@ public final class PutDataTransactionUtil { if (dataSchemaNode instanceof ListSchemaNode) { if (!((ListSchemaNode) dataSchemaNode).isUserOrdered()) { - throw new RestconfDocumentedException("Insert parameter can be used only with ordered-by user list."); + throw new RestconfDocumentedException("Insert parameter can be used only with ordered-by user list.", + RestconfError.ErrorType.PROTOCOL, ErrorTag.BAD_ELEMENT); } return dataSchemaNode; } if (dataSchemaNode instanceof LeafListSchemaNode) { if (!((LeafListSchemaNode) dataSchemaNode).isUserOrdered()) { throw new RestconfDocumentedException( - "Insert parameter can be used only with ordered-by user leaf-list."); + "Insert parameter can be used only with ordered-by user leaf-list.", + RestconfError.ErrorType.PROTOCOL, ErrorTag.BAD_ELEMENT); } return dataSchemaNode; } - throw new RestconfDocumentedException("Insert parameter can be used only with list or leaf-list"); + throw new RestconfDocumentedException("Insert parameter can be used only with list or leaf-list", + RestconfError.ErrorType.PROTOCOL, ErrorTag.BAD_ELEMENT); } }