Reduce the use of AttrBuilders
[netconf.git] / restconf / restconf-nb-bierman02 / src / main / java / org / opendaylight / netconf / sal / restconf / impl / BrokerFacade.java
index 85263d056b86feb3418e3626dde47dbf0bb832ff..689f201536a58f26c93898ca8044bf3373e9f2a7 100644 (file)
@@ -7,40 +7,40 @@
  */
 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.MoreExecutors;
+import java.io.Closeable;
 import java.util.ArrayList;
 import java.util.Collection;
 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.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.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.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.netconf.sal.streams.listeners.ListenerAdapter;
 import org.opendaylight.netconf.sal.streams.listeners.NotificationListenerAdapter;
 import org.opendaylight.restconf.common.context.InstanceIdentifierContext;
@@ -53,9 +53,9 @@ import org.opendaylight.restconf.common.patch.PatchEditOperation;
 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;
@@ -73,8 +73,8 @@ import org.opendaylight.yangtools.yang.data.api.schema.OrderedMapNode;
 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;
@@ -87,33 +87,31 @@ import org.opendaylight.yangtools.yang.model.api.SchemaPath;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-public class BrokerFacade {
+@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 final DOMDataBroker domDataBroker;
+    private final DOMNotificationService domNotification;
+    private final ControllerContext controllerContext;
 
-    private BrokerFacade() {}
-
-    public void setRpcService(final DOMRpcService router) {
-        this.rpcService = router;
-    }
-
-    public void setDomNotificationService(final DOMNotificationService domNotification) {
-        this.domNotification = domNotification;
+    private BrokerFacade(final DOMRpcService rpcService, final DOMDataBroker domDataBroker,
+            final 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);
     }
 
-    public static BrokerFacade getInstance() {
-        return BrokerFacade.INSTANCE;
+    public static BrokerFacade newInstance(final DOMRpcService rpcService, final DOMDataBroker domDataBroker,
+            final DOMNotificationService domNotification, final ControllerContext controllerContext) {
+        return new BrokerFacade(rpcService, domDataBroker, domNotification, controllerContext);
     }
 
-    private void checkPreconditions() {
-        if (this.domDataBroker == null) {
-            throw new RestconfDocumentedException(Status.SERVICE_UNAVAILABLE);
-        }
+    @Override
+    public void close() {
     }
 
     /**
@@ -137,8 +135,7 @@ public class BrokerFacade {
      * @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);
         }
     }
@@ -172,13 +169,11 @@ public class BrokerFacade {
             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);
     }
 
     /**
@@ -189,9 +184,7 @@ public class BrokerFacade {
      * @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);
         }
     }
@@ -208,13 +201,11 @@ public class BrokerFacade {
     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);
     }
 
     /**
@@ -243,12 +234,10 @@ public class BrokerFacade {
         Preconditions.checkNotNull(path);
         Preconditions.checkNotNull(payload);
 
-        checkPreconditions();
-
-        final DOMDataReadWriteTransaction newReadWriteTransaction = this.domDataBroker.newReadWriteTransaction();
+        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);
         return new PutResult(status, future);
     }
@@ -282,18 +271,16 @@ public class BrokerFacade {
 
         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(
+            final FluentFuture<? extends CommitInfo> future = putDataViaTransaction(
                     newReadWriteTransaction, CONFIGURATION, path, payload, mountPoint.getSchemaContext(), insert,
                     point);
             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);
+        throw dataBrokerUnavailable(path);
     }
 
     public PatchStatusContext patchConfigurationDataWithinTransaction(final PatchContext patchContext)
@@ -302,7 +289,7 @@ public class BrokerFacade {
 
         // get new transaction and schema context on server or on mounted device
         final SchemaContext schemaContext;
-        final DOMDataReadWriteTransaction patchTransaction;
+        final DOMDataTreeReadWriteTransaction patchTransaction;
         if (mountPoint == null) {
             schemaContext = patchContext.getInstanceIdentifierContext().getSchemaContext();
             patchTransaction = this.domDataBroker.newReadWriteTransaction();
@@ -374,23 +361,6 @@ public class BrokerFacade {
                     }
                     break;
                 case DELETE:
-                    if (withoutError) {
-                        try {
-                            deleteDataWithinTransaction(patchTransaction, CONFIGURATION, patchEntity
-                                    .getTargetNode());
-                            editCollection.add(new PatchStatusEntity(patchEntity.getEditId(), true, null));
-                        } catch (final RestconfDocumentedException e) {
-                            LOG.error("Error call http Patch operation {} on target {}",
-                                    operation,
-                                    patchEntity.getTargetNode().toString());
-
-                            editErrors = new ArrayList<>();
-                            editErrors.addAll(e.getErrors());
-                            editCollection.add(new PatchStatusEntity(patchEntity.getEditId(), false, editErrors));
-                            withoutError = false;
-                        }
-                    }
-                    break;
                 case REMOVE:
                     if (withoutError) {
                         try {
@@ -443,12 +413,12 @@ public class BrokerFacade {
 
         // 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();
@@ -463,22 +433,21 @@ public class BrokerFacade {
                         new RestconfError(ErrorType.APPLICATION, ErrorTag.OPERATION_FAILED, throwable.getMessage()))));
                 waiter.countDown();
             }
-        });
+        }, MoreExecutors.directExecutor());
 
         waiter.await();
         return status.getStatus();
     }
 
     // POST configuration
-    public CheckedFuture<Void, TransactionCommitFailedException> commitConfigurationDataPost(
+    public FluentFuture<? extends CommitInfo> 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 CheckedFuture<Void, TransactionCommitFailedException> commitConfigurationDataPost(
+    public FluentFuture<? extends CommitInfo> commitConfigurationDataPost(
             final DOMMountPoint mountPoint, final YangInstanceIdentifier path, final NormalizedNode<?, ?> payload,
             final String insert, final String point) {
         final Optional<DOMDataBroker> domDataBrokerService = mountPoint.getService(DOMDataBroker.class);
@@ -486,33 +455,25 @@ public class BrokerFacade {
             return postDataViaTransaction(domDataBrokerService.get().newReadWriteTransaction(), CONFIGURATION, path,
                     payload, mountPoint.getSchemaContext(), insert, point);
         }
-        final String errMsg = "DOM data broker service isn't available for mount point " + path;
-        LOG.warn(errMsg);
-        throw new RestconfDocumentedException(errMsg);
+        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 FluentFuture<DOMRpcResult> invokeRpc(final SchemaPath type, final NormalizedNode<?, ?> input) {
         if (this.rpcService == null) {
             throw new RestconfDocumentedException(Status.SERVICE_UNAVAILABLE);
         }
@@ -522,15 +483,13 @@ public class BrokerFacade {
 
     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);
@@ -541,31 +500,26 @@ public class BrokerFacade {
         listener.setRegistration(registration);
     }
 
-    private NormalizedNode<?, ?> readDataViaTransaction(final DOMDataReadTransaction transaction,
+    private NormalizedNode<?, ?> readDataViaTransaction(final DOMDataTreeReadTransaction transaction,
             final LogicalDatastoreType datastore, final YangInstanceIdentifier path) {
         return readDataViaTransaction(transaction, datastore, path, null);
     }
 
-    private NormalizedNode<?, ?> readDataViaTransaction(final DOMDataReadTransaction transaction,
+    private NormalizedNode<?, ?> readDataViaTransaction(final DOMDataTreeReadTransaction 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);
-                }
-            }
-            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));
         }
     }
 
@@ -583,17 +537,17 @@ public class BrokerFacade {
                 throw new RestconfDocumentedException("Bad value used with with-defaults parameter : " + withDefa);
         }
 
-        final SchemaContext ctx = ControllerContext.getInstance().getGlobalSchema();
+        final SchemaContext ctx = controllerContext.getGlobalSchema();
         final DataSchemaContextTree baseSchemaCtxTree = DataSchemaContextTree.from(ctx);
         final DataSchemaNode baseSchemaNode = baseSchemaCtxTree.getChild(path).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());
@@ -601,14 +555,14 @@ public class BrokerFacade {
     }
 
     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();
             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());
@@ -619,22 +573,22 @@ public class BrokerFacade {
                         ((ListSchemaNode) childSchema).getKeyDefinition());
                 builder.withChild(childBuilder.build());
             } else if (child instanceof LeafNode) {
-                final String defaultVal = ((LeafSchemaNode) childSchema).getDefault();
-                final String nodeVal = ((LeafNode<String>) child).getValue();
-                final NormalizedNodeAttrBuilder<NodeIdentifier, Object, LeafNode<Object>> leafBuilder =
+                final Object defaultVal = ((LeafSchemaNode) childSchema).getType().getDefaultValue().orElse(null);
+                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());
                         }
                     }
@@ -649,21 +603,21 @@ public class BrokerFacade {
         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 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();
             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());
@@ -674,18 +628,18 @@ public class BrokerFacade {
                         ((ListSchemaNode) childSchema).getKeyDefinition());
                 builder.withChild(childBuilder.build());
             } else if (child instanceof LeafNode) {
-                final String defaultVal = ((LeafSchemaNode) childSchema).getDefault();
-                final String nodeVal = ((LeafNode<String>) child).getValue();
-                final NormalizedNodeAttrBuilder<NodeIdentifier, Object, LeafNode<Object>> leafBuilder =
+                final Object defaultVal = ((LeafSchemaNode) childSchema).getType().getDefaultValue().orElse(null);
+                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());
                     }
                 }
@@ -696,26 +650,26 @@ public class BrokerFacade {
     /**
      * POST data and submit transaction {@link DOMDataReadWriteTransaction}.
      */
-    private CheckedFuture<Void, TransactionCommitFailedException> postDataViaTransaction(
-            final DOMDataReadWriteTransaction rwTransaction, final LogicalDatastoreType datastore,
+    private FluentFuture<? extends CommitInfo> postDataViaTransaction(
+            final DOMDataTreeReadWriteTransaction rwTransaction, final LogicalDatastoreType datastore,
             final YangInstanceIdentifier path, final NormalizedNode<?, ?> payload, final SchemaContext 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 DOMDataTreeReadWriteTransaction rwTransaction, final LogicalDatastoreType datastore,
             final YangInstanceIdentifier path, final NormalizedNode<?, ?> payload, final SchemaContext 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) {
         if (insert == null) {
@@ -805,13 +759,12 @@ public class BrokerFacade {
         }
     }
 
-    private static 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) {
         rwTransaction.delete(datastore, path.getParent().getParent());
-        final InstanceIdentifierContext<?> instanceIdentifier =
-                ControllerContext.getInstance().toInstanceIdentifier(point);
+        final InstanceIdentifierContext<?> instanceIdentifier = controllerContext.toInstanceIdentifier(point);
         int lastItemPosition = 0;
         for (final LeafSetEntryNode<?> nodeChild : readLeafList.getValue()) {
             if (nodeChild.getIdentifier().equals(instanceIdentifier.getInstanceIdentifier().getLastPathArgument())) {
@@ -838,13 +791,12 @@ public class BrokerFacade {
         }
     }
 
-    private static 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) {
         rwTransaction.delete(datastore, path.getParent().getParent());
-        final InstanceIdentifierContext<?> instanceIdentifier =
-                ControllerContext.getInstance().toInstanceIdentifier(point);
+        final InstanceIdentifierContext<?> instanceIdentifier = controllerContext.toInstanceIdentifier(point);
         int lastItemPosition = 0;
         for (final MapEntryNode mapEntryNode : readList.getValue()) {
             if (mapEntryNode.getIdentifier()
@@ -893,7 +845,7 @@ public class BrokerFacade {
         throw new RestconfDocumentedException("Insert parameter can be used only with list or leaf-list");
     }
 
-    private static void makeNormalPost(final DOMDataReadWriteTransaction rwTransaction,
+    private static void makeNormalPost(final DOMDataTreeReadWriteTransaction rwTransaction,
             final LogicalDatastoreType datastore, final YangInstanceIdentifier path, final NormalizedNode<?, ?> payload,
             final SchemaContext schemaContext) {
         final Collection<? extends NormalizedNode<?, ?>> children;
@@ -948,7 +900,7 @@ public class BrokerFacade {
         }
     }
 
-    private static void simplePostPut(final DOMDataReadWriteTransaction rwTransaction,
+    private static void simplePostPut(final DOMDataTreeReadWriteTransaction rwTransaction,
             final LogicalDatastoreType datastore, final YangInstanceIdentifier path, final NormalizedNode<?, ?> payload,
             final SchemaContext schemaContext) {
         checkItemDoesNotExists(rwTransaction, datastore, path);
@@ -956,14 +908,17 @@ public class BrokerFacade {
         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));
         }
     }
 
@@ -973,11 +928,10 @@ public class BrokerFacade {
      * @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);
@@ -990,11 +944,10 @@ public class BrokerFacade {
      * @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);
@@ -1009,27 +962,27 @@ public class BrokerFacade {
      * @param insert
      *            insert
      */
-    private CheckedFuture<Void, TransactionCommitFailedException> putDataViaTransaction(
-            final DOMDataReadWriteTransaction readWriteTransaction, final LogicalDatastoreType datastore,
+    private FluentFuture<? extends CommitInfo> putDataViaTransaction(
+            final DOMDataTreeReadWriteTransaction readWriteTransaction, final LogicalDatastoreType datastore,
             final YangInstanceIdentifier path, final NormalizedNode<?, ?> payload, final SchemaContext 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 DOMDataTreeReadWriteTransaction writeTransaction, final LogicalDatastoreType datastore,
             final YangInstanceIdentifier path, final NormalizedNode<?, ?> payload, final SchemaContext 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,
+    private void putData(final DOMDataTreeReadWriteTransaction rwTransaction, final LogicalDatastoreType datastore,
             final YangInstanceIdentifier path, final NormalizedNode<?, ?> payload, final SchemaContext schemaContext,
             final String insert, final String point) {
         if (insert == null) {
@@ -1116,13 +1069,12 @@ public class BrokerFacade {
         }
     }
 
-    private static 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) {
         tx.delete(datastore, path.getParent());
-        final InstanceIdentifierContext<?> instanceIdentifier =
-                ControllerContext.getInstance().toInstanceIdentifier(point);
+        final InstanceIdentifierContext<?> instanceIdentifier = controllerContext.toInstanceIdentifier(point);
         int index1 = 0;
         for (final LeafSetEntryNode<?> nodeChild : readLeafList.getValue()) {
             if (nodeChild.getIdentifier().equals(instanceIdentifier.getInstanceIdentifier().getLastPathArgument())) {
@@ -1147,12 +1099,11 @@ public class BrokerFacade {
         }
     }
 
-    private static 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());
-        final InstanceIdentifierContext<?> instanceIdentifier =
-                ControllerContext.getInstance().toInstanceIdentifier(point);
+        final InstanceIdentifierContext<?> instanceIdentifier = controllerContext.toInstanceIdentifier(point);
         int index1 = 0;
         for (final MapEntryNode mapEntryNode : readList.getValue()) {
             if (mapEntryNode.getIdentifier().equals(instanceIdentifier.getInstanceIdentifier().getLastPathArgument())) {
@@ -1177,7 +1128,7 @@ public class BrokerFacade {
         }
     }
 
-    private static void makePut(final DOMDataWriteTransaction tx, final LogicalDatastoreType datastore,
+    private static 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);
@@ -1193,27 +1144,28 @@ public class BrokerFacade {
     }
 
     private static void simplePut(final LogicalDatastoreType datastore, final YangInstanceIdentifier path,
-            final DOMDataWriteTransaction tx, final SchemaContext schemaContext, final NormalizedNode<?, ?> payload) {
+            final DOMDataTreeWriteTransaction tx, final SchemaContext schemaContext,
+            final NormalizedNode<?, ?> payload) {
         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);
@@ -1224,13 +1176,7 @@ public class BrokerFacade {
         tx.merge(datastore, path, payload);
     }
 
-    public void setDomDataBroker(final DOMDataBroker domDataBroker) {
-        this.domDataBroker = domDataBroker;
-    }
-
     public void registerToListenNotification(final NotificationListenerAdapter listener) {
-        checkPreconditions();
-
         if (listener.isListening()) {
             return;
         }
@@ -1243,7 +1189,7 @@ public class BrokerFacade {
     }
 
     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;
@@ -1272,6 +1218,11 @@ public class BrokerFacade {
         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 final class PatchStatusContextHelper {
         PatchStatusContext status;