summaryrefslogtreecommitdiffstats
path: root/v3po/data-impl/src/main/java/io
diff options
context:
space:
mode:
authorMaros Marsalek <mmarsale@cisco.com>2016-07-27 11:05:51 +0200
committerMaros Marsalek <mmarsale@cisco.com>2016-07-29 16:32:07 +0200
commit0578156b721fa01c8c645b8f9625ecebdb6449e4 (patch)
tree49d36f24e5d984a8c9f151b1440de88619f8b7de /v3po/data-impl/src/main/java/io
parent007d4542388ca89be409ce1a4a4c7a36ddcb538f (diff)
HONEYCOMB-130: Separate v3po plugin from HC infra
Creating folders: - common/ - infra/ - v3po/ - vpp-common/ Change-Id: I2c39e1b17e39e7c0f0628f44aa5fe08563fa06e4 Signed-off-by: Maros Marsalek <mmarsale@cisco.com>
Diffstat (limited to 'v3po/data-impl/src/main/java/io')
-rw-r--r--v3po/data-impl/src/main/java/io/fd/honeycomb/v3po/data/impl/DataBroker.java198
-rw-r--r--v3po/data-impl/src/main/java/io/fd/honeycomb/v3po/data/impl/ModifiableDataTreeDelegator.java236
-rw-r--r--v3po/data-impl/src/main/java/io/fd/honeycomb/v3po/data/impl/ModifiableDataTreeManager.java122
-rw-r--r--v3po/data-impl/src/main/java/io/fd/honeycomb/v3po/data/impl/ModificationDiff.java278
-rw-r--r--v3po/data-impl/src/main/java/io/fd/honeycomb/v3po/data/impl/PersistingDataTreeAdapter.java151
-rw-r--r--v3po/data-impl/src/main/java/io/fd/honeycomb/v3po/data/impl/ReadOnlyTransaction.java119
-rw-r--r--v3po/data-impl/src/main/java/io/fd/honeycomb/v3po/data/impl/ReadWriteTransaction.java101
-rw-r--r--v3po/data-impl/src/main/java/io/fd/honeycomb/v3po/data/impl/ReadableDataTreeDelegator.java242
-rw-r--r--v3po/data-impl/src/main/java/io/fd/honeycomb/v3po/data/impl/WriteTransaction.java177
9 files changed, 0 insertions, 1624 deletions
diff --git a/v3po/data-impl/src/main/java/io/fd/honeycomb/v3po/data/impl/DataBroker.java b/v3po/data-impl/src/main/java/io/fd/honeycomb/v3po/data/impl/DataBroker.java
deleted file mode 100644
index c418ed332..000000000
--- a/v3po/data-impl/src/main/java/io/fd/honeycomb/v3po/data/impl/DataBroker.java
+++ /dev/null
@@ -1,198 +0,0 @@
-/*
- * Copyright (c) 2016 Cisco and/or its affiliates.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at:
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package io.fd.honeycomb.v3po.data.impl;
-
-import static com.google.common.base.Preconditions.checkNotNull;
-
-import io.fd.honeycomb.v3po.data.DataModification;
-import io.fd.honeycomb.v3po.data.ModifiableDataManager;
-import io.fd.honeycomb.v3po.data.ReadableDataManager;
-import java.io.Closeable;
-import java.io.IOException;
-import java.util.Collections;
-import java.util.Map;
-import javax.annotation.Nonnull;
-import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
-import org.opendaylight.controller.md.sal.common.api.data.TransactionChainListener;
-import org.opendaylight.controller.md.sal.dom.api.DOMDataBroker;
-import org.opendaylight.controller.md.sal.dom.api.DOMDataBrokerExtension;
-import org.opendaylight.controller.md.sal.dom.api.DOMDataChangeListener;
-import org.opendaylight.controller.md.sal.dom.api.DOMDataReadOnlyTransaction;
-import org.opendaylight.controller.md.sal.dom.api.DOMDataReadWriteTransaction;
-import org.opendaylight.controller.md.sal.dom.api.DOMDataWriteTransaction;
-import org.opendaylight.controller.md.sal.dom.api.DOMTransactionChain;
-import org.opendaylight.yangtools.concepts.ListenerRegistration;
-import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
-import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/**
- * Data Broker which provides data transaction functionality for YANG capable data provider using {@link NormalizedNode}
- * data format.
- */
-public class DataBroker implements DOMDataBroker, Closeable {
-
- private static final Logger LOG = LoggerFactory.getLogger(DataBroker.class);
- private final TransactionFactory transactionFactory;
-
- /**
- * Creates DataBroker instance.
- *
- * @param transactionFactory transaction producing factory
- */
- public DataBroker(final TransactionFactory transactionFactory) {
- this.transactionFactory = transactionFactory;
- }
-
- @Override
- public DOMDataReadOnlyTransaction newReadOnlyTransaction() {
- LOG.trace("DataBroker({}).newReadOnlyTransaction()", this);
- return transactionFactory.newReadOnlyTransaction();
- }
-
- @Override
- public DOMDataReadWriteTransaction newReadWriteTransaction() {
- LOG.trace("DataBroker({}).newReadWriteTransaction()", this);
- return transactionFactory.newReadWriteTransaction();
- }
-
- @Override
- public DOMDataWriteTransaction newWriteOnlyTransaction() {
- LOG.trace("DataBroker({}).newWriteOnlyTransaction()", this);
- return transactionFactory.newWriteOnlyTransaction();
- }
-
- @Override
- public ListenerRegistration<DOMDataChangeListener> registerDataChangeListener(final LogicalDatastoreType store,
- final YangInstanceIdentifier path,
- final DOMDataChangeListener listener,
- final DataChangeScope triggeringScope) {
- throw new UnsupportedOperationException("Not supported");
- }
-
- @Override
- public DOMTransactionChain createTransactionChain(final TransactionChainListener listener) {
- throw new UnsupportedOperationException("Not supported");
- }
-
- @Nonnull
- @Override
- public Map<Class<? extends DOMDataBrokerExtension>, DOMDataBrokerExtension> getSupportedExtensions() {
- return Collections.emptyMap();
- }
-
- /**
- * Create DataBroker for a modifiable config DT, but only readable Operational
- */
- @Nonnull
- public static DataBroker create(@Nonnull final ModifiableDataManager configDataTree,
- @Nonnull final ReadableDataManager operationalDataTree) {
- checkNotNull(operationalDataTree, "operationalDataTree should not be null");
- checkNotNull(configDataTree, "configDataTree should not be null");
- return new DataBroker(new MainPipelineTxFactory(configDataTree, operationalDataTree));
- }
-
- /**
- * Create DataBroker for modifiable operational DT, but no support for config
- */
- @Nonnull
- public static DataBroker create(@Nonnull final ModifiableDataManager operationalDataTree) {
- checkNotNull(operationalDataTree, "operationalDataTree should not be null");
- return new DataBroker(new ContextPipelineTxFactory(operationalDataTree));
- }
-
- @Override
- public void close() throws IOException {
- // NOOP
- }
-
- /**
- * Transaction provider factory to be used by {@link DataBroker}
- */
- public interface TransactionFactory {
-
- DOMDataReadOnlyTransaction newReadOnlyTransaction();
-
- DOMDataReadWriteTransaction newReadWriteTransaction();
-
- DOMDataWriteTransaction newWriteOnlyTransaction();
- }
-
- /**
- * Transaction factory specific for Honeycomb's main pipeline (config: read+write, operational: read-only)
- */
- private static class MainPipelineTxFactory implements TransactionFactory {
- private final ReadableDataManager operationalDataTree;
- private final ModifiableDataManager configDataTree;
-
- MainPipelineTxFactory(@Nonnull final ModifiableDataManager configDataTree,
- @Nonnull final ReadableDataManager operationalDataTree) {
- this.operationalDataTree = operationalDataTree;
- this.configDataTree = configDataTree;
- }
-
- @Override
- public DOMDataReadOnlyTransaction newReadOnlyTransaction() {
- return ReadOnlyTransaction.create(configDataTree.newModification(), operationalDataTree);
- }
-
- @Override
- public DOMDataReadWriteTransaction newReadWriteTransaction() {
- final DataModification configModification = configDataTree.newModification();
- return new ReadWriteTransaction(
- ReadOnlyTransaction.create(configModification, operationalDataTree),
- WriteTransaction.createConfigOnly(configModification));
- }
-
- @Override
- public DOMDataWriteTransaction newWriteOnlyTransaction() {
- return WriteTransaction.createConfigOnly(configDataTree.newModification());
- }
- }
-
- /**
- * Transaction factory specific for Honeycomb's context pipeline (config: none, operational: read+write)
- */
- private static class ContextPipelineTxFactory implements TransactionFactory {
- private final ModifiableDataManager operationalDataTree;
-
- ContextPipelineTxFactory(@Nonnull final ModifiableDataManager operationalDataTree) {
- this.operationalDataTree = operationalDataTree;
- }
-
- @Override
- public DOMDataReadOnlyTransaction newReadOnlyTransaction() {
- return ReadOnlyTransaction.createOperationalOnly(operationalDataTree);
- }
-
- @Override
- public DOMDataReadWriteTransaction newReadWriteTransaction() {
- final DataModification dataModification = operationalDataTree.newModification();
- return new ReadWriteTransaction(
- ReadOnlyTransaction.createOperationalOnly(dataModification),
- WriteTransaction.createOperationalOnly(dataModification));
- }
-
- @Override
- public DOMDataWriteTransaction newWriteOnlyTransaction() {
- return WriteTransaction.createOperationalOnly(operationalDataTree.newModification());
- }
- }
-}
-
-
diff --git a/v3po/data-impl/src/main/java/io/fd/honeycomb/v3po/data/impl/ModifiableDataTreeDelegator.java b/v3po/data-impl/src/main/java/io/fd/honeycomb/v3po/data/impl/ModifiableDataTreeDelegator.java
deleted file mode 100644
index 2c2581ec0..000000000
--- a/v3po/data-impl/src/main/java/io/fd/honeycomb/v3po/data/impl/ModifiableDataTreeDelegator.java
+++ /dev/null
@@ -1,236 +0,0 @@
-/*
- * Copyright (c) 2016 Cisco and/or its affiliates.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at:
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package io.fd.honeycomb.v3po.data.impl;
-
-import static com.google.common.base.Preconditions.checkNotNull;
-import static com.google.common.util.concurrent.Futures.immediateCheckedFuture;
-
-import com.google.common.annotations.VisibleForTesting;
-import com.google.common.base.Optional;
-import com.google.common.collect.HashMultimap;
-import com.google.common.collect.Multimap;
-import com.google.common.util.concurrent.CheckedFuture;
-import io.fd.honeycomb.v3po.data.DataModification;
-import io.fd.honeycomb.v3po.data.ReadableDataManager;
-import io.fd.honeycomb.v3po.translate.TranslationException;
-import io.fd.honeycomb.v3po.translate.util.RWUtils;
-import io.fd.honeycomb.v3po.translate.util.TransactionMappingContext;
-import io.fd.honeycomb.v3po.translate.util.write.TransactionWriteContext;
-import io.fd.honeycomb.v3po.translate.write.DataObjectUpdate;
-import io.fd.honeycomb.v3po.translate.write.WriteContext;
-import io.fd.honeycomb.v3po.translate.write.registry.WriterRegistry;
-import java.util.Map;
-import javax.annotation.Nonnull;
-import javax.annotation.Nullable;
-import org.opendaylight.controller.md.sal.common.api.data.TransactionCommitFailedException;
-import org.opendaylight.controller.md.sal.dom.api.DOMDataReadOnlyTransaction;
-import org.opendaylight.yangtools.binding.data.codec.api.BindingNormalizedNodeSerializer;
-import org.opendaylight.yangtools.yang.binding.DataObject;
-import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
-import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
-import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
-import org.opendaylight.yangtools.yang.data.api.schema.tree.DataTree;
-import org.opendaylight.yangtools.yang.data.api.schema.tree.DataTreeCandidate;
-import org.opendaylight.yangtools.yang.data.api.schema.tree.DataTreeCandidateNode;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/**
- * Extension of {@link ModifiableDataTreeManager} that propagates data changes to underlying writer layer before they
- * are fully committed in the backing data tree. Data changes are propagated in BA format.
- */
-public final class ModifiableDataTreeDelegator extends ModifiableDataTreeManager {
-
- private static final Logger LOG = LoggerFactory.getLogger(ModifiableDataTreeDelegator.class);
- private static final ReadableDataManager EMPTY_OPERATIONAL = p -> immediateCheckedFuture(Optional.absent());
-
- private final WriterRegistry writerRegistry;
- private final org.opendaylight.controller.md.sal.binding.api.DataBroker contextBroker;
- // TODO what to use instead of deprecated BindingNormalizedNodeSerializer ?
- private final BindingNormalizedNodeSerializer serializer;
-
- /**
- * Creates configuration data tree instance.
- * @param serializer service for serialization between Java Binding Data representation and NormalizedNode
- * representation.
- * @param dataTree data tree for configuration data representation
- * @param writerRegistry service for translation between Java Binding Data and data provider, capable of performing
- * @param contextBroker BA broker providing full access to mapping context data
- */
- public ModifiableDataTreeDelegator(@Nonnull final BindingNormalizedNodeSerializer serializer,
- @Nonnull final DataTree dataTree,
- @Nonnull final WriterRegistry writerRegistry,
- @Nonnull final org.opendaylight.controller.md.sal.binding.api.DataBroker contextBroker) {
- super(dataTree);
- this.contextBroker = checkNotNull(contextBroker, "contextBroker should not be null");
- this.serializer = checkNotNull(serializer, "serializer should not be null");
- this.writerRegistry = checkNotNull(writerRegistry, "writerRegistry should not be null");
- }
-
- @Override
- public DataModification newModification() {
- return new ConfigSnapshot(super.newModification());
- }
-
- private final class ConfigSnapshot extends ModifiableDataTreeManager.ConfigSnapshot {
-
- private final DataModification untouchedModification;
-
- /**
- * @param untouchedModification DataModification captured while this modification/snapshot was created.
- * To be used later while invoking writers to provide them with before state
- * (state without current modifications).
- * It must be captured as close as possible to when current modification started.
- */
- ConfigSnapshot(final DataModification untouchedModification) {
- this.untouchedModification = untouchedModification;
- }
-
- /**
- * Pass the changes to underlying writer layer.
- * Transform from BI to BA.
- * Revert(Write data before to subtrees that have been successfully modified before failure) in case of failure.
- */
- @Override
- protected void processCandidate(final DataTreeCandidate candidate)
- throws TranslationException {
-
- final DataTreeCandidateNode rootNode = candidate.getRootNode();
- final YangInstanceIdentifier rootPath = candidate.getRootPath();
- LOG.trace("ConfigDataTree.modify() rootPath={}, rootNode={}, dataBefore={}, dataAfter={}",
- rootPath, rootNode, rootNode.getDataBefore(), rootNode.getDataAfter());
-
- final ModificationDiff modificationDiff =
- ModificationDiff.recursivelyFromCandidate(YangInstanceIdentifier.EMPTY, rootNode);
- LOG.debug("ConfigDataTree.modify() diff: {}", modificationDiff);
-
- // Distinguish between updates (create + update) and deletes
- final WriterRegistry.DataObjectUpdates baUpdates = toBindingAware(modificationDiff.getUpdates());
- LOG.debug("ConfigDataTree.modify() extracted updates={}", baUpdates);
-
- try (final WriteContext ctx = getTransactionWriteContext()) {
- writerRegistry.update(baUpdates, ctx);
-
- final CheckedFuture<Void, TransactionCommitFailedException> contextUpdateResult =
- ((TransactionMappingContext) ctx.getMappingContext()).submit();
- // Blocking on context data update
- contextUpdateResult.checkedGet();
-
- } catch (WriterRegistry.BulkUpdateException e) {
- LOG.warn("Failed to apply all changes", e);
- LOG.info("Trying to revert successful changes for current transaction");
-
- try {
- e.revertChanges();
- LOG.info("Changes successfully reverted");
- } catch (WriterRegistry.Reverter.RevertFailedException revertFailedException) {
- // fail with failed revert
- LOG.error("Failed to revert successful changes", revertFailedException);
- throw revertFailedException;
- }
-
- throw e; // fail with success revert
- } catch (TransactionCommitFailedException e) {
- // FIXME revert should probably occur when context is not written successfully
- final String msg = "Error while updating mapping context data";
- LOG.error(msg, e);
- throw new TranslationException(msg, e);
- } catch (TranslationException e) {
- LOG.error("Error while processing data change (updates={})", baUpdates, e);
- throw e;
- }
- }
-
- private TransactionWriteContext getTransactionWriteContext() {
- // Before Tx must use modification
- final DOMDataReadOnlyTransaction beforeTx = ReadOnlyTransaction.create(untouchedModification, EMPTY_OPERATIONAL);
- // After Tx must use current modification
- final DOMDataReadOnlyTransaction afterTx = ReadOnlyTransaction.create(this, EMPTY_OPERATIONAL);
- final TransactionMappingContext mappingContext = new TransactionMappingContext(
- contextBroker.newReadWriteTransaction());
- return new TransactionWriteContext(serializer, beforeTx, afterTx, mappingContext);
- }
-
- private WriterRegistry.DataObjectUpdates toBindingAware(
- final Map<YangInstanceIdentifier, ModificationDiff.NormalizedNodeUpdate> biNodes) {
- return ModifiableDataTreeDelegator.toBindingAware(biNodes, serializer);
- }
- }
-
- @VisibleForTesting
- static WriterRegistry.DataObjectUpdates toBindingAware(
- final Map<YangInstanceIdentifier, ModificationDiff.NormalizedNodeUpdate> biNodes,
- final BindingNormalizedNodeSerializer serializer) {
-
- final Multimap<InstanceIdentifier<?>, DataObjectUpdate> dataObjectUpdates = HashMultimap.create();
- final Multimap<InstanceIdentifier<?>, DataObjectUpdate.DataObjectDelete> dataObjectDeletes =
- HashMultimap.create();
-
- for (Map.Entry<YangInstanceIdentifier, ModificationDiff.NormalizedNodeUpdate> biEntry : biNodes.entrySet()) {
- final InstanceIdentifier<?> unkeyedIid =
- RWUtils.makeIidWildcarded(serializer.fromYangInstanceIdentifier(biEntry.getKey()));
-
- ModificationDiff.NormalizedNodeUpdate normalizedNodeUpdate = biEntry.getValue();
- final DataObjectUpdate dataObjectUpdate = toDataObjectUpdate(normalizedNodeUpdate, serializer);
- if (dataObjectUpdate != null) {
- if (dataObjectUpdate instanceof DataObjectUpdate.DataObjectDelete) {
- dataObjectDeletes.put(unkeyedIid, ((DataObjectUpdate.DataObjectDelete) dataObjectUpdate));
- } else {
- dataObjectUpdates.put(unkeyedIid, dataObjectUpdate);
- }
- }
- }
- return new WriterRegistry.DataObjectUpdates(dataObjectUpdates, dataObjectDeletes);
- }
-
- @Nullable
- private static DataObjectUpdate toDataObjectUpdate(
- final ModificationDiff.NormalizedNodeUpdate normalizedNodeUpdate,
- final BindingNormalizedNodeSerializer serializer) {
-
- InstanceIdentifier<?> baId = serializer.fromYangInstanceIdentifier(normalizedNodeUpdate.getId());
- checkNotNull(baId, "Unable to transform instance identifier: %s into BA", normalizedNodeUpdate.getId());
-
- DataObject dataObjectBefore = getDataObject(serializer,
- normalizedNodeUpdate.getDataBefore(), normalizedNodeUpdate.getId());
- DataObject dataObjectAfter =
- getDataObject(serializer, normalizedNodeUpdate.getDataAfter(), normalizedNodeUpdate.getId());
-
- return dataObjectBefore == null && dataObjectAfter == null
- ? null
- : DataObjectUpdate.create(baId, dataObjectBefore, dataObjectAfter);
- }
-
- @Nullable
- private static DataObject getDataObject(@Nonnull final BindingNormalizedNodeSerializer serializer,
- @Nullable final NormalizedNode<?, ?> data,
- @Nonnull final YangInstanceIdentifier id) {
- DataObject dataObject = null;
- if (data != null) {
- final Map.Entry<InstanceIdentifier<?>, DataObject> dataObjectEntry =
- serializer.fromNormalizedNode(id, data);
- if (dataObjectEntry != null) {
- dataObject = dataObjectEntry.getValue();
- }
- }
- return dataObject;
- }
-
-}
-
-
-
diff --git a/v3po/data-impl/src/main/java/io/fd/honeycomb/v3po/data/impl/ModifiableDataTreeManager.java b/v3po/data-impl/src/main/java/io/fd/honeycomb/v3po/data/impl/ModifiableDataTreeManager.java
deleted file mode 100644
index 1082c479b..000000000
--- a/v3po/data-impl/src/main/java/io/fd/honeycomb/v3po/data/impl/ModifiableDataTreeManager.java
+++ /dev/null
@@ -1,122 +0,0 @@
-/*
- * Copyright (c) 2016 Cisco and/or its affiliates.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at:
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package io.fd.honeycomb.v3po.data.impl;
-
-import static com.google.common.base.Preconditions.checkNotNull;
-import static com.google.common.util.concurrent.Futures.immediateCheckedFuture;
-
-import com.google.common.base.Optional;
-import com.google.common.util.concurrent.CheckedFuture;
-import io.fd.honeycomb.v3po.data.DataModification;
-import io.fd.honeycomb.v3po.data.ModifiableDataManager;
-import io.fd.honeycomb.v3po.translate.TranslationException;
-import javax.annotation.Nonnull;
-import org.opendaylight.controller.md.sal.common.api.data.ReadFailedException;
-import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
-import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
-import org.opendaylight.yangtools.yang.data.api.schema.tree.DataTree;
-import org.opendaylight.yangtools.yang.data.api.schema.tree.DataTreeCandidate;
-import org.opendaylight.yangtools.yang.data.api.schema.tree.DataTreeModification;
-import org.opendaylight.yangtools.yang.data.api.schema.tree.DataValidationFailedException;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/**
- * DataTree backed implementation for modifiable data manager.
- */
-public class ModifiableDataTreeManager implements ModifiableDataManager {
-
- private static final Logger LOG = LoggerFactory.getLogger(ModifiableDataTreeManager.class);
-
- private final DataTree dataTree;
-
- public ModifiableDataTreeManager(@Nonnull final DataTree dataTree) {
- this.dataTree = checkNotNull(dataTree, "dataTree should not be null");
- }
-
- @Override
- public DataModification newModification() {
- return new ConfigSnapshot();
- }
-
- @Override
- public final CheckedFuture<Optional<NormalizedNode<?, ?>>, ReadFailedException> read(@Nonnull final YangInstanceIdentifier path) {
- return newModification().read(path);
- }
-
- protected class ConfigSnapshot implements DataModification {
- private final DataTreeModification modification;
- private boolean validated = false;
-
- ConfigSnapshot() {
- this(dataTree.takeSnapshot().newModification());
- }
-
- protected ConfigSnapshot(final DataTreeModification modification) {
- this.modification = modification;
- }
-
- @Override
- public CheckedFuture<Optional<NormalizedNode<?, ?>>, ReadFailedException> read(
- @Nonnull final YangInstanceIdentifier path) {
- final Optional<NormalizedNode<?, ?>> node = modification.readNode(path);
- if (LOG.isTraceEnabled() && node.isPresent()) {
- LOG.trace("ConfigSnapshot.read: {}", node.get());
- }
- return immediateCheckedFuture(node);
- }
-
- @Override
- public final void delete(final YangInstanceIdentifier path) {
- modification.delete(path);
- }
-
- @Override
- public final void merge(final YangInstanceIdentifier path, final NormalizedNode<?, ?> data) {
- modification.merge(path, data);
- }
-
- @Override
- public final void write(final YangInstanceIdentifier path, final NormalizedNode<?, ?> data) {
- modification.write(path, data);
- }
-
- @Override
- public final void commit() throws DataValidationFailedException, TranslationException {
- if(!validated) {
- validate();
- }
- final DataTreeCandidate candidate = dataTree.prepare(modification);
- processCandidate(candidate);
- dataTree.commit(candidate);
- }
-
- protected void processCandidate(final DataTreeCandidate candidate) throws TranslationException {
- // NOOP
- }
-
- @Override
- public final void validate() throws DataValidationFailedException {
- modification.ready();
- dataTree.validate(modification);
- validated = true;
- }
- }
-}
-
-
-
diff --git a/v3po/data-impl/src/main/java/io/fd/honeycomb/v3po/data/impl/ModificationDiff.java b/v3po/data-impl/src/main/java/io/fd/honeycomb/v3po/data/impl/ModificationDiff.java
deleted file mode 100644
index abc0062de..000000000
--- a/v3po/data-impl/src/main/java/io/fd/honeycomb/v3po/data/impl/ModificationDiff.java
+++ /dev/null
@@ -1,278 +0,0 @@
-/*
- * Copyright (c) 2016 Cisco and/or its affiliates.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at:
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package io.fd.honeycomb.v3po.data.impl;
-
-import static com.google.common.base.Preconditions.checkArgument;
-import static com.google.common.base.Preconditions.checkNotNull;
-
-import com.google.common.collect.ImmutableMap;
-import java.util.Collections;
-import java.util.EnumSet;
-import java.util.HashMap;
-import java.util.Map;
-import javax.annotation.Nonnull;
-import javax.annotation.Nullable;
-import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
-import org.opendaylight.yangtools.yang.data.api.schema.AugmentationNode;
-import org.opendaylight.yangtools.yang.data.api.schema.ChoiceNode;
-import org.opendaylight.yangtools.yang.data.api.schema.LeafNode;
-import org.opendaylight.yangtools.yang.data.api.schema.MixinNode;
-import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
-import org.opendaylight.yangtools.yang.data.api.schema.tree.DataTreeCandidateNode;
-import org.opendaylight.yangtools.yang.data.api.schema.tree.ModificationType;
-
-/**
- * Recursively collects and provides all unique and non-null modifications (modified normalized nodes).
- */
-final class ModificationDiff {
-
- private static final ModificationDiff EMPTY_DIFF = new ModificationDiff(Collections.emptyMap());
- private static final EnumSet LEAF_MODIFICATIONS = EnumSet.of(ModificationType.WRITE, ModificationType.DELETE);
-
- private final Map<YangInstanceIdentifier, NormalizedNodeUpdate> updates;
-
- private ModificationDiff(@Nonnull Map<YangInstanceIdentifier, NormalizedNodeUpdate> updates) {
- this.updates = updates;
- }
-
- /**
- * Get processed modifications.
- *
- * @return mapped modifications, where key is keyed {@link YangInstanceIdentifier}.
- */
- Map<YangInstanceIdentifier, NormalizedNodeUpdate> getUpdates() {
- return updates;
- }
-
- private ModificationDiff merge(final ModificationDiff other) {
- if (this == EMPTY_DIFF) {
- return other;
- }
-
- if (other == EMPTY_DIFF) {
- return this;
- }
-
- return new ModificationDiff(join(updates, other.updates));
- }
-
- private static Map<YangInstanceIdentifier, NormalizedNodeUpdate> join(Map<YangInstanceIdentifier, NormalizedNodeUpdate> first,
- Map<YangInstanceIdentifier, NormalizedNodeUpdate> second) {
- final Map<YangInstanceIdentifier, NormalizedNodeUpdate> merged = new HashMap<>();
- merged.putAll(first);
- merged.putAll(second);
- return merged;
- }
-
- private static ModificationDiff create(YangInstanceIdentifier id, DataTreeCandidateNode candidate) {
- return new ModificationDiff(ImmutableMap.of(id, NormalizedNodeUpdate.create(id, candidate)));
- }
-
- /**
- * Produce an aggregated diff from a candidate node recursively. MixinNodes are ignored as modifications and so
- * are complex nodes which direct leaves were not modified.
- */
- @Nonnull
- static ModificationDiff recursivelyFromCandidate(@Nonnull final YangInstanceIdentifier yangIid,
- @Nonnull final DataTreeCandidateNode currentCandidate) {
- // recursively process child nodes for exact modifications
- return recursivelyChildrenFromCandidate(yangIid, currentCandidate)
- // also add modification on current level, if elligible
- .merge(isModification(currentCandidate)
- ? ModificationDiff.create(yangIid, currentCandidate)
- : EMPTY_DIFF);
- }
-
- /**
- * Check whether current node was modified. {@link MixinNode}s are ignored
- * and only nodes which direct leaves(or choices) are modified are considered a modification.
- */
- private static Boolean isModification(@Nonnull final DataTreeCandidateNode currentCandidate) {
- // Mixin nodes are not considered modifications
- if (isMixin(currentCandidate) && !isAugment(currentCandidate)) {
- return false;
- } else {
- return isCurrentModified(currentCandidate);
- }
- }
-
- private static Boolean isCurrentModified(final @Nonnull DataTreeCandidateNode currentCandidate) {
- // Check if there are any modified leaves and if so, consider current node as modified
- final Boolean directLeavesModified = currentCandidate.getChildNodes().stream()
- .filter(ModificationDiff::isLeaf)
- // For some reason, we get modifications on unmodified list keys TODO debug and report ODL bug
- // and that messes up our modifications collection here, so we need to skip
- .filter(ModificationDiff::isBeforeAndAfterDifferent)
- .filter(child -> LEAF_MODIFICATIONS.contains(child.getModificationType()))
- .findFirst()
- .isPresent();
-
- return directLeavesModified
- // Also check choices (choices do not exist in BA world and if anything within a choice was modified,
- // consider its parent as being modified)
- || currentCandidate.getChildNodes().stream()
- .filter(ModificationDiff::isChoice)
- // Recursively check each choice if there was any change to it
- .filter(ModificationDiff::isCurrentModified)
- .findFirst()
- .isPresent();
- }
-
- /**
- * Process all non-leaf child nodes recursively, creating aggregated {@link ModificationDiff}.
- */
- private static ModificationDiff recursivelyChildrenFromCandidate(final @Nonnull YangInstanceIdentifier yangIid,
- final @Nonnull DataTreeCandidateNode currentCandidate) {
- // recursively process child nodes for specific modifications
- return currentCandidate.getChildNodes().stream()
- // not interested in modifications to leaves
- .filter(child -> !isLeaf(child))
- .map(candidate -> recursivelyFromCandidate(yangIid.node(candidate.getIdentifier()), candidate))
- .reduce(ModificationDiff::merge)
- .orElse(EMPTY_DIFF);
- }
-
- /**
- * Check whether candidate.before and candidate.after is different. If not return false.
- */
- private static boolean isBeforeAndAfterDifferent(@Nonnull final DataTreeCandidateNode candidateNode) {
- if (candidateNode.getDataBefore().isPresent()) {
- return !candidateNode.getDataBefore().get().equals(candidateNode.getDataAfter().orNull());
- }
-
- // considering not a modification if data after is also null
- return candidateNode.getDataAfter().isPresent();
- }
-
- /**
- * Check whether candidate node is for a leaf type node.
- */
- private static boolean isLeaf(final DataTreeCandidateNode candidateNode) {
- // orNull intentional, some candidate nodes have both data after and data before null
- return candidateNode.getDataAfter().orNull() instanceof LeafNode<?>
- || candidateNode.getDataBefore().orNull() instanceof LeafNode<?>;
- }
-
- /**
- * Check whether candidate node is for a Mixin type node.
- */
- private static boolean isMixin(final DataTreeCandidateNode candidateNode) {
- // orNull intentional, some candidate nodes have both data after and data before null
- return candidateNode.getDataAfter().orNull() instanceof MixinNode
- || candidateNode.getDataBefore().orNull() instanceof MixinNode;
- }
-
- /**
- * Check whether candidate node is for an Augmentation type node.
- */
- private static boolean isAugment(final DataTreeCandidateNode candidateNode) {
- // orNull intentional, some candidate nodes have both data after and data before null
- return candidateNode.getDataAfter().orNull() instanceof AugmentationNode
- || candidateNode.getDataBefore().orNull() instanceof AugmentationNode;
- }
-
- /**
- * Check whether candidate node is for a Choice type node.
- */
- private static boolean isChoice(final DataTreeCandidateNode candidateNode) {
- // orNull intentional, some candidate nodes have both data after and data before null
- return candidateNode.getDataAfter().orNull() instanceof ChoiceNode
- || candidateNode.getDataBefore().orNull() instanceof ChoiceNode;
- }
-
- @Override
- public String toString() {
- return "ModificationDiff{updates=" + updates + '}';
- }
-
- /**
- * Update to a normalized node identifiable by its {@link YangInstanceIdentifier}.
- */
- static final class NormalizedNodeUpdate {
-
- @Nonnull
- private final YangInstanceIdentifier id;
- @Nullable
- private final NormalizedNode<?, ?> dataBefore;
- @Nullable
- private final NormalizedNode<?, ?> dataAfter;
-
- private NormalizedNodeUpdate(@Nonnull final YangInstanceIdentifier id,
- @Nullable final NormalizedNode<?, ?> dataBefore,
- @Nullable final NormalizedNode<?, ?> dataAfter) {
- this.id = checkNotNull(id);
- this.dataAfter = dataAfter;
- this.dataBefore = dataBefore;
- }
-
- @Nullable
- public NormalizedNode<?, ?> getDataBefore() {
- return dataBefore;
- }
-
- @Nullable
- public NormalizedNode<?, ?> getDataAfter() {
- return dataAfter;
- }
-
- @Nonnull
- public YangInstanceIdentifier getId() {
- return id;
- }
-
- static NormalizedNodeUpdate create(@Nonnull final YangInstanceIdentifier id,
- @Nonnull final DataTreeCandidateNode candidate) {
- return create(id, candidate.getDataBefore().orNull(), candidate.getDataAfter().orNull());
- }
-
- static NormalizedNodeUpdate create(@Nonnull final YangInstanceIdentifier id,
- @Nullable final NormalizedNode<?, ?> dataBefore,
- @Nullable final NormalizedNode<?, ?> dataAfter) {
- checkArgument(!(dataBefore == null && dataAfter == null), "Both before and after data are null");
- return new NormalizedNodeUpdate(id, dataBefore, dataAfter);
- }
-
- @Override
- public boolean equals(final Object other) {
- if (this == other) {
- return true;
- }
- if (other == null || getClass() != other.getClass()) {
- return false;
- }
-
- final NormalizedNodeUpdate that = (NormalizedNodeUpdate) other;
-
- return id.equals(that.id);
-
- }
-
- @Override
- public int hashCode() {
- return id.hashCode();
- }
-
- @Override
- public String toString() {
- return "NormalizedNodeUpdate{" + "id=" + id
- + ", dataBefore=" + dataBefore
- + ", dataAfter=" + dataAfter
- + '}';
- }
- }
-
-}
diff --git a/v3po/data-impl/src/main/java/io/fd/honeycomb/v3po/data/impl/PersistingDataTreeAdapter.java b/v3po/data-impl/src/main/java/io/fd/honeycomb/v3po/data/impl/PersistingDataTreeAdapter.java
deleted file mode 100644
index 9b71dfd62..000000000
--- a/v3po/data-impl/src/main/java/io/fd/honeycomb/v3po/data/impl/PersistingDataTreeAdapter.java
+++ /dev/null
@@ -1,151 +0,0 @@
-/*
- * Copyright (c) 2016 Cisco and/or its affiliates.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at:
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package io.fd.honeycomb.v3po.data.impl;
-
-import static com.google.common.base.Preconditions.checkArgument;
-import static com.google.common.base.Preconditions.checkNotNull;
-
-import com.google.common.base.Optional;
-import io.fd.honeycomb.v3po.translate.util.JsonUtils;
-import java.io.IOException;
-import java.nio.file.Files;
-import java.nio.file.Path;
-import java.nio.file.StandardOpenOption;
-import javax.annotation.Nonnull;
-import org.opendaylight.controller.sal.core.api.model.SchemaService;
-import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
-import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
-import org.opendaylight.yangtools.yang.data.api.schema.tree.DataTree;
-import org.opendaylight.yangtools.yang.data.api.schema.tree.DataTreeCandidate;
-import org.opendaylight.yangtools.yang.data.api.schema.tree.DataTreeModification;
-import org.opendaylight.yangtools.yang.data.api.schema.tree.DataTreeSnapshot;
-import org.opendaylight.yangtools.yang.data.api.schema.tree.DataValidationFailedException;
-import org.opendaylight.yangtools.yang.model.api.SchemaContext;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/**
- * Adapter for a DataTree that stores current state of data in backing DataTree on each successful commit.
- * Uses JSON format.
- */
-public class PersistingDataTreeAdapter implements DataTree, AutoCloseable {
-
- private static final Logger LOG = LoggerFactory.getLogger(PersistingDataTreeAdapter.class);
-
- private final DataTree delegateDependency;
- private final SchemaService schemaServiceDependency;
- private final Path path;
-
- /**
- * Create new Persisting DataTree adapter
- *
- * @param delegate backing data tree that actually handles all the operations
- * @param persistPath path to a file (existing or not) to be used as storage for persistence. Full control over
- * a file at peristPath is expected
- * @param schemaService schemaContext provier
- */
- public PersistingDataTreeAdapter(@Nonnull final DataTree delegate,
- @Nonnull final SchemaService schemaService,
- @Nonnull final Path persistPath) {
- this.path = testPersistPath(checkNotNull(persistPath, "persistPath is null"));
- this.delegateDependency = checkNotNull(delegate, "delegate is null");
- this.schemaServiceDependency = checkNotNull(schemaService, "schemaService is null");
- }
-
- /**
- * Test whether file at persistPath exists and is readable or create it along with its parent structure
- */
- private Path testPersistPath(final Path persistPath) {
- try {
- checkArgument(!Files.isDirectory(persistPath), "Path %s points to a directory", persistPath);
- if(Files.exists(persistPath)) {
- checkArgument(Files.isReadable(persistPath),
- "Provided path %s points to existing, but non-readable file", persistPath);
- return persistPath;
- }
- Files.createDirectories(persistPath.getParent());
- Files.write(persistPath, new byte[]{}, StandardOpenOption.CREATE);
- } catch (IOException | UnsupportedOperationException e) {
- LOG.warn("Provided path for persistence: {} is not usable", persistPath, e);
- throw new IllegalArgumentException("Path " + persistPath + " cannot be used as ");
- }
-
- return persistPath;
- }
-
- @Override
- public DataTreeSnapshot takeSnapshot() {
- return delegateDependency.takeSnapshot();
- }
-
- @Override
- public void setSchemaContext(final SchemaContext schemaContext) {
- delegateDependency.setSchemaContext(schemaContext);
- }
-
- @Override
- public void commit(final DataTreeCandidate dataTreeCandidate) {
- LOG.trace("Commit detected");
- delegateDependency.commit(dataTreeCandidate);
- LOG.debug("Delegate commit successful. Persisting data");
-
- // FIXME doing full read and full write might not be the fastest way of persisting data here
- final DataTreeSnapshot dataTreeSnapshot = delegateDependency.takeSnapshot();
-
- // TODO this can be handled in background by a dedicated thread + a limited blocking queue
- // TODO enable configurable granularity for persists. Maybe doing write on every modification is too much
- // and we could do bulk persist
- persistCurrentData(dataTreeSnapshot.readNode(YangInstanceIdentifier.EMPTY));
- }
-
- private void persistCurrentData(final Optional<NormalizedNode<?, ?>> currentRoot) {
- if(currentRoot.isPresent()) {
- try {
- LOG.trace("Persisting current data: {} into: {}", currentRoot.get(), path);
- JsonUtils.writeJsonRoot(currentRoot.get(), schemaServiceDependency.getGlobalContext(),
- Files.newOutputStream(path, StandardOpenOption.CREATE, StandardOpenOption.TRUNCATE_EXISTING));
- LOG.trace("Data persisted successfully in {}", path);
- } catch (IOException e) {
- throw new IllegalStateException("Unable to persist current data", e);
- }
- } else {
- LOG.debug("Skipping persistence, since there's no data to persist");
- }
- }
-
- @Override
- public YangInstanceIdentifier getRootPath() {
- return delegateDependency.getRootPath();
- }
-
- @Override
- public void validate(final DataTreeModification dataTreeModification) throws DataValidationFailedException {
- delegateDependency.validate(dataTreeModification);
- }
-
- @Override
- public DataTreeCandidate prepare(
- final DataTreeModification dataTreeModification) {
- return delegateDependency.prepare(dataTreeModification);
- }
-
- @Override
- public void close() throws Exception {
- LOG.trace("Closing {} for {}", getClass().getSimpleName(), path);
- // NOOP
- }
-}
diff --git a/v3po/data-impl/src/main/java/io/fd/honeycomb/v3po/data/impl/ReadOnlyTransaction.java b/v3po/data-impl/src/main/java/io/fd/honeycomb/v3po/data/impl/ReadOnlyTransaction.java
deleted file mode 100644
index 2850a0d9a..000000000
--- a/v3po/data-impl/src/main/java/io/fd/honeycomb/v3po/data/impl/ReadOnlyTransaction.java
+++ /dev/null
@@ -1,119 +0,0 @@
-/*
- * Copyright (c) 2016 Cisco and/or its affiliates.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at:
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package io.fd.honeycomb.v3po.data.impl;
-
-import static com.google.common.base.Preconditions.checkArgument;
-import static com.google.common.base.Preconditions.checkState;
-import static java.util.Objects.requireNonNull;
-
-import com.google.common.base.Function;
-import com.google.common.base.Optional;
-import com.google.common.util.concurrent.CheckedFuture;
-import com.google.common.util.concurrent.Futures;
-import com.google.common.util.concurrent.ListenableFuture;
-import io.fd.honeycomb.v3po.data.ReadableDataManager;
-import javax.annotation.Nonnull;
-import javax.annotation.Nullable;
-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.dom.api.DOMDataReadOnlyTransaction;
-import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
-import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-final class ReadOnlyTransaction implements DOMDataReadOnlyTransaction {
-
- private static final Logger LOG = LoggerFactory.getLogger(ReadOnlyTransaction.class);
-
- @Nullable
- private ReadableDataManager operationalData;
- @Nullable
- private ReadableDataManager configSnapshot;
-
- private boolean closed = false;
-
- /**
- * @param configData config data tree manager. Null if config reads are not to be supported
- * @param operationalData operational data tree manager. Null if operational reads are not to be supported
- */
- private ReadOnlyTransaction(@Nullable final ReadableDataManager configData,
- @Nullable final ReadableDataManager operationalData) {
- this.configSnapshot = configData;
- this.operationalData = operationalData;
- }
-
- @Override
- public synchronized void close() {
- closed = true;
- configSnapshot = null;
- operationalData = null;
- }
-
- @Override
- public synchronized CheckedFuture<Optional<NormalizedNode<?, ?>>, ReadFailedException> read(
- final LogicalDatastoreType store,
- final YangInstanceIdentifier path) {
- LOG.debug("ReadOnlyTransaction.read(), store={}, path={}", store, path);
- checkState(!closed, "Transaction has been closed");
-
- if (store == LogicalDatastoreType.OPERATIONAL) {
- checkArgument(operationalData != null, "{} reads not supported", store);
- return operationalData.read(path);
- } else {
- checkArgument(configSnapshot != null, "{} reads not supported", store);
- return configSnapshot.read(path);
- }
- }
-
- @Override
- public CheckedFuture<Boolean, ReadFailedException> exists(final LogicalDatastoreType store,
- final YangInstanceIdentifier path) {
- LOG.debug("ReadOnlyTransaction.exists() store={}, path={}", store, path);
-
- ListenableFuture<Boolean> listenableFuture = Futures.transform(read(store, path), IS_NODE_PRESENT);
- return Futures.makeChecked(listenableFuture, ANY_EX_TO_READ_FAILED_EXCEPTION_MAPPER);
- }
-
- @Nonnull
- @Override
- public Object getIdentifier() {
- return this;
- }
-
- @Nonnull
- static ReadOnlyTransaction createOperationalOnly(@Nonnull final ReadableDataManager operationalData) {
- return new ReadOnlyTransaction(null, requireNonNull(operationalData));
- }
-
- @Nonnull
- static ReadOnlyTransaction createConfigOnly(@Nonnull final ReadableDataManager configData) {
- return new ReadOnlyTransaction(requireNonNull(configData), null);
- }
-
- @Nonnull
- static ReadOnlyTransaction create(@Nonnull final ReadableDataManager configData,
- @Nonnull final ReadableDataManager operationalData) {
- return new ReadOnlyTransaction(requireNonNull(configData), requireNonNull(operationalData));
- }
-
- private static final Function<? super Optional<NormalizedNode<?, ?>>, ? extends Boolean> IS_NODE_PRESENT =
- (Function<Optional<NormalizedNode<?, ?>>, Boolean>) input -> input == null ? Boolean.FALSE : input.isPresent();
-
- private static final Function<? super Exception, ReadFailedException> ANY_EX_TO_READ_FAILED_EXCEPTION_MAPPER =
- (Function<Exception, ReadFailedException>) e -> new ReadFailedException("Exists failed", e);
-} \ No newline at end of file
diff --git a/v3po/data-impl/src/main/java/io/fd/honeycomb/v3po/data/impl/ReadWriteTransaction.java b/v3po/data-impl/src/main/java/io/fd/honeycomb/v3po/data/impl/ReadWriteTransaction.java
deleted file mode 100644
index 88b46437e..000000000
--- a/v3po/data-impl/src/main/java/io/fd/honeycomb/v3po/data/impl/ReadWriteTransaction.java
+++ /dev/null
@@ -1,101 +0,0 @@
-/*
- * Copyright (c) 2016 Cisco and/or its affiliates.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at:
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package io.fd.honeycomb.v3po.data.impl;
-
-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.ListenableFuture;
-import javax.annotation.Nonnull;
-import org.opendaylight.controller.md.sal.common.api.TransactionStatus;
-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.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.DOMDataWriteTransaction;
-import org.opendaylight.yangtools.yang.common.RpcResult;
-import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
-import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
-
-/**
- * Composite DOM transaction that delegates reads to a {@link DOMDataReadTransaction} delegate and writes to a {@link
- * DOMDataWriteTransaction} delegate.
- */
-final class ReadWriteTransaction implements DOMDataReadWriteTransaction {
-
- private final DOMDataReadOnlyTransaction delegateReadTx;
- private final DOMDataWriteTransaction delegateWriteTx;
-
- ReadWriteTransaction(@Nonnull final DOMDataReadOnlyTransaction delegateReadTx,
- @Nonnull final DOMDataWriteTransaction delegateWriteTx) {
- this.delegateReadTx = Preconditions.checkNotNull(delegateReadTx, "delegateReadTx should not be null");
- this.delegateWriteTx = Preconditions.checkNotNull(delegateWriteTx, "delegateWriteTx should not be null");
- }
-
- @Override
- public boolean cancel() {
- delegateReadTx.close();
- return delegateWriteTx.cancel();
- }
-
- @Override
- public void put(final LogicalDatastoreType store, final YangInstanceIdentifier path,
- final NormalizedNode<?, ?> data) {
- delegateWriteTx.put(store, path, data);
- }
-
- @Override
- public void merge(final LogicalDatastoreType store, final YangInstanceIdentifier path,
- final NormalizedNode<?, ?> data) {
- delegateWriteTx.merge(store, path, data);
- }
-
- @Override
- public void delete(final LogicalDatastoreType store, final YangInstanceIdentifier path) {
- delegateWriteTx.delete(store, path);
- }
-
- @Override
- public CheckedFuture<Void, TransactionCommitFailedException> submit() {
- return delegateWriteTx.submit();
- }
-
- @Override
- public ListenableFuture<RpcResult<TransactionStatus>> commit() {
- return delegateWriteTx.commit();
- }
-
- @Override
- public CheckedFuture<Optional<NormalizedNode<?, ?>>, ReadFailedException> read(final LogicalDatastoreType store,
- final YangInstanceIdentifier path) {
- return delegateReadTx.read(store, path);
- }
-
- @Override
- public CheckedFuture<Boolean, ReadFailedException> exists(final LogicalDatastoreType store,
- final YangInstanceIdentifier path) {
- return delegateReadTx.exists(store, path);
- }
-
- @Override
- public Object getIdentifier() {
- return this;
- }
-}
-
diff --git a/v3po/data-impl/src/main/java/io/fd/honeycomb/v3po/data/impl/ReadableDataTreeDelegator.java b/v3po/data-impl/src/main/java/io/fd/honeycomb/v3po/data/impl/ReadableDataTreeDelegator.java
deleted file mode 100644
index aff023ebc..000000000
--- a/v3po/data-impl/src/main/java/io/fd/honeycomb/v3po/data/impl/ReadableDataTreeDelegator.java
+++ /dev/null
@@ -1,242 +0,0 @@
-/*
- * Copyright (c) 2016 Cisco and/or its affiliates.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at:
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package io.fd.honeycomb.v3po.data.impl;
-
-import static com.google.common.base.Preconditions.checkNotNull;
-import static com.google.common.collect.Iterables.getOnlyElement;
-
-import com.google.common.base.Function;
-import com.google.common.base.Optional;
-import com.google.common.base.Preconditions;
-import com.google.common.collect.Collections2;
-import com.google.common.collect.Multimap;
-import com.google.common.util.concurrent.CheckedFuture;
-import com.google.common.util.concurrent.Futures;
-import io.fd.honeycomb.v3po.data.ReadableDataManager;
-import io.fd.honeycomb.v3po.translate.MappingContext;
-import io.fd.honeycomb.v3po.translate.ModificationCache;
-import io.fd.honeycomb.v3po.translate.read.ReadContext;
-import io.fd.honeycomb.v3po.translate.read.ReadFailedException;
-import io.fd.honeycomb.v3po.translate.read.registry.ReaderRegistry;
-import io.fd.honeycomb.v3po.translate.util.TransactionMappingContext;
-import java.util.Collection;
-import java.util.Map;
-import javax.annotation.Nonnull;
-import org.opendaylight.controller.md.sal.common.api.data.TransactionCommitFailedException;
-import org.opendaylight.yangtools.binding.data.codec.api.BindingNormalizedNodeSerializer;
-import org.opendaylight.yangtools.yang.binding.DataObject;
-import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
-import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
-import org.opendaylight.yangtools.yang.data.api.schema.ContainerNode;
-import org.opendaylight.yangtools.yang.data.api.schema.DataContainerChild;
-import org.opendaylight.yangtools.yang.data.api.schema.MapEntryNode;
-import org.opendaylight.yangtools.yang.data.api.schema.MapNode;
-import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
-import org.opendaylight.yangtools.yang.data.api.schema.UnkeyedListEntryNode;
-import org.opendaylight.yangtools.yang.data.api.schema.UnkeyedListNode;
-import org.opendaylight.yangtools.yang.data.impl.schema.Builders;
-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.model.api.DataSchemaNode;
-import org.opendaylight.yangtools.yang.model.api.ListSchemaNode;
-import org.opendaylight.yangtools.yang.model.api.SchemaContext;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/**
- * ReadableDataTree implementation for operational data.
- */
-public final class ReadableDataTreeDelegator implements ReadableDataManager {
- private static final Logger LOG = LoggerFactory.getLogger(ReadableDataTreeDelegator.class);
-
- private final BindingNormalizedNodeSerializer serializer;
- private final ReaderRegistry readerRegistry;
- private final SchemaContext globalContext;
- private final org.opendaylight.controller.md.sal.binding.api.DataBroker contextBroker;
-
- /**
- * Creates operational data tree instance.
- * @param serializer service for serialization between Java Binding Data representation and NormalizedNode
- * representation.
- * @param globalContext service for obtaining top level context data from all yang modules.
- * @param readerRegistry service responsible for translation between DataObjects and data provider.
- * @param contextBroker BA broker for context data
- */
- public ReadableDataTreeDelegator(@Nonnull BindingNormalizedNodeSerializer serializer,
- @Nonnull final SchemaContext globalContext,
- @Nonnull final ReaderRegistry readerRegistry,
- @Nonnull final org.opendaylight.controller.md.sal.binding.api.DataBroker contextBroker) {
- this.contextBroker = checkNotNull(contextBroker, "contextBroker should not be null");
- this.globalContext = checkNotNull(globalContext, "globalContext should not be null");
- this.serializer = checkNotNull(serializer, "serializer should not be null");
- this.readerRegistry = checkNotNull(readerRegistry, "reader should not be null");
- }
-
- @Override
- public CheckedFuture<Optional<NormalizedNode<?, ?>>,
- org.opendaylight.controller.md.sal.common.api.data.ReadFailedException> read(
- @Nonnull final YangInstanceIdentifier yangInstanceIdentifier) {
-
- try(TransactionMappingContext mappingContext = new TransactionMappingContext(contextBroker.newReadWriteTransaction());
- ReadContext ctx = new ReadContextImpl(mappingContext)) {
-
- final Optional<NormalizedNode<?, ?>> value;
- if (checkNotNull(yangInstanceIdentifier).equals(YangInstanceIdentifier.EMPTY)) {
- value = readRoot(ctx);
- } else {
- value = readNode(yangInstanceIdentifier, ctx);
- }
-
- // Submit context mapping updates
- final CheckedFuture<Void, TransactionCommitFailedException> contextUpdateResult =
- ((TransactionMappingContext) ctx.getMappingContext()).submit();
- // Blocking on context data update
- contextUpdateResult.checkedGet();
-
- return Futures.immediateCheckedFuture(value);
-
- } catch (ReadFailedException e) {
- return Futures.immediateFailedCheckedFuture(
- new org.opendaylight.controller.md.sal.common.api.data.ReadFailedException(
- "Failed to read VPP data", e));
- } catch (TransactionCommitFailedException e) {
- // FIXME revert should probably occur when context is not written successfully
- final String msg = "Error while updating mapping context data";
- LOG.error(msg, e);
- return Futures.immediateFailedCheckedFuture(
- new org.opendaylight.controller.md.sal.common.api.data.ReadFailedException(msg, e)
- );
- }
- }
-
- private Optional<NormalizedNode<?, ?>> readNode(final YangInstanceIdentifier yangInstanceIdentifier,
- final ReadContext ctx) throws ReadFailedException {
- LOG.debug("OperationalDataTree.readNode(), yangInstanceIdentifier={}", yangInstanceIdentifier);
- final InstanceIdentifier<?> path = serializer.fromYangInstanceIdentifier(yangInstanceIdentifier);
- checkNotNull(path, "Invalid instance identifier %s. Cannot create BA equivalent.", yangInstanceIdentifier);
- LOG.debug("OperationalDataTree.readNode(), path={}", path);
-
- final Optional<? extends DataObject> dataObject;
-
- dataObject = readerRegistry.read(path, ctx);
- if (dataObject.isPresent()) {
- final NormalizedNode<?, ?> value = toNormalizedNodeFunction(path).apply(dataObject.get());
- return Optional.<NormalizedNode<?, ?>>fromNullable(value);
- } else {
- return Optional.absent();
- }
- }
-
- private Optional<NormalizedNode<?, ?>> readRoot(final ReadContext ctx) throws ReadFailedException {
- LOG.debug("OperationalDataTree.readRoot()");
-
- final DataContainerNodeAttrBuilder<YangInstanceIdentifier.NodeIdentifier, ContainerNode> dataNodeBuilder =
- Builders.containerBuilder()
- .withNodeIdentifier(new YangInstanceIdentifier.NodeIdentifier(SchemaContext.NAME));
-
- final Multimap<InstanceIdentifier<? extends DataObject>, ? extends DataObject> dataObjects =
- readerRegistry.readAll(ctx);
-
- for (final InstanceIdentifier<? extends DataObject> instanceIdentifier : dataObjects.keySet()) {
- final YangInstanceIdentifier rootElementId = serializer.toYangInstanceIdentifier(instanceIdentifier);
- final NormalizedNode<?, ?> node =
- wrapDataObjects(rootElementId, instanceIdentifier, dataObjects.get(instanceIdentifier));
- dataNodeBuilder.withChild((DataContainerChild<?, ?>) node);
- }
- return Optional.<NormalizedNode<?, ?>>of(dataNodeBuilder.build());
- }
-
- private NormalizedNode<?, ?> wrapDataObjects(final YangInstanceIdentifier yangInstanceIdentifier,
- final InstanceIdentifier<? extends DataObject> instanceIdentifier,
- final Collection<? extends DataObject> dataObjects) {
- final Collection<NormalizedNode<?, ?>> normalizedRootElements = Collections2
- .transform(dataObjects, toNormalizedNodeFunction(instanceIdentifier));
-
- final DataSchemaNode schemaNode =
- globalContext.getDataChildByName(yangInstanceIdentifier.getLastPathArgument().getNodeType());
- if (schemaNode instanceof ListSchemaNode) {
- // In case of a list, wrap all the values in a Mixin parent node
- final ListSchemaNode listSchema = (ListSchemaNode) schemaNode;
- return wrapListIntoMixinNode(normalizedRootElements, listSchema);
- } else {
- Preconditions.checkState(dataObjects.size() == 1, "Singleton list was expected");
- return getOnlyElement(normalizedRootElements);
- }
- }
-
- private static DataContainerChild<?, ?> wrapListIntoMixinNode(
- final Collection<NormalizedNode<?, ?>> normalizedRootElements, final ListSchemaNode listSchema) {
- if (listSchema.getKeyDefinition().isEmpty()) {
- final CollectionNodeBuilder<UnkeyedListEntryNode, UnkeyedListNode> listBuilder =
- Builders.unkeyedListBuilder();
- for (NormalizedNode<?, ?> normalizedRootElement : normalizedRootElements) {
- listBuilder.withChild((UnkeyedListEntryNode) normalizedRootElement);
- }
- return listBuilder.build();
- } else {
- final CollectionNodeBuilder<MapEntryNode, ? extends MapNode> listBuilder =
- listSchema.isUserOrdered()
- ? Builders.orderedMapBuilder()
- : Builders.mapBuilder();
-
- for (NormalizedNode<?, ?> normalizedRootElement : normalizedRootElements) {
- listBuilder.withChild((MapEntryNode) normalizedRootElement);
- }
- return listBuilder.build();
- }
- }
-
- @SuppressWarnings("unchecked")
- private Function<DataObject, NormalizedNode<?, ?>> toNormalizedNodeFunction(final InstanceIdentifier path) {
- return dataObject -> {
- LOG.trace("OperationalDataTree.toNormalizedNode(), path={}, dataObject={}", path, dataObject);
- final Map.Entry<YangInstanceIdentifier, NormalizedNode<?, ?>> entry =
- serializer.toNormalizedNode(path, dataObject);
-
- LOG.trace("OperationalDataTree.toNormalizedNode(), normalizedNodeEntry={}", entry);
- return entry.getValue();
- };
- }
-
- private static final class ReadContextImpl implements ReadContext {
-
- private final ModificationCache ctx = new ModificationCache();
- private final MappingContext mappingContext;
-
- private ReadContextImpl(final MappingContext mappingContext) {
- this.mappingContext = mappingContext;
- }
-
- @Nonnull
- @Override
- public ModificationCache getModificationCache() {
- return ctx;
- }
-
- @Nonnull
- @Override
- public MappingContext getMappingContext() {
- return mappingContext;
- }
-
- @Override
- public void close() {
- // Make sure to clear the storage in case some customizer stored a reference to it to prevent memory leaks
- ctx.close();
- }
- }
-}
diff --git a/v3po/data-impl/src/main/java/io/fd/honeycomb/v3po/data/impl/WriteTransaction.java b/v3po/data-impl/src/main/java/io/fd/honeycomb/v3po/data/impl/WriteTransaction.java
deleted file mode 100644
index c8f9bd3db..000000000
--- a/v3po/data-impl/src/main/java/io/fd/honeycomb/v3po/data/impl/WriteTransaction.java
+++ /dev/null
@@ -1,177 +0,0 @@
-/*
- * Copyright (c) 2016 Cisco and/or its affiliates.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at:
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package io.fd.honeycomb.v3po.data.impl;
-
-import static com.google.common.base.Preconditions.checkArgument;
-import static java.util.Objects.requireNonNull;
-import static org.opendaylight.controller.md.sal.common.api.TransactionStatus.CANCELED;
-import static org.opendaylight.controller.md.sal.common.api.TransactionStatus.COMMITED;
-import static org.opendaylight.controller.md.sal.common.api.TransactionStatus.FAILED;
-import static org.opendaylight.controller.md.sal.common.api.TransactionStatus.NEW;
-import static org.opendaylight.controller.md.sal.common.api.TransactionStatus.SUBMITED;
-
-import com.google.common.base.Preconditions;
-import com.google.common.util.concurrent.CheckedFuture;
-import com.google.common.util.concurrent.Futures;
-import com.google.common.util.concurrent.ListenableFuture;
-import io.fd.honeycomb.v3po.data.DataModification;
-import io.fd.honeycomb.v3po.translate.TranslationException;
-import java.util.function.Consumer;
-import javax.annotation.Nonnull;
-import javax.annotation.Nullable;
-import javax.annotation.concurrent.NotThreadSafe;
-import org.opendaylight.controller.md.sal.common.api.TransactionStatus;
-import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
-import org.opendaylight.controller.md.sal.common.api.data.TransactionCommitFailedException;
-import org.opendaylight.controller.md.sal.dom.api.DOMDataWriteTransaction;
-import org.opendaylight.yangtools.yang.common.RpcResult;
-import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
-import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
-import org.opendaylight.yangtools.yang.data.api.schema.tree.DataValidationFailedException;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-@NotThreadSafe
-final class WriteTransaction implements DOMDataWriteTransaction {
-
- private static final Logger LOG = LoggerFactory.getLogger(WriteTransaction.class);
-
- @Nullable
- private DataModification operationalModification;
- @Nullable
- private DataModification configModification;
- private TransactionStatus status = NEW;
-
- private WriteTransaction(@Nullable final DataModification configModification,
- @Nullable final DataModification operationalModification) {
- this.operationalModification = operationalModification;
- this.configModification = configModification;
- }
-
- private void checkIsNew() {
- Preconditions.checkState(status == NEW, "Transaction was submitted or canceled");
- }
-
- @Override
- public void put(final LogicalDatastoreType store, final YangInstanceIdentifier path,
- final NormalizedNode<?, ?> data) {
- LOG.debug("WriteTransaction.put() store={}, path={}, data={}", store, path, data);
- checkIsNew();
- handleOperation(store, (modification) -> modification.write(path, data));
- }
-
- private void handleOperation(final LogicalDatastoreType store,
- final Consumer<DataModification> r) {
- switch (store) {
- case CONFIGURATION:
- checkArgument(configModification != null, "Modification of %s is not supported", store);
- r.accept(configModification);
- break;
- case OPERATIONAL:
- checkArgument(operationalModification != null, "Modification of %s is not supported", store);
- r.accept(operationalModification);
- break;
- }
- }
-
- @Override
- public void merge(final LogicalDatastoreType store, final YangInstanceIdentifier path,
- final NormalizedNode<?, ?> data) {
- LOG.debug("WriteTransaction.merge() store={}, path={}, data={}", store, path, data);
- checkIsNew();
- handleOperation(store, (modification) -> modification.merge(path, data));
- }
-
- @Override
- public boolean cancel() {
- if (status != NEW) {
- // only NEW transactions can be cancelled
- return false;
- } else {
- status = CANCELED;
- return true;
- }
- }
-
- @Override
- public void delete(LogicalDatastoreType store, final YangInstanceIdentifier path) {
- LOG.debug("WriteTransaction.delete() store={}, path={}", store, path);
- checkIsNew();
- handleOperation(store, (modification) -> modification.delete(path));
- }
-
- @Override
- public CheckedFuture<Void, TransactionCommitFailedException> submit() {
- LOG.trace("WriteTransaction.submit()");
- checkIsNew();
-
- try {
- status = SUBMITED;
-
- // Validate first to catch any issues before attempting commit
- if (configModification != null) {
- configModification.validate();
- }
- if (operationalModification != null) {
- operationalModification.validate();
- }
-
- if(configModification != null) {
- configModification.commit();
- }
- if(operationalModification != null) {
- operationalModification.commit();
- }
-
- status = COMMITED;
- } catch (DataValidationFailedException | TranslationException e) {
- status = FAILED;
- LOG.error("Failed modify data tree", e);
- return Futures.immediateFailedCheckedFuture(
- new TransactionCommitFailedException("Failed to validate DataTreeModification", e));
- }
- return Futures.immediateCheckedFuture(null);
- }
-
- @Override
- @Deprecated
- public ListenableFuture<RpcResult<TransactionStatus>> commit() {
- throw new UnsupportedOperationException("deprecated");
- }
-
- @Override
- public Object getIdentifier() {
- return this;
- }
-
-
- @Nonnull
- static WriteTransaction createOperationalOnly(@Nonnull final DataModification operationalData) {
- return new WriteTransaction(null, requireNonNull(operationalData));
- }
-
- @Nonnull
- static WriteTransaction createConfigOnly(@Nonnull final DataModification configData) {
- return new WriteTransaction(requireNonNull(configData), null);
- }
-
- @Nonnull
- static WriteTransaction create(@Nonnull final DataModification configData,
- @Nonnull final DataModification operationalData) {
- return new WriteTransaction(requireNonNull(configData), requireNonNull(operationalData));
- }
-}