diff options
Diffstat (limited to 'v3po/impl/src/main/java/io/fd/honeycomb/v3po/impl/data/VppConfigDataTree.java')
-rw-r--r-- | v3po/impl/src/main/java/io/fd/honeycomb/v3po/impl/data/VppConfigDataTree.java | 102 |
1 files changed, 72 insertions, 30 deletions
diff --git a/v3po/impl/src/main/java/io/fd/honeycomb/v3po/impl/data/VppConfigDataTree.java b/v3po/impl/src/main/java/io/fd/honeycomb/v3po/impl/data/VppConfigDataTree.java index 41a68e7bb..6fdeea348 100644 --- a/v3po/impl/src/main/java/io/fd/honeycomb/v3po/impl/data/VppConfigDataTree.java +++ b/v3po/impl/src/main/java/io/fd/honeycomb/v3po/impl/data/VppConfigDataTree.java @@ -16,12 +16,15 @@ package io.fd.honeycomb.v3po.impl.data; +import static com.google.common.base.Preconditions.checkNotNull; +import static java.util.Collections.singletonList; + import com.google.common.base.Optional; -import com.google.common.base.Preconditions; import com.google.common.util.concurrent.CheckedFuture; import com.google.common.util.concurrent.Futures; -import io.fd.honeycomb.v3po.impl.trans0.VppApiInvocationException; -import io.fd.honeycomb.v3po.impl.trans0.VppWriter; +import io.fd.honeycomb.v3po.impl.trans.w.WriteContext; +import io.fd.honeycomb.v3po.impl.trans.w.util.TransactionWriteContext; +import io.fd.honeycomb.v3po.impl.trans.VppApiInvocationException; import java.util.ArrayList; import java.util.Collections; import java.util.HashSet; @@ -31,6 +34,7 @@ import java.util.Map; import java.util.Set; import javax.annotation.Nonnull; import org.opendaylight.controller.md.sal.common.api.data.ReadFailedException; +import org.opendaylight.controller.md.sal.dom.api.DOMDataReadOnlyTransaction; import org.opendaylight.mdsal.binding.dom.codec.api.BindingNormalizedNodeSerializer; import org.opendaylight.yangtools.yang.binding.DataObject; import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; @@ -55,7 +59,14 @@ public final class VppConfigDataTree implements VppDataTree { private final BindingNormalizedNodeSerializer serializer; private final DataTree dataTree; - private final VppWriter writer; + private final VppWriterRegistry writer; + public static final ReadableVppDataTree EMPTY_OPERATIONAL = new ReadableVppDataTree() { + @Override + public CheckedFuture<Optional<NormalizedNode<?, ?>>, ReadFailedException> read( + @Nonnull final YangInstanceIdentifier path) { + return Futures.immediateCheckedFuture(Optional.<NormalizedNode<?, ?>>absent()); + } + }; /** * Creates configuration data tree instance. @@ -66,10 +77,10 @@ public final class VppConfigDataTree implements VppDataTree { * @param vppWriter service for translation between Java Binding Data and Vpp. */ public VppConfigDataTree(@Nonnull final BindingNormalizedNodeSerializer serializer, - @Nonnull final DataTree dataTree, @Nonnull final VppWriter vppWriter) { - this.serializer = Preconditions.checkNotNull(serializer, "serializer should not be null"); - this.dataTree = Preconditions.checkNotNull(dataTree, "dataTree should not be null"); - this.writer = Preconditions.checkNotNull(vppWriter, "vppWriter should not be null"); + @Nonnull final DataTree dataTree, @Nonnull final VppWriterRegistry vppWriter) { + this.serializer = checkNotNull(serializer, "serializer should not be null"); + this.dataTree = checkNotNull(dataTree, "dataTree should not be null"); + this.writer = checkNotNull(vppWriter, "vppWriter should not be null"); } @Override @@ -78,7 +89,8 @@ public final class VppConfigDataTree implements VppDataTree { } @Override - public void commit(final DataTreeModification modification) throws DataValidationFailedException, VppApiInvocationException { + public void commit(final DataTreeModification modification) + throws DataValidationFailedException, VppApiInvocationException { dataTree.validate(modification); final DataTreeCandidate candidate = dataTree.prepare(modification); @@ -87,16 +99,22 @@ public final class VppConfigDataTree implements VppDataTree { final YangInstanceIdentifier rootPath = candidate.getRootPath(); final Optional<NormalizedNode<?, ?>> normalizedDataBefore = rootNode.getDataBefore(); final Optional<NormalizedNode<?, ?>> normalizedDataAfter = rootNode.getDataAfter(); - LOG.debug("VppConfigDataProxy.commit() rootPath={}, rootNode={}, dataBefore={}, dataAfter={}", + LOG.debug("VppConfigDataTree.commit() rootPath={}, rootNode={}, dataBefore={}, dataAfter={}", rootPath, rootNode, normalizedDataBefore, normalizedDataAfter); final Map<InstanceIdentifier<?>, DataObject> nodesBefore = extractNetconfData(normalizedDataBefore); - LOG.debug("VppConfigDataProxy.commit() extracted nodesBefore={}", nodesBefore.keySet()); + LOG.debug("VppConfigDataTree.commit() extracted nodesBefore={}", nodesBefore.keySet()); final Map<InstanceIdentifier<?>, DataObject> nodesAfter = extractNetconfData(normalizedDataAfter); - LOG.debug("VppConfigDataProxy.commit() extracted nodesAfter={}", nodesAfter.keySet()); + LOG.debug("VppConfigDataTree.commit() extracted nodesAfter={}", nodesAfter.keySet()); - final ChangesProcessor processor = new ChangesProcessor(writer, nodesBefore, nodesAfter); + + final DOMDataReadOnlyTransaction beforeTx = new VppReadOnlyTransaction(EMPTY_OPERATIONAL, takeSnapshot()); + final ConfigSnapshot modificationSnapshot = new ConfigSnapshot(modification); + final DOMDataReadOnlyTransaction afterTx = new VppReadOnlyTransaction(EMPTY_OPERATIONAL, modificationSnapshot); + final WriteContext ctx = new TransactionWriteContext(serializer, beforeTx, afterTx); + + final ChangesProcessor processor = new ChangesProcessor(writer, nodesBefore, nodesAfter, ctx); try { processor.applyChanges(); } catch (VppApiInvocationException e) { @@ -118,9 +136,10 @@ public final class VppConfigDataTree implements VppDataTree { dataTree.commit(candidate); } - private Map<InstanceIdentifier<?>, DataObject> extractNetconfData(final Optional<NormalizedNode<?, ?>> parentOptional) { + private Map<InstanceIdentifier<?>, DataObject> extractNetconfData( + final Optional<NormalizedNode<?, ?>> parentOptional) { if (parentOptional.isPresent()) { - final DataContainerNode parent = (DataContainerNode)parentOptional.get(); + final DataContainerNode parent = (DataContainerNode) parentOptional.get(); return DataTreeUtils.childrenFromNormalized(parent, serializer); } return Collections.emptyMap(); @@ -135,7 +154,7 @@ public final class VppConfigDataTree implements VppDataTree { @Override public CheckedFuture<Optional<NormalizedNode<?, ?>>, ReadFailedException> read( - final YangInstanceIdentifier path) { + @Nonnull final YangInstanceIdentifier path) { final Optional<NormalizedNode<?, ?>> node = snapshot.readNode(path); if (LOG.isTraceEnabled() && node.isPresent()) { LOG.trace("ConfigSnapshot.read: {}", node.get()); @@ -150,57 +169,80 @@ public final class VppConfigDataTree implements VppDataTree { } private static final class ChangesProcessor { - private final VppWriter writer; + private final VppWriterRegistry writer; private final List<InstanceIdentifier<?>> processedNodes; private final Map<InstanceIdentifier<?>, DataObject> nodesBefore; private final Map<InstanceIdentifier<?>, DataObject> nodesAfter; + private final WriteContext ctx; - ChangesProcessor(@Nonnull final VppWriter writer, + ChangesProcessor(@Nonnull final VppWriterRegistry writer, final Map<InstanceIdentifier<?>, DataObject> nodesBefore, - final Map<InstanceIdentifier<?>, DataObject> nodesAfter) { - this.writer = Preconditions.checkNotNull(writer, "VppWriter is null!"); - this.nodesBefore = Preconditions.checkNotNull(nodesBefore, "nodesBefore is null!"); - this.nodesAfter = Preconditions.checkNotNull(nodesAfter, "nodesAfter is null!"); + final Map<InstanceIdentifier<?>, DataObject> nodesAfter, + @Nonnull final WriteContext writeContext) { + this.ctx = checkNotNull(writeContext, "writeContext is null!"); + this.writer = checkNotNull(writer, "VppWriter is null!"); + this.nodesBefore = checkNotNull(nodesBefore, "nodesBefore is null!"); + this.nodesAfter = checkNotNull(nodesAfter, "nodesAfter is null!"); processedNodes = new ArrayList<>(); } void applyChanges() throws VppApiInvocationException { // TODO we should care about the order of modified subtrees + // TODO maybe WriterRegistry could provide writeAll method and it will process the updates + // in order in which it child writers are registered final Set<InstanceIdentifier<?>> allNodes = new HashSet<>(); allNodes.addAll(nodesBefore.keySet()); allNodes.addAll(nodesAfter.keySet()); - LOG.debug("VppConfigDataProxy.applyChanges() all extracted nodes: {}", allNodes); + LOG.debug("ChangesProcessor.applyChanges() all extracted nodes: {}", allNodes); for (InstanceIdentifier<?> node : allNodes) { - LOG.debug("VppConfigDataProxy.applyChanges() processing node={}", node); + LOG.debug("ChangesProcessor.applyChanges() processing node={}", node); final DataObject dataBefore = nodesBefore.get(node); final DataObject dataAfter = nodesAfter.get(node); + LOG.debug("ChangesProcessor.applyChanges() processing dataBefore={}, dataAfter={}", dataBefore, + dataAfter); try { - writer.process(dataBefore, dataAfter); + // TODO is List as input argument really necessary for writer ? + final List<DataObject> dataObjectsBefore = dataBefore == null + ? Collections.<DataObject>emptyList() + : singletonList(dataBefore); + final List<DataObject> dataObjectsAfter = dataAfter == null + ? Collections.<DataObject>emptyList() + : singletonList(dataAfter); + LOG.debug("ChangesProcessor.applyChanges() processing dataObjectsBefore={}, dataObjectsAfter={}", + dataObjectsBefore, dataObjectsAfter); + writer.update(node, dataObjectsBefore, dataObjectsAfter, ctx); processedNodes.add(node); - } catch (VppApiInvocationException e) { + } catch (RuntimeException e) { LOG.error("Error while processing data change (before={}, after={})", dataBefore, dataAfter, e); - throw e; + // FIXME ex handling + throw new VppApiInvocationException("", 1, -1); } } } void revertChanges() throws VppApiInvocationException { - Preconditions.checkNotNull(writer, "VppWriter is null!"); + checkNotNull(writer, "VppWriter is null!"); // revert changes in reverse order they were applied final ListIterator<InstanceIdentifier<?>> iterator = processedNodes.listIterator(processedNodes.size()); while (iterator.hasPrevious()) { final InstanceIdentifier<?> node = iterator.previous(); - LOG.debug("VppConfigDataProxy.revertChanges() processing node={}", node); + LOG.debug("ChangesProcessor.revertChanges() processing node={}", node); final DataObject dataBefore = nodesBefore.get(node); final DataObject dataAfter = nodesAfter.get(node); // revert a change by invoking writer with reordered arguments - writer.process(dataAfter, dataBefore); + try { + // TODO is List as input argument really necessary for writer ? + writer.update(node, singletonList(dataAfter), singletonList(dataBefore), ctx); + } catch (RuntimeException e) { + // FIXME ex handling + throw new VppApiInvocationException("", 1, -1); + } } } } |