From 5970b9ec4f014869118026001e933c9847da2509 Mon Sep 17 00:00:00 2001 From: Maros Marsalek Date: Tue, 12 Apr 2016 10:13:21 +0200 Subject: HONEYCOMB-8: Move data layer from impl module into submodules Change-Id: Ic75793f65cfcad7cc2c96e7a09093e0e1802e4e5 Signed-off-by: Marek Gradzki Signed-off-by: Maros Marsalek --- .../io/fd/honeycomb/v3po/impl/V3poProvider.java | 5 +- .../impl/VppDataBrokerInitializationProvider.java | 282 +++++++++++++++++++++ .../fd/honeycomb/v3po/impl/data/DataTreeUtils.java | 76 ------ .../v3po/impl/data/ReadWriteTransaction.java | 101 -------- .../v3po/impl/data/ReadableVppDataTree.java | 39 --- .../honeycomb/v3po/impl/data/ReaderRegistry.java | 116 --------- .../v3po/impl/data/VppConfigDataTree.java | 167 ------------ .../fd/honeycomb/v3po/impl/data/VppDataBroker.java | 95 ------- .../data/VppDataBrokerInitializationProvider.java | 277 -------------------- .../fd/honeycomb/v3po/impl/data/VppDataTree.java | 44 ---- .../v3po/impl/data/VppDataTreeSnapshot.java | 34 --- .../v3po/impl/data/VppOperationalDataTree.java | 209 --------------- .../v3po/impl/data/VppReadOnlyTransaction.java | 103 -------- .../v3po/impl/data/VppWriteTransaction.java | 145 ----------- .../honeycomb/v3po/impl/data/WriterRegistry.java | 104 -------- 15 files changed, 284 insertions(+), 1513 deletions(-) create mode 100644 v3po/impl/src/main/java/io/fd/honeycomb/v3po/impl/VppDataBrokerInitializationProvider.java delete mode 100644 v3po/impl/src/main/java/io/fd/honeycomb/v3po/impl/data/DataTreeUtils.java delete mode 100644 v3po/impl/src/main/java/io/fd/honeycomb/v3po/impl/data/ReadWriteTransaction.java delete mode 100644 v3po/impl/src/main/java/io/fd/honeycomb/v3po/impl/data/ReadableVppDataTree.java delete mode 100644 v3po/impl/src/main/java/io/fd/honeycomb/v3po/impl/data/ReaderRegistry.java delete mode 100644 v3po/impl/src/main/java/io/fd/honeycomb/v3po/impl/data/VppConfigDataTree.java delete mode 100644 v3po/impl/src/main/java/io/fd/honeycomb/v3po/impl/data/VppDataBroker.java delete mode 100644 v3po/impl/src/main/java/io/fd/honeycomb/v3po/impl/data/VppDataBrokerInitializationProvider.java delete mode 100644 v3po/impl/src/main/java/io/fd/honeycomb/v3po/impl/data/VppDataTree.java delete mode 100644 v3po/impl/src/main/java/io/fd/honeycomb/v3po/impl/data/VppDataTreeSnapshot.java delete mode 100644 v3po/impl/src/main/java/io/fd/honeycomb/v3po/impl/data/VppOperationalDataTree.java delete mode 100644 v3po/impl/src/main/java/io/fd/honeycomb/v3po/impl/data/VppReadOnlyTransaction.java delete mode 100644 v3po/impl/src/main/java/io/fd/honeycomb/v3po/impl/data/VppWriteTransaction.java delete mode 100644 v3po/impl/src/main/java/io/fd/honeycomb/v3po/impl/data/WriterRegistry.java (limited to 'v3po/impl/src/main') diff --git a/v3po/impl/src/main/java/io/fd/honeycomb/v3po/impl/V3poProvider.java b/v3po/impl/src/main/java/io/fd/honeycomb/v3po/impl/V3poProvider.java index 0ea4525f0..a97909190 100644 --- a/v3po/impl/src/main/java/io/fd/honeycomb/v3po/impl/V3poProvider.java +++ b/v3po/impl/src/main/java/io/fd/honeycomb/v3po/impl/V3poProvider.java @@ -20,9 +20,8 @@ import com.google.common.base.Preconditions; import com.google.common.collect.Lists; import com.google.common.util.concurrent.CheckedFuture; import com.google.common.util.concurrent.Futures; -import io.fd.honeycomb.v3po.impl.data.VppDataBrokerInitializationProvider; -import io.fd.honeycomb.v3po.impl.data.ReaderRegistry; -import io.fd.honeycomb.v3po.impl.data.WriterRegistry; +import io.fd.honeycomb.v3po.config.ReaderRegistry; +import io.fd.honeycomb.v3po.config.WriterRegistry; import java.io.IOException; import java.util.Collections; import java.util.HashMap; diff --git a/v3po/impl/src/main/java/io/fd/honeycomb/v3po/impl/VppDataBrokerInitializationProvider.java b/v3po/impl/src/main/java/io/fd/honeycomb/v3po/impl/VppDataBrokerInitializationProvider.java new file mode 100644 index 000000000..288463f74 --- /dev/null +++ b/v3po/impl/src/main/java/io/fd/honeycomb/v3po/impl/VppDataBrokerInitializationProvider.java @@ -0,0 +1,282 @@ +/* + * 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.impl; + +import static com.google.common.base.Preconditions.checkNotNull; + +import com.google.common.base.Optional; +import com.google.common.base.Preconditions; +import com.google.common.util.concurrent.AsyncFunction; +import com.google.common.util.concurrent.Futures; +import com.google.common.util.concurrent.ListenableFuture; +import io.fd.honeycomb.v3po.config.WriterRegistry; +import io.fd.honeycomb.v3po.data.ReadableVppDataTree; +import io.fd.honeycomb.v3po.data.VppDataTree; +import io.fd.honeycomb.v3po.data.impl.VppConfigDataTree; +import io.fd.honeycomb.v3po.data.impl.VppDataBroker; +import io.fd.honeycomb.v3po.data.impl.VppOperationalDataTree; +import io.fd.honeycomb.v3po.translate.read.ReaderRegistry; +import java.util.Collection; +import java.util.Collections; +import javassist.ClassPool; +import javax.annotation.Nonnull; +import org.opendaylight.controller.md.sal.binding.api.DataBroker; +import org.opendaylight.controller.md.sal.binding.api.ReadOnlyTransaction; +import org.opendaylight.controller.md.sal.binding.api.WriteTransaction; +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.DOMDataWriteTransaction; +import org.opendaylight.controller.md.sal.dom.api.DOMMountPoint; +import org.opendaylight.controller.md.sal.dom.api.DOMMountPointService; +import org.opendaylight.controller.sal.core.api.Broker; +import org.opendaylight.controller.sal.core.api.Provider; +import org.opendaylight.controller.sal.core.api.model.SchemaService; +import org.opendaylight.mdsal.binding.dom.codec.api.BindingNormalizedNodeSerializer; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.VppState; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.vpp.state.BridgeDomains; +import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NetworkTopology; +import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NodeId; +import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.TopologyId; +import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.Topology; +import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.TopologyKey; +import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node; +import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.NodeBuilder; +import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.NodeKey; +import org.opendaylight.yangtools.binding.data.codec.gen.impl.DataObjectSerializerGenerator; +import org.opendaylight.yangtools.binding.data.codec.gen.impl.StreamWriterGenerator; +import org.opendaylight.yangtools.binding.data.codec.impl.BindingNormalizedNodeCodecRegistry; +import org.opendaylight.yangtools.concepts.ObjectRegistration; +import org.opendaylight.yangtools.sal.binding.generator.impl.GeneratedClassLoadingStrategy; +import org.opendaylight.yangtools.sal.binding.generator.util.BindingRuntimeContext; +import org.opendaylight.yangtools.sal.binding.generator.util.JavassistUtils; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; +import org.opendaylight.yangtools.yang.binding.KeyedInstanceIdentifier; +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.TreeType; +import org.opendaylight.yangtools.yang.data.impl.schema.tree.InMemoryDataTreeFactory; +import org.opendaylight.yangtools.yang.model.api.SchemaContext; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Creates VppDataBroker which uses DataTree instead of DataStore internally in order to obtain better control over the + * data processing in Honeycomb agent + */ +public final class VppDataBrokerInitializationProvider implements Provider, AutoCloseable { + + private static final Logger LOG = LoggerFactory.getLogger(VppDataBrokerInitializationProvider.class); + + private final TopologyId VPP_TOPOLOGY_ID = TopologyId.getDefaultInstance("vpp-topology"); + private final NodeId VPP_TOPOLOGY_NODE_ID = NodeId.getDefaultInstance("vpp"); + private final DataBroker bindingBroker; + private final ReaderRegistry readerRegistry; + private final InstanceIdentifier mountPointPath; + private final WriterRegistry writerRegistry; + private ObjectRegistration mountPointRegistration; + private DOMDataBroker broker; + + public VppDataBrokerInitializationProvider(@Nonnull final DataBroker bindingBroker, + final ReaderRegistry readerRegistry, + final WriterRegistry writerRegistry) { + this.bindingBroker = checkNotNull(bindingBroker, "bindingBroker should not be null"); + this.readerRegistry = checkNotNull(readerRegistry, "readerRegistry should not be null"); + this.writerRegistry = checkNotNull(writerRegistry, "writerRegistry should not be null"); + this.mountPointPath = getMountPointPath(); + } + + // TODO make configurable + private InstanceIdentifier getMountPointPath() { + final InstanceIdentifier networkTopology = + InstanceIdentifier.builder(NetworkTopology.class).build(); + final KeyedInstanceIdentifier topology = + networkTopology.child(Topology.class, new TopologyKey(VPP_TOPOLOGY_ID)); + return topology.child(Node.class, new NodeKey(VPP_TOPOLOGY_NODE_ID)); + } + + @Override + public void onSessionInitiated(final Broker.ProviderSession providerSession) { + LOG.info("Session initialized, providerSession={}", providerSession); + Preconditions.checkState(!isMountPointRegistered(), "Mount point is already registered"); + + final DOMMountPointService mountPointService = providerSession.getService(DOMMountPointService.class); + final SchemaService schemaService = providerSession.getService(SchemaService.class); + + final SchemaContext globalContext = schemaService.getGlobalContext(); + final BindingNormalizedNodeSerializer serializer = initSerializer(globalContext); + final YangInstanceIdentifier path = serializer.toYangInstanceIdentifier(mountPointPath); + + final DOMMountPointService.DOMMountPointBuilder mountPointBuilder = mountPointService.createMountPoint(path); + mountPointBuilder.addInitialSchemaContext(globalContext); + + broker = initVppDataBroker(globalContext, serializer); + mountPointBuilder.addService(DOMDataBroker.class, broker); + + mountPointRegistration = mountPointBuilder.register(); + final DOMMountPoint mountPoint = mountPointRegistration.getInstance(); + LOG.debug("Created mountPoint: identifier={}, schemaContext={}", mountPoint.getIdentifier(), + mountPoint.getSchemaContext()); + + createMountPointPlaceholder(); + + initialVppConfigSynchronization(broker); + } + + @Override + public Collection getProviderFunctionality() { + return Collections.EMPTY_LIST; + } + + private boolean isMountPointRegistered() { + final ReadOnlyTransaction readTx = bindingBroker.newReadOnlyTransaction(); + try { + final Optional cfgPlaceholder = + readTx.read(LogicalDatastoreType.CONFIGURATION, mountPointPath).checkedGet(); + final Optional operPlaceholder = + readTx.read(LogicalDatastoreType.OPERATIONAL, mountPointPath).checkedGet(); + return cfgPlaceholder.isPresent() || operPlaceholder.isPresent(); + } catch (ReadFailedException e) { + throw new IllegalStateException("Failed to read mountpoint placeholder data", e); + } + } + + private BindingNormalizedNodeSerializer initSerializer(final SchemaContext globalContext) { + final JavassistUtils utils = JavassistUtils.forClassPool(ClassPool.getDefault()); + // TODO this produces ClassNotFoundException + //final GeneratedClassLoadingStrategy loading = GeneratedClassLoadingStrategy.getTCCLClassLoadingStrategy(); + + // FIXME get global class loader instance + final GeneratedClassLoadingStrategy loadingStrategy = + new GeneratedClassLoadingStrategy() { + @Override + public Class loadClass(final String fullyQualifiedName) + throws ClassNotFoundException { + return Class.forName(fullyQualifiedName); + } + }; + final DataObjectSerializerGenerator generator = StreamWriterGenerator.create(utils); + + // TODO make configurable: + final BindingNormalizedNodeCodecRegistry serializer = new BindingNormalizedNodeCodecRegistry(generator); + final BindingRuntimeContext context = BindingRuntimeContext.create(loadingStrategy, globalContext); + serializer.onBindingRuntimeContextUpdated(context); + return serializer; + } + + private DOMDataBroker initVppDataBroker(final SchemaContext globalContext, + final BindingNormalizedNodeSerializer serializer) { + final ReadableVppDataTree operationalData = + new VppOperationalDataTree(serializer, globalContext, readerRegistry); // TODO make configurable + + final DataTree dataTree = + InMemoryDataTreeFactory.getInstance().create(TreeType.CONFIGURATION); // TODO make configurable + dataTree.setSchemaContext(globalContext); + + final VppDataTree configDataProxy = new VppConfigDataTree(serializer, dataTree, writerRegistry); // TODO make configurable + return new VppDataBroker(operationalData, configDataProxy); + } + + /** + * Writes placeholder data into MD-SAL's global datastore to indicate the presence of VPP mountpoint. + */ + private void createMountPointPlaceholder() { + final NodeBuilder nodeBuilder = new NodeBuilder(); + nodeBuilder.setKey(new NodeKey(VPP_TOPOLOGY_NODE_ID)); + final Node node = nodeBuilder.build(); + + final WriteTransaction writeTx = bindingBroker.newWriteOnlyTransaction(); + writeTx.merge(LogicalDatastoreType.CONFIGURATION, mountPointPath, node, true); + writeTx.merge(LogicalDatastoreType.OPERATIONAL, mountPointPath, node, true); + + try { + writeTx.submit().checkedGet(); + } catch (TransactionCommitFailedException e) { + throw new IllegalStateException("Failed to create mountpoint placeholder", e); + } + } + + // TODO operational and config models are not 1-1 + // decide what part of operational data should be written to config during initialization + private void initialVppConfigSynchronization(final DOMDataBroker broker) { + // read from operational + final DOMDataReadOnlyTransaction readTx = broker.newReadOnlyTransaction(); + + final YangInstanceIdentifier + id = YangInstanceIdentifier.builder().node(VppState.QNAME).node(BridgeDomains.QNAME).build(); + + LOG.trace("initialVppStateSynchronization id: {}", id); + + final ListenableFuture writeFuture = Futures.transform( + readTx.read(LogicalDatastoreType.OPERATIONAL, id), + new AsyncFunction>, Void>() { + @Override + public ListenableFuture apply(final Optional> readResult) + throws Exception { + if (readResult.isPresent()) { + final DOMDataWriteTransaction writeTx = broker.newWriteOnlyTransaction(); + final NormalizedNode node = readResult.get(); + LOG.trace("Read result: {}", node); + + // FIXME + // this will fail because we are reading OPERATIONAL data and writing to CONFIGURATION + // we need to provide extensible way to register initializer that would + // translate between models + + // writeTx.put(LogicalDatastoreType.CONFIGURATION, id, node); + return writeTx.submit(); + } else { + return Futures + .immediateFailedFuture( + new IllegalStateException("Failed to read data from VPP.")); + } + } + }); + + Futures.addCallback(writeFuture, + new LoggingFuturesCallBack("Initializing VPP config DataTree failed", LOG)); + } + + public Optional getBroker() { + return Optional.fromNullable(broker); + } + + @Override + public void close() throws Exception { + if (mountPointRegistration != null) { + mountPointRegistration.close(); + } + + if (broker != null) { + broker = null; + } + + // remove MD-SAL placeholder data for VPP mount point: + final WriteTransaction rwTx = bindingBroker.newWriteOnlyTransaction(); + // does not fail if data is not present: + rwTx.delete(LogicalDatastoreType.CONFIGURATION, mountPointPath); + try { + rwTx.submit().checkedGet(); + } catch (TransactionCommitFailedException e) { + throw new IllegalStateException("Failed to remove mountpoint's placeholder from MD-SAL's global datastore", + e); + } + } +} diff --git a/v3po/impl/src/main/java/io/fd/honeycomb/v3po/impl/data/DataTreeUtils.java b/v3po/impl/src/main/java/io/fd/honeycomb/v3po/impl/data/DataTreeUtils.java deleted file mode 100644 index bb9da5695..000000000 --- a/v3po/impl/src/main/java/io/fd/honeycomb/v3po/impl/data/DataTreeUtils.java +++ /dev/null @@ -1,76 +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.impl.data; - -import com.google.common.base.Preconditions; -import java.util.Collection; -import java.util.HashMap; -import java.util.Map; -import javax.annotation.Nonnull; -import org.opendaylight.mdsal.binding.dom.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.DataContainerChild; -import org.opendaylight.yangtools.yang.data.api.schema.DataContainerNode; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -/** - * Utility class for various operations on DataTree. - */ -final class DataTreeUtils { - private static final Logger LOG = LoggerFactory.getLogger(DataTreeUtils.class); - - private DataTreeUtils() { - throw new UnsupportedOperationException("Can't instantiate util class"); - } - - /** - * Translates children of supplied YANG ContainerNode into Binding data. - * - * @param parent ContainerNode representing data - * @param serializer service for serialization between Java Binding Data representation and NormalizedNode - * representation. - * @return NormalizedNode representation of parent's node children - */ - static Map, DataObject> childrenFromNormalized(@Nonnull final DataContainerNode parent, - @Nonnull final BindingNormalizedNodeSerializer serializer) { - - Preconditions.checkNotNull(parent, "parent node should not be null"); - Preconditions.checkNotNull(serializer, "serializer should not be null"); - - final Map, DataObject> map = new HashMap<>(); - - final Collection> children = - parent.getValue(); - - for (final DataContainerChild child : children) { - final YangInstanceIdentifier.PathArgument pathArgument = child.getIdentifier(); - final YangInstanceIdentifier identifier = YangInstanceIdentifier.create(pathArgument); - LOG.debug("VppConfigDataProxy.extractDataObject() child={}, pathArgument={}, identifier={}", child, - pathArgument, identifier); - - final Map.Entry, DataObject> entry = serializer.fromNormalizedNode(identifier, child); - if (entry != null) { - map.put(entry.getKey(), entry.getValue()); - } - } - - return map; - } -} diff --git a/v3po/impl/src/main/java/io/fd/honeycomb/v3po/impl/data/ReadWriteTransaction.java b/v3po/impl/src/main/java/io/fd/honeycomb/v3po/impl/data/ReadWriteTransaction.java deleted file mode 100644 index 7faeba54a..000000000 --- a/v3po/impl/src/main/java/io/fd/honeycomb/v3po/impl/data/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.impl.data; - -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 submit() { - return delegateWriteTx.submit(); - } - - @Override - public ListenableFuture> commit() { - return delegateWriteTx.commit(); - } - - @Override - public CheckedFuture>, ReadFailedException> read(final LogicalDatastoreType store, - final YangInstanceIdentifier path) { - return delegateReadTx.read(store, path); - } - - @Override - public CheckedFuture exists(final LogicalDatastoreType store, - final YangInstanceIdentifier path) { - return delegateReadTx.exists(store, path); - } - - @Override - public Object getIdentifier() { - return this; - } -} - diff --git a/v3po/impl/src/main/java/io/fd/honeycomb/v3po/impl/data/ReadableVppDataTree.java b/v3po/impl/src/main/java/io/fd/honeycomb/v3po/impl/data/ReadableVppDataTree.java deleted file mode 100644 index 19248ddf0..000000000 --- a/v3po/impl/src/main/java/io/fd/honeycomb/v3po/impl/data/ReadableVppDataTree.java +++ /dev/null @@ -1,39 +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.impl.data; - -import com.google.common.annotations.Beta; -import com.google.common.base.Optional; -import com.google.common.util.concurrent.CheckedFuture; -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; - -/** - * Facade over VPP data tree that allows reading tree nodes. - */ -@Beta -public interface ReadableVppDataTree { - /** - * Reads a particular node from the VPP data tree. - * - * @param path Path of the node - * @return a CheckFuture containing the result of the read. - */ - CheckedFuture>, ReadFailedException> read(@Nonnull final YangInstanceIdentifier path); -} diff --git a/v3po/impl/src/main/java/io/fd/honeycomb/v3po/impl/data/ReaderRegistry.java b/v3po/impl/src/main/java/io/fd/honeycomb/v3po/impl/data/ReaderRegistry.java deleted file mode 100644 index 5e547094f..000000000 --- a/v3po/impl/src/main/java/io/fd/honeycomb/v3po/impl/data/ReaderRegistry.java +++ /dev/null @@ -1,116 +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.impl.data; - -import com.google.common.base.Optional; -import com.google.common.collect.Multimap; -import io.fd.honeycomb.v3po.translate.impl.read.CompositeChildReader; -import io.fd.honeycomb.v3po.translate.impl.read.CompositeListReader; -import io.fd.honeycomb.v3po.translate.impl.read.CompositeRootReader; -import io.fd.honeycomb.v3po.translate.util.read.DelegatingReaderRegistry; -import io.fd.honeycomb.v3po.translate.util.read.ReflexiveChildReaderCustomizer; -import io.fd.honeycomb.v3po.translate.util.read.ReflexiveRootReaderCustomizer; -import io.fd.honeycomb.v3po.translate.util.RWUtils; -import io.fd.honeycomb.v3po.translate.read.ChildReader; -import io.fd.honeycomb.v3po.translate.read.ReadContext; -import io.fd.honeycomb.v3po.translate.read.ReadFailedException; -import io.fd.honeycomb.v3po.translate.read.Reader; -import io.fd.honeycomb.v3po.translate.v3po.vppstate.BridgeDomainCustomizer; -import io.fd.honeycomb.v3po.translate.v3po.vppstate.VersionCustomizer; -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; -import javax.annotation.Nonnull; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.VppState; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.VppStateBuilder; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.vpp.state.BridgeDomains; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.vpp.state.BridgeDomainsBuilder; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.vpp.state.Version; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.vpp.state.bridge.domains.BridgeDomain; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.vpp.state.bridge.domains.BridgeDomainBuilder; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.vpp.state.bridge.domains.BridgeDomainKey; -import org.opendaylight.yangtools.yang.binding.ChildOf; -import org.opendaylight.yangtools.yang.binding.DataObject; -import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; -import org.openvpp.vppjapi.vppApi; - -// TODO use some DI framework instead of singleton -public class ReaderRegistry implements io.fd.honeycomb.v3po.translate.read.ReaderRegistry { - - private static ReaderRegistry instance; - - private final DelegatingReaderRegistry reader; - - private ReaderRegistry(@Nonnull final vppApi vppApi) { - final CompositeRootReader vppStateReader = initVppStateReader(vppApi); - // TODO add more root readers - reader = new DelegatingReaderRegistry(Collections.>singletonList(vppStateReader)); - } - - private static CompositeRootReader initVppStateReader(@Nonnull final vppApi vppApi) { - - final ChildReader versionReader = new CompositeChildReader<>( - Version.class, new VersionCustomizer(vppApi)); - - final CompositeListReader - bridgeDomainReader = new CompositeListReader<>( - BridgeDomain.class, - new BridgeDomainCustomizer(vppApi)); - - final ChildReader bridgeDomainsReader = new CompositeChildReader<>( - BridgeDomains.class, - RWUtils.singletonChildReaderList(bridgeDomainReader), - new ReflexiveChildReaderCustomizer<>(BridgeDomainsBuilder.class)); - - final List>> childVppReaders = new ArrayList<>(); - childVppReaders.add(versionReader); - childVppReaders.add(bridgeDomainsReader); - - return new CompositeRootReader<>( - VppState.class, - childVppReaders, - RWUtils.emptyAugReaderList(), - new ReflexiveRootReaderCustomizer<>(VppStateBuilder.class)); - } - - public static synchronized ReaderRegistry getInstance(@Nonnull final vppApi vppApi) { - if (instance == null) { - instance = new ReaderRegistry(vppApi); - } - return instance; - } - - @Nonnull - @Override - public Multimap, ? extends DataObject> readAll( - @Nonnull final ReadContext ctx) throws ReadFailedException { - return reader.readAll(ctx); - } - - @Nonnull - @Override - public Optional read(@Nonnull final InstanceIdentifier id, - @Nonnull final ReadContext ctx) throws ReadFailedException { - return reader.read(id, ctx); - } - - @Nonnull - @Override - public InstanceIdentifier getManagedDataObjectType() { - return reader.getManagedDataObjectType(); - } -} 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 deleted file mode 100644 index 1a631fc2e..000000000 --- a/v3po/impl/src/main/java/io/fd/honeycomb/v3po/impl/data/VppConfigDataTree.java +++ /dev/null @@ -1,167 +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.impl.data; - -import static com.google.common.base.Preconditions.checkNotNull; - -import com.google.common.base.Optional; -import com.google.common.util.concurrent.CheckedFuture; -import com.google.common.util.concurrent.Futures; -import io.fd.honeycomb.v3po.translate.TranslationException; -import io.fd.honeycomb.v3po.translate.util.write.TransactionWriteContext; -import io.fd.honeycomb.v3po.translate.write.WriteContext; -import java.util.Collections; -import java.util.Map; -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; -import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier; -import org.opendaylight.yangtools.yang.data.api.schema.DataContainerNode; -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.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.slf4j.Logger; -import org.slf4j.LoggerFactory; - -/** - * VppDataTree implementation for configuration data. - */ -public final class VppConfigDataTree implements VppDataTree { - - private static final Logger LOG = LoggerFactory.getLogger(VppConfigDataTree.class); - - private final BindingNormalizedNodeSerializer serializer; - private final DataTree dataTree; - private final WriterRegistry writer; - public static final ReadableVppDataTree EMPTY_OPERATIONAL = new ReadableVppDataTree() { - @Override - public CheckedFuture>, ReadFailedException> read( - @Nonnull final YangInstanceIdentifier path) { - return Futures.immediateCheckedFuture(Optional.>absent()); - } - }; - - /** - * 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 vppWriter service for translation between Java Binding Data and Vpp. - */ - public VppConfigDataTree(@Nonnull final BindingNormalizedNodeSerializer serializer, - @Nonnull final DataTree dataTree, @Nonnull final WriterRegistry 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 - public VppDataTreeSnapshot takeSnapshot() { - return new ConfigSnapshot(dataTree.takeSnapshot()); - } - - @Override - public void commit(final DataTreeModification modification) - throws DataValidationFailedException, TranslationException { - dataTree.validate(modification); - - final DataTreeCandidate candidate = dataTree.prepare(modification); - - final DataTreeCandidateNode rootNode = candidate.getRootNode(); - final YangInstanceIdentifier rootPath = candidate.getRootPath(); - final Optional> normalizedDataBefore = rootNode.getDataBefore(); - final Optional> normalizedDataAfter = rootNode.getDataAfter(); - LOG.debug("VppConfigDataTree.commit() rootPath={}, rootNode={}, dataBefore={}, dataAfter={}", - rootPath, rootNode, normalizedDataBefore, normalizedDataAfter); - - final Map, DataObject> nodesBefore = extractNetconfData(normalizedDataBefore); - LOG.debug("VppConfigDataTree.commit() extracted nodesBefore={}", nodesBefore.keySet()); - - final Map, DataObject> nodesAfter = extractNetconfData(normalizedDataAfter); - LOG.debug("VppConfigDataTree.commit() extracted nodesAfter={}", nodesAfter.keySet()); - - - final DOMDataReadOnlyTransaction beforeTx = new VppReadOnlyTransaction(EMPTY_OPERATIONAL, takeSnapshot()); - final ConfigSnapshot modificationSnapshot = new ConfigSnapshot(modification); - final DOMDataReadOnlyTransaction afterTx = new VppReadOnlyTransaction(EMPTY_OPERATIONAL, modificationSnapshot); - try(final WriteContext ctx = new TransactionWriteContext(serializer, beforeTx, afterTx)) { - writer.update(nodesBefore, nodesAfter, ctx); - } catch (io.fd.honeycomb.v3po.translate.write.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 (io.fd.honeycomb.v3po.translate.write.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 (TranslationException e) { - LOG.error("Error while processing data change (before={}, after={})", nodesBefore, nodesAfter, e); - throw e; - } - - dataTree.commit(candidate); - } - - private Map, DataObject> extractNetconfData( - final Optional> parentOptional) { - if (parentOptional.isPresent()) { - final DataContainerNode parent = (DataContainerNode) parentOptional.get(); - return DataTreeUtils.childrenFromNormalized(parent, serializer); - } - return Collections.emptyMap(); - } - - private final static class ConfigSnapshot implements VppDataTreeSnapshot { - private final DataTreeSnapshot snapshot; - - ConfigSnapshot(@Nonnull final DataTreeSnapshot snapshot) { - this.snapshot = snapshot; - } - - @Override - public CheckedFuture>, ReadFailedException> read( - @Nonnull final YangInstanceIdentifier path) { - final Optional> node = snapshot.readNode(path); - if (LOG.isTraceEnabled() && node.isPresent()) { - LOG.trace("ConfigSnapshot.read: {}", node.get()); - } - return Futures.immediateCheckedFuture(node); - } - - @Override - public DataTreeModification newModification() { - return snapshot.newModification(); - } - } -} - - - diff --git a/v3po/impl/src/main/java/io/fd/honeycomb/v3po/impl/data/VppDataBroker.java b/v3po/impl/src/main/java/io/fd/honeycomb/v3po/impl/data/VppDataBroker.java deleted file mode 100644 index 97697da65..000000000 --- a/v3po/impl/src/main/java/io/fd/honeycomb/v3po/impl/data/VppDataBroker.java +++ /dev/null @@ -1,95 +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.impl.data; - -import com.google.common.base.Preconditions; -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; - -/** - * Data Broker which provides data transaction functionality for VPP using {@link NormalizedNode} data format. - */ -public class VppDataBroker implements DOMDataBroker { - - private final ReadableVppDataTree operationalData; - private final VppDataTree configDataTree; - - /** - * Creates VppDataBroker instance. - * - * @param operationalData VPP operational data - * @param configDataTree VPP configuration data - */ - public VppDataBroker(@Nonnull final ReadableVppDataTree operationalData, - @Nonnull final VppDataTree configDataTree) { - this.operationalData = Preconditions.checkNotNull(operationalData, "operationalData should not be null"); - this.configDataTree = Preconditions.checkNotNull(configDataTree, "configDataProxy should not be null"); - } - - @Override - public DOMDataReadOnlyTransaction newReadOnlyTransaction() { - return new VppReadOnlyTransaction(operationalData, configDataTree.takeSnapshot()); - } - - @Override - public DOMDataReadWriteTransaction newReadWriteTransaction() { - // todo use the same snapshot - final VppDataTreeSnapshot configSnapshot = configDataTree.takeSnapshot(); - final DOMDataReadOnlyTransaction readOnlyTx = new VppReadOnlyTransaction(operationalData, configSnapshot); - final DOMDataWriteTransaction writeOnlyTx = new VppWriteTransaction(configDataTree, configSnapshot); - return new ReadWriteTransaction(readOnlyTx, writeOnlyTx); - } - - @Override - public DOMDataWriteTransaction newWriteOnlyTransaction() { - return new VppWriteTransaction(configDataTree); - } - - @Override - public ListenerRegistration 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, DOMDataBrokerExtension> getSupportedExtensions() { - return Collections.emptyMap(); - } -} - - diff --git a/v3po/impl/src/main/java/io/fd/honeycomb/v3po/impl/data/VppDataBrokerInitializationProvider.java b/v3po/impl/src/main/java/io/fd/honeycomb/v3po/impl/data/VppDataBrokerInitializationProvider.java deleted file mode 100644 index bdfc89079..000000000 --- a/v3po/impl/src/main/java/io/fd/honeycomb/v3po/impl/data/VppDataBrokerInitializationProvider.java +++ /dev/null @@ -1,277 +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.impl.data; - -import static com.google.common.base.Preconditions.checkNotNull; - -import com.google.common.base.Optional; -import com.google.common.base.Preconditions; -import com.google.common.util.concurrent.AsyncFunction; -import com.google.common.util.concurrent.Futures; -import com.google.common.util.concurrent.ListenableFuture; -import io.fd.honeycomb.v3po.impl.LoggingFuturesCallBack; -import io.fd.honeycomb.v3po.translate.read.ReaderRegistry; -import java.util.Collection; -import java.util.Collections; -import javassist.ClassPool; -import javax.annotation.Nonnull; -import org.opendaylight.controller.md.sal.binding.api.DataBroker; -import org.opendaylight.controller.md.sal.binding.api.ReadOnlyTransaction; -import org.opendaylight.controller.md.sal.binding.api.WriteTransaction; -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.DOMDataWriteTransaction; -import org.opendaylight.controller.md.sal.dom.api.DOMMountPoint; -import org.opendaylight.controller.md.sal.dom.api.DOMMountPointService; -import org.opendaylight.controller.sal.core.api.Broker; -import org.opendaylight.controller.sal.core.api.Provider; -import org.opendaylight.controller.sal.core.api.model.SchemaService; -import org.opendaylight.mdsal.binding.dom.codec.api.BindingNormalizedNodeSerializer; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.VppState; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.vpp.state.BridgeDomains; -import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NetworkTopology; -import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NodeId; -import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.TopologyId; -import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.Topology; -import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.TopologyKey; -import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node; -import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.NodeBuilder; -import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.NodeKey; -import org.opendaylight.yangtools.binding.data.codec.gen.impl.DataObjectSerializerGenerator; -import org.opendaylight.yangtools.binding.data.codec.gen.impl.StreamWriterGenerator; -import org.opendaylight.yangtools.binding.data.codec.impl.BindingNormalizedNodeCodecRegistry; -import org.opendaylight.yangtools.concepts.ObjectRegistration; -import org.opendaylight.yangtools.sal.binding.generator.impl.GeneratedClassLoadingStrategy; -import org.opendaylight.yangtools.sal.binding.generator.util.BindingRuntimeContext; -import org.opendaylight.yangtools.sal.binding.generator.util.JavassistUtils; -import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; -import org.opendaylight.yangtools.yang.binding.KeyedInstanceIdentifier; -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.TreeType; -import org.opendaylight.yangtools.yang.data.impl.schema.tree.InMemoryDataTreeFactory; -import org.opendaylight.yangtools.yang.model.api.SchemaContext; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -/** - * Creates VppDataBroker which uses DataTree instead of DataStore internally in order to obtain better control over the - * data processing in Honeycomb agent - */ -public final class VppDataBrokerInitializationProvider implements Provider, AutoCloseable { - - private static final Logger LOG = LoggerFactory.getLogger(VppDataBrokerInitializationProvider.class); - - private final TopologyId VPP_TOPOLOGY_ID = TopologyId.getDefaultInstance("vpp-topology"); - private final NodeId VPP_TOPOLOGY_NODE_ID = NodeId.getDefaultInstance("vpp"); - private final DataBroker bindingBroker; - private final ReaderRegistry readerRegistry; - private final InstanceIdentifier mountPointPath; - private final WriterRegistry writerRegistry; - private ObjectRegistration mountPointRegistration; - private DOMDataBroker broker; - - public VppDataBrokerInitializationProvider(@Nonnull final DataBroker bindingBroker, - final ReaderRegistry readerRegistry, - final WriterRegistry writerRegistry) { - this.bindingBroker = checkNotNull(bindingBroker, "bindingBroker should not be null"); - this.readerRegistry = checkNotNull(readerRegistry, "readerRegistry should not be null"); - this.writerRegistry = checkNotNull(writerRegistry, "writerRegistry should not be null"); - this.mountPointPath = getMountPointPath(); - } - - // TODO make configurable - private InstanceIdentifier getMountPointPath() { - final InstanceIdentifier networkTopology = - InstanceIdentifier.builder(NetworkTopology.class).build(); - final KeyedInstanceIdentifier topology = - networkTopology.child(Topology.class, new TopologyKey(VPP_TOPOLOGY_ID)); - return topology.child(Node.class, new NodeKey(VPP_TOPOLOGY_NODE_ID)); - } - - @Override - public void onSessionInitiated(final Broker.ProviderSession providerSession) { - LOG.info("Session initialized, providerSession={}", providerSession); - Preconditions.checkState(!isMountPointRegistered(), "Mount point is already registered"); - - final DOMMountPointService mountPointService = providerSession.getService(DOMMountPointService.class); - final SchemaService schemaService = providerSession.getService(SchemaService.class); - - final SchemaContext globalContext = schemaService.getGlobalContext(); - final BindingNormalizedNodeSerializer serializer = initSerializer(globalContext); - final YangInstanceIdentifier path = serializer.toYangInstanceIdentifier(mountPointPath); - - final DOMMountPointService.DOMMountPointBuilder mountPointBuilder = mountPointService.createMountPoint(path); - mountPointBuilder.addInitialSchemaContext(globalContext); - - broker = initVppDataBroker(globalContext, serializer); - mountPointBuilder.addService(DOMDataBroker.class, broker); - - mountPointRegistration = mountPointBuilder.register(); - final DOMMountPoint mountPoint = mountPointRegistration.getInstance(); - LOG.debug("Created mountPoint: identifier={}, schemaContext={}", mountPoint.getIdentifier(), - mountPoint.getSchemaContext()); - - createMountPointPlaceholder(); - - initialVppConfigSynchronization(broker); - } - - @Override - public Collection getProviderFunctionality() { - return Collections.EMPTY_LIST; - } - - private boolean isMountPointRegistered() { - final ReadOnlyTransaction readTx = bindingBroker.newReadOnlyTransaction(); - try { - final Optional cfgPlaceholder = - readTx.read(LogicalDatastoreType.CONFIGURATION, mountPointPath).checkedGet(); - final Optional operPlaceholder = - readTx.read(LogicalDatastoreType.OPERATIONAL, mountPointPath).checkedGet(); - return cfgPlaceholder.isPresent() || operPlaceholder.isPresent(); - } catch (ReadFailedException e) { - throw new IllegalStateException("Failed to read mountpoint placeholder data", e); - } - } - - private BindingNormalizedNodeSerializer initSerializer(final SchemaContext globalContext) { - final JavassistUtils utils = JavassistUtils.forClassPool(ClassPool.getDefault()); - // TODO this produces ClassNotFoundException - //final GeneratedClassLoadingStrategy loading = GeneratedClassLoadingStrategy.getTCCLClassLoadingStrategy(); - - // FIXME get global class loader instance - final GeneratedClassLoadingStrategy loadingStrategy = - new GeneratedClassLoadingStrategy() { - @Override - public Class loadClass(final String fullyQualifiedName) - throws ClassNotFoundException { - return Class.forName(fullyQualifiedName); - } - }; - final DataObjectSerializerGenerator generator = StreamWriterGenerator.create(utils); - - // TODO make configurable: - final BindingNormalizedNodeCodecRegistry serializer = new BindingNormalizedNodeCodecRegistry(generator); - final BindingRuntimeContext context = BindingRuntimeContext.create(loadingStrategy, globalContext); - serializer.onBindingRuntimeContextUpdated(context); - return serializer; - } - - private DOMDataBroker initVppDataBroker(final SchemaContext globalContext, - final BindingNormalizedNodeSerializer serializer) { - final ReadableVppDataTree operationalData = - new VppOperationalDataTree(serializer, globalContext, readerRegistry); // TODO make configurable - - final DataTree dataTree = - InMemoryDataTreeFactory.getInstance().create(TreeType.CONFIGURATION); // TODO make configurable - dataTree.setSchemaContext(globalContext); - - final VppDataTree configDataProxy = new VppConfigDataTree(serializer, dataTree, writerRegistry); // TODO make configurable - return new VppDataBroker(operationalData, configDataProxy); - } - - /** - * Writes placeholder data into MD-SAL's global datastore to indicate the presence of VPP mountpoint. - */ - private void createMountPointPlaceholder() { - final NodeBuilder nodeBuilder = new NodeBuilder(); - nodeBuilder.setKey(new NodeKey(VPP_TOPOLOGY_NODE_ID)); - final Node node = nodeBuilder.build(); - - final WriteTransaction writeTx = bindingBroker.newWriteOnlyTransaction(); - writeTx.merge(LogicalDatastoreType.CONFIGURATION, mountPointPath, node, true); - writeTx.merge(LogicalDatastoreType.OPERATIONAL, mountPointPath, node, true); - - try { - writeTx.submit().checkedGet(); - } catch (TransactionCommitFailedException e) { - throw new IllegalStateException("Failed to create mountpoint placeholder", e); - } - } - - // TODO operational and config models are not 1-1 - // decide what part of operational data should be written to config during initialization - private void initialVppConfigSynchronization(final DOMDataBroker broker) { - // read from operational - final DOMDataReadOnlyTransaction readTx = broker.newReadOnlyTransaction(); - - final YangInstanceIdentifier - id = YangInstanceIdentifier.builder().node(VppState.QNAME).node(BridgeDomains.QNAME).build(); - - LOG.trace("initialVppStateSynchronization id: {}", id); - - final ListenableFuture writeFuture = Futures.transform( - readTx.read(LogicalDatastoreType.OPERATIONAL, id), - new AsyncFunction>, Void>() { - @Override - public ListenableFuture apply(final Optional> readResult) - throws Exception { - if (readResult.isPresent()) { - final DOMDataWriteTransaction writeTx = broker.newWriteOnlyTransaction(); - final NormalizedNode node = readResult.get(); - LOG.trace("Read result: {}", node); - - // FIXME - // this will fail because we are reading OPERATIONAL data and writing to CONFIGURATION - // we need to provide extensible way to register initializer that would - // translate between models - - // writeTx.put(LogicalDatastoreType.CONFIGURATION, id, node); - return writeTx.submit(); - } else { - return Futures - .immediateFailedFuture( - new IllegalStateException("Failed to read data from VPP.")); - } - } - }); - - Futures.addCallback(writeFuture, - new LoggingFuturesCallBack("Initializing VPP config DataTree failed", LOG)); - } - - public Optional getBroker() { - return Optional.fromNullable(broker); - } - - @Override - public void close() throws Exception { - if (mountPointRegistration != null) { - mountPointRegistration.close(); - } - - if (broker != null) { - broker = null; - } - - // remove MD-SAL placeholder data for VPP mount point: - final WriteTransaction rwTx = bindingBroker.newWriteOnlyTransaction(); - // does not fail if data is not present: - rwTx.delete(LogicalDatastoreType.CONFIGURATION, mountPointPath); - try { - rwTx.submit().checkedGet(); - } catch (TransactionCommitFailedException e) { - throw new IllegalStateException("Failed to remove mountpoint's placeholder from MD-SAL's global datastore", - e); - } - } -} diff --git a/v3po/impl/src/main/java/io/fd/honeycomb/v3po/impl/data/VppDataTree.java b/v3po/impl/src/main/java/io/fd/honeycomb/v3po/impl/data/VppDataTree.java deleted file mode 100644 index aba8ab133..000000000 --- a/v3po/impl/src/main/java/io/fd/honeycomb/v3po/impl/data/VppDataTree.java +++ /dev/null @@ -1,44 +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.impl.data; - -import com.google.common.annotations.Beta; -import io.fd.honeycomb.v3po.translate.TranslationException; -import org.opendaylight.yangtools.yang.data.api.schema.tree.DataTreeModification; -import org.opendaylight.yangtools.yang.data.api.schema.tree.DataValidationFailedException; - -/** - * Facade over VPP data tree that allows tree modification. - */ -@Beta -public interface VppDataTree { - /** - * Commits modification to VPP data tree. - * - * @param modification VPP data tree modification - * @throws DataValidationFailedException if modification data is not valid - * @throws TranslationException if commit failed while updating VPP state - */ - void commit(final DataTreeModification modification) throws DataValidationFailedException, TranslationException; - - /** - * Creates read-only snapshot of a VppDataTree. - * - * @return Data tree snapshot. - */ - VppDataTreeSnapshot takeSnapshot(); -} diff --git a/v3po/impl/src/main/java/io/fd/honeycomb/v3po/impl/data/VppDataTreeSnapshot.java b/v3po/impl/src/main/java/io/fd/honeycomb/v3po/impl/data/VppDataTreeSnapshot.java deleted file mode 100644 index f4d68306f..000000000 --- a/v3po/impl/src/main/java/io/fd/honeycomb/v3po/impl/data/VppDataTreeSnapshot.java +++ /dev/null @@ -1,34 +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.impl.data; - -import com.google.common.annotations.Beta; -import org.opendaylight.yangtools.yang.data.api.schema.tree.DataTreeModification; - -/** - * Read-only snapshot of a {@link ReadableVppDataTree}. - */ -@Beta -public interface VppDataTreeSnapshot extends ReadableVppDataTree { - - /** - * Creates a new VPP data tree modification. - * - * @return A new data tree modification - */ - DataTreeModification newModification(); -} diff --git a/v3po/impl/src/main/java/io/fd/honeycomb/v3po/impl/data/VppOperationalDataTree.java b/v3po/impl/src/main/java/io/fd/honeycomb/v3po/impl/data/VppOperationalDataTree.java deleted file mode 100644 index 8f606fdbf..000000000 --- a/v3po/impl/src/main/java/io/fd/honeycomb/v3po/impl/data/VppOperationalDataTree.java +++ /dev/null @@ -1,209 +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.impl.data; - -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.translate.Context; -import io.fd.honeycomb.v3po.translate.read.ReadContext; -import io.fd.honeycomb.v3po.translate.read.ReadFailedException; -import io.fd.honeycomb.v3po.translate.read.ReaderRegistry; -import java.util.Collection; -import java.util.Map; -import javax.annotation.Nonnull; -import javax.annotation.Nullable; -import org.opendaylight.mdsal.binding.dom.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; - -/** - * ReadableVppDataTree implementation for operational data. - */ -public final class VppOperationalDataTree implements ReadableVppDataTree { - private static final Logger LOG = LoggerFactory.getLogger(VppOperationalDataTree.class); - - private final BindingNormalizedNodeSerializer serializer; - private final ReaderRegistry readerRegistry; - private final SchemaContext globalContext; - - /** - * 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 VPP APIs. - */ - public VppOperationalDataTree(@Nonnull BindingNormalizedNodeSerializer serializer, - @Nonnull final SchemaContext globalContext, @Nonnull ReaderRegistry readerRegistry) { - this.globalContext = checkNotNull(globalContext, "serializer 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>, - org.opendaylight.controller.md.sal.common.api.data.ReadFailedException> read( - @Nonnull final YangInstanceIdentifier yangInstanceIdentifier) { - - try(ReadContext ctx = new ReadContextImpl()) { - if (checkNotNull(yangInstanceIdentifier).equals(YangInstanceIdentifier.EMPTY)) { - return Futures.immediateCheckedFuture(readRoot(ctx)); - } else { - return Futures.immediateCheckedFuture(readNode(yangInstanceIdentifier, ctx)); - } - } catch (ReadFailedException e) { - return Futures.immediateFailedCheckedFuture( - new org.opendaylight.controller.md.sal.common.api.data.ReadFailedException( - "Failed to read VPP data", e)); - } - } - - private Optional> readNode(final YangInstanceIdentifier yangInstanceIdentifier, - final ReadContext ctx) - throws ReadFailedException { - LOG.debug("VppOperationalDataTree.readNode(), yangInstanceIdentifier={}", yangInstanceIdentifier); - final InstanceIdentifier path = serializer.fromYangInstanceIdentifier(yangInstanceIdentifier); - checkNotNull(path, "Invalid instance identifier %s. Cannot create BA equivalent.", yangInstanceIdentifier); - LOG.debug("VppOperationalDataTree.readNode(), path={}", path); - - final Optional dataObject; - - dataObject = readerRegistry.read(path, ctx); - if (dataObject.isPresent()) { - final NormalizedNode value = toNormalizedNodeFunction(path).apply(dataObject.get()); - return Optional.>fromNullable(value); - } else { - return Optional.absent(); - } - } - - private Optional> readRoot(final ReadContext ctx) throws ReadFailedException { - LOG.debug("VppOperationalDataTree.readRoot()"); - - final DataContainerNodeAttrBuilder dataNodeBuilder = - Builders.containerBuilder() - .withNodeIdentifier(new YangInstanceIdentifier.NodeIdentifier(SchemaContext.NAME)); - - final Multimap, ? extends DataObject> dataObjects = - readerRegistry.readAll(ctx); - - for (final InstanceIdentifier instanceIdentifier : dataObjects.keySet()) { - final YangInstanceIdentifier rootElementId = serializer.toYangInstanceIdentifier(instanceIdentifier); - final NormalizedNode node = - wrapDataObjects(rootElementId, instanceIdentifier, dataObjects.get(instanceIdentifier)); - dataNodeBuilder.withChild((DataContainerChild) node); - } - - return Optional.>of(dataNodeBuilder.build()); - } - - private NormalizedNode wrapDataObjects(final YangInstanceIdentifier yangInstanceIdentifier, - final InstanceIdentifier instanceIdentifier, - final Collection dataObjects) { - final Collection> 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> normalizedRootElements, final ListSchemaNode listSchema) { - if (listSchema.getKeyDefinition().isEmpty()) { - final CollectionNodeBuilder listBuilder = - Builders.unkeyedListBuilder(); - for (NormalizedNode normalizedRootElement : normalizedRootElements) { - listBuilder.withChild((UnkeyedListEntryNode) normalizedRootElement); - } - return listBuilder.build(); - } else { - final CollectionNodeBuilder listBuilder = - listSchema.isUserOrdered() - ? Builders.orderedMapBuilder() - : Builders.mapBuilder(); - - for (NormalizedNode normalizedRootElement : normalizedRootElements) { - listBuilder.withChild((MapEntryNode) normalizedRootElement); - } - return listBuilder.build(); - } - } - - @SuppressWarnings("unchecked") - private Function> toNormalizedNodeFunction(final InstanceIdentifier path) { - return new Function>() { - @Override - public NormalizedNode apply(@Nullable final DataObject dataObject) { - LOG.trace("VppOperationalDataTree.toNormalizedNode(), path={}, dataObject={}", path, dataObject); - final Map.Entry> entry = - serializer.toNormalizedNode(path, dataObject); - - LOG.trace("VppOperationalDataTree.toNormalizedNode(), normalizedNodeEntry={}", entry); - return entry.getValue(); - } - }; - } - - private static final class ReadContextImpl implements ReadContext { - public final Context ctx = new Context(); - - @Nonnull - @Override - public Context getContext() { - return ctx; - } - - @Override - public void close() { - // Make sure to clear the storage in case some customizer stored it to prevent memory leaks - ctx.close(); - } - } -} diff --git a/v3po/impl/src/main/java/io/fd/honeycomb/v3po/impl/data/VppReadOnlyTransaction.java b/v3po/impl/src/main/java/io/fd/honeycomb/v3po/impl/data/VppReadOnlyTransaction.java deleted file mode 100644 index 94cef679f..000000000 --- a/v3po/impl/src/main/java/io/fd/honeycomb/v3po/impl/data/VppReadOnlyTransaction.java +++ /dev/null @@ -1,103 +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.impl.data; - -import com.google.common.base.Function; -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 com.google.common.util.concurrent.ListenableFuture; -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 VppReadOnlyTransaction implements DOMDataReadOnlyTransaction { - - private static final Logger LOG = LoggerFactory.getLogger(VppReadOnlyTransaction.class); - private volatile ReadableVppDataTree operationalData; - private volatile VppDataTreeSnapshot configSnapshot; - - VppReadOnlyTransaction(@Nonnull final ReadableVppDataTree operationalData, - @Nonnull final VppDataTreeSnapshot configSnapshot) { - this.operationalData = Preconditions.checkNotNull(operationalData, "operationalData should not be null"); - this.configSnapshot = Preconditions.checkNotNull(configSnapshot, "config should not be null"); - } - - @Override - public void close() { - configSnapshot = null; - operationalData = null; - } - - @Override - public CheckedFuture>, ReadFailedException> read( - final LogicalDatastoreType store, - final YangInstanceIdentifier path) { - LOG.debug("VppReadOnlyTransaction.read(), store={}, path={}", store, path); - - Preconditions.checkState(configSnapshot != null, "Transaction was closed"); - - if (store == LogicalDatastoreType.OPERATIONAL) { - return operationalData.read(path); - } else { - return configSnapshot.read(path); - } - } - - @Override - public CheckedFuture exists(final LogicalDatastoreType store, - final YangInstanceIdentifier path) { - LOG.debug("VppReadOnlyTransaction.exists() store={}, path={}", store, path); - - ListenableFuture 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; - } - - - private static final Function>, ? extends Boolean> IS_NODE_PRESENT = - new Function>, Boolean>() { - @Nullable - @Override - public Boolean apply(@Nullable final Optional> input) { - return input == null - ? Boolean.FALSE - : input.isPresent(); - } - }; - - private static final Function ANY_EX_TO_READ_FAILED_EXCEPTION_MAPPER = - new Function() { - @Override - public ReadFailedException apply(@Nullable final Exception e) { - return new ReadFailedException("Exists failed", e); - } - }; -} \ No newline at end of file diff --git a/v3po/impl/src/main/java/io/fd/honeycomb/v3po/impl/data/VppWriteTransaction.java b/v3po/impl/src/main/java/io/fd/honeycomb/v3po/impl/data/VppWriteTransaction.java deleted file mode 100644 index b33fffa68..000000000 --- a/v3po/impl/src/main/java/io/fd/honeycomb/v3po/impl/data/VppWriteTransaction.java +++ /dev/null @@ -1,145 +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.impl.data; - -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.translate.TranslationException; -import javax.annotation.Nonnull; -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.DataTreeModification; -import org.opendaylight.yangtools.yang.data.api.schema.tree.DataValidationFailedException; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -@NotThreadSafe -final class VppWriteTransaction implements DOMDataWriteTransaction { - - private static final Logger LOG = LoggerFactory.getLogger(VppWriteTransaction.class); - private final VppDataTree configDataTree; - private DataTreeModification modification; - private TransactionStatus status; - - VppWriteTransaction(@Nonnull final VppDataTree configDataTree, - @Nonnull final VppDataTreeSnapshot configSnapshot) { - this.configDataTree = Preconditions.checkNotNull(configDataTree, "configDataTree should not be null"); - Preconditions.checkNotNull(configSnapshot, "configSnapshot should not be null"); - // initialize transaction state: - modification = configSnapshot.newModification(); - status = NEW; - } - - VppWriteTransaction(@Nonnull final VppDataTree configDataTree) { - this(configDataTree, configDataTree.takeSnapshot()); - } - - private static void checkConfigurationWrite(final LogicalDatastoreType store) { - Preconditions.checkArgument(LogicalDatastoreType.CONFIGURATION == store, "Write is not supported for operational data store"); - } - - private void checkIsNew() { - Preconditions.checkState(status == NEW, "Transaction was submitted or canceled"); - Preconditions.checkState(modification != null, "VPPDataTree modification should not be null"); - } - - @Override - public void put(final LogicalDatastoreType store, final YangInstanceIdentifier path, - final NormalizedNode data) { - LOG.debug("VppWriteTransaction.put() store={}, path={}, data={}", store, path, data); - checkIsNew(); - checkConfigurationWrite(store); - modification.write(path, data); - } - - @Override - public void merge(final LogicalDatastoreType store, final YangInstanceIdentifier path, - final NormalizedNode data) { - LOG.debug("VppWriteTransaction.merge() store={}, path={}, data={}", store, path, data); - checkIsNew(); - checkConfigurationWrite(store); - modification.merge(path, data); - } - - @Override - public boolean cancel() { - if (status != NEW) { - // only NEW transactions can be cancelled - return false; - } else { - status = CANCELED; - modification = null; - return true; - } - } - - @Override - public void delete(LogicalDatastoreType store, final YangInstanceIdentifier path) { - LOG.debug("VppWriteTransaction.delete() store={}, path={}", store, path); - checkIsNew(); - checkConfigurationWrite(store); - modification.delete(path); - } - - @Override - public CheckedFuture submit() { - LOG.debug("VppWriteTransaction.submit()"); - checkIsNew(); - - // seal transaction: - modification.ready(); - status = SUBMITED; - - try { - configDataTree.commit(modification); - status = COMMITED; - } catch (DataValidationFailedException | TranslationException e) { - status = FAILED; - LOG.error("Failed to commit VPP state modification", e); - return Futures.immediateFailedCheckedFuture( - new TransactionCommitFailedException("Failed to validate DataTreeModification", e)); - } finally { - modification = null; - } - return Futures.immediateCheckedFuture(null); - } - - @Override - @Deprecated - public ListenableFuture> commit() { - throw new UnsupportedOperationException("deprecated"); - } - - @Override - public Object getIdentifier() { - return this; - } -} diff --git a/v3po/impl/src/main/java/io/fd/honeycomb/v3po/impl/data/WriterRegistry.java b/v3po/impl/src/main/java/io/fd/honeycomb/v3po/impl/data/WriterRegistry.java deleted file mode 100644 index 00dc22520..000000000 --- a/v3po/impl/src/main/java/io/fd/honeycomb/v3po/impl/data/WriterRegistry.java +++ /dev/null @@ -1,104 +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.impl.data; - -import io.fd.honeycomb.v3po.translate.TranslationException; -import io.fd.honeycomb.v3po.translate.util.RWUtils; -import io.fd.honeycomb.v3po.translate.impl.write.CompositeChildWriter; -import io.fd.honeycomb.v3po.translate.impl.write.CompositeListWriter; -import io.fd.honeycomb.v3po.translate.impl.write.CompositeRootWriter; -import io.fd.honeycomb.v3po.translate.util.write.DelegatingWriterRegistry; -import io.fd.honeycomb.v3po.translate.util.write.NoopWriterCustomizer; -import io.fd.honeycomb.v3po.translate.util.write.ReflexiveChildWriterCustomizer; -import io.fd.honeycomb.v3po.translate.v3po.vpp.BridgeDomainCustomizer; -import io.fd.honeycomb.v3po.translate.write.ChildWriter; -import io.fd.honeycomb.v3po.translate.write.Writer; -import io.fd.honeycomb.v3po.translate.write.WriteContext; -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; -import java.util.Map; -import javax.annotation.Nonnull; -import javax.annotation.Nullable; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.Vpp; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.vpp.BridgeDomains; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.vpp.bridge.domains.BridgeDomain; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.vpp.bridge.domains.BridgeDomainKey; -import org.opendaylight.yangtools.yang.binding.ChildOf; -import org.opendaylight.yangtools.yang.binding.DataObject; -import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; -import org.openvpp.vppjapi.vppApi; - -// TODO use some DI framework instead of singleton -public class WriterRegistry implements io.fd.honeycomb.v3po.translate.write.WriterRegistry { - - private static WriterRegistry instance; - - private final DelegatingWriterRegistry writer; - - private WriterRegistry(@Nonnull final vppApi vppApi) { - final CompositeRootWriter vppWriter = initVppStateWriter(vppApi); - writer = new DelegatingWriterRegistry(Collections.>singletonList(vppWriter)); - } - - private static CompositeRootWriter initVppStateWriter(@Nonnull final vppApi vppApi) { - final CompositeListWriter bridgeDomainWriter = new CompositeListWriter<>( - BridgeDomain.class, - new BridgeDomainCustomizer(vppApi)); - - final ChildWriter bridgeDomainsWriter = new CompositeChildWriter<>( - BridgeDomains.class, - RWUtils.singletonChildWriterList(bridgeDomainWriter), - new ReflexiveChildWriterCustomizer()); - - final List>> childWriters = new ArrayList<>(); - childWriters.add(bridgeDomainsWriter); - - return new CompositeRootWriter<>( - Vpp.class, - childWriters, - new NoopWriterCustomizer()); - } - - public static synchronized WriterRegistry getInstance(@Nonnull final vppApi vppApi) { - if (instance == null) { - instance = new WriterRegistry(vppApi); - } - return instance; - } - - @Nonnull - @Override - public InstanceIdentifier getManagedDataObjectType() { - return writer.getManagedDataObjectType(); - } - - @Override - public void update(@Nonnull final InstanceIdentifier id, - @Nullable final DataObject dataBefore, - @Nullable final DataObject data, @Nonnull final WriteContext ctx) throws TranslationException { - writer.update(id, dataBefore, data, ctx); - } - - @Override - public void update(@Nonnull final Map, DataObject> dataBefore, - @Nonnull final Map, DataObject> dataAfter, - @Nonnull final WriteContext ctx) - throws TranslationException { - writer.update(dataBefore, dataAfter, ctx); - } -} -- cgit 1.2.3-korg