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.nb.rfc8040.InsertParam;
+import org.opendaylight.restconf.nb.rfc8040.PointParam;
+import org.opendaylight.restconf.nb.rfc8040.WriteDataParams;
+import org.opendaylight.restconf.nb.rfc8040.legacy.NormalizedNodePayload;
import org.opendaylight.restconf.nb.rfc8040.rests.transactions.RestconfStrategy;
-import org.opendaylight.restconf.nb.rfc8040.rests.utils.RestconfDataServiceConstant.PostPutQueryParameters.Insert;
+import org.opendaylight.restconf.nb.rfc8040.rests.transactions.RestconfTransaction;
+import org.opendaylight.restconf.nb.rfc8040.utils.parser.IdentifierCodec;
import org.opendaylight.restconf.nb.rfc8040.utils.parser.ParserIdentifier;
+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.MapEntryNode;
import org.opendaylight.yangtools.yang.data.api.schema.MapNode;
/**
* Util class to post data to DS.
- *
*/
public final class PostDataTransactionUtil {
private static final Logger LOG = LoggerFactory.getLogger(PostDataTransactionUtil.class);
- // FIXME: why is this being reused from other places?
- static final String POST_TX_TYPE = "POST";
+ private static final String POST_TX_TYPE = "POST";
private PostDataTransactionUtil() {
// Hidden on purpose
* @param payload data
* @param strategy Object that perform the actual DS operations
* @param schemaContext reference to actual {@link EffectiveModelContext}
- * @param point point
- * @param insert insert
+ * @param params {@link WriteDataParams}
* @return {@link Response}
*/
- public static Response postData(final UriInfo uriInfo, final NormalizedNodeContext payload,
+ public static Response postData(final UriInfo uriInfo, final NormalizedNodePayload payload,
final RestconfStrategy strategy,
- final EffectiveModelContext schemaContext, final Insert insert,
- final String point) {
+ final EffectiveModelContext schemaContext, final WriteDataParams params) {
final YangInstanceIdentifier path = payload.getInstanceIdentifierContext().getInstanceIdentifier();
final FluentFuture<? extends CommitInfo> future = submitData(path, payload.getData(),
- strategy, schemaContext, insert, point);
+ strategy, schemaContext, params);
final URI location = resolveLocation(uriInfo, path, schemaContext, payload.getData());
final ResponseFactory dataFactory = new ResponseFactory(Status.CREATED).location(location);
//This method will close transactionChain if any
- FutureCallbackTx.addCallback(future, POST_TX_TYPE, dataFactory, strategy.getTransactionChain(), path);
+ FutureCallbackTx.addCallback(future, POST_TX_TYPE, dataFactory, path);
return dataFactory.build();
}
* @return {@link FluentFuture}
*/
private static FluentFuture<? extends CommitInfo> submitData(final YangInstanceIdentifier path,
- final NormalizedNode<?, ?> data,
+ final NormalizedNode data,
final RestconfStrategy strategy,
final EffectiveModelContext schemaContext,
- final Insert insert, final String point) {
- strategy.prepareReadWriteExecution();
+ final WriteDataParams params) {
+ final RestconfTransaction transaction = strategy.prepareWriteExecution();
+ final InsertParam insert = params.insert();
if (insert == null) {
- makePost(path, data, schemaContext, strategy);
- return strategy.commit();
+ makePost(path, data, schemaContext, transaction);
+ return transaction.commit();
}
PutDataTransactionUtil.checkListAndOrderedType(schemaContext, path);
- final NormalizedNode<?, ?> readData;
+ final NormalizedNode readData;
switch (insert) {
case FIRST:
readData = PutDataTransactionUtil.readList(strategy, path.getParent().getParent());
- if (readData == null || ((NormalizedNodeContainer<?, ?, ?>) readData).getValue().isEmpty()) {
- strategy.replace(LogicalDatastoreType.CONFIGURATION, path, data, schemaContext);
- return strategy.commit();
+ if (readData == null || ((NormalizedNodeContainer<?>) readData).isEmpty()) {
+ transaction.replace(path, data, schemaContext);
+ return transaction.commit();
}
- checkItemDoesNotExists(strategy, LogicalDatastoreType.CONFIGURATION, path);
- strategy.remove(LogicalDatastoreType.CONFIGURATION, path.getParent().getParent());
- strategy.replace(LogicalDatastoreType.CONFIGURATION, path, data, schemaContext);
- strategy.replace(LogicalDatastoreType.CONFIGURATION, path.getParent().getParent(), readData,
- schemaContext);
- return strategy.commit();
+ checkItemDoesNotExists(strategy.exists(LogicalDatastoreType.CONFIGURATION, path), path);
+ transaction.remove(path.getParent().getParent());
+ transaction.replace(path, data, schemaContext);
+ transaction.replace(path.getParent().getParent(), readData, schemaContext);
+ return transaction.commit();
case LAST:
- makePost(path, data, schemaContext, strategy);
- return strategy.commit();
+ makePost(path, data, schemaContext, transaction);
+ return transaction.commit();
case BEFORE:
readData = PutDataTransactionUtil.readList(strategy, path.getParent().getParent());
- if (readData == null || ((NormalizedNodeContainer<?, ?, ?>) readData).getValue().isEmpty()) {
- strategy.replace(LogicalDatastoreType.CONFIGURATION, path, data, schemaContext);
- return strategy.commit();
+ if (readData == null || ((NormalizedNodeContainer<?>) readData).isEmpty()) {
+ transaction.replace(path, data, schemaContext);
+ return transaction.commit();
}
- checkItemDoesNotExists(strategy, LogicalDatastoreType.CONFIGURATION, path);
- insertWithPointPost(path, data, schemaContext, point,
- (NormalizedNodeContainer<?, ?, NormalizedNode<?, ?>>) readData, true, strategy);
- return strategy.commit();
+ checkItemDoesNotExists(strategy.exists(LogicalDatastoreType.CONFIGURATION, path), path);
+ insertWithPointPost(path, data, schemaContext, params.getPoint(),
+ (NormalizedNodeContainer<?>) readData, true, transaction);
+ return transaction.commit();
case AFTER:
readData = PutDataTransactionUtil.readList(strategy, path.getParent().getParent());
- if (readData == null || ((NormalizedNodeContainer<?, ?, ?>) readData).getValue().isEmpty()) {
- strategy.replace(LogicalDatastoreType.CONFIGURATION, path, data, schemaContext);
- return strategy.commit();
+ if (readData == null || ((NormalizedNodeContainer<?>) readData).isEmpty()) {
+ transaction.replace(path, data, schemaContext);
+ return transaction.commit();
}
- checkItemDoesNotExists(strategy, LogicalDatastoreType.CONFIGURATION, path);
- insertWithPointPost(path, data, schemaContext, point,
- (NormalizedNodeContainer<?, ?, NormalizedNode<?, ?>>) readData, false, strategy);
- return strategy.commit();
+ checkItemDoesNotExists(strategy.exists(LogicalDatastoreType.CONFIGURATION, path), path);
+ insertWithPointPost(path, data, schemaContext, params.getPoint(),
+ (NormalizedNodeContainer<?>) readData, false, transaction);
+ return transaction.commit();
default:
throw new RestconfDocumentedException(
"Used bad value of insert parameter. Possible values are first, last, before or after, but was: "
- + insert, RestconfError.ErrorType.PROTOCOL, RestconfError.ErrorTag.BAD_ATTRIBUTE);
+ + insert, ErrorType.PROTOCOL, ErrorTag.BAD_ATTRIBUTE);
}
}
- private static void insertWithPointPost(final YangInstanceIdentifier path,
- final NormalizedNode<?, ?> data,
- final EffectiveModelContext schemaContext, final String point,
- final NormalizedNodeContainer<?, ?, NormalizedNode<?, ?>> readList,
- final boolean before, final RestconfStrategy strategy) {
+ 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.getParent().getParent();
- strategy.remove(LogicalDatastoreType.CONFIGURATION, parent);
- final InstanceIdentifierContext<?> instanceIdentifier =
- ParserIdentifier.toInstanceIdentifier(point, schemaContext, Optional.empty());
+ transaction.remove(parent);
+ final InstanceIdentifierContext instanceIdentifier =
+ // FIXME: Point should be able to give us this method
+ ParserIdentifier.toInstanceIdentifier(point.value(), schemaContext, Optional.empty());
int lastItemPosition = 0;
- for (final NormalizedNode<?, ?> nodeChild : readList.getValue()) {
+ for (final NormalizedNode nodeChild : readList.body()) {
if (nodeChild.getIdentifier().equals(instanceIdentifier.getInstanceIdentifier().getLastPathArgument())) {
break;
}
lastItemPosition++;
}
int lastInsertedPosition = 0;
- final NormalizedNode<?, ?> emptySubtree = ImmutableNodes.fromInstanceId(schemaContext, parent);
- strategy.merge(LogicalDatastoreType.CONFIGURATION,
- YangInstanceIdentifier.create(emptySubtree.getIdentifier()), emptySubtree);
- for (final NormalizedNode<?, ?> nodeChild : readList.getValue()) {
+ final NormalizedNode emptySubtree = ImmutableNodes.fromInstanceId(schemaContext, parent);
+ transaction.merge(YangInstanceIdentifier.create(emptySubtree.getIdentifier()), emptySubtree);
+ for (final NormalizedNode nodeChild : readList.body()) {
if (lastInsertedPosition == lastItemPosition) {
- strategy.replace(LogicalDatastoreType.CONFIGURATION, path, data, schemaContext);
+ transaction.replace(path, data, schemaContext);
}
final YangInstanceIdentifier childPath = parent.node(nodeChild.getIdentifier());
- strategy.replace(LogicalDatastoreType.CONFIGURATION, childPath, nodeChild, schemaContext);
+ transaction.replace(childPath, nodeChild, schemaContext);
lastInsertedPosition++;
}
}
- private static void makePost(final YangInstanceIdentifier path, final NormalizedNode<?, ?> data,
- final SchemaContext schemaContext, final RestconfStrategy strategy) {
+ private static void makePost(final YangInstanceIdentifier path, final NormalizedNode data,
+ final SchemaContext schemaContext, final RestconfTransaction transaction) {
try {
- strategy.create(LogicalDatastoreType.CONFIGURATION, path, data, schemaContext);
+ transaction.create(path, data, schemaContext);
} catch (RestconfDocumentedException e) {
// close transaction if any and pass exception further
- strategy.cancel();
+ transaction.cancel();
throw e;
}
}
* @return {@link URI}
*/
private static URI resolveLocation(final UriInfo uriInfo, final YangInstanceIdentifier initialPath,
- final EffectiveModelContext schemaContext, final NormalizedNode<?, ?> data) {
+ final EffectiveModelContext schemaContext, final NormalizedNode data) {
if (uriInfo == null) {
return null;
}
YangInstanceIdentifier path = initialPath;
if (data instanceof MapNode) {
- final Collection<MapEntryNode> children = ((MapNode) data).getValue();
+ final Collection<MapEntryNode> children = ((MapNode) data).body();
if (!children.isEmpty()) {
path = path.node(children.iterator().next().getIdentifier());
}
}
- return uriInfo.getBaseUriBuilder()
- .path("data")
- .path(ParserIdentifier.stringFromYangInstanceIdentifier(path, schemaContext))
- .build();
+ return uriInfo.getBaseUriBuilder().path("data").path(IdentifierCodec.serialize(path, schemaContext)).build();
}
/**
* Check if items do NOT already exists at specified {@code path}. Throws {@link RestconfDocumentedException} if
* data already exists.
*
- * @param strategy Object that perform the actual DS operations
- * @param store Datastore
- * @param path Path to be checked
+ * @param isExistsFuture if checked data exists
+ * @param path Path to be checked
*/
- public static void checkItemDoesNotExists(final RestconfStrategy strategy,
- final LogicalDatastoreType store, final YangInstanceIdentifier path) {
- final FluentFuture<Boolean> future = strategy.exists(store, path);
+ public static void checkItemDoesNotExists(final FluentFuture<Boolean> isExistsFuture,
+ final YangInstanceIdentifier path) {
final FutureDataFactory<Boolean> response = new FutureDataFactory<>();
-
- FutureCallbackTx.addCallback(future, POST_TX_TYPE, response);
+ FutureCallbackTx.addCallback(isExistsFuture, POST_TX_TYPE, response);
if (response.result) {
LOG.trace("Operation via Restconf was not executed because data at {} already exists", path);