*/
package org.opendaylight.netconf.sal.restconf.impl;
-import static org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType.CONFIGURATION;
-import static org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType.OPERATIONAL;
+import static org.opendaylight.mdsal.common.api.LogicalDatastoreType.CONFIGURATION;
+import static org.opendaylight.mdsal.common.api.LogicalDatastoreType.OPERATIONAL;
-import com.google.common.base.Optional;
import com.google.common.base.Preconditions;
+import com.google.common.base.Throwables;
import com.google.common.collect.ImmutableList;
-import com.google.common.util.concurrent.CheckedFuture;
+import com.google.common.util.concurrent.FluentFuture;
import com.google.common.util.concurrent.FutureCallback;
-import com.google.common.util.concurrent.Futures;
+import com.google.common.util.concurrent.ListenableFuture;
import com.google.common.util.concurrent.MoreExecutors;
import java.io.Closeable;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Map.Entry;
+import java.util.Objects;
+import java.util.Optional;
import java.util.concurrent.CountDownLatch;
-import javax.annotation.Nullable;
+import java.util.concurrent.ExecutionException;
+import javax.annotation.PreDestroy;
+import javax.inject.Inject;
+import javax.inject.Singleton;
import javax.ws.rs.core.Response.Status;
-import org.opendaylight.controller.md.sal.common.api.data.AsyncDataBroker.DataChangeScope;
-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.DOMDataBroker;
-import org.opendaylight.controller.md.sal.dom.api.DOMDataReadOnlyTransaction;
-import org.opendaylight.controller.md.sal.dom.api.DOMDataReadTransaction;
-import org.opendaylight.controller.md.sal.dom.api.DOMDataReadWriteTransaction;
-import org.opendaylight.controller.md.sal.dom.api.DOMDataTreeChangeService;
-import org.opendaylight.controller.md.sal.dom.api.DOMDataTreeIdentifier;
-import org.opendaylight.controller.md.sal.dom.api.DOMDataWriteTransaction;
-import org.opendaylight.controller.md.sal.dom.api.DOMMountPoint;
-import org.opendaylight.controller.md.sal.dom.api.DOMNotificationListener;
-import org.opendaylight.controller.md.sal.dom.api.DOMNotificationService;
-import org.opendaylight.controller.md.sal.dom.api.DOMRpcException;
-import org.opendaylight.controller.md.sal.dom.api.DOMRpcResult;
-import org.opendaylight.controller.md.sal.dom.api.DOMRpcService;
+import org.apache.aries.blueprint.annotation.service.Reference;
+import org.eclipse.jdt.annotation.NonNull;
+import org.opendaylight.mdsal.common.api.CommitInfo;
+import org.opendaylight.mdsal.common.api.LogicalDatastoreType;
+import org.opendaylight.mdsal.common.api.ReadFailedException;
+import org.opendaylight.mdsal.dom.api.DOMDataBroker;
+import org.opendaylight.mdsal.dom.api.DOMDataTreeChangeService;
+import org.opendaylight.mdsal.dom.api.DOMDataTreeIdentifier;
+import org.opendaylight.mdsal.dom.api.DOMDataTreeReadOperations;
+import org.opendaylight.mdsal.dom.api.DOMDataTreeReadTransaction;
+import org.opendaylight.mdsal.dom.api.DOMDataTreeReadWriteTransaction;
+import org.opendaylight.mdsal.dom.api.DOMDataTreeWriteTransaction;
+import org.opendaylight.mdsal.dom.api.DOMMountPoint;
+import org.opendaylight.mdsal.dom.api.DOMNotificationListener;
+import org.opendaylight.mdsal.dom.api.DOMNotificationService;
+import org.opendaylight.mdsal.dom.api.DOMRpcResult;
+import org.opendaylight.mdsal.dom.api.DOMRpcService;
+import org.opendaylight.mdsal.dom.api.DOMSchemaService;
import org.opendaylight.netconf.sal.streams.listeners.ListenerAdapter;
import org.opendaylight.netconf.sal.streams.listeners.NotificationListenerAdapter;
import org.opendaylight.restconf.common.context.InstanceIdentifierContext;
import org.opendaylight.restconf.common.patch.PatchEntity;
import org.opendaylight.restconf.common.patch.PatchStatusContext;
import org.opendaylight.restconf.common.patch.PatchStatusEntity;
+import org.opendaylight.restconf.common.util.DataChangeScope;
import org.opendaylight.yangtools.concepts.ListenerRegistration;
import org.opendaylight.yangtools.yang.common.QName;
-import org.opendaylight.yangtools.yang.common.RpcError;
import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifier;
import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifierWithPredicates;
import org.opendaylight.yangtools.yang.data.impl.schema.Builders;
import org.opendaylight.yangtools.yang.data.impl.schema.ImmutableNodes;
import org.opendaylight.yangtools.yang.data.impl.schema.builder.api.CollectionNodeBuilder;
-import org.opendaylight.yangtools.yang.data.impl.schema.builder.api.DataContainerNodeAttrBuilder;
-import org.opendaylight.yangtools.yang.data.impl.schema.builder.api.NormalizedNodeAttrBuilder;
+import org.opendaylight.yangtools.yang.data.impl.schema.builder.api.DataContainerNodeBuilder;
+import org.opendaylight.yangtools.yang.data.impl.schema.builder.api.NormalizedNodeBuilder;
import org.opendaylight.yangtools.yang.data.util.DataSchemaContextNode;
import org.opendaylight.yangtools.yang.data.util.DataSchemaContextTree;
import org.opendaylight.yangtools.yang.model.api.ContainerSchemaNode;
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.LeafSchemaNode;
import org.opendaylight.yangtools.yang.model.api.ListSchemaNode;
import org.opendaylight.yangtools.yang.model.api.SchemaContext;
import org.opendaylight.yangtools.yang.model.api.SchemaPath;
+import org.opendaylight.yangtools.yang.model.api.stmt.SchemaNodeIdentifier.Absolute;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+@Singleton
@SuppressWarnings("checkstyle:FinalClass")
public class BrokerFacade implements Closeable {
private static final Logger LOG = LoggerFactory.getLogger(BrokerFacade.class);
- private static final BrokerFacade INSTANCE = new BrokerFacade();
private volatile DOMRpcService rpcService;
- private DOMDataBroker domDataBroker;
- private DOMNotificationService domNotification;
- private ControllerContext controllerContext;
+ private final DOMDataBroker domDataBroker;
+ private final DOMNotificationService domNotification;
+ private final ControllerContext controllerContext;
- // Temporary until the static instance is removed.
- @Deprecated
- private BrokerFacade() {
- }
+ private final ThreadLocal<Boolean> isMounted = new ThreadLocal<>();
- private BrokerFacade(DOMRpcService rpcService, DOMDataBroker domDataBroker, DOMNotificationService domNotification,
- ControllerContext controllerContext) {
- this.rpcService = rpcService;
- this.domDataBroker = domDataBroker;
- this.domNotification = domNotification;
- this.controllerContext = controllerContext;
+ @Inject
+ public BrokerFacade(final @Reference DOMRpcService rpcService, final DOMDataBroker domDataBroker,
+ final @Reference DOMNotificationService domNotification, final ControllerContext controllerContext) {
+ this.rpcService = Objects.requireNonNull(rpcService);
+ this.domDataBroker = Objects.requireNonNull(domDataBroker);
+ this.domNotification = Objects.requireNonNull(domNotification);
+ this.controllerContext = Objects.requireNonNull(controllerContext);
}
+ /**
+ * Factory method.
+ *
+ * @deprecated Just use
+ * {@link #BrokerFacade(DOMRpcService, DOMDataBroker, DOMNotificationService, ControllerContext)}
+ * constructor instead.
+ */
@Deprecated
- public static BrokerFacade getInstance() {
- return BrokerFacade.INSTANCE;
- }
-
- public static BrokerFacade newInstance(DOMRpcService rpcService, DOMDataBroker domDataBroker,
- DOMNotificationService domNotification, ControllerContext controllerContext) {
- INSTANCE.rpcService = rpcService;
- INSTANCE.domDataBroker = domDataBroker;
- INSTANCE.controllerContext = controllerContext;
- INSTANCE.domNotification = domNotification;
- return INSTANCE;
- //return new BrokerFacade(pcService, domDataBroker, controllerContext);
+ public static BrokerFacade newInstance(final DOMRpcService rpcService, final DOMDataBroker domDataBroker,
+ final DOMNotificationService domNotification, final ControllerContext controllerContext) {
+ return new BrokerFacade(rpcService, domDataBroker, domNotification, controllerContext);
}
@Override
+ @PreDestroy
public void close() {
- domDataBroker = null;
- }
-
- private void checkPreconditions() {
- if (this.domDataBroker == null) {
- throw new RestconfDocumentedException(Status.SERVICE_UNAVAILABLE);
- }
}
/**
* @return read date
*/
public NormalizedNode<?, ?> readConfigurationData(final YangInstanceIdentifier path, final String withDefa) {
- checkPreconditions();
- try (DOMDataReadOnlyTransaction tx = this.domDataBroker.newReadOnlyTransaction()) {
+ try (DOMDataTreeReadTransaction tx = this.domDataBroker.newReadOnlyTransaction()) {
return readDataViaTransaction(tx, CONFIGURATION, path, withDefa);
}
}
final String withDefa) {
final Optional<DOMDataBroker> domDataBrokerService = mountPoint.getService(DOMDataBroker.class);
if (domDataBrokerService.isPresent()) {
- try (DOMDataReadOnlyTransaction tx = domDataBrokerService.get().newReadOnlyTransaction()) {
+ try (DOMDataTreeReadTransaction tx = domDataBrokerService.get().newReadOnlyTransaction()) {
return readDataViaTransaction(tx, CONFIGURATION, path, withDefa);
}
}
- final String errMsg = "DOM data broker service isn't available for mount point " + path;
- LOG.warn(errMsg);
- throw new RestconfDocumentedException(errMsg);
+ throw dataBrokerUnavailable(path);
}
/**
* @return read data
*/
public NormalizedNode<?, ?> readOperationalData(final YangInstanceIdentifier path) {
- checkPreconditions();
-
- try (DOMDataReadOnlyTransaction tx = this.domDataBroker.newReadOnlyTransaction()) {
+ try (DOMDataTreeReadTransaction tx = this.domDataBroker.newReadOnlyTransaction()) {
return readDataViaTransaction(tx, OPERATIONAL, path);
}
}
public NormalizedNode<?, ?> readOperationalData(final DOMMountPoint mountPoint, final YangInstanceIdentifier path) {
final Optional<DOMDataBroker> domDataBrokerService = mountPoint.getService(DOMDataBroker.class);
if (domDataBrokerService.isPresent()) {
- try (DOMDataReadOnlyTransaction tx = domDataBrokerService.get().newReadOnlyTransaction()) {
+ try (DOMDataTreeReadTransaction tx = domDataBrokerService.get().newReadOnlyTransaction()) {
return readDataViaTransaction(tx, OPERATIONAL, path);
}
}
- final String errMsg = "DOM data broker service isn't available for mount point " + path;
- LOG.warn(errMsg);
- throw new RestconfDocumentedException(errMsg);
+ throw dataBrokerUnavailable(path);
}
/**
* @return wrapper of status and future of PUT
*/
public PutResult commitConfigurationDataPut(
- final SchemaContext globalSchema, final YangInstanceIdentifier path, final NormalizedNode<?, ?> payload,
- final String insert, final String point) {
+ final EffectiveModelContext globalSchema, final YangInstanceIdentifier path,
+ final NormalizedNode<?, ?> payload, final String insert, final String point) {
Preconditions.checkNotNull(globalSchema);
Preconditions.checkNotNull(path);
Preconditions.checkNotNull(payload);
- checkPreconditions();
-
- final DOMDataReadWriteTransaction newReadWriteTransaction = this.domDataBroker.newReadWriteTransaction();
+ isMounted.set(false);
+ final DOMDataTreeReadWriteTransaction newReadWriteTransaction = this.domDataBroker.newReadWriteTransaction();
final Status status = readDataViaTransaction(newReadWriteTransaction, CONFIGURATION, path) != null ? Status.OK
: Status.CREATED;
- final CheckedFuture<Void, TransactionCommitFailedException> future = putDataViaTransaction(
+ final FluentFuture<? extends CommitInfo> future = putDataViaTransaction(
newReadWriteTransaction, CONFIGURATION, path, payload, globalSchema, insert, point);
+ isMounted.remove();
return new PutResult(status, future);
}
Preconditions.checkNotNull(path);
Preconditions.checkNotNull(payload);
+ isMounted.set(true);
final Optional<DOMDataBroker> domDataBrokerService = mountPoint.getService(DOMDataBroker.class);
if (domDataBrokerService.isPresent()) {
- final DOMDataReadWriteTransaction newReadWriteTransaction =
+ final DOMDataTreeReadWriteTransaction newReadWriteTransaction =
domDataBrokerService.get().newReadWriteTransaction();
final Status status = readDataViaTransaction(newReadWriteTransaction, CONFIGURATION, path) != null
? Status.OK : Status.CREATED;
- final CheckedFuture<Void, TransactionCommitFailedException> future = putDataViaTransaction(
- newReadWriteTransaction, CONFIGURATION, path, payload, mountPoint.getSchemaContext(), insert,
- point);
+ final FluentFuture<? extends CommitInfo> future = putDataViaTransaction(
+ newReadWriteTransaction, CONFIGURATION, path, payload, modelContext(mountPoint), insert, point);
+ isMounted.remove();
return new PutResult(status, future);
}
- final String errMsg = "DOM data broker service isn't available for mount point " + path;
- LOG.warn(errMsg);
- throw new RestconfDocumentedException(errMsg);
+ isMounted.remove();
+ throw dataBrokerUnavailable(path);
}
public PatchStatusContext patchConfigurationDataWithinTransaction(final PatchContext patchContext)
final DOMMountPoint mountPoint = patchContext.getInstanceIdentifierContext().getMountPoint();
// get new transaction and schema context on server or on mounted device
- final SchemaContext schemaContext;
- final DOMDataReadWriteTransaction patchTransaction;
+ final EffectiveModelContext schemaContext;
+ final DOMDataTreeReadWriteTransaction patchTransaction;
if (mountPoint == null) {
schemaContext = patchContext.getInstanceIdentifierContext().getSchemaContext();
patchTransaction = this.domDataBroker.newReadWriteTransaction();
} else {
- schemaContext = mountPoint.getSchemaContext();
+ schemaContext = modelContext(mountPoint);
final Optional<DOMDataBroker> optional = mountPoint.getService(DOMDataBroker.class);
// if no errors commit transaction
final CountDownLatch waiter = new CountDownLatch(1);
- final CheckedFuture<Void, TransactionCommitFailedException> future = patchTransaction.submit();
+ final FluentFuture<? extends CommitInfo> future = patchTransaction.commit();
final PatchStatusContextHelper status = new PatchStatusContextHelper();
- Futures.addCallback(future, new FutureCallback<Void>() {
+ future.addCallback(new FutureCallback<CommitInfo>() {
@Override
- public void onSuccess(@Nullable final Void result) {
+ public void onSuccess(final CommitInfo result) {
status.setStatus(new PatchStatusContext(patchContext.getPatchId(), ImmutableList.copyOf(editCollection),
true, null));
waiter.countDown();
// if commit failed it is global error
LOG.error("Http Patch {} transaction commit has failed", patchContext.getPatchId());
status.setStatus(new PatchStatusContext(patchContext.getPatchId(), ImmutableList.copyOf(editCollection),
- false, ImmutableList.of(
+ false, ImmutableList.of(
new RestconfError(ErrorType.APPLICATION, ErrorTag.OPERATION_FAILED, throwable.getMessage()))));
waiter.countDown();
}
}
// POST configuration
- public CheckedFuture<Void, TransactionCommitFailedException> commitConfigurationDataPost(
- final SchemaContext globalSchema, final YangInstanceIdentifier path, final NormalizedNode<?, ?> payload,
- final String insert, final String point) {
- checkPreconditions();
- return postDataViaTransaction(this.domDataBroker.newReadWriteTransaction(), CONFIGURATION, path, payload,
- globalSchema, insert, point);
+ public FluentFuture<? extends CommitInfo> commitConfigurationDataPost(
+ final EffectiveModelContext globalSchema, final YangInstanceIdentifier path,
+ final NormalizedNode<?, ?> payload, final String insert, final String point) {
+ isMounted.set(false);
+ FluentFuture<? extends CommitInfo> future =
+ postDataViaTransaction(this.domDataBroker.newReadWriteTransaction(), CONFIGURATION, path, payload,
+ globalSchema, insert, point);
+ isMounted.remove();
+ return future;
}
- public CheckedFuture<Void, TransactionCommitFailedException> commitConfigurationDataPost(
+ public FluentFuture<? extends CommitInfo> commitConfigurationDataPost(
final DOMMountPoint mountPoint, final YangInstanceIdentifier path, final NormalizedNode<?, ?> payload,
final String insert, final String point) {
+ isMounted.set(true);
final Optional<DOMDataBroker> domDataBrokerService = mountPoint.getService(DOMDataBroker.class);
if (domDataBrokerService.isPresent()) {
- return postDataViaTransaction(domDataBrokerService.get().newReadWriteTransaction(), CONFIGURATION, path,
- payload, mountPoint.getSchemaContext(), insert, point);
+ FluentFuture<? extends CommitInfo> future =
+ postDataViaTransaction(domDataBrokerService.get().newReadWriteTransaction(), CONFIGURATION, path,
+ payload, modelContext(mountPoint), insert, point);
+ isMounted.remove();
+ return future;
}
- final String errMsg = "DOM data broker service isn't available for mount point " + path;
- LOG.warn(errMsg);
- throw new RestconfDocumentedException(errMsg);
+ isMounted.remove();
+ throw dataBrokerUnavailable(path);
}
// DELETE configuration
- public CheckedFuture<Void, TransactionCommitFailedException> commitConfigurationDataDelete(
- final YangInstanceIdentifier path) {
- checkPreconditions();
+ public FluentFuture<? extends CommitInfo> commitConfigurationDataDelete(final YangInstanceIdentifier path) {
return deleteDataViaTransaction(this.domDataBroker.newReadWriteTransaction(), CONFIGURATION, path);
}
- public CheckedFuture<Void, TransactionCommitFailedException> commitConfigurationDataDelete(
+ public FluentFuture<? extends CommitInfo> commitConfigurationDataDelete(
final DOMMountPoint mountPoint, final YangInstanceIdentifier path) {
final Optional<DOMDataBroker> domDataBrokerService = mountPoint.getService(DOMDataBroker.class);
if (domDataBrokerService.isPresent()) {
return deleteDataViaTransaction(domDataBrokerService.get().newReadWriteTransaction(), CONFIGURATION, path);
}
- final String errMsg = "DOM data broker service isn't available for mount point " + path;
- LOG.warn(errMsg);
- throw new RestconfDocumentedException(errMsg);
+ throw dataBrokerUnavailable(path);
}
// RPC
- public CheckedFuture<DOMRpcResult, DOMRpcException> invokeRpc(final SchemaPath type,
- final NormalizedNode<?, ?> input) {
- checkPreconditions();
+ public ListenableFuture<? extends DOMRpcResult> invokeRpc(final @NonNull QName type,
+ final @NonNull NormalizedNode<?, ?> input) {
if (this.rpcService == null) {
throw new RestconfDocumentedException(Status.SERVICE_UNAVAILABLE);
}
public void registerToListenDataChanges(final LogicalDatastoreType datastore, final DataChangeScope scope,
final ListenerAdapter listener) {
- checkPreconditions();
-
if (listener.isListening()) {
return;
}
final YangInstanceIdentifier path = listener.getPath();
- DOMDataTreeChangeService changeService = (DOMDataTreeChangeService)
- this.domDataBroker.getSupportedExtensions().get(DOMDataTreeChangeService.class);
+ DOMDataTreeChangeService changeService = this.domDataBroker.getExtensions()
+ .getInstance(DOMDataTreeChangeService.class);
if (changeService == null) {
throw new UnsupportedOperationException("DOMDataBroker does not support the DOMDataTreeChangeService"
+ this.domDataBroker);
listener.setRegistration(registration);
}
- private NormalizedNode<?, ?> readDataViaTransaction(final DOMDataReadTransaction transaction,
+ private NormalizedNode<?, ?> readDataViaTransaction(final DOMDataTreeReadOperations transaction,
final LogicalDatastoreType datastore, final YangInstanceIdentifier path) {
return readDataViaTransaction(transaction, datastore, path, null);
}
- private NormalizedNode<?, ?> readDataViaTransaction(final DOMDataReadTransaction transaction,
+ private NormalizedNode<?, ?> readDataViaTransaction(final DOMDataTreeReadOperations transaction,
final LogicalDatastoreType datastore, final YangInstanceIdentifier path, final String withDefa) {
LOG.trace("Read {} via Restconf: {}", datastore.name(), path);
try {
- final Optional<NormalizedNode<?, ?>> optional = transaction.read(datastore, path).checkedGet();
+ final Optional<NormalizedNode<?, ?>> optional = transaction.read(datastore, path).get();
return !optional.isPresent() ? null : withDefa == null ? optional.get() :
prepareDataByParamWithDef(optional.get(), path, withDefa);
- } catch (ReadFailedException e) {
+ } catch (InterruptedException e) {
LOG.warn("Error reading {} from datastore {}", path, datastore.name(), e);
- for (final RpcError error : e.getErrorList()) {
- if (error.getErrorType() == RpcError.ErrorType.TRANSPORT
- && error.getTag().equals(ErrorTag.RESOURCE_DENIED.getTagValue())) {
- throw new RestconfDocumentedException(
- error.getMessage(),
- ErrorType.TRANSPORT,
- ErrorTag.RESOURCE_DENIED_TRANSPORT, e);
- }
- }
- throw new RestconfDocumentedException("Error reading data.", e, e.getErrorList());
+ throw new RestconfDocumentedException("Error reading data.", e);
+ } catch (ExecutionException e) {
+ LOG.warn("Error reading {} from datastore {}", path, datastore.name(), e);
+ throw RestconfDocumentedException.decodeAndThrow("Error reading data.", Throwables.getCauseAs(e,
+ ReadFailedException.class));
}
}
throw new RestconfDocumentedException("Bad value used with with-defaults parameter : " + withDefa);
}
- final SchemaContext ctx = controllerContext.getGlobalSchema();
+ final EffectiveModelContext ctx = controllerContext.getGlobalSchema();
final DataSchemaContextTree baseSchemaCtxTree = DataSchemaContextTree.from(ctx);
- final DataSchemaNode baseSchemaNode = baseSchemaCtxTree.getChild(path).getDataSchemaNode();
+ final DataSchemaNode baseSchemaNode = baseSchemaCtxTree.findChild(path).orElseThrow().getDataSchemaNode();
if (result instanceof ContainerNode) {
- final DataContainerNodeAttrBuilder<NodeIdentifier, ContainerNode> builder =
+ final DataContainerNodeBuilder<NodeIdentifier, ContainerNode> builder =
Builders.containerBuilder((ContainerSchemaNode) baseSchemaNode);
buildCont(builder, (ContainerNode) result, baseSchemaCtxTree, path, trim);
return builder.build();
}
- final DataContainerNodeAttrBuilder<NodeIdentifierWithPredicates, MapEntryNode> builder =
+ final DataContainerNodeBuilder<NodeIdentifierWithPredicates, MapEntryNode> builder =
Builders.mapEntryBuilder((ListSchemaNode) baseSchemaNode);
buildMapEntryBuilder(builder, (MapEntryNode) result, baseSchemaCtxTree, path, trim,
((ListSchemaNode) baseSchemaNode).getKeyDefinition());
}
private void buildMapEntryBuilder(
- final DataContainerNodeAttrBuilder<NodeIdentifierWithPredicates, MapEntryNode> builder,
+ final DataContainerNodeBuilder<NodeIdentifierWithPredicates, MapEntryNode> builder,
final MapEntryNode result, final DataSchemaContextTree baseSchemaCtxTree,
final YangInstanceIdentifier actualPath, final boolean trim, final List<QName> keys) {
for (final DataContainerChild<? extends PathArgument, ?> child : result.getValue()) {
final YangInstanceIdentifier path = actualPath.node(child.getIdentifier());
- final DataSchemaNode childSchema = baseSchemaCtxTree.getChild(path).getDataSchemaNode();
+ final DataSchemaNode childSchema = baseSchemaCtxTree.findChild(path).orElseThrow().getDataSchemaNode();
if (child instanceof ContainerNode) {
- final DataContainerNodeAttrBuilder<NodeIdentifier, ContainerNode> childBuilder =
+ final DataContainerNodeBuilder<NodeIdentifier, ContainerNode> childBuilder =
Builders.containerBuilder((ContainerSchemaNode) childSchema);
buildCont(childBuilder, (ContainerNode) child, baseSchemaCtxTree, path, trim);
builder.withChild(childBuilder.build());
builder.withChild(childBuilder.build());
} else if (child instanceof LeafNode) {
final Object defaultVal = ((LeafSchemaNode) childSchema).getType().getDefaultValue().orElse(null);
- final Object nodeVal = ((LeafNode<?>) child).getValue();
- final NormalizedNodeAttrBuilder<NodeIdentifier, Object, LeafNode<Object>> leafBuilder =
+ final Object nodeVal = child.getValue();
+ final NormalizedNodeBuilder<NodeIdentifier, Object, LeafNode<Object>> leafBuilder =
Builders.leafBuilder((LeafSchemaNode) childSchema);
if (keys.contains(child.getNodeType())) {
- leafBuilder.withValue(((LeafNode<?>) child).getValue());
+ leafBuilder.withValue(child.getValue());
builder.withChild(leafBuilder.build());
} else {
if (trim) {
if (defaultVal == null || !defaultVal.equals(nodeVal)) {
- leafBuilder.withValue(((LeafNode<?>) child).getValue());
+ leafBuilder.withValue(child.getValue());
builder.withChild(leafBuilder.build());
}
} else {
if (defaultVal != null && defaultVal.equals(nodeVal)) {
- leafBuilder.withValue(((LeafNode<?>) child).getValue());
+ leafBuilder.withValue(child.getValue());
builder.withChild(leafBuilder.build());
}
}
final List<QName> keys) {
for (final MapEntryNode mapEntryNode : result.getValue()) {
final YangInstanceIdentifier actualNode = path.node(mapEntryNode.getIdentifier());
- final DataSchemaNode childSchema = baseSchemaCtxTree.getChild(actualNode).getDataSchemaNode();
- final DataContainerNodeAttrBuilder<NodeIdentifierWithPredicates, MapEntryNode> mapEntryBuilder =
+ final DataSchemaNode childSchema = baseSchemaCtxTree.findChild(actualNode).orElseThrow()
+ .getDataSchemaNode();
+ final DataContainerNodeBuilder<NodeIdentifierWithPredicates, MapEntryNode> mapEntryBuilder =
Builders.mapEntryBuilder((ListSchemaNode) childSchema);
buildMapEntryBuilder(mapEntryBuilder, mapEntryNode, baseSchemaCtxTree, actualNode, trim, keys);
builder.withChild(mapEntryBuilder.build());
}
}
- private void buildCont(final DataContainerNodeAttrBuilder<NodeIdentifier, ContainerNode> builder,
+ private void buildCont(final DataContainerNodeBuilder<NodeIdentifier, ContainerNode> builder,
final ContainerNode result, final DataSchemaContextTree baseSchemaCtxTree,
final YangInstanceIdentifier actualPath, final boolean trim) {
for (final DataContainerChild<? extends PathArgument, ?> child : result.getValue()) {
final YangInstanceIdentifier path = actualPath.node(child.getIdentifier());
- final DataSchemaNode childSchema = baseSchemaCtxTree.getChild(path).getDataSchemaNode();
+ final DataSchemaNode childSchema = baseSchemaCtxTree.findChild(path).orElseThrow().getDataSchemaNode();
if (child instanceof ContainerNode) {
- final DataContainerNodeAttrBuilder<NodeIdentifier, ContainerNode> builderChild =
+ final DataContainerNodeBuilder<NodeIdentifier, ContainerNode> builderChild =
Builders.containerBuilder((ContainerSchemaNode) childSchema);
buildCont(builderChild, result, baseSchemaCtxTree, actualPath, trim);
builder.withChild(builderChild.build());
builder.withChild(childBuilder.build());
} else if (child instanceof LeafNode) {
final Object defaultVal = ((LeafSchemaNode) childSchema).getType().getDefaultValue().orElse(null);
- final Object nodeVal = ((LeafNode<?>) child).getValue();
- final NormalizedNodeAttrBuilder<NodeIdentifier, Object, LeafNode<Object>> leafBuilder =
+ final Object nodeVal = child.getValue();
+ final NormalizedNodeBuilder<NodeIdentifier, Object, LeafNode<Object>> leafBuilder =
Builders.leafBuilder((LeafSchemaNode) childSchema);
if (trim) {
if (defaultVal == null || !defaultVal.equals(nodeVal)) {
- leafBuilder.withValue(((LeafNode<?>) child).getValue());
+ leafBuilder.withValue(child.getValue());
builder.withChild(leafBuilder.build());
}
} else {
if (defaultVal != null && defaultVal.equals(nodeVal)) {
- leafBuilder.withValue(((LeafNode<?>) child).getValue());
+ leafBuilder.withValue(child.getValue());
builder.withChild(leafBuilder.build());
}
}
/**
* POST data and submit transaction {@link DOMDataReadWriteTransaction}.
*/
- private CheckedFuture<Void, TransactionCommitFailedException> postDataViaTransaction(
- final DOMDataReadWriteTransaction rwTransaction, final LogicalDatastoreType datastore,
- final YangInstanceIdentifier path, final NormalizedNode<?, ?> payload, final SchemaContext schemaContext,
- final String insert, final String point) {
+ private FluentFuture<? extends CommitInfo> postDataViaTransaction(
+ final DOMDataTreeReadWriteTransaction rwTransaction, final LogicalDatastoreType datastore,
+ final YangInstanceIdentifier path, final NormalizedNode<?, ?> payload,
+ final EffectiveModelContext schemaContext, final String insert, final String point) {
LOG.trace("POST {} via Restconf: {} with payload {}", datastore.name(), path, payload);
postData(rwTransaction, datastore, path, payload, schemaContext, insert, point);
- return rwTransaction.submit();
+ return rwTransaction.commit();
}
/**
* POST data and do NOT submit transaction {@link DOMDataReadWriteTransaction}.
*/
private void postDataWithinTransaction(
- final DOMDataReadWriteTransaction rwTransaction, final LogicalDatastoreType datastore,
- final YangInstanceIdentifier path, final NormalizedNode<?, ?> payload, final SchemaContext schemaContext) {
+ final DOMDataTreeReadWriteTransaction rwTransaction, final LogicalDatastoreType datastore,
+ final YangInstanceIdentifier path, final NormalizedNode<?, ?> payload,
+ final EffectiveModelContext schemaContext) {
LOG.trace("POST {} within Restconf Patch: {} with payload {}", datastore.name(), path, payload);
postData(rwTransaction, datastore, path, payload, schemaContext, null, null);
}
- private void postData(final DOMDataReadWriteTransaction rwTransaction, final LogicalDatastoreType datastore,
+ private void postData(final DOMDataTreeReadWriteTransaction rwTransaction, final LogicalDatastoreType datastore,
final YangInstanceIdentifier path, final NormalizedNode<?, ?> payload,
- final SchemaContext schemaContext, final String insert, final String point) {
+ final EffectiveModelContext schemaContext, final String insert, final String point) {
if (insert == null) {
makeNormalPost(rwTransaction, datastore, path, payload, schemaContext);
return;
}
}
- private void insertWithPointLeafListPost(final DOMDataReadWriteTransaction rwTransaction,
+ private void insertWithPointLeafListPost(final DOMDataTreeReadWriteTransaction rwTransaction,
final LogicalDatastoreType datastore, final YangInstanceIdentifier path, final NormalizedNode<?, ?> payload,
final SchemaContext schemaContext, final String point, final OrderedLeafSetNode<?> readLeafList,
final boolean before) {
}
}
- private void insertWithPointListPost(final DOMDataReadWriteTransaction rwTransaction,
+ private void insertWithPointListPost(final DOMDataTreeReadWriteTransaction rwTransaction,
final LogicalDatastoreType datastore,
final YangInstanceIdentifier path, final NormalizedNode<?, ?> payload, final SchemaContext schemaContext,
final String point, final MapNode readList, final boolean before) {
}
}
- private static DataSchemaNode checkListAndOrderedType(final SchemaContext ctx, final YangInstanceIdentifier path) {
+ private static DataSchemaNode checkListAndOrderedType(final EffectiveModelContext ctx,
+ final YangInstanceIdentifier path) {
final YangInstanceIdentifier parent = path.getParent();
- final DataSchemaContextNode<?> node = DataSchemaContextTree.from(ctx).getChild(parent);
+ final DataSchemaContextNode<?> node = DataSchemaContextTree.from(ctx).findChild(parent).orElseThrow();
final DataSchemaNode dataSchemaNode = node.getDataSchemaNode();
if (dataSchemaNode instanceof ListSchemaNode) {
throw new RestconfDocumentedException("Insert parameter can be used only with list or leaf-list");
}
- private static void makeNormalPost(final DOMDataReadWriteTransaction rwTransaction,
+ private void makeNormalPost(final DOMDataTreeReadWriteTransaction rwTransaction,
final LogicalDatastoreType datastore, final YangInstanceIdentifier path, final NormalizedNode<?, ?> payload,
final SchemaContext schemaContext) {
final Collection<? extends NormalizedNode<?, ?>> children;
final NormalizedNode<?, ?> emptySubtree = ImmutableNodes.fromInstanceId(schemaContext, path);
if (children.isEmpty()) {
- rwTransaction.merge(datastore, YangInstanceIdentifier.create(emptySubtree.getIdentifier()), emptySubtree);
- ensureParentsByMerge(datastore, path, rwTransaction, schemaContext);
+ if (isMounted != null && !isMounted.get()) {
+
+ rwTransaction.merge(datastore, YangInstanceIdentifier.create(emptySubtree.getIdentifier()),
+ emptySubtree);
+ ensureParentsByMerge(datastore, path, rwTransaction, schemaContext);
+ }
return;
}
// ... now enqueue modifications. This relies on proper ordering of requests, i.e. these will not affect the
// result of the existence checks...
- rwTransaction.merge(datastore, YangInstanceIdentifier.create(emptySubtree.getIdentifier()), emptySubtree);
- ensureParentsByMerge(datastore, path, rwTransaction, schemaContext);
+ if (isMounted != null && !isMounted.get()) {
+
+ rwTransaction.merge(datastore, YangInstanceIdentifier.create(emptySubtree.getIdentifier()), emptySubtree);
+ ensureParentsByMerge(datastore, path, rwTransaction, schemaContext);
+ }
for (final NormalizedNode<?, ?> child : children) {
// FIXME: we really want a create(YangInstanceIdentifier, NormalizedNode) method in the transaction,
// as that would allow us to skip the existence checks
}
}
- private static void simplePostPut(final DOMDataReadWriteTransaction rwTransaction,
+ private void simplePostPut(final DOMDataTreeReadWriteTransaction rwTransaction,
final LogicalDatastoreType datastore, final YangInstanceIdentifier path, final NormalizedNode<?, ?> payload,
final SchemaContext schemaContext) {
checkItemDoesNotExists(rwTransaction, datastore, path);
- ensureParentsByMerge(datastore, path, rwTransaction, schemaContext);
+ if (isMounted != null && !isMounted.get()) {
+ ensureParentsByMerge(datastore, path, rwTransaction, schemaContext);
+ }
rwTransaction.put(datastore, path, payload);
}
- private static boolean doesItemExist(final DOMDataReadWriteTransaction rwTransaction,
+ private static boolean doesItemExist(final DOMDataTreeReadWriteTransaction rwTransaction,
final LogicalDatastoreType store, final YangInstanceIdentifier path) {
try {
- return rwTransaction.exists(store, path).checkedGet();
- } catch (ReadFailedException e) {
+ return rwTransaction.exists(store, path).get();
+ } catch (InterruptedException e) {
rwTransaction.cancel();
- throw new RestconfDocumentedException("Could not determine the existence of path " + path,
- e, e.getErrorList());
+ throw new RestconfDocumentedException("Could not determine the existence of path " + path, e);
+ } catch (ExecutionException e) {
+ rwTransaction.cancel();
+ throw RestconfDocumentedException.decodeAndThrow("Could not determine the existence of path " + path,
+ Throwables.getCauseAs(e, ReadFailedException.class));
}
}
* @param store Used datastore
* @param path Path to item to verify its existence
*/
- private static void checkItemExists(final DOMDataReadWriteTransaction rwTransaction,
+ private static void checkItemExists(final DOMDataTreeReadWriteTransaction rwTransaction,
final LogicalDatastoreType store, final YangInstanceIdentifier path) {
if (!doesItemExist(rwTransaction, store, path)) {
- final String errMsg = "Operation via Restconf was not executed because data does not exist";
- LOG.trace("{}:{}", errMsg, path);
+ LOG.trace("Operation via Restconf was not executed because data at {} does not exist", path);
rwTransaction.cancel();
throw new RestconfDocumentedException("Data does not exist for path: " + path, ErrorType.PROTOCOL,
ErrorTag.DATA_MISSING);
* @param store Used datastore
* @param path Path to item to verify its existence
*/
- private static void checkItemDoesNotExists(final DOMDataReadWriteTransaction rwTransaction,
+ private static void checkItemDoesNotExists(final DOMDataTreeReadWriteTransaction rwTransaction,
final LogicalDatastoreType store, final YangInstanceIdentifier path) {
if (doesItemExist(rwTransaction, store, path)) {
- final String errMsg = "Operation via Restconf was not executed because data already exists";
- LOG.trace("{}:{}", errMsg, path);
+ LOG.trace("Operation via Restconf was not executed because data at {} already exists", path);
rwTransaction.cancel();
throw new RestconfDocumentedException("Data already exists for path: " + path, ErrorType.PROTOCOL,
ErrorTag.DATA_EXISTS);
* @param insert
* insert
*/
- private CheckedFuture<Void, TransactionCommitFailedException> putDataViaTransaction(
- final DOMDataReadWriteTransaction readWriteTransaction, final LogicalDatastoreType datastore,
- final YangInstanceIdentifier path, final NormalizedNode<?, ?> payload, final SchemaContext schemaContext,
- final String insert, final String point) {
+ private FluentFuture<? extends CommitInfo> putDataViaTransaction(
+ final DOMDataTreeReadWriteTransaction readWriteTransaction, final LogicalDatastoreType datastore,
+ final YangInstanceIdentifier path, final NormalizedNode<?, ?> payload,
+ final EffectiveModelContext schemaContext, final String insert, final String point) {
LOG.trace("Put {} via Restconf: {} with payload {}", datastore.name(), path, payload);
putData(readWriteTransaction, datastore, path, payload, schemaContext, insert, point);
- return readWriteTransaction.submit();
+ return readWriteTransaction.commit();
}
/**
* PUT data and do NOT submit {@link DOMDataReadWriteTransaction}.
*/
private void putDataWithinTransaction(
- final DOMDataReadWriteTransaction writeTransaction, final LogicalDatastoreType datastore,
- final YangInstanceIdentifier path, final NormalizedNode<?, ?> payload, final SchemaContext schemaContext) {
+ final DOMDataTreeReadWriteTransaction writeTransaction, final LogicalDatastoreType datastore,
+ final YangInstanceIdentifier path, final NormalizedNode<?, ?> payload,
+ final EffectiveModelContext schemaContext) {
LOG.trace("Put {} within Restconf Patch: {} with payload {}", datastore.name(), path, payload);
putData(writeTransaction, datastore, path, payload, schemaContext, null, null);
}
// FIXME: This is doing correct put for container and list children, not sure if this will work for choice case
- private void putData(final DOMDataReadWriteTransaction rwTransaction, final LogicalDatastoreType datastore,
- final YangInstanceIdentifier path, final NormalizedNode<?, ?> payload, final SchemaContext schemaContext,
- final String insert, final String point) {
+ private void putData(final DOMDataTreeReadWriteTransaction rwTransaction, final LogicalDatastoreType datastore,
+ final YangInstanceIdentifier path, final NormalizedNode<?, ?> payload,
+ final EffectiveModelContext schemaContext, final String insert, final String point) {
if (insert == null) {
makePut(rwTransaction, datastore, path, payload, schemaContext);
return;
}
}
- private void insertWithPointLeafListPut(final DOMDataWriteTransaction tx,
+ private void insertWithPointLeafListPut(final DOMDataTreeWriteTransaction tx,
final LogicalDatastoreType datastore, final YangInstanceIdentifier path, final NormalizedNode<?, ?> payload,
final SchemaContext schemaContext, final String point, final OrderedLeafSetNode<?> readLeafList,
final boolean before) {
}
}
- private void insertWithPointListPut(final DOMDataWriteTransaction tx, final LogicalDatastoreType datastore,
+ private void insertWithPointListPut(final DOMDataTreeWriteTransaction tx, final LogicalDatastoreType datastore,
final YangInstanceIdentifier path, final NormalizedNode<?, ?> payload, final SchemaContext schemaContext,
final String point, final OrderedMapNode readList, final boolean before) {
tx.delete(datastore, path.getParent());
}
}
- private static void makePut(final DOMDataWriteTransaction tx, final LogicalDatastoreType datastore,
+ private void makePut(final DOMDataTreeWriteTransaction tx, final LogicalDatastoreType datastore,
final YangInstanceIdentifier path, final NormalizedNode<?, ?> payload, final SchemaContext schemaContext) {
if (payload instanceof MapNode) {
final NormalizedNode<?, ?> emptySubtree = ImmutableNodes.fromInstanceId(schemaContext, path);
- tx.merge(datastore, YangInstanceIdentifier.create(emptySubtree.getIdentifier()), emptySubtree);
- ensureParentsByMerge(datastore, path, tx, schemaContext);
+ if (isMounted != null && !isMounted.get()) {
+ tx.merge(datastore, YangInstanceIdentifier.create(emptySubtree.getIdentifier()), emptySubtree);
+ ensureParentsByMerge(datastore, path, tx, schemaContext);
+ }
for (final MapEntryNode child : ((MapNode) payload).getValue()) {
final YangInstanceIdentifier childPath = path.node(child.getIdentifier());
tx.put(datastore, childPath, child);
}
}
- private static void simplePut(final LogicalDatastoreType datastore, final YangInstanceIdentifier path,
- final DOMDataWriteTransaction tx, final SchemaContext schemaContext, final NormalizedNode<?, ?> payload) {
- ensureParentsByMerge(datastore, path, tx, schemaContext);
+ private void simplePut(final LogicalDatastoreType datastore, final YangInstanceIdentifier path,
+ final DOMDataTreeWriteTransaction tx, final SchemaContext schemaContext,
+ final NormalizedNode<?, ?> payload) {
+ if (isMounted != null && !isMounted.get()) {
+ ensureParentsByMerge(datastore, path, tx, schemaContext);
+ }
tx.put(datastore, path, payload);
}
- private static CheckedFuture<Void, TransactionCommitFailedException> deleteDataViaTransaction(
- final DOMDataReadWriteTransaction readWriteTransaction, final LogicalDatastoreType datastore,
+ private static FluentFuture<? extends CommitInfo> deleteDataViaTransaction(
+ final DOMDataTreeReadWriteTransaction readWriteTransaction, final LogicalDatastoreType datastore,
final YangInstanceIdentifier path) {
LOG.trace("Delete {} via Restconf: {}", datastore.name(), path);
checkItemExists(readWriteTransaction, datastore, path);
readWriteTransaction.delete(datastore, path);
- return readWriteTransaction.submit();
+ return readWriteTransaction.commit();
}
- private static void deleteDataWithinTransaction(final DOMDataWriteTransaction tx,
+ private static void deleteDataWithinTransaction(final DOMDataTreeWriteTransaction tx,
final LogicalDatastoreType datastore, final YangInstanceIdentifier path) {
LOG.trace("Delete {} within Restconf Patch: {}", datastore.name(), path);
tx.delete(datastore, path);
}
- private static void mergeDataWithinTransaction(final DOMDataWriteTransaction tx,
+ private static void mergeDataWithinTransaction(final DOMDataTreeWriteTransaction tx,
final LogicalDatastoreType datastore, final YangInstanceIdentifier path, final NormalizedNode<?, ?> payload,
final SchemaContext schemaContext) {
LOG.trace("Merge {} within Restconf Patch: {} with payload {}", datastore.name(), path, payload);
}
public void registerToListenNotification(final NotificationListenerAdapter listener) {
- checkPreconditions();
-
if (listener.isListening()) {
return;
}
final SchemaPath path = listener.getSchemaPath();
final ListenerRegistration<DOMNotificationListener> registration = this.domNotification
- .registerNotificationListener(listener, path);
+ .registerNotificationListener(listener, Absolute.of(ImmutableList.copyOf(path.getPathFromRoot())));
listener.setRegistration(registration);
}
private static void ensureParentsByMerge(final LogicalDatastoreType store,
- final YangInstanceIdentifier normalizedPath, final DOMDataWriteTransaction tx,
+ final YangInstanceIdentifier normalizedPath, final DOMDataTreeWriteTransaction tx,
final SchemaContext schemaContext) {
final List<PathArgument> normalizedPathWithoutChildArgs = new ArrayList<>();
YangInstanceIdentifier rootNormalizedPath = null;
tx.merge(store, rootNormalizedPath, parentStructure);
}
+ private static RestconfDocumentedException dataBrokerUnavailable(final YangInstanceIdentifier path) {
+ LOG.warn("DOM data broker service is not available for mount point {}", path);
+ return new RestconfDocumentedException("DOM data broker service is not available for mount point " + path);
+ }
+
+ private static EffectiveModelContext modelContext(final DOMMountPoint mountPoint) {
+ return mountPoint.getService(DOMSchemaService.class)
+ .flatMap(svc -> Optional.ofNullable(svc.getGlobalContext()))
+ .orElse(null);
+ }
+
private static final class PatchStatusContextHelper {
PatchStatusContext status;