Bug-1741: Fix read/write operations 99/10899/2
authorMilos Fabian <milfabia@cisco.com>
Mon, 8 Sep 2014 12:01:43 +0000 (14:01 +0200)
committerMilos Fabian <milfabia@cisco.com>
Mon, 8 Sep 2014 12:11:37 +0000 (14:11 +0200)
Change-Id: I77c6ddef5ce38a8284eaa8f39a04cac9eda90a10
Signed-off-by: Milos Fabian <milfabia@cisco.com>
pcep/tunnel-provider/src/main/java/org/opendaylight/bgpcep/pcep/tunnel/provider/NodeChangedListener.java
pcep/tunnel-provider/src/main/java/org/opendaylight/bgpcep/pcep/tunnel/provider/TunnelProgramming.java

index 69aff5f670765a02f627da5f117ff25c723b3945..6c0a63c5a1a88c682c526365027d97b89ab3a515 100644 (file)
@@ -16,23 +16,24 @@ import com.google.common.util.concurrent.JdkFutureAdapters;
 import java.util.HashSet;
 import java.util.Map;
 import java.util.Set;
-import java.util.concurrent.ExecutionException;
 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
 import org.opendaylight.controller.md.sal.binding.api.DataChangeListener;
 import org.opendaylight.controller.md.sal.binding.api.ReadWriteTransaction;
 import org.opendaylight.controller.md.sal.common.api.data.AsyncDataChangeEvent;
 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
+import org.opendaylight.controller.md.sal.common.api.data.ReadFailedException;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.IpAddress;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.ietf.stateful.rev131222.AdministrativeStatus;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.ietf.stateful.rev131222.Path1;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.ietf.stateful.rev131222.lsp.identifiers.tlv.lsp.identifiers.AddressFamily;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.endpoints.address.family.Ipv4Case;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.endpoints.address.family.Ipv6Case;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.endpoints.address.family.ipv4._case.Ipv4;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.endpoints.address.family.ipv6._case.Ipv6;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.ietf.stateful.rev131222.lsp.identifiers.tlv.lsp.identifiers.address.family.Ipv4Case;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.ietf.stateful.rev131222.lsp.identifiers.tlv.lsp.identifiers.address.family.Ipv6Case;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.ietf.stateful.rev131222.lsp.identifiers.tlv.lsp.identifiers.address.family.ipv4._case.Ipv4;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.ietf.stateful.rev131222.lsp.identifiers.tlv.lsp.identifiers.address.family.ipv6._case.Ipv6;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.topology.pcep.rev131024.Node1;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.topology.pcep.rev131024.pcep.client.attributes.PathComputationClient;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.topology.pcep.rev131024.pcep.client.attributes.path.computation.client.ReportedLsp;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.topology.pcep.rev131024.pcep.client.attributes.path.computation.client.reported.lsp.Path;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.topology.tunnel.pcep.rev130820.Link1;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.topology.tunnel.pcep.rev130820.Link1Builder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.topology.tunnel.pcep.rev130820.SupportingNode1;
@@ -128,45 +129,50 @@ public final class NodeChangedListener implements DataChangeListener {
     }
 
     private InstanceIdentifier<TerminationPoint> getIpTerminationPoint(final ReadWriteTransaction trans, final IpAddress addr,
-            final InstanceIdentifier<Node> sni, final Boolean inControl) throws InterruptedException, ExecutionException {
-        for (final Node n : ((Topology) trans.read(LogicalDatastoreType.OPERATIONAL, this.target).get().get()).getNode()) {
-            for (final TerminationPoint tp : n.getTerminationPoint()) {
-                final TerminationPoint1 tpa = tp.getAugmentation(TerminationPoint1.class);
-
-                if (tpa != null) {
-                    final TerminationPointType tpt = tpa.getIgpTerminationPointAttributes().getTerminationPointType();
-
-                    if (tpt instanceof Ip) {
-                        for (final IpAddress a : ((Ip) tpt).getIpAddress()) {
-                            if (addr.equals(a.getIpv6Address())) {
-                                if (sni != null) {
-                                    final NodeKey k = InstanceIdentifier.keyOf(sni);
-                                    boolean have = false;
-
-                                    /*
-                                     * We may have found a termination point which has been created as a destination,
-                                     * so it does not have a supporting node pointer. Since we now know what it is,
-                                     * fill it in.
-                                     */
-                                    for (final SupportingNode sn : n.getSupportingNode()) {
-                                        if (sn.getNodeRef().equals(k.getNodeId())) {
-                                            have = true;
-                                            break;
+            final InstanceIdentifier<Node> sni, final Boolean inControl) throws ReadFailedException {
+        final Topology topo = trans.read(LogicalDatastoreType.OPERATIONAL, this.target).checkedGet().get();
+        if (topo.getNode() != null && !topo.getNode().isEmpty()) {
+            for (final Node n : topo.getNode()) {
+                if(n.getTerminationPoint() != null && !n.getTerminationPoint().isEmpty()) {
+                    for (final TerminationPoint tp : n.getTerminationPoint()) {
+                        final TerminationPoint1 tpa = tp.getAugmentation(TerminationPoint1.class);
+
+                        if (tpa != null) {
+                            final TerminationPointType tpt = tpa.getIgpTerminationPointAttributes().getTerminationPointType();
+
+                            if (tpt instanceof Ip) {
+                                for (final IpAddress a : ((Ip) tpt).getIpAddress()) {
+                                    if (addr.equals(a.getIpv6Address())) {
+                                        if (sni != null) {
+                                            final NodeKey k = InstanceIdentifier.keyOf(sni);
+                                            boolean have = false;
+
+                                            /*
+                                             * We may have found a termination point which has been created as a destination,
+                                             * so it does not have a supporting node pointer. Since we now know what it is,
+                                             * fill it in.
+                                             */
+                                            for (final SupportingNode sn : n.getSupportingNode()) {
+                                                if (sn.getNodeRef().equals(k.getNodeId())) {
+                                                    have = true;
+                                                    break;
+                                                }
+                                            }
+
+                                            if (!have) {
+                                                final SupportingNode sn = createSupportingNode(k.getNodeId(), inControl);
+
+                                                trans.put(LogicalDatastoreType.OPERATIONAL, this.target.child(Node.class, n.getKey()).child(
+                                                        SupportingNode.class, sn.getKey()), sn);
+                                            }
                                         }
-                                    }
-
-                                    if (!have) {
-                                        final SupportingNode sn = createSupportingNode(k.getNodeId(), inControl);
-
-                                        trans.put(LogicalDatastoreType.OPERATIONAL, this.target.child(Node.class, n.getKey()).child(
-                                                SupportingNode.class, sn.getKey()), sn);
+                                        return this.target.builder().child(Node.class, n.getKey()).child(TerminationPoint.class, tp.getKey()).toInstance();
                                     }
                                 }
-                                return this.target.builder().child(Node.class, n.getKey()).child(TerminationPoint.class, tp.getKey()).toInstance();
+                            } else {
+                                LOG.debug("Ignoring termination point type {}", tpt);
                             }
                         }
-                    } else {
-                        LOG.debug("Ignoring termination point type {}", tpt);
                     }
                 }
             }
@@ -195,7 +201,7 @@ public final class NodeChangedListener implements DataChangeListener {
         return nid.child(TerminationPoint.class, tpb.getKey());
     }
 
-    private void create(final ReadWriteTransaction trans, final InstanceIdentifier<ReportedLsp> i, final ReportedLsp value) throws InterruptedException, ExecutionException {
+    private void create(final ReadWriteTransaction trans, final InstanceIdentifier<ReportedLsp> i, final ReportedLsp value) throws ReadFailedException {
         final InstanceIdentifier<Node> ni = i.firstIdentifierOf(Node.class);
 
         final Path1 rl = value.getPath().get(0).getAugmentation(Path1.class);
@@ -208,19 +214,24 @@ public final class NodeChangedListener implements DataChangeListener {
         final IpAddress srcIp, dstIp;
         if (af instanceof Ipv4Case) {
             final Ipv4 ipv4 = ((Ipv4Case) af).getIpv4();
-            srcIp = new IpAddress(ipv4.getSourceIpv4Address());
-            dstIp = new IpAddress(ipv4.getDestinationIpv4Address());
+            srcIp = new IpAddress(ipv4.getIpv4TunnelSenderAddress());
+            dstIp = new IpAddress(ipv4.getIpv4TunnelEndpointAddress());
         } else if (af instanceof Ipv6Case) {
             final Ipv6 ipv6 = ((Ipv6Case) af).getIpv6();
-            srcIp = new IpAddress(ipv6.getSourceIpv6Address());
-            dstIp = new IpAddress(ipv6.getDestinationIpv6Address());
+            srcIp = new IpAddress(ipv6.getIpv6TunnelSenderAddress());
+            dstIp = new IpAddress(ipv6.getIpv6TunnelSenderAddress());
         } else {
             throw new IllegalArgumentException("Unsupported address family: " + af.getImplementedInterface());
         }
 
-        final Link1Builder lab = new Link1Builder(value.getPath().get(0).getLspa());
-        lab.setBandwidth(value.getPath().get(0).getBandwidth().getBandwidth());
-        lab.setClassType(value.getPath().get(0).getClassType().getClassType());
+        final Path path0 = value.getPath().get(0);
+        final Link1Builder lab = new Link1Builder();
+        if (path0.getBandwidth() != null) {
+            lab.setBandwidth(path0.getBandwidth().getBandwidth());
+        }
+        if (path0.getClassType() != null) {
+            lab.setClassType(path0.getClassType().getClassType());
+        }
         lab.setSymbolicPathName(value.getName());
 
         final InstanceIdentifier<TerminationPoint> dst = getIpTerminationPoint(trans, dstIp, null, Boolean.FALSE);
@@ -253,10 +264,10 @@ public final class NodeChangedListener implements DataChangeListener {
         return this.target.child(Node.class, new NodeKey(node));
     }
 
-    private void remove(final ReadWriteTransaction trans, final InstanceIdentifier<ReportedLsp> i, final ReportedLsp value) throws InterruptedException, ExecutionException {
+    private void remove(final ReadWriteTransaction trans, final InstanceIdentifier<ReportedLsp> i, final ReportedLsp value) throws ReadFailedException {
         final InstanceIdentifier<Link> li = linkForLsp(linkIdForLsp(i, value));
 
-        final Optional<Link> ol = trans.read(LogicalDatastoreType.OPERATIONAL, li).get();
+        final Optional<Link> ol = trans.read(LogicalDatastoreType.OPERATIONAL, li).checkedGet();
         if (!ol.isPresent()) {
             return;
         }
@@ -266,7 +277,7 @@ public final class NodeChangedListener implements DataChangeListener {
         trans.delete(LogicalDatastoreType.OPERATIONAL, li);
 
         LOG.debug("Searching for orphan links/nodes");
-        final Optional<Topology> ot = trans.read(LogicalDatastoreType.OPERATIONAL, this.target).get();
+        final Optional<Topology> ot = trans.read(LogicalDatastoreType.OPERATIONAL, this.target).checkedGet();
         Preconditions.checkState(ot.isPresent());
 
         final Topology t = (Topology) ot.get();
@@ -374,31 +385,36 @@ public final class NodeChangedListener implements DataChangeListener {
 
         // Get the subtrees
         final Map<InstanceIdentifier<?>, ? extends DataObject> o = change.getOriginalData();
-        final Map<InstanceIdentifier<?>, DataObject> n = change.getUpdatedData();
+        final Map<InstanceIdentifier<?>, DataObject> u = change.getUpdatedData();
+        final Map<InstanceIdentifier<?>, DataObject> c = change.getCreatedData();
 
         // Now walk all nodes, check for removals/additions and cascade them to LSPs
         for (final InstanceIdentifier<Node> i : nodes) {
             enumerateLsps(i, (Node) o.get(i), lsps);
-            enumerateLsps(i, (Node) n.get(i), lsps);
+            enumerateLsps(i, (Node) u.get(i), lsps);
+            enumerateLsps(i, (Node) c.get(i), lsps);
         }
 
         // We now have list of all affected LSPs. Walk them create/remove them
         for (final InstanceIdentifier<ReportedLsp> i : lsps) {
             final ReportedLsp oldValue = (ReportedLsp) o.get(i);
-            final ReportedLsp newValue = (ReportedLsp) n.get(i);
+            ReportedLsp newValue = (ReportedLsp) u.get(i);
+            if (newValue == null) {
+                newValue = (ReportedLsp) c.get(i);
+            }
 
             LOG.debug("Updating lsp {} value {} -> {}", i, oldValue, newValue);
             if (oldValue != null) {
                 try {
                     remove(trans, i, oldValue);
-                } catch (InterruptedException | ExecutionException e) {
+                } catch (ReadFailedException e) {
                     LOG.warn("Failed to remove LSP {}", i, e);
                 }
             }
             if (newValue != null) {
                 try {
                     create(trans, i, newValue);
-                } catch (InterruptedException | ExecutionException e) {
+                } catch (ReadFailedException e) {
                     LOG.warn("Failed to add LSP {}", i, e);
                 }
             }
index c13b8014355c54381dd1fd35247b702b11339bce..7bd10faf72cb8f5f5354a3c9da0eeeac4f12b1a3 100644 (file)
@@ -15,7 +15,6 @@ import com.google.common.util.concurrent.ListenableFuture;
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.List;
-import java.util.concurrent.ExecutionException;
 import org.opendaylight.bgpcep.pcep.topology.spi.AbstractInstructionExecutor;
 import org.opendaylight.bgpcep.programming.spi.InstructionScheduler;
 import org.opendaylight.bgpcep.programming.spi.SuccessfulRpcResult;
@@ -24,6 +23,7 @@ import org.opendaylight.bgpcep.programming.tunnel.TunnelProgrammingUtil;
 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
 import org.opendaylight.controller.md.sal.binding.api.ReadTransaction;
 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
+import org.opendaylight.controller.md.sal.common.api.data.ReadFailedException;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.IpAddress;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.ietf.stateful.rev131222.AdministrativeStatus;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.ietf.stateful.rev131222.Arguments2;
@@ -117,9 +117,9 @@ public final class TunnelProgramming implements TopologyTunnelPcepProgrammingSer
 
         private DataObject read(final InstanceIdentifier<?> id) {
             try {
-                return this.t.read(LogicalDatastoreType.OPERATIONAL, this.nii).get().get();
-            } catch (InterruptedException | ExecutionException e) {
-                throw new IllegalStateException("Failed to read " + id, e);
+                return this.t.read(LogicalDatastoreType.OPERATIONAL, id).checkedGet().get();
+            } catch (ReadFailedException | IllegalStateException e) {
+                throw new IllegalStateException("Failed to read data.", e);
             }
         }
 
@@ -250,11 +250,19 @@ public final class TunnelProgramming implements TopologyTunnelPcepProgrammingSer
 
                 // The link has to be non-existent
                 final InstanceIdentifier<Link> lii = NodeChangedListener.linkIdentifier(tii, ab.getNode(), ab.getName());
-                Preconditions.checkState(t.read(LogicalDatastoreType.OPERATIONAL, lii) == null);
+                try {
+                    Preconditions.checkState(! t.read(LogicalDatastoreType.OPERATIONAL, lii).checkedGet().isPresent());
+                } catch (ReadFailedException e) {
+                    throw new IllegalStateException("Failed to ensure link existence.", e);
+                }
 
                 final ArgumentsBuilder args = new ArgumentsBuilder();
-                args.setBandwidth(new BandwidthBuilder().setBandwidth(input.getBandwidth()).build());
-                args.setClassType(new ClassTypeBuilder().setClassType(input.getClassType()).build());
+                if (input.getBandwidth() != null) {
+                    args.setBandwidth(new BandwidthBuilder().setBandwidth(input.getBandwidth()).build());
+                }
+                if (input.getClassType() != null) {
+                    args.setClassType(new ClassTypeBuilder().setClassType(input.getClassType()).build());
+                }
                 args.setEndpointsObj(new EndpointsObjBuilder().setAddressFamily(buildAddressFamily(sp, dp)).build());
                 args.setEro(buildEro(input.getExplicitHops()));
                 args.setLspa(new LspaBuilder(input).build());
@@ -281,10 +289,9 @@ public final class TunnelProgramming implements TopologyTunnelPcepProgrammingSer
         return Futures.immediateFuture(res);
     }
 
-    private Node sourceNode(final ReadTransaction t, final InstanceIdentifier<Topology> topology, final Link link) throws InterruptedException, ExecutionException {
-        Optional<Node> o = t.read(LogicalDatastoreType.OPERATIONAL,
-                topology.child(Node.class, new NodeKey(link.getSource().getSourceNode()))).get();
-        return (Node)o.get();
+    private Optional<Node> sourceNode(final ReadTransaction t, final InstanceIdentifier<Topology> topology, final Link link) throws ReadFailedException {
+        return t.read(LogicalDatastoreType.OPERATIONAL,
+                topology.child(Node.class, new NodeKey(link.getSource().getSourceNode()))).checkedGet();
     }
 
     @Override
@@ -302,11 +309,11 @@ public final class TunnelProgramming implements TopologyTunnelPcepProgrammingSer
 
                 try {
                     // The link has to exist
-                    link = (Link) t.read(LogicalDatastoreType.OPERATIONAL, lii).get().get();
+                    link = (Link) t.read(LogicalDatastoreType.OPERATIONAL, lii).checkedGet().get();
 
                     // The source node has to exist
-                    node = sourceNode(t, tii, link);
-                } catch (InterruptedException | ExecutionException e) {
+                    node = sourceNode(t, tii, link).get();
+                } catch (IllegalStateException | ReadFailedException e) {
                     return Futures.<OperationResult>immediateFuture(new OperationResult() {
                         @Override
                         public Class<? extends DataContainer> getImplementedInterface() {
@@ -360,11 +367,11 @@ public final class TunnelProgramming implements TopologyTunnelPcepProgrammingSer
 
                 try {
                     // The link has to exist
-                    link = (Link) t.read(LogicalDatastoreType.OPERATIONAL, lii).get().get();
+                    link = (Link) t.read(LogicalDatastoreType.OPERATIONAL, lii).checkedGet().get();
 
                     // The source node has to exist
-                    node = sourceNode(t, tii, link);
-                } catch (InterruptedException | ExecutionException e) {
+                    node = sourceNode(t, tii, link).get();
+                } catch (IllegalStateException | ReadFailedException e) {
                     return Futures.<OperationResult>immediateFuture(new OperationResult() {
                         @Override
                         public Class<? extends DataContainer> getImplementedInterface() {