2 * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
4 * This program and the accompanying materials are made available under the
5 * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6 * and is available at http://www.eclipse.org/legal/epl-v10.html
9 package org.opendaylight.netconf.topology.impl;
11 import com.google.common.base.Preconditions;
12 import com.google.common.util.concurrent.CheckedFuture;
13 import com.google.common.util.concurrent.FutureCallback;
14 import com.google.common.util.concurrent.Futures;
15 import javax.annotation.Nonnull;
16 import org.opendaylight.controller.md.sal.binding.api.BindingTransactionChain;
17 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
18 import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
19 import org.opendaylight.controller.md.sal.common.api.data.AsyncTransaction;
20 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
21 import org.opendaylight.controller.md.sal.common.api.data.TransactionChain;
22 import org.opendaylight.controller.md.sal.common.api.data.TransactionChainListener;
23 import org.opendaylight.controller.md.sal.common.api.data.TransactionCommitFailedException;
24 import org.opendaylight.netconf.topology.util.NodeWriter;
25 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NetworkTopology;
26 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NetworkTopologyBuilder;
27 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NodeId;
28 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.TopologyId;
29 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.Topology;
30 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.TopologyBuilder;
31 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.TopologyKey;
32 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node;
33 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.NodeKey;
34 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
35 import org.opendaylight.yangtools.yang.binding.KeyedInstanceIdentifier;
36 import org.opendaylight.yangtools.yang.common.QName;
37 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
38 import org.slf4j.Logger;
39 import org.slf4j.LoggerFactory;
41 public class TopologyNodeWriter implements NodeWriter{
43 private static final Logger LOG = LoggerFactory.getLogger(TopologyNodeWriter.class);
45 private final String topologyId;
46 private final BindingTransactionChain txChain;
48 private final InstanceIdentifier<NetworkTopology> networkTopologyPath;
49 private final KeyedInstanceIdentifier<Topology, TopologyKey> topologyListPath;
51 public TopologyNodeWriter(final String topologyId, final DataBroker dataBroker) {
52 this.topologyId = topologyId;
53 this.txChain = Preconditions.checkNotNull(dataBroker).createTransactionChain(new TransactionChainListener() {
55 public void onTransactionChainFailed(TransactionChain<?, ?> chain, AsyncTransaction<?, ?> transaction, Throwable cause) {
56 LOG.error("{}: TransactionChain({}) {} FAILED!", chain,
57 transaction.getIdentifier(), cause);
58 throw new IllegalStateException("Clustered topology writer TransactionChain(" + chain + ") not committed correctly", cause);
62 public void onTransactionChainSuccessful(TransactionChain<?, ?> chain) {
63 LOG.trace("Clustered topology writer TransactionChain({}) SUCCESSFUL", chain);
67 this.networkTopologyPath = InstanceIdentifier.builder(NetworkTopology.class).build();
68 this.topologyListPath = networkTopologyPath.child(Topology.class, new TopologyKey(new TopologyId(topologyId)));
72 public void init(@Nonnull NodeId id, @Nonnull Node operationalDataNode) {
73 final WriteTransaction writeTx = txChain.newWriteOnlyTransaction();
75 createNetworkTopologyIfNotPresent(writeTx);
76 final InstanceIdentifier<Node> path = createBindingPathForTopology(new NodeKey(id), topologyId);
78 LOG.trace("{}: Init device state transaction {} putting if absent operational data started. Putting data on path {}",
79 id.getValue(), writeTx.getIdentifier(), path);
80 writeTx.put(LogicalDatastoreType.OPERATIONAL, path, operationalDataNode);
81 LOG.trace("{}: Init device state transaction {} putting operational data ended.",
82 id.getValue(), writeTx.getIdentifier());
84 commitTransaction(writeTx, "init", id);
88 public void update(@Nonnull NodeId id, @Nonnull Node operationalDataNode) {
89 final WriteTransaction writeTx = txChain.newWriteOnlyTransaction();
91 final InstanceIdentifier<Node> path = createBindingPathForTopology(new NodeKey(id), topologyId);
92 LOG.trace("{}: Update device state transaction {} merging operational data started. Putting data on path {}",
93 id, writeTx.getIdentifier(), operationalDataNode);
94 writeTx.put(LogicalDatastoreType.OPERATIONAL, path, operationalDataNode);
95 LOG.trace("{}: Update device state transaction {} merging operational data ended.",
96 id, writeTx.getIdentifier());
98 commitTransaction(writeTx, "update", id);
102 public void delete(@Nonnull NodeId id) {
103 final WriteTransaction writeTx = txChain.newWriteOnlyTransaction();
105 final InstanceIdentifier<Node> path = createBindingPathForTopology(new NodeKey(id), topologyId);
108 "{}: Close device state transaction {} removing all data started. Path: {}",
109 id, writeTx.getIdentifier(), path);
110 writeTx.delete(LogicalDatastoreType.OPERATIONAL, path);
112 "{}: Close device state transaction {} removing all data ended.",
113 id, writeTx.getIdentifier());
115 commitTransaction(writeTx, "close", id);
118 private void commitTransaction(final WriteTransaction transaction, final String txType, final NodeId id) {
119 LOG.trace("{}: Committing Transaction {}:{}", id.getValue(), txType,
120 transaction.getIdentifier());
121 final CheckedFuture<Void, TransactionCommitFailedException> result = transaction.submit();
123 Futures.addCallback(result, new FutureCallback<Void>() {
125 public void onSuccess(final Void result) {
126 LOG.trace("{}: Transaction({}) {} SUCCESSFUL", id.getValue(), txType,
127 transaction.getIdentifier());
131 public void onFailure(final Throwable t) {
132 LOG.error("{}: Transaction({}) {} FAILED!", id.getValue(), txType,
133 transaction.getIdentifier(), t);
134 throw new IllegalStateException(id.getValue() + " Transaction(" + txType + ") not committed correctly", t);
139 private void createNetworkTopologyIfNotPresent(final WriteTransaction writeTx) {
141 final NetworkTopology networkTopology = new NetworkTopologyBuilder().build();
142 LOG.trace("{}: Merging {} container to ensure its presence", topologyId,
143 NetworkTopology.QNAME, writeTx.getIdentifier());
144 writeTx.merge(LogicalDatastoreType.OPERATIONAL, networkTopologyPath, networkTopology);
146 final Topology topology = new TopologyBuilder().setTopologyId(new TopologyId(topologyId)).build();
147 LOG.trace("{}: Merging {} container to ensure its presence", topologyId,
148 Topology.QNAME, writeTx.getIdentifier());
149 writeTx.merge(LogicalDatastoreType.OPERATIONAL, topologyListPath, topology);
152 private static InstanceIdentifier<Node> createBindingPathForTopology(final NodeKey key, final String topologyId) {
153 final InstanceIdentifier<NetworkTopology> networkTopology = InstanceIdentifier.builder(NetworkTopology.class).build();
154 final KeyedInstanceIdentifier<Topology, TopologyKey> topology = networkTopology.child(Topology.class, new TopologyKey(new TopologyId(topologyId)));
156 .child(Node.class, new NodeKey(new NodeId(key.getNodeId().getValue())));
159 private static org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier createBIPathForTopology(final String name, final String topologyId) {
160 final YangInstanceIdentifier.InstanceIdentifierBuilder builder = YangInstanceIdentifier.builder();
162 .node(NetworkTopology.QNAME)
163 .node(Topology.QNAME)
164 .nodeWithKey(Topology.QNAME, QName.create(Topology.QNAME, "topology-id"), topologyId)
166 .nodeWithKey(Node.QNAME, QName.create(Node.QNAME, "node-id"), name);
167 return builder.build();