From: Claudio D. Gasparini Date: Mon, 27 Nov 2017 16:31:17 +0000 (+0100) Subject: BGPCEP-726: Migrate PCEP Tunnel config X-Git-Tag: release/oxygen~100 X-Git-Url: https://git.opendaylight.org/gerrit/gitweb?a=commitdiff_plain;h=fdb5ffad3d5a38dda0a06db75631a2083e62ee6e;p=bgpcep.git BGPCEP-726: Migrate PCEP Tunnel config from deprecated CSS to DS Config. Change-Id: I038da50451ae18de05ccea12f9b105593924bc7f Signed-off-by: Claudio D. Gasparini --- diff --git a/pcep/config-example/src/main/resources/initial/network-topology-pcep-config.xml b/pcep/config-example/src/main/resources/initial/network-topology-pcep-config.xml index 9b7cdcaa44..f3e37ae1f2 100644 --- a/pcep/config-example/src/main/resources/initial/network-topology-pcep-config.xml +++ b/pcep/config-example/src/main/resources/initial/network-topology-pcep-config.xml @@ -7,6 +7,13 @@ ~ and is available at http://www.eclipse.org/legal/epl-v10.html --> + + tunnel-topology + pcep-topology + + + + pcep-topology diff --git a/pcep/tunnel/tunnel-provider/pom.xml b/pcep/tunnel/tunnel-provider/pom.xml index 1a5ad225df..aae2883d10 100644 --- a/pcep/tunnel/tunnel-provider/pom.xml +++ b/pcep/tunnel/tunnel-provider/pom.xml @@ -220,6 +220,25 @@ + + + + org.apache.maven.plugins + maven-checkstyle-plugin + + checkstyle.violationSeverity=error + + + + org.codehaus.mojo + findbugs-maven-plugin + + true + + + + + scm:git:ssh://git.opendaylight.org:29418/bgpcep.git scm:git:ssh://git.opendaylight.org:29418/bgpcep.git diff --git a/pcep/tunnel/tunnel-provider/src/main/java/org/opendaylight/bgpcep/pcep/tunnel/provider/CreateTunnelInstructionExecutor.java b/pcep/tunnel/tunnel-provider/src/main/java/org/opendaylight/bgpcep/pcep/tunnel/provider/CreateTunnelInstructionExecutor.java index c5a1f71ff7..ea6890e7f3 100644 --- a/pcep/tunnel/tunnel-provider/src/main/java/org/opendaylight/bgpcep/pcep/tunnel/provider/CreateTunnelInstructionExecutor.java +++ b/pcep/tunnel/tunnel-provider/src/main/java/org/opendaylight/bgpcep/pcep/tunnel/provider/CreateTunnelInstructionExecutor.java @@ -66,50 +66,96 @@ final class CreateTunnelInstructionExecutor extends AbstractInstructionExecutor private final PcepCreateP2pTunnelInput p2pTunnelInput; CreateTunnelInstructionExecutor(final PcepCreateP2pTunnelInput p2pTunnelInput, final DataBroker dataProvider, - final NetworkTopologyPcepService topologyService) { + final NetworkTopologyPcepService topologyService) { super(p2pTunnelInput); this.p2pTunnelInput = p2pTunnelInput; this.dataProvider = dataProvider; this.topologyService = topologyService; } - private static final class TpReader { - private final ReadTransaction t; - private final InstanceIdentifier nii; - private final InstanceIdentifier tii; + private static void checkLinkIsnotExistent(final InstanceIdentifier tii, + final AddLspInputBuilder addLspInput, final ReadOnlyTransaction rt) { + final InstanceIdentifier lii = NodeChangedListener.linkIdentifier(tii, addLspInput.getNode(), + addLspInput.getName()); + try { + Preconditions.checkState(!rt.read(LogicalDatastoreType.OPERATIONAL, lii).checkedGet().isPresent()); + } catch (final ReadFailedException e) { + throw new IllegalStateException("Failed to ensure link existence.", e); + } + } - TpReader(final ReadTransaction t, final InstanceIdentifier topo, final TpReference ref) { - this.t = requireNonNull(t); + private static AddressFamily buildAddressFamily(final TerminationPoint sp, final TerminationPoint dp) { + // We need the IGP augmentation -- it has IP addresses + final TerminationPoint1 sp1 = requireNonNull(sp.getAugmentation(TerminationPoint1.class)); + final TerminationPoint1 dp1 = requireNonNull(dp.getAugmentation(TerminationPoint1.class)); - this.nii = topo.child(Node.class, new NodeKey(ref.getNode())); - this.tii = this.nii.child(TerminationPoint.class, new TerminationPointKey(ref.getTp())); + // Get the types + final TerminationPointType spt = sp1.getIgpTerminationPointAttributes().getTerminationPointType(); + final TerminationPointType dpt = dp1.getIgpTerminationPointAttributes().getTerminationPointType(); + + // The types have to match + Preconditions.checkArgument(spt.getImplementedInterface().equals(dpt.getImplementedInterface())); + + // And they have to actually be Ip + final Ip sips = (Ip) spt; + final Ip dips = (Ip) dpt; + + /* + * Now a bit of magic. We need to find 'like' addresses, e.g. both + * IPv4 or both IPv6. We are in IPv6-enabled world now, so let's + * prefer that. + */ + Optional ret = findIpv6(sips.getIpAddress(), dips.getIpAddress()); + if (!ret.isPresent()) { + ret = findIpv4(sips.getIpAddress(), dips.getIpAddress()); } - private DataObject read(final InstanceIdentifier id) { - try { - return this.t.read(LogicalDatastoreType.OPERATIONAL, id).checkedGet().get(); - } catch (ReadFailedException | IllegalStateException e) { - throw new IllegalStateException("Failed to read data.", e); + // We need to have a ret now + Preconditions.checkArgument(ret != null, "Failed to find like Endpoint addresses"); + + return ret.get(); + } + + private static Optional findIpv4(final List srcs, final List dsts) { + for (final IpAddress sc : srcs) { + if (sc.getIpv4Address() != null) { + for (final IpAddress dc : dsts) { + if (dc.getIpv4Address() != null) { + return Optional.of(new Ipv4CaseBuilder().setIpv4(new Ipv4Builder() + .setSourceIpv4Address(sc.getIpv4Address()) + .setDestinationIpv4Address(dc.getIpv4Address()).build()).build()); + } + } } } - private Node getNode() { - return (Node) read(this.nii); - } + return Optional.absent(); + } - private TerminationPoint getTp() { - return (TerminationPoint) read(this.tii); + private static Optional findIpv6(final List srcs, final List dsts) { + for (final IpAddress sc : srcs) { + if (sc.getIpv6Address() != null) { + for (final IpAddress dc : dsts) { + if (dc.getIpv6Address() != null) { + return Optional.of(new Ipv6CaseBuilder().setIpv6(new Ipv6Builder() + .setSourceIpv6Address(sc.getIpv6Address()) + .setDestinationIpv6Address(dc.getIpv6Address()).build()).build()); + } + } + } } + + return Optional.absent(); } @Override protected ListenableFuture invokeOperation() { - try (final ReadOnlyTransaction transaction = this.dataProvider.newReadOnlyTransaction()) { + try (ReadOnlyTransaction transaction = this.dataProvider.newReadOnlyTransaction()) { AddLspInput addLspInput = createAddLspInput(transaction); return Futures.transform( - (ListenableFuture>) this.topologyService.addLsp(addLspInput), - RpcResult::getResult, MoreExecutors.directExecutor()); + (ListenableFuture>) this.topologyService.addLsp(addLspInput), + RpcResult::getResult, MoreExecutors.directExecutor()); } } @@ -132,16 +178,6 @@ final class CreateTunnelInstructionExecutor extends AbstractInstructionExecutor return ab.build(); } - private static void checkLinkIsnotExistent(final InstanceIdentifier tii, final AddLspInputBuilder addLspInput, - final ReadOnlyTransaction t) { - final InstanceIdentifier lii = NodeChangedListener.linkIdentifier(tii, addLspInput.getNode(), addLspInput.getName()); - try { - Preconditions.checkState(!t.read(LogicalDatastoreType.OPERATIONAL, lii).checkedGet().isPresent()); - } catch (final ReadFailedException e) { - throw new IllegalStateException("Failed to ensure link existence.", e); - } - } - private Arguments buildArguments(final TerminationPoint sp, final TerminationPoint dp) { final ArgumentsBuilder args = new ArgumentsBuilder(); if (this.p2pTunnelInput.getBandwidth() != null) { @@ -154,72 +190,41 @@ final class CreateTunnelInstructionExecutor extends AbstractInstructionExecutor args.setEro(TunelProgrammingUtil.buildEro(this.p2pTunnelInput.getExplicitHops())); args.setLspa(new LspaBuilder(this.p2pTunnelInput).build()); - final AdministrativeStatus adminStatus = this.p2pTunnelInput.getAugmentation(PcepCreateP2pTunnelInput1.class).getAdministrativeStatus(); + final AdministrativeStatus adminStatus = this.p2pTunnelInput.getAugmentation(PcepCreateP2pTunnelInput1.class) + .getAdministrativeStatus(); if (adminStatus != null) { - args.addAugmentation(Arguments2.class, new Arguments2Builder().setLsp(new LspBuilder().setAdministrative(adminStatus == AdministrativeStatus.Active).build()).build()); + args.addAugmentation(Arguments2.class, new Arguments2Builder().setLsp(new LspBuilder() + .setAdministrative(adminStatus == AdministrativeStatus.Active).build()).build()); } return args.build(); } - private static AddressFamily buildAddressFamily(final TerminationPoint sp, final TerminationPoint dp) { - // We need the IGP augmentation -- it has IP addresses - final TerminationPoint1 sp1 = requireNonNull(sp.getAugmentation(TerminationPoint1.class)); - final TerminationPoint1 dp1 = requireNonNull(dp.getAugmentation(TerminationPoint1.class)); - - // Get the types - final TerminationPointType spt = sp1.getIgpTerminationPointAttributes().getTerminationPointType(); - final TerminationPointType dpt = dp1.getIgpTerminationPointAttributes().getTerminationPointType(); - - // The types have to match - Preconditions.checkArgument(spt.getImplementedInterface().equals(dpt.getImplementedInterface())); + private static final class TpReader { + private final ReadTransaction rt; + private final InstanceIdentifier nii; + private final InstanceIdentifier tii; - // And they have to actually be Ip - final Ip sips = (Ip) spt; - final Ip dips = (Ip) dpt; + TpReader(final ReadTransaction rt, final InstanceIdentifier topo, final TpReference ref) { + this.rt = requireNonNull(rt); - /* - * Now a bit of magic. We need to find 'like' addresses, e.g. both - * IPv4 or both IPv6. We are in IPv6-enabled world now, so let's - * prefer that. - */ - Optional ret = findIpv6(sips.getIpAddress(), dips.getIpAddress()); - if (!ret.isPresent()) { - ret = findIpv4(sips.getIpAddress(), dips.getIpAddress()); + this.nii = topo.child(Node.class, new NodeKey(ref.getNode())); + this.tii = this.nii.child(TerminationPoint.class, new TerminationPointKey(ref.getTp())); } - // We need to have a ret now - Preconditions.checkArgument(ret != null, "Failed to find like Endpoint addresses"); - - return ret.get(); - } - - private static Optional findIpv4(final List srcs, final List dsts) { - for (final IpAddress sc : srcs) { - if (sc.getIpv4Address() != null) { - for (final IpAddress dc : dsts) { - if (dc.getIpv4Address() != null) { - return Optional.of(new Ipv4CaseBuilder().setIpv4(new Ipv4Builder().setSourceIpv4Address(sc.getIpv4Address()). - setDestinationIpv4Address(dc.getIpv4Address()).build()).build()); - } - } + private DataObject read(final InstanceIdentifier id) { + try { + return this.rt.read(LogicalDatastoreType.OPERATIONAL, id).checkedGet().get(); + } catch (ReadFailedException | IllegalStateException e) { + throw new IllegalStateException("Failed to read data.", e); } } - return Optional.absent(); - } - - private static Optional findIpv6(final List srcs, final List dsts) { - for (final IpAddress sc : srcs) { - if (sc.getIpv6Address() != null) { - for (final IpAddress dc : dsts) { - if (dc.getIpv6Address() != null) { - return Optional.of(new Ipv6CaseBuilder().setIpv6(new Ipv6Builder().setSourceIpv6Address(sc.getIpv6Address()). - setDestinationIpv6Address(dc.getIpv6Address()).build()).build()); - } - } - } + private Node getNode() { + return (Node) read(this.nii); } - return Optional.absent(); + private TerminationPoint getTp() { + return (TerminationPoint) read(this.tii); + } } } diff --git a/pcep/tunnel/tunnel-provider/src/main/java/org/opendaylight/bgpcep/pcep/tunnel/provider/DestroyTunnelInstructionExecutor.java b/pcep/tunnel/tunnel-provider/src/main/java/org/opendaylight/bgpcep/pcep/tunnel/provider/DestroyTunnelInstructionExecutor.java index 10d8fc7dbd..b22f94adfb 100644 --- a/pcep/tunnel/tunnel-provider/src/main/java/org/opendaylight/bgpcep/pcep/tunnel/provider/DestroyTunnelInstructionExecutor.java +++ b/pcep/tunnel/tunnel-provider/src/main/java/org/opendaylight/bgpcep/pcep/tunnel/provider/DestroyTunnelInstructionExecutor.java @@ -50,7 +50,7 @@ final class DestroyTunnelInstructionExecutor extends AbstractInstructionExecutor protected ListenableFuture invokeOperation() { final InstanceIdentifier tii = TopologyProgrammingUtil.topologyForInput(this.pcepDestroyTunnelInput); final InstanceIdentifier lii = TunnelProgrammingUtil.linkIdentifier(tii, this.pcepDestroyTunnelInput); - try (final ReadOnlyTransaction t = this.dataProvider.newReadOnlyTransaction()) { + try (ReadOnlyTransaction t = this.dataProvider.newReadOnlyTransaction()) { final Node node; final Link link; try { diff --git a/pcep/tunnel/tunnel-provider/src/main/java/org/opendaylight/bgpcep/pcep/tunnel/provider/NodeChangedListener.java b/pcep/tunnel/tunnel-provider/src/main/java/org/opendaylight/bgpcep/pcep/tunnel/provider/NodeChangedListener.java index 80e348d666..e7f22b0546 100644 --- a/pcep/tunnel/tunnel-provider/src/main/java/org/opendaylight/bgpcep/pcep/tunnel/provider/NodeChangedListener.java +++ b/pcep/tunnel/tunnel-provider/src/main/java/org/opendaylight/bgpcep/pcep/tunnel/provider/NodeChangedListener.java @@ -84,19 +84,21 @@ public final class NodeChangedListener implements ClusteredDataTreeChangeListene private final DataBroker dataProvider; private final TopologyId source; - NodeChangedListener(final DataBroker dataProvider, final TopologyId source, final InstanceIdentifier target) { + NodeChangedListener(final DataBroker dataProvider, final TopologyId source, + final InstanceIdentifier target) { this.dataProvider = requireNonNull(dataProvider); this.target = requireNonNull(target); this.source = requireNonNull(source); } - private static void categorizeIdentifier(final InstanceIdentifier i, final Set> changedLsps, + private static void categorizeIdentifier(final InstanceIdentifier identifier, + final Set> changedLsps, final Set> changedNodes) { - final InstanceIdentifier li = i.firstIdentifierOf(ReportedLsp.class); + final InstanceIdentifier li = identifier.firstIdentifierOf(ReportedLsp.class); if (li == null) { - final InstanceIdentifier ni = i.firstIdentifierOf(Node.class); + final InstanceIdentifier ni = identifier.firstIdentifierOf(Node.class); if (ni == null) { - LOG.warn("Ignoring uncategorized identifier {}", i); + LOG.warn("Ignoring uncategorized identifier {}", identifier); } else { changedNodes.add(ni); } @@ -105,7 +107,8 @@ public final class NodeChangedListener implements ClusteredDataTreeChangeListene } } - private static void enumerateLsps(final InstanceIdentifier id, final Node node, final Set> lsps) { + private static void enumerateLsps(final InstanceIdentifier id, final Node node, + final Set> lsps) { if (node == null) { LOG.trace("Skipping null node", id); return; @@ -117,12 +120,18 @@ public final class NodeChangedListener implements ClusteredDataTreeChangeListene } for (final ReportedLsp l : pccnode.getPathComputationClient().getReportedLsp()) { - lsps.add(id.builder().augmentation(Node1.class).child(PathComputationClient.class).child(ReportedLsp.class, l.getKey()).build()); + lsps.add(id.builder().augmentation(Node1.class).child(PathComputationClient.class) + .child(ReportedLsp.class, l.getKey()).build()); } } - private static LinkId linkIdForLsp(final InstanceIdentifier i, final ReportedLsp lsp) { - return new LinkId(i.firstKeyOf(Node.class, NodeKey.class).getNodeId().getValue() + "/lsps/" + lsp.getName()); + private static LinkId linkIdForLsp(final InstanceIdentifier identifier, final ReportedLsp lsp) { + return new LinkId(identifier.firstKeyOf(Node.class).getNodeId().getValue() + "/lsps/" + lsp.getName()); + } + + public static InstanceIdentifier linkIdentifier(final InstanceIdentifier topology, + final NodeId node, final String name) { + return topology.child(Link.class, new LinkKey(new LinkId(node.getValue() + "/lsp/" + name))); } private InstanceIdentifier linkForLsp(final LinkId linkId) { @@ -140,7 +149,8 @@ public final class NodeChangedListener implements ClusteredDataTreeChangeListene return snb.build(); } - private void handleSni(final InstanceIdentifier sni, final Node n, final Boolean inControl, final ReadWriteTransaction trans) { + private void handleSni(final InstanceIdentifier sni, final Node node, final Boolean inControl, + final ReadWriteTransaction trans) { if (sni != null) { final NodeKey k = InstanceIdentifier.keyOf(sni); boolean have = false; @@ -149,8 +159,8 @@ public final class NodeChangedListener implements ClusteredDataTreeChangeListene * so it does not have a supporting node pointer. Since we now know what it is, * fill it in. */ - if (n.getSupportingNode() != null) { - for (final SupportingNode sn : n.getSupportingNode()) { + if (node.getSupportingNode() != null) { + for (final SupportingNode sn : node.getSupportingNode()) { if (sn.getNodeRef().equals(k.getNodeId())) { have = true; break; @@ -159,27 +169,30 @@ public final class NodeChangedListener implements ClusteredDataTreeChangeListene } if (!have) { final SupportingNode sn = createSupportingNode(k.getNodeId(), inControl); - trans.put(LogicalDatastoreType.OPERATIONAL, this.target.child(Node.class, n.getKey()).child( + trans.put(LogicalDatastoreType.OPERATIONAL, this.target.child(Node.class, node.getKey()).child( SupportingNode.class, sn.getKey()), sn); } } } - private InstanceIdentifier getIpTerminationPoint(final ReadWriteTransaction trans, final IpAddress addr, - final InstanceIdentifier sni, final Boolean inControl) throws ReadFailedException { + private InstanceIdentifier getIpTerminationPoint(final ReadWriteTransaction trans, + final IpAddress addr, final InstanceIdentifier sni, final Boolean inControl) + throws ReadFailedException { final Topology topo = trans.read(LogicalDatastoreType.OPERATIONAL, this.target).checkedGet().get(); if (topo.getNode() != null) { for (final Node n : topo.getNode()) { - if(n.getTerminationPoint() != null) { + if (n.getTerminationPoint() != null) { for (final TerminationPoint tp : n.getTerminationPoint()) { final TerminationPoint1 tpa = tp.getAugmentation(TerminationPoint1.class); if (tpa != null) { - final TerminationPointType tpt = tpa.getIgpTerminationPointAttributes().getTerminationPointType(); + final TerminationPointType tpt = tpa.getIgpTerminationPointAttributes() + .getTerminationPointType(); if (tpt instanceof Ip) { - for (final IpAddress a : ((Ip) tpt).getIpAddress()) { - if (addr.equals(a)) { + for (final IpAddress address : ((Ip) tpt).getIpAddress()) { + if (addr.equals(address)) { handleSni(sni, n, inControl, trans); - return this.target.builder().child(Node.class, n.getKey()).child(TerminationPoint.class, tp.getKey()).build(); + return this.target.builder().child(Node.class, n.getKey()) + .child(TerminationPoint.class, tp.getKey()).build(); } } } else { @@ -209,15 +222,17 @@ public final class NodeChangedListener implements ClusteredDataTreeChangeListene nb.setKey(nk).setNodeId(nk.getNodeId()); nb.setTerminationPoint(Lists.newArrayList(tpb.build())); if (sni != null) { - nb.setSupportingNode(Lists.newArrayList(createSupportingNode(InstanceIdentifier.keyOf(sni).getNodeId(), inControl))); + nb.setSupportingNode(Lists.newArrayList(createSupportingNode(InstanceIdentifier.keyOf(sni).getNodeId(), + inControl))); } final InstanceIdentifier nid = this.target.child(Node.class, nb.getKey()); trans.put(LogicalDatastoreType.OPERATIONAL, nid, nb.build()); return nid.child(TerminationPoint.class, tpb.getKey()); } - private void create(final ReadWriteTransaction trans, final InstanceIdentifier i, final ReportedLsp value) throws ReadFailedException { - final InstanceIdentifier ni = i.firstIdentifierOf(Node.class); + private void create(final ReadWriteTransaction trans, final InstanceIdentifier identifier, + final ReportedLsp value) throws ReadFailedException { + final InstanceIdentifier ni = identifier.firstIdentifierOf(Node.class); final Path1 rl = value.getPath().get(0).getAugmentation(Path1.class); @@ -226,7 +241,8 @@ public final class NodeChangedListener implements ClusteredDataTreeChangeListene /* * We are trying to ensure we have source and destination nodes. */ - final IpAddress srcIp, dstIp; + final IpAddress srcIp; + final IpAddress dstIp; if (af instanceof Ipv4Case) { final Ipv4 ipv4 = ((Ipv4Case) af).getIpv4(); srcIp = new IpAddress(ipv4.getIpv4TunnelSenderAddress()); @@ -250,37 +266,43 @@ public final class NodeChangedListener implements ClusteredDataTreeChangeListene lab.setSymbolicPathName(value.getName()); final InstanceIdentifier dst = getIpTerminationPoint(trans, dstIp, null, Boolean.FALSE); - final InstanceIdentifier src = getIpTerminationPoint(trans, srcIp, ni, rl.getLsp().isDelegate()); + final InstanceIdentifier src = getIpTerminationPoint(trans, srcIp, ni, + rl.getLsp().isDelegate()); - final org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.ietf.stateful.rev171025.Link1Builder slab = new org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.ietf.stateful.rev171025.Link1Builder(); + final org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.ietf.stateful.rev171025 + .Link1Builder slab = new org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.ietf + .stateful.rev171025.Link1Builder(); slab.setOperationalStatus(rl.getLsp().getOperational()); - slab.setAdministrativeStatus(rl.getLsp().isAdministrative() ? AdministrativeStatus.Active : AdministrativeStatus.Inactive); + slab.setAdministrativeStatus(rl.getLsp().isAdministrative() ? AdministrativeStatus.Active : + AdministrativeStatus.Inactive); - final LinkId id = linkIdForLsp(i, value); + final LinkId id = linkIdForLsp(identifier, value); final LinkBuilder lb = new LinkBuilder(); lb.setLinkId(id); - lb.setSource(new SourceBuilder().setSourceNode(src.firstKeyOf(Node.class, NodeKey.class).getNodeId()).setSourceTp( - src.firstKeyOf(TerminationPoint.class, TerminationPointKey.class).getTpId()).build()); - lb.setDestination(new DestinationBuilder().setDestNode(dst.firstKeyOf(Node.class, NodeKey.class).getNodeId()).setDestTp( - dst.firstKeyOf(TerminationPoint.class, TerminationPointKey.class).getTpId()).build()); + lb.setSource(new SourceBuilder().setSourceNode(src.firstKeyOf(Node.class).getNodeId()) + .setSourceTp(src.firstKeyOf(TerminationPoint.class).getTpId()).build()); + lb.setDestination(new DestinationBuilder().setDestNode(dst.firstKeyOf(Node.class).getNodeId()) + .setDestTp(dst.firstKeyOf(TerminationPoint.class).getTpId()).build()); lb.addAugmentation(Link1.class, lab.build()); - lb.addAugmentation(org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.ietf.stateful.rev171025.Link1.class, - slab.build()); + lb.addAugmentation(org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.ietf.stateful + .rev171025.Link1.class, slab.build()); trans.put(LogicalDatastoreType.OPERATIONAL, linkForLsp(id), lb.build()); } private InstanceIdentifier tpIdentifier(final NodeId node, final TpId tp) { - return this.target.builder().child(Node.class, new NodeKey(node)).child(TerminationPoint.class, new TerminationPointKey(tp)).build(); + return this.target.builder().child(Node.class, new NodeKey(node)).child(TerminationPoint.class, + new TerminationPointKey(tp)).build(); } private InstanceIdentifier nodeIdentifier(final NodeId node) { return this.target.child(Node.class, new NodeKey(node)); } - private void remove(final ReadWriteTransaction trans, final InstanceIdentifier i, final ReportedLsp value) throws ReadFailedException { - final InstanceIdentifier li = linkForLsp(linkIdForLsp(i, value)); + private void remove(final ReadWriteTransaction trans, final InstanceIdentifier identifier, + final ReportedLsp value) throws ReadFailedException { + final InstanceIdentifier li = linkForLsp(linkIdForLsp(identifier, value)); final Optional ol = trans.read(LogicalDatastoreType.OPERATIONAL, li).checkedGet(); if (!ol.isPresent()) { @@ -295,14 +317,17 @@ public final class NodeChangedListener implements ClusteredDataTreeChangeListene final Optional ot = trans.read(LogicalDatastoreType.OPERATIONAL, this.target).checkedGet(); Preconditions.checkState(ot.isPresent()); - final Topology t = ot.get(); + final Topology topology = ot.get(); final NodeId srcNode = l.getSource().getSourceNode(); final NodeId dstNode = l.getDestination().getDestNode(); final TpId srcTp = l.getSource().getSourceTp(); final TpId dstTp = l.getDestination().getDestTp(); - boolean orphSrcNode = true, orphDstNode = true, orphDstTp = true, orphSrcTp = true; - for (final Link lw : t.getLink()) { + boolean orphSrcNode = true; + boolean orphDstNode = true; + boolean orphDstTp = true; + boolean orphSrcTp = true; + for (final Link lw : topology.getLink()) { LOG.trace("Checking link {}", lw); final NodeId sn = lw.getSource().getSourceNode(); @@ -414,8 +439,8 @@ public final class NodeChangedListener implements ClusteredDataTreeChangeListene } @Override - public void onFailure(final Throwable t) { - LOG.error("Failed to propagate a topology change, target topology became inconsistent", t); + public void onFailure(final Throwable throwable) { + LOG.error("Failed to propagate a topology change, target topology became inconsistent", throwable); } }, MoreExecutors.directExecutor()); } @@ -430,18 +455,18 @@ public final class NodeChangedListener implements ClusteredDataTreeChangeListene // Get the subtrees switch (changedNode.getModificationType()) { - case DELETE: - original.put(iid, changedNode.getDataBefore()); - break; - case SUBTREE_MODIFIED: - original.put(iid, changedNode.getDataBefore()); - updated.put(iid, changedNode.getDataAfter()); - break; - case WRITE: - created.put(iid, changedNode.getDataAfter()); - break; - default: - throw new IllegalArgumentException("Unhandled modification type " + changedNode.getModificationType()); + case DELETE: + original.put(iid, changedNode.getDataBefore()); + break; + case SUBTREE_MODIFIED: + original.put(iid, changedNode.getDataBefore()); + updated.put(iid, changedNode.getDataAfter()); + break; + case WRITE: + created.put(iid, changedNode.getDataAfter()); + break; + default: + throw new IllegalArgumentException("Unhandled modification type " + changedNode.getModificationType()); } for (DataObjectModification child : changedNode.getModifiedChildren()) { @@ -455,9 +480,11 @@ public final class NodeChangedListener implements ClusteredDataTreeChangeListene } } - private void updateTransaction(final ReadWriteTransaction trans, final Set> lsps, - final Map, ? extends DataObject> old, final Map, DataObject> updated, - final Map, DataObject> created) { + private void updateTransaction(final ReadWriteTransaction trans, + final Set> lsps, + final Map, ? extends DataObject> old, + final Map, DataObject> updated, + final Map, DataObject> created) { for (final InstanceIdentifier i : lsps) { final ReportedLsp oldValue = (ReportedLsp) old.get(i); @@ -484,7 +511,7 @@ public final class NodeChangedListener implements ClusteredDataTreeChangeListene } } - public static InstanceIdentifier linkIdentifier(final InstanceIdentifier topology, final NodeId node, final String name) { - return topology.child(Link.class, new LinkKey(new LinkId(node.getValue() + "/lsp/" + name))); + DataBroker getDataProvider() { + return dataProvider; } } diff --git a/pcep/tunnel/tunnel-provider/src/main/java/org/opendaylight/bgpcep/pcep/tunnel/provider/PCEPTunnelClusterSingletonService.java b/pcep/tunnel/tunnel-provider/src/main/java/org/opendaylight/bgpcep/pcep/tunnel/provider/PCEPTunnelClusterSingletonService.java new file mode 100644 index 0000000000..0bbf0a1f06 --- /dev/null +++ b/pcep/tunnel/tunnel-provider/src/main/java/org/opendaylight/bgpcep/pcep/tunnel/provider/PCEPTunnelClusterSingletonService.java @@ -0,0 +1,133 @@ +/* + * Copyright (c) 2017 AT&T Intellectual Property. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v1.0 which accompanies this distribution, + * and is available at http://www.eclipse.org/legal/epl-v10.html + */ +package org.opendaylight.bgpcep.pcep.tunnel.provider; + +import static java.util.Objects.requireNonNull; + +import com.google.common.util.concurrent.Futures; +import com.google.common.util.concurrent.ListenableFuture; +import java.util.Dictionary; +import java.util.Hashtable; +import javax.annotation.Nonnull; +import javax.annotation.concurrent.GuardedBy; +import org.opendaylight.bgpcep.programming.spi.InstructionScheduler; +import org.opendaylight.bgpcep.topology.DefaultTopologyReference; +import org.opendaylight.controller.config.api.osgi.WaitingServiceTracker; +import org.opendaylight.controller.sal.binding.api.BindingAwareBroker; +import org.opendaylight.mdsal.singleton.common.api.ClusterSingletonService; +import org.opendaylight.mdsal.singleton.common.api.ClusterSingletonServiceRegistration; +import org.opendaylight.mdsal.singleton.common.api.ServiceGroupIdentifier; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.network.topology.rev140113.NetworkTopologyContext; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.topology.tunnel.pcep.programming.rev131030.TopologyTunnelPcepProgrammingService; +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.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.yangtools.yang.binding.InstanceIdentifier; +import org.osgi.framework.ServiceRegistration; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public final class PCEPTunnelClusterSingletonService implements ClusterSingletonService, AutoCloseable { + + private static final Logger LOG = LoggerFactory.getLogger(PCEPTunnelClusterSingletonService.class); + private final PCEPTunnelTopologyProvider ttp; + private final TunnelProgramming tp; + private final ServiceGroupIdentifier sgi; + private final TopologyId tunnelTopologyId; + private final TunnelProviderDependencies dependencies; + @GuardedBy("this") + private ServiceRegistration serviceRegistration; + @GuardedBy("this") + private ClusterSingletonServiceRegistration pcepTunnelCssReg; + @GuardedBy("this") + private BindingAwareBroker.RoutedRpcRegistration reg; + + public PCEPTunnelClusterSingletonService( + final TunnelProviderDependencies dependencies, + final InstanceIdentifier pcepTopology, + final TopologyId tunnelTopologyId + ) { + this.dependencies = requireNonNull(dependencies); + this.tunnelTopologyId = requireNonNull(tunnelTopologyId); + final TopologyId pcepTopologyId = pcepTopology.firstKeyOf(Topology.class).getTopologyId(); + + final WaitingServiceTracker schedulerTracker = + WaitingServiceTracker.create(InstructionScheduler.class, + dependencies.getBundleContext(), "(" + InstructionScheduler.class.getName() + + "=" + pcepTopologyId.getValue() + ")"); + final InstructionScheduler scheduler = schedulerTracker.waitForService(WaitingServiceTracker.FIVE_MINUTES); + schedulerTracker.close(); + + final InstanceIdentifier tunnelTopology = InstanceIdentifier.builder(NetworkTopology.class) + .child(Topology.class, new TopologyKey(tunnelTopologyId)).build(); + this.ttp = new PCEPTunnelTopologyProvider(dependencies.getDataBroker(), pcepTopology, pcepTopologyId, + tunnelTopology, tunnelTopologyId); + + + this.sgi = scheduler.getIdentifier(); + this.tp = new TunnelProgramming(scheduler, dependencies); + + + final Dictionary properties = new Hashtable<>(); + properties.put(PCEPTunnelTopologyProvider.class.getName(), tunnelTopologyId.getValue()); + this.serviceRegistration = dependencies.getBundleContext() + .registerService(DefaultTopologyReference.class.getName(), this.ttp, properties); + + LOG.info("PCEP Tunnel Cluster Singleton service {} registered", getIdentifier().getValue()); + this.pcepTunnelCssReg = dependencies.getCssp().registerClusterSingletonService(this); + } + + + @Override + public synchronized void instantiateServiceInstance() { + LOG.info("Instantiate PCEP Tunnel Topology Provider Singleton Service {}", getIdentifier().getValue()); + this.reg = this.dependencies.getRpcProviderRegistry() + .addRoutedRpcImplementation(TopologyTunnelPcepProgrammingService.class, this.tp); + + final InstanceIdentifier topology = InstanceIdentifier + .builder(NetworkTopology.class).child(Topology.class, new TopologyKey(this.tunnelTopologyId)).build(); + this.reg.registerPath(NetworkTopologyContext.class, topology); + this.ttp.init(); + } + + @Override + public synchronized ListenableFuture closeServiceInstance() { + LOG.info("Close Service Instance PCEP Tunnel Topology Provider Singleton Service {}", + getIdentifier().getValue()); + this.reg.close(); + this.tp.close(); + this.ttp.close(); + return Futures.immediateFuture(null); + } + + @Nonnull + @Override + public ServiceGroupIdentifier getIdentifier() { + return this.sgi; + } + + @Override + @SuppressWarnings("checkstyle:IllegalCatch") + public synchronized void close() { + LOG.info("Close PCEP Tunnel Topology Provider Singleton Service {}", getIdentifier().getValue()); + + if (this.pcepTunnelCssReg != null) { + try { + this.pcepTunnelCssReg.close(); + } catch (final Exception e) { + LOG.debug("Failed to close PCEP Tunnel Topology service {}", this.sgi.getValue(), e); + } + this.pcepTunnelCssReg = null; + } + if (this.serviceRegistration != null) { + this.serviceRegistration.unregister(); + this.serviceRegistration = null; + } + } +} diff --git a/pcep/tunnel/tunnel-provider/src/main/java/org/opendaylight/bgpcep/pcep/tunnel/provider/PCEPTunnelTopologyProvider.java b/pcep/tunnel/tunnel-provider/src/main/java/org/opendaylight/bgpcep/pcep/tunnel/provider/PCEPTunnelTopologyProvider.java index b9518cf811..72f81de768 100644 --- a/pcep/tunnel/tunnel-provider/src/main/java/org/opendaylight/bgpcep/pcep/tunnel/provider/PCEPTunnelTopologyProvider.java +++ b/pcep/tunnel/tunnel-provider/src/main/java/org/opendaylight/bgpcep/pcep/tunnel/provider/PCEPTunnelTopologyProvider.java @@ -7,48 +7,73 @@ */ package org.opendaylight.bgpcep.pcep.tunnel.provider; -import static java.util.Objects.requireNonNull; - +import java.util.ArrayList; +import javax.annotation.concurrent.GuardedBy; import org.opendaylight.bgpcep.topology.DefaultTopologyReference; import org.opendaylight.bgpcep.topology.TopologyReference; import org.opendaylight.controller.md.sal.binding.api.DataBroker; import org.opendaylight.controller.md.sal.binding.api.DataTreeIdentifier; +import org.opendaylight.controller.md.sal.binding.api.WriteTransaction; import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType; -import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NetworkTopology; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.topology.tunnel.pcep.rev130820.TopologyTypes1; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.topology.tunnel.pcep.rev130820.TopologyTypes1Builder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.topology.tunnel.pcep.rev130820.topology.tunnel.pcep.type.TopologyTunnelPcepBuilder; 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.TopologyBuilder; 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.TopologyTypesBuilder; import org.opendaylight.yangtools.concepts.ListenerRegistration; import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; -public final class PCEPTunnelTopologyProvider implements AutoCloseable { - private final ListenerRegistration reg; - private final TopologyReference ref; - - private PCEPTunnelTopologyProvider(final InstanceIdentifier dst, final ListenerRegistration reg) { - this.ref = new DefaultTopologyReference(dst); - this.reg = requireNonNull(reg); - } - - public static PCEPTunnelTopologyProvider create(final DataBroker dataProvider, - final InstanceIdentifier sourceTopology, final TopologyId targetTopology) { - final InstanceIdentifier dst = InstanceIdentifier.builder(NetworkTopology.class).child(Topology.class, - new TopologyKey(targetTopology)).build(); - final NodeChangedListener ncl = new NodeChangedListener(dataProvider, sourceTopology.firstKeyOf(Topology.class).getTopologyId(), dst); +public final class PCEPTunnelTopologyProvider extends DefaultTopologyReference implements AutoCloseable { - final InstanceIdentifier src = sourceTopology.child(Node.class); - final ListenerRegistration reg = dataProvider.registerDataTreeChangeListener(new DataTreeIdentifier<>(LogicalDatastoreType.OPERATIONAL, src), ncl); + private final NodeChangedListener ncl; + private final InstanceIdentifier src; + private final DefaultTopologyReference ref; + private final DataBroker dataBroker; + private final TopologyId tunneltopologyId; + @GuardedBy("this") + private ListenerRegistration reg; - return new PCEPTunnelTopologyProvider(dst, reg); + public PCEPTunnelTopologyProvider( + final DataBroker dataBroker, + final InstanceIdentifier pcepTopology, + final TopologyId pcepTopologyId, + final InstanceIdentifier tunnelTopology, + final TopologyId tunneltopologyId) { + super(tunnelTopology); + this.dataBroker = dataBroker; + this.tunneltopologyId = tunneltopologyId; + this.ncl = new NodeChangedListener(dataBroker, pcepTopologyId, tunnelTopology); + this.src = pcepTopology.child(Node.class); + this.ref = new DefaultTopologyReference(tunnelTopology); } - @Override - public void close() { - this.reg.close(); + synchronized void init() { + final WriteTransaction tx = this.dataBroker.newWriteOnlyTransaction(); + tx.put(LogicalDatastoreType.OPERATIONAL, getTopologyReference().getInstanceIdentifier(), + new TopologyBuilder().setTopologyId(this.tunneltopologyId) + .setTopologyTypes(new TopologyTypesBuilder() + .addAugmentation(TopologyTypes1.class, new TopologyTypes1Builder() + .setTopologyTunnelPcep( + new TopologyTunnelPcepBuilder().build()).build()).build()) + .setNode(new ArrayList<>()).build(), true); + tx.submit(); + this.reg = this.ncl.getDataProvider() + .registerDataTreeChangeListener(new DataTreeIdentifier<>(LogicalDatastoreType.OPERATIONAL, this.src), + this.ncl); } public TopologyReference getTopologyReference() { return this.ref; } + + @Override + public synchronized void close() { + if (this.reg != null) { + this.reg.close(); + this.reg = null; + } + } } diff --git a/pcep/tunnel/tunnel-provider/src/main/java/org/opendaylight/bgpcep/pcep/tunnel/provider/TunelProgrammingUtil.java b/pcep/tunnel/tunnel-provider/src/main/java/org/opendaylight/bgpcep/pcep/tunnel/provider/TunelProgrammingUtil.java index 5ab40625c3..7621573495 100644 --- a/pcep/tunnel/tunnel-provider/src/main/java/org/opendaylight/bgpcep/pcep/tunnel/provider/TunelProgrammingUtil.java +++ b/pcep/tunnel/tunnel-provider/src/main/java/org/opendaylight/bgpcep/pcep/tunnel/provider/TunelProgrammingUtil.java @@ -50,7 +50,8 @@ final class TunelProgrammingUtil { } @Override - public List getError() { + public List getError() { return Collections.emptyList(); } }); @@ -93,9 +94,9 @@ final class TunelProgrammingUtil { return null; } - public static Optional sourceNode(final ReadTransaction t, final InstanceIdentifier topology, final Link link) throws - ReadFailedException { - return t.read(LogicalDatastoreType.OPERATIONAL, - topology.child(Node.class, new NodeKey(link.getSource().getSourceNode()))).checkedGet(); + public static Optional sourceNode(final ReadTransaction rt, final InstanceIdentifier topology, + final Link link) throws ReadFailedException { + return rt.read(LogicalDatastoreType.OPERATIONAL, + topology.child(Node.class, new NodeKey(link.getSource().getSourceNode()))).checkedGet(); } } diff --git a/pcep/tunnel/tunnel-provider/src/main/java/org/opendaylight/bgpcep/pcep/tunnel/provider/TunnelProgramming.java b/pcep/tunnel/tunnel-provider/src/main/java/org/opendaylight/bgpcep/pcep/tunnel/provider/TunnelProgramming.java index 6de9d4d98c..d0d1233ba3 100644 --- a/pcep/tunnel/tunnel-provider/src/main/java/org/opendaylight/bgpcep/pcep/tunnel/provider/TunnelProgramming.java +++ b/pcep/tunnel/tunnel-provider/src/main/java/org/opendaylight/bgpcep/pcep/tunnel/provider/TunnelProgramming.java @@ -11,11 +11,10 @@ import static java.util.Objects.requireNonNull; import com.google.common.util.concurrent.Futures; import com.google.common.util.concurrent.ListenableFuture; +import javax.annotation.Nonnull; import org.opendaylight.bgpcep.pcep.topology.spi.AbstractInstructionExecutor; import org.opendaylight.bgpcep.programming.spi.InstructionScheduler; import org.opendaylight.bgpcep.programming.spi.SuccessfulRpcResult; -import org.opendaylight.controller.md.sal.binding.api.DataBroker; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.topology.pcep.rev171025.NetworkTopologyPcepService; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.topology.tunnel.pcep.programming.rev131030.PcepCreateP2pTunnelInput; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.topology.tunnel.pcep.programming.rev131030.PcepCreateP2pTunnelOutput; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.topology.tunnel.pcep.programming.rev131030.PcepCreateP2pTunnelOutputBuilder; @@ -32,39 +31,48 @@ import org.slf4j.LoggerFactory; public final class TunnelProgramming implements TopologyTunnelPcepProgrammingService, AutoCloseable { private static final Logger LOG = LoggerFactory.getLogger(TunnelProgramming.class); - private final NetworkTopologyPcepService topologyService; - private final DataBroker dataProvider; private final InstructionScheduler scheduler; + private final TunnelProviderDependencies dependencies; - public TunnelProgramming(final InstructionScheduler scheduler, final DataBroker dataProvider, final NetworkTopologyPcepService topologyService) { + TunnelProgramming( + @Nonnull final InstructionScheduler scheduler, + @Nonnull final TunnelProviderDependencies dependencies) { this.scheduler = requireNonNull(scheduler); - this.dataProvider = requireNonNull(dataProvider); - this.topologyService = requireNonNull(topologyService); + this.dependencies = requireNonNull(dependencies); } @Override - public ListenableFuture> pcepCreateP2pTunnel(final PcepCreateP2pTunnelInput p2pTunnelInput) { + public ListenableFuture> pcepCreateP2pTunnel( + final PcepCreateP2pTunnelInput p2pTunnelInput) { final PcepCreateP2pTunnelOutputBuilder b = new PcepCreateP2pTunnelOutputBuilder(); - b.setResult(AbstractInstructionExecutor.schedule(this.scheduler, new CreateTunnelInstructionExecutor(p2pTunnelInput, - TunnelProgramming.this.dataProvider, this.topologyService))); + b.setResult(AbstractInstructionExecutor.schedule(this.scheduler, + new CreateTunnelInstructionExecutor(p2pTunnelInput, + TunnelProgramming.this.dependencies.getDataBroker(), + TunnelProgramming.this.dependencies.getNtps()))); final RpcResult res = SuccessfulRpcResult.create(b.build()); return Futures.immediateFuture(res); } @Override - public ListenableFuture> pcepDestroyTunnel(final PcepDestroyTunnelInput destroyTunnelInput) { + public ListenableFuture> pcepDestroyTunnel( + final PcepDestroyTunnelInput destroyTunnelInput) { final PcepDestroyTunnelOutputBuilder b = new PcepDestroyTunnelOutputBuilder(); - b.setResult(AbstractInstructionExecutor.schedule(this.scheduler, new DestroyTunnelInstructionExecutor(destroyTunnelInput, - TunnelProgramming.this.dataProvider, this.topologyService))); + b.setResult(AbstractInstructionExecutor.schedule(this.scheduler, + new DestroyTunnelInstructionExecutor(destroyTunnelInput, + TunnelProgramming.this.dependencies.getDataBroker(), + TunnelProgramming.this.dependencies.getNtps()))); final RpcResult res = SuccessfulRpcResult.create(b.build()); return Futures.immediateFuture(res); } @Override - public ListenableFuture> pcepUpdateTunnel(final PcepUpdateTunnelInput updateTunnelInput) { + public ListenableFuture> pcepUpdateTunnel( + final PcepUpdateTunnelInput updateTunnelInput) { final PcepUpdateTunnelOutputBuilder b = new PcepUpdateTunnelOutputBuilder(); - b.setResult(AbstractInstructionExecutor.schedule(this.scheduler, new UpdateTunnelInstructionExecutor(updateTunnelInput, - TunnelProgramming.this.dataProvider, this.topologyService))); + b.setResult(AbstractInstructionExecutor.schedule(this.scheduler, + new UpdateTunnelInstructionExecutor(updateTunnelInput, + TunnelProgramming.this.dependencies.getDataBroker(), + TunnelProgramming.this.dependencies.getNtps()))); final RpcResult res = SuccessfulRpcResult.create(b.build()); return Futures.immediateFuture(res); diff --git a/pcep/tunnel/tunnel-provider/src/main/java/org/opendaylight/bgpcep/pcep/tunnel/provider/TunnelProviderDependencies.java b/pcep/tunnel/tunnel-provider/src/main/java/org/opendaylight/bgpcep/pcep/tunnel/provider/TunnelProviderDependencies.java new file mode 100644 index 0000000000..0bf428c3f9 --- /dev/null +++ b/pcep/tunnel/tunnel-provider/src/main/java/org/opendaylight/bgpcep/pcep/tunnel/provider/TunnelProviderDependencies.java @@ -0,0 +1,58 @@ +/* + * Copyright (c) 2017 AT&T Intellectual Property. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v1.0 which accompanies this distribution, + * and is available at http://www.eclipse.org/legal/epl-v10.html + */ +package org.opendaylight.bgpcep.pcep.tunnel.provider; + +import static java.util.Objects.requireNonNull; + +import org.opendaylight.controller.md.sal.binding.api.DataBroker; +import org.opendaylight.controller.sal.binding.api.RpcProviderRegistry; +import org.opendaylight.mdsal.singleton.common.api.ClusterSingletonServiceProvider; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.topology.pcep.rev171025.NetworkTopologyPcepService; +import org.osgi.framework.BundleContext; + +final class TunnelProviderDependencies { + private final DataBroker dataBroker; + private final ClusterSingletonServiceProvider cssp; + private final NetworkTopologyPcepService ntps; + private final RpcProviderRegistry rpcProviderRegistry; + private final BundleContext bundleContext; + + TunnelProviderDependencies( + final DataBroker dataBroker, + final ClusterSingletonServiceProvider cssp, + final RpcProviderRegistry rpcProviderRegistry, + final BundleContext bundleContext + ) { + + this.dataBroker = requireNonNull(dataBroker); + this.cssp = requireNonNull(cssp); + this.rpcProviderRegistry = requireNonNull(rpcProviderRegistry); + this.bundleContext = requireNonNull(bundleContext); + this.ntps = this.rpcProviderRegistry.getRpcService(NetworkTopologyPcepService.class); + } + + DataBroker getDataBroker() { + return this.dataBroker; + } + + ClusterSingletonServiceProvider getCssp() { + return this.cssp; + } + + NetworkTopologyPcepService getNtps() { + return this.ntps; + } + + RpcProviderRegistry getRpcProviderRegistry() { + return this.rpcProviderRegistry; + } + + BundleContext getBundleContext() { + return this.bundleContext; + } +} diff --git a/pcep/tunnel/tunnel-provider/src/main/java/org/opendaylight/bgpcep/pcep/tunnel/provider/TunnelProviderDeployer.java b/pcep/tunnel/tunnel-provider/src/main/java/org/opendaylight/bgpcep/pcep/tunnel/provider/TunnelProviderDeployer.java new file mode 100644 index 0000000000..26cde11443 --- /dev/null +++ b/pcep/tunnel/tunnel-provider/src/main/java/org/opendaylight/bgpcep/pcep/tunnel/provider/TunnelProviderDeployer.java @@ -0,0 +1,162 @@ +/* + * Copyright (c) 2017 AT&T Intellectual Property. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v1.0 which accompanies this distribution, + * and is available at http://www.eclipse.org/legal/epl-v10.html + */ +package org.opendaylight.bgpcep.pcep.tunnel.provider; + +import static org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType.CONFIGURATION; + +import java.util.Collection; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.concurrent.TimeUnit; +import java.util.stream.Collectors; +import javax.annotation.Nonnull; +import javax.annotation.concurrent.GuardedBy; +import org.opendaylight.bgpcep.pcep.topology.provider.config.PCEPTopologyDeployerImpl; +import org.opendaylight.controller.md.sal.binding.api.ClusteredDataTreeChangeListener; +import org.opendaylight.controller.md.sal.binding.api.DataBroker; +import org.opendaylight.controller.md.sal.binding.api.DataObjectModification; +import org.opendaylight.controller.md.sal.binding.api.DataTreeIdentifier; +import org.opendaylight.controller.md.sal.binding.api.DataTreeModification; +import org.opendaylight.controller.sal.binding.api.RpcProviderRegistry; +import org.opendaylight.mdsal.singleton.common.api.ClusterSingletonServiceProvider; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.topology.tunnel.pcep.config.rev171127.PcepTunnelTopologyConfig; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.topology.tunnel.pcep.rev130820.TopologyTypes1; +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.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.TopologyTypes; +import org.opendaylight.yangtools.concepts.ListenerRegistration; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; +import org.osgi.framework.BundleContext; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public final class TunnelProviderDeployer implements ClusteredDataTreeChangeListener, AutoCloseable { + + private static final Logger LOG = LoggerFactory.getLogger(PCEPTopologyDeployerImpl.class); + + private static final long TIMEOUT_NS = TimeUnit.SECONDS.toNanos(5); + private final TunnelProviderDependencies dependencies; + private final InstanceIdentifier networTopology; + @GuardedBy("this") + private final Map pcepTunnelServices = new HashMap<>(); + @GuardedBy("this") + private ListenerRegistration listenerRegistration; + + public TunnelProviderDeployer( + final DataBroker dataBroker, + final RpcProviderRegistry rpcProviderRegistry, + final BundleContext bundleContext, + final ClusterSingletonServiceProvider cssp + ) { + this.dependencies = new TunnelProviderDependencies(dataBroker, cssp, rpcProviderRegistry, bundleContext); + this.networTopology = InstanceIdentifier.builder(NetworkTopology.class).child(Topology.class).build(); + } + + @SuppressWarnings("checkstyle:IllegalCatch") + private static void closeTopology(final PCEPTunnelClusterSingletonService topology, final TopologyId topologyId) { + if (topology != null) { + try { + topology.closeServiceInstance().get(TIMEOUT_NS, TimeUnit.NANOSECONDS); + } catch (final Exception e) { + LOG.error("Topology {} instance failed to close service instance", topologyId, e); + } + topology.close(); + } + } + + public synchronized void init() { + this.listenerRegistration = this.dependencies.getDataBroker().registerDataTreeChangeListener( + new DataTreeIdentifier<>(CONFIGURATION, this.networTopology), this); + } + + @Override + public synchronized void onDataTreeChanged(@Nonnull final Collection> changes) { + final List> topoChanges = changes.stream() + .map(DataTreeModification::getRootNode) + .collect(Collectors.toList()); + + topoChanges.stream().iterator().forEachRemaining(this::handleTopologyChange); + } + + private synchronized void handleTopologyChange(final DataObjectModification topo) { + switch (topo.getModificationType()) { + case SUBTREE_MODIFIED: + updateTunnelTopologyProvider(topo.getDataAfter()); + break; + case WRITE: + createTunnelTopologyProvider(topo.getDataAfter()); + break; + case DELETE: + removeTunnelTopologyProvider(topo.getDataBefore()); + break; + default: + } + } + + private boolean filterPcepTopologies(final TopologyTypes topologyTypes) { + if (topologyTypes == null) { + return false; + } + final TopologyTypes1 aug = topologyTypes.getAugmentation(TopologyTypes1.class); + return aug != null && aug.getTopologyTunnelPcep() != null; + } + + private synchronized void createTunnelTopologyProvider(final Topology topology) { + if (!filterPcepTopologies(topology.getTopologyTypes())) { + return; + } + final TopologyId topologyId = topology.getTopologyId(); + if (this.pcepTunnelServices.containsKey(topology.getTopologyId())) { + LOG.warn("Tunnel Topology {} already exist. New instance won't be created", topologyId); + return; + } + + final PcepTunnelTopologyConfig config = topology.getAugmentation(PcepTunnelTopologyConfig.class); + final String pcepTopoID = config.getPcepTopologyReference().getValue(); + + final InstanceIdentifier pcepTopoRef = InstanceIdentifier.builder(NetworkTopology.class) + .child(Topology.class, new TopologyKey(new TopologyId(pcepTopoID))).build(); + + + final PCEPTunnelClusterSingletonService tunnelTopoCss = + new PCEPTunnelClusterSingletonService(this.dependencies, pcepTopoRef, topologyId); + this.pcepTunnelServices.put(topology.getTopologyId(), tunnelTopoCss); + } + + private synchronized void updateTunnelTopologyProvider(final Topology topology) { + if (!filterPcepTopologies(topology.getTopologyTypes())) { + return; + } + final TopologyId topologyId = topology.getTopologyId(); + final PCEPTunnelClusterSingletonService previous = this.pcepTunnelServices.remove(topology.getTopologyId()); + closeTopology(previous, topologyId); + createTunnelTopologyProvider(topology); + } + + private synchronized void removeTunnelTopologyProvider(final Topology topo) { + if (!filterPcepTopologies(topo.getTopologyTypes())) { + return; + } + final TopologyId topologyId = topo.getTopologyId(); + final PCEPTunnelClusterSingletonService topology = this.pcepTunnelServices.remove(topologyId); + closeTopology(topology, topologyId); + } + + @Override + public synchronized void close() { + if (this.listenerRegistration != null) { + this.listenerRegistration.close(); + this.listenerRegistration = null; + } + this.pcepTunnelServices.values().iterator().forEachRemaining(PCEPTunnelClusterSingletonService::close); + this.pcepTunnelServices.clear(); + } +} diff --git a/pcep/tunnel/tunnel-provider/src/main/java/org/opendaylight/bgpcep/pcep/tunnel/provider/UpdateTunnelInstructionExecutor.java b/pcep/tunnel/tunnel-provider/src/main/java/org/opendaylight/bgpcep/pcep/tunnel/provider/UpdateTunnelInstructionExecutor.java index 7ed172c2a2..fce111a706 100644 --- a/pcep/tunnel/tunnel-provider/src/main/java/org/opendaylight/bgpcep/pcep/tunnel/provider/UpdateTunnelInstructionExecutor.java +++ b/pcep/tunnel/tunnel-provider/src/main/java/org/opendaylight/bgpcep/pcep/tunnel/provider/UpdateTunnelInstructionExecutor.java @@ -50,7 +50,7 @@ final class UpdateTunnelInstructionExecutor extends AbstractInstructionExecutor private final NetworkTopologyPcepService topologyService; UpdateTunnelInstructionExecutor(final PcepUpdateTunnelInput updateTunnelInput, final DataBroker dataProvider, - final NetworkTopologyPcepService topologyService) { + final NetworkTopologyPcepService topologyService) { super(updateTunnelInput); this.updateTunnelInput = updateTunnelInput; this.dataProvider = dataProvider; @@ -61,7 +61,7 @@ final class UpdateTunnelInstructionExecutor extends AbstractInstructionExecutor protected ListenableFuture invokeOperation() { final InstanceIdentifier tii = TopologyProgrammingUtil.topologyForInput(this.updateTunnelInput); final InstanceIdentifier lii = TunnelProgrammingUtil.linkIdentifier(tii, this.updateTunnelInput); - try (final ReadOnlyTransaction t = this.dataProvider.newReadOnlyTransaction()) { + try (ReadOnlyTransaction t = this.dataProvider.newReadOnlyTransaction()) { final Link link; final Node node; try { @@ -74,8 +74,9 @@ final class UpdateTunnelInstructionExecutor extends AbstractInstructionExecutor return TunelProgrammingUtil.RESULT; } return Futures.transform( - (ListenableFuture>) this.topologyService.updateLsp(buildUpdateInput(link, node)), - RpcResult::getResult, MoreExecutors.directExecutor()); + (ListenableFuture>) this.topologyService + .updateLsp(buildUpdateInput(link, node)), + RpcResult::getResult, MoreExecutors.directExecutor()); } } @@ -84,17 +85,19 @@ final class UpdateTunnelInstructionExecutor extends AbstractInstructionExecutor ab.setName(link.getAugmentation(Link1.class).getSymbolicPathName()); ab.setNode(requireNonNull(TunelProgrammingUtil.supportingNode(node))); - final org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.topology.pcep.rev171025.update.lsp.args.ArgumentsBuilder args = - new org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.topology.pcep.rev171025.update.lsp.args.ArgumentsBuilder(); + final org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.topology.pcep.rev171025.update.lsp + .args.ArgumentsBuilder args = new org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns + .yang.topology.pcep.rev171025.update.lsp.args.ArgumentsBuilder(); args.setBandwidth(new BandwidthBuilder().setBandwidth(this.updateTunnelInput.getBandwidth()).build()); args.setClassType(new ClassTypeBuilder().setClassType(this.updateTunnelInput.getClassType()).build()); args.setEro(TunelProgrammingUtil.buildEro(this.updateTunnelInput.getExplicitHops())); args.setLspa(new LspaBuilder(this.updateTunnelInput).build()); - final AdministrativeStatus adminStatus = this.updateTunnelInput.getAugmentation(PcepUpdateTunnelInput1.class).getAdministrativeStatus(); + final AdministrativeStatus adminStatus = this.updateTunnelInput.getAugmentation(PcepUpdateTunnelInput1.class) + .getAdministrativeStatus(); if (adminStatus != null) { - args.addAugmentation(Arguments3.class, new Arguments3Builder().setLsp(new LspBuilder(). - setAdministrative(adminStatus == AdministrativeStatus.Active).build()).build()); + args.addAugmentation(Arguments3.class, new Arguments3Builder().setLsp(new LspBuilder() + .setAdministrative(adminStatus == AdministrativeStatus.Active).build()).build()); } ab.setArguments(args.build()); return ab.build(); diff --git a/pcep/tunnel/tunnel-provider/src/main/java/org/opendaylight/controller/config/yang/pcep/tunnel/provider/PCEPTunnelTopologyProviderModule.java b/pcep/tunnel/tunnel-provider/src/main/java/org/opendaylight/controller/config/yang/pcep/tunnel/provider/PCEPTunnelTopologyProviderModule.java deleted file mode 100644 index 1f0a4004fc..0000000000 --- a/pcep/tunnel/tunnel-provider/src/main/java/org/opendaylight/controller/config/yang/pcep/tunnel/provider/PCEPTunnelTopologyProviderModule.java +++ /dev/null @@ -1,82 +0,0 @@ -/* - * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved. - * - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v1.0 which accompanies this distribution, - * and is available at http://www.eclipse.org/legal/epl-v10.html - */ -/** - * Generated file - - * Generated from: yang module name: config-pcep-tunnel-provider yang module local name: pcep-tunnel-topology-impl - * Generated by: org.opendaylight.controller.config.yangjmxgenerator.plugin.JMXGenerator - * Generated at: Tue Nov 19 04:23:38 CET 2013 - * - * Do not modify this file unless it is present under src/main directory - */ -package org.opendaylight.controller.config.yang.pcep.tunnel.provider; - -import org.opendaylight.bgpcep.pcep.tunnel.provider.PCEPTunnelTopologyProvider; -import org.opendaylight.bgpcep.pcep.tunnel.provider.TunnelProgramming; -import org.opendaylight.bgpcep.topology.DefaultTopologyReference; -import org.opendaylight.controller.config.api.JmxAttributeValidationException; -import org.opendaylight.controller.sal.binding.api.BindingAwareBroker; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.network.topology.rev140113.NetworkTopologyContext; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.topology.pcep.rev171025.NetworkTopologyPcepService; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.topology.tunnel.pcep.programming.rev131030.TopologyTunnelPcepProgrammingService; -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.network.topology.Topology; -import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.TopologyKey; -import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; - -/** - * - */ -public final class PCEPTunnelTopologyProviderModule extends AbstractPCEPTunnelTopologyProviderModule { - - public PCEPTunnelTopologyProviderModule(final org.opendaylight.controller.config.api.ModuleIdentifier identifier, - final org.opendaylight.controller.config.api.DependencyResolver dependencyResolver) { - super(identifier, dependencyResolver); - } - - public PCEPTunnelTopologyProviderModule(final org.opendaylight.controller.config.api.ModuleIdentifier identifier, - final org.opendaylight.controller.config.api.DependencyResolver dependencyResolver, - final PCEPTunnelTopologyProviderModule oldModule, final java.lang.AutoCloseable oldInstance) { - super(identifier, dependencyResolver, oldModule, oldInstance); - } - - @Override - public void validate() { - super.validate(); - JmxAttributeValidationException.checkNotNull(getTopologyId(), "is not set.", topologyIdJmxAttribute); - } - - @Override - public java.lang.AutoCloseable createInstance() { - final PCEPTunnelTopologyProvider ttp = PCEPTunnelTopologyProvider.create(getDataProviderDependency(), - getSourceTopologyDependency().getInstanceIdentifier(), getTopologyId()); - final NetworkTopologyPcepService ntps = getRpcRegistryDependency().getRpcService(NetworkTopologyPcepService.class); - final TunnelProgramming tp = new TunnelProgramming(getSchedulerDependency(), getDataProviderDependency(), ntps); - - final BindingAwareBroker.RoutedRpcRegistration reg = getRpcRegistryDependency().addRoutedRpcImplementation( - TopologyTunnelPcepProgrammingService.class, tp); - final InstanceIdentifier topology = InstanceIdentifier.builder(NetworkTopology.class).child(Topology.class, - new TopologyKey(getTopologyId())).build(); - reg.registerPath(NetworkTopologyContext.class, topology); - - final class TunnelTopologyReferenceCloseable extends DefaultTopologyReference implements AutoCloseable { - public TunnelTopologyReferenceCloseable(final InstanceIdentifier instanceIdentifier) { - super(instanceIdentifier); - } - - @Override - public void close() { - reg.close(); - tp.close(); - ttp.close(); - } - } - - return new TunnelTopologyReferenceCloseable(ttp.getTopologyReference().getInstanceIdentifier()); - } -} diff --git a/pcep/tunnel/tunnel-provider/src/main/java/org/opendaylight/controller/config/yang/pcep/tunnel/provider/PCEPTunnelTopologyProviderModuleFactory.java b/pcep/tunnel/tunnel-provider/src/main/java/org/opendaylight/controller/config/yang/pcep/tunnel/provider/PCEPTunnelTopologyProviderModuleFactory.java deleted file mode 100644 index 92f10cf155..0000000000 --- a/pcep/tunnel/tunnel-provider/src/main/java/org/opendaylight/controller/config/yang/pcep/tunnel/provider/PCEPTunnelTopologyProviderModuleFactory.java +++ /dev/null @@ -1,25 +0,0 @@ -/* - * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved. - * - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v1.0 which accompanies this distribution, - * and is available at http://www.eclipse.org/legal/epl-v10.html - */ -/** - * Generated file - - * Generated from: yang module name: config-pcep-tunnel-provider yang module local name: pcep-tunnel-topology-impl - * Generated by: org.opendaylight.controller.config.yangjmxgenerator.plugin.JMXGenerator - * Generated at: Tue Nov 19 04:23:38 CET 2013 - * - * Do not modify this file unless it is present under src/main directory - */ -package org.opendaylight.controller.config.yang.pcep.tunnel.provider; - -/** -* -*/ -public class PCEPTunnelTopologyProviderModuleFactory extends - org.opendaylight.controller.config.yang.pcep.tunnel.provider.AbstractPCEPTunnelTopologyProviderModuleFactory { - -} diff --git a/pcep/tunnel/tunnel-provider/src/main/resources/org/opendaylight/blueprint/pcep-tunnel-provider.xml b/pcep/tunnel/tunnel-provider/src/main/resources/org/opendaylight/blueprint/pcep-tunnel-provider.xml new file mode 100644 index 0000000000..af8d98c4e2 --- /dev/null +++ b/pcep/tunnel/tunnel-provider/src/main/resources/org/opendaylight/blueprint/pcep-tunnel-provider.xml @@ -0,0 +1,18 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/pcep/tunnel/tunnel-provider/src/main/yang/odl-pcep-tunnel-provider-cfg.yang b/pcep/tunnel/tunnel-provider/src/main/yang/odl-pcep-tunnel-provider-cfg.yang deleted file mode 100644 index 6f1f063051..0000000000 --- a/pcep/tunnel/tunnel-provider/src/main/yang/odl-pcep-tunnel-provider-cfg.yang +++ /dev/null @@ -1,96 +0,0 @@ -// vi: set smarttab et sw=4 tabstop=4: -module odl-pcep-tunnel-provider-cfg { - yang-version 1; - namespace "urn:opendaylight:params:xml:ns:yang:controller:pcep:tunnel:provider"; - prefix "tun"; - - import config { prefix config; revision-date 2013-04-05; } - import odl-programming-spi-cfg { prefix pgmspi; revision-date 2013-11-15; } - import odl-pcep-topology-provider-cfg { prefix pceptopo; revision-date 2013-11-15; } - import odl-topology-api-cfg { prefix topo; revision-date 2013-11-15; } - import ietf-inet-types { prefix inet; revision-date 2013-07-15; } - import network-topology { prefix nt; revision-date 2013-10-21; } - import opendaylight-md-sal-binding { prefix mdsal; revision-date 2013-10-28; } - - organization "Cisco Systems, Inc."; - - contact "Robert Varga "; - - description - "This module contains the base YANG definitions for - PCEP tunnel topology provider service. - - Copyright (c)2013 Cisco Systems, Inc. All rights reserved.; - - This program and the accompanying materials are made available - under the terms of the Eclipse Public License v1.0 which - accompanies this distribution, and is available at - http://www.eclipse.org/legal/epl-v10.html"; - - revision "2013-11-15" { - description - "Initial revision"; - } - - identity pcep-tunnel-topology-reference { - description - "Service representing a PCEP-enabled tunnel topology."; - - base "config:service-type"; - config:java-class "org.opendaylight.bgpcep.topology.TopologyReference"; - } - - identity pcep-tunnel-topology-provider { - base config:module-type; - config:provided-service pcep-tunnel-topology-reference; - config:java-name-prefix PCEPTunnelTopologyProvider; - } - - augment "/config:modules/config:module/config:configuration" { - case pcep-tunnel-topology-provider { - when "/config:modules/config:module/config:type = 'pcep-tunnel-topology-provider'"; - - container data-provider { - uses config:service-ref { - refine type { - mandatory true; - config:required-identity mdsal:binding-async-data-broker; - } - } - } - - container rpc-registry { - uses config:service-ref { - refine type { - mandatory true; - config:required-identity mdsal:binding-rpc-registry; - } - } - } - - container scheduler { - uses config:service-ref { - refine type { - mandatory true; - config:required-identity pgmspi:instruction-scheduler; - } - } - } - - container source-topology { - uses config:service-ref { - refine type { - mandatory true; - config:required-identity pceptopo:pcep-topology-reference; - } - } - } - - leaf topology-id { - type nt:topology-id; - mandatory true; - } - } - } -} - diff --git a/pcep/tunnel/tunnel-provider/src/test/java/org/opendaylight/bgpcep/pcep/tunnel/provider/NodeChangedListenerTest.java b/pcep/tunnel/tunnel-provider/src/test/java/org/opendaylight/bgpcep/pcep/tunnel/provider/NodeChangedListenerTest.java index 28f4c27301..06c1412ebe 100644 --- a/pcep/tunnel/tunnel-provider/src/test/java/org/opendaylight/bgpcep/pcep/tunnel/provider/NodeChangedListenerTest.java +++ b/pcep/tunnel/tunnel-provider/src/test/java/org/opendaylight/bgpcep/pcep/tunnel/provider/NodeChangedListenerTest.java @@ -78,9 +78,9 @@ public class NodeChangedListenerTest extends AbstractConcurrentDataBrokerTest { private static final long LSP2_ID = 2; private static final InstanceIdentifier PCEP_TOPO_IID = InstanceIdentifier.builder(NetworkTopology.class) - .child(Topology.class, new TopologyKey(PCEP_TOPOLOGY_ID)).build(); - private static final InstanceIdentifier TUNNEL_TOPO_IID = InstanceIdentifier. - builder(NetworkTopology.class).child(Topology.class, new TopologyKey(TUNNEL_TOPOLOGY_ID)).build(); + .child(Topology.class, new TopologyKey(PCEP_TOPOLOGY_ID)).build(); + private static final InstanceIdentifier TUNNEL_TOPO_IID = InstanceIdentifier + .builder(NetworkTopology.class).child(Topology.class, new TopologyKey(TUNNEL_TOPOLOGY_ID)).build(); private ListenerRegistration listenerRegistration; @@ -88,15 +88,15 @@ public class NodeChangedListenerTest extends AbstractConcurrentDataBrokerTest { public void setUp() throws TransactionCommitFailedException { final WriteTransaction wTx = getDataBroker().newWriteOnlyTransaction(); wTx.put(LogicalDatastoreType.OPERATIONAL, PCEP_TOPO_IID, new TopologyBuilder() - .setKey(new TopologyKey(PCEP_TOPOLOGY_ID)).setNode(Lists.newArrayList()) - .setTopologyId(PCEP_TOPOLOGY_ID).build(), true); + .setKey(new TopologyKey(PCEP_TOPOLOGY_ID)).setNode(Lists.newArrayList()) + .setTopologyId(PCEP_TOPOLOGY_ID).build(), true); wTx.put(LogicalDatastoreType.OPERATIONAL, TUNNEL_TOPO_IID, new TopologyBuilder() - .setKey(new TopologyKey(TUNNEL_TOPOLOGY_ID)).setTopologyId(TUNNEL_TOPOLOGY_ID).build(), true); + .setKey(new TopologyKey(TUNNEL_TOPOLOGY_ID)).setTopologyId(TUNNEL_TOPOLOGY_ID).build(), true); wTx.submit().checkedGet(); final NodeChangedListener nodeListener = new NodeChangedListener(getDataBroker(), - PCEP_TOPOLOGY_ID, TUNNEL_TOPO_IID); + PCEP_TOPOLOGY_ID, TUNNEL_TOPO_IID); this.listenerRegistration = getDataBroker().registerDataTreeChangeListener(new DataTreeIdentifier<>( - LogicalDatastoreType.OPERATIONAL, PCEP_TOPO_IID.child(Node.class)), nodeListener); + LogicalDatastoreType.OPERATIONAL, PCEP_TOPO_IID.child(Node.class)), nodeListener); } @Test @@ -198,35 +198,40 @@ public class NodeChangedListenerTest extends AbstractConcurrentDataBrokerTest { } private void createNode(final NodeId nodeId, final String ipv4Address, final String lspName, final long lspId, - final String dstIpv4Address) throws TransactionCommitFailedException { + final String dstIpv4Address) throws TransactionCommitFailedException { final NodeBuilder nodeBuilder = new NodeBuilder(); nodeBuilder.setKey(new NodeKey(nodeId)); nodeBuilder.setNodeId(nodeId); final PathBuilder pathBuilder = new PathBuilder(); pathBuilder.setKey(new PathKey(new LspId(lspId))); pathBuilder.setBandwidth(new BandwidthBuilder().setBandwidth( - new Bandwidth(new byte[]{0x00, 0x00, (byte) 0xff, (byte) 0xff})).build()); + new Bandwidth(new byte[]{0x00, 0x00, (byte) 0xff, (byte) 0xff})).build()); pathBuilder.addAugmentation(Path1.class, new Path1Builder().setLsp(new LspBuilder().setTlvs(new TlvsBuilder() - .setLspIdentifiers(new LspIdentifiersBuilder().setAddressFamily(new Ipv4CaseBuilder().setIpv4( - new Ipv4Builder().setIpv4TunnelSenderAddress(new Ipv4Address(ipv4Address)).setIpv4ExtendedTunnelId( - new Ipv4ExtendedTunnelId(ipv4Address)).setIpv4TunnelEndpointAddress(new Ipv4Address(dstIpv4Address)) - .build()).build()).build()).build()).setAdministrative(true).setDelegate(true).build()).build()); + .setLspIdentifiers(new LspIdentifiersBuilder().setAddressFamily(new Ipv4CaseBuilder().setIpv4( + new Ipv4Builder().setIpv4TunnelSenderAddress(new Ipv4Address(ipv4Address)) + .setIpv4ExtendedTunnelId(new Ipv4ExtendedTunnelId(ipv4Address)) + .setIpv4TunnelEndpointAddress(new Ipv4Address(dstIpv4Address)) + .build()).build()).build()).build()).setAdministrative(true) + .setDelegate(true).build()).build()); final ReportedLsp reportedLps = new ReportedLspBuilder().setKey(new ReportedLspKey(lspName)).setPath( - Collections.singletonList(pathBuilder.build())).build(); + Collections.singletonList(pathBuilder.build())).build(); final Node1Builder node1Builder = new Node1Builder(); - node1Builder.setPathComputationClient(new PathComputationClientBuilder().setStateSync(PccSyncState.Synchronized) - .setReportedLsp(Lists.newArrayList(reportedLps)).setIpAddress(new IpAddress(new Ipv4Address(ipv4Address))) - .build()); + node1Builder.setPathComputationClient(new PathComputationClientBuilder() + .setStateSync(PccSyncState.Synchronized) + .setReportedLsp(Lists.newArrayList(reportedLps)) + .setIpAddress(new IpAddress(new Ipv4Address(ipv4Address))) + .build()); nodeBuilder.addAugmentation(Node1.class, node1Builder.build()); final WriteTransaction wTx = getDataBroker().newWriteOnlyTransaction(); wTx.put(LogicalDatastoreType.OPERATIONAL, PCEP_TOPO_IID.builder().child(Node.class, - new NodeKey(nodeId)).build(), nodeBuilder.build()); + new NodeKey(nodeId)).build(), nodeBuilder.build()); wTx.submit().checkedGet(); } private void removeNode(final NodeId nodeId) throws TransactionCommitFailedException { final WriteTransaction wTx = getDataBroker().newWriteOnlyTransaction(); - wTx.delete(LogicalDatastoreType.OPERATIONAL, PCEP_TOPO_IID.builder().child(Node.class, new NodeKey(nodeId)).build()); + wTx.delete(LogicalDatastoreType.OPERATIONAL, PCEP_TOPO_IID.builder() + .child(Node.class, new NodeKey(nodeId)).build()); wTx.submit().checkedGet(); } } diff --git a/pcep/tunnel/tunnel-provider/src/test/java/org/opendaylight/bgpcep/pcep/tunnel/provider/TunnelProgrammingTest.java b/pcep/tunnel/tunnel-provider/src/test/java/org/opendaylight/bgpcep/pcep/tunnel/provider/TunnelProgrammingTest.java index 391df75069..3a997a780e 100644 --- a/pcep/tunnel/tunnel-provider/src/test/java/org/opendaylight/bgpcep/pcep/tunnel/provider/TunnelProgrammingTest.java +++ b/pcep/tunnel/tunnel-provider/src/test/java/org/opendaylight/bgpcep/pcep/tunnel/provider/TunnelProgrammingTest.java @@ -10,6 +10,7 @@ package org.opendaylight.bgpcep.pcep.tunnel.provider; import com.google.common.collect.Lists; import com.google.common.util.concurrent.ListenableFuture; +import java.util.Collections; import java.util.List; import java.util.concurrent.ExecutionException; import java.util.concurrent.Executor; @@ -26,6 +27,8 @@ import org.opendaylight.controller.md.sal.binding.api.WriteTransaction; import org.opendaylight.controller.md.sal.binding.test.AbstractConcurrentDataBrokerTest; import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType; import org.opendaylight.controller.md.sal.common.api.data.TransactionCommitFailedException; +import org.opendaylight.controller.sal.binding.api.RpcProviderRegistry; +import org.opendaylight.mdsal.singleton.common.api.ClusterSingletonServiceProvider; import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpAddress; import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpPrefix; import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv4Address; @@ -93,11 +96,13 @@ import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.nt.l3.unicast.igp import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.nt.l3.unicast.igp.topology.rev131021.igp.termination.point.attributes.igp.termination.point.attributes.termination.point.type.IpBuilder; import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; import org.opendaylight.yangtools.yang.common.RpcResult; +import org.osgi.framework.BundleContext; public class TunnelProgrammingTest extends AbstractConcurrentDataBrokerTest { private static final TopologyId TOPOLOGY_ID = new TopologyId("tunnel-topo"); - private static final InstanceIdentifier TOPO_IID = InstanceIdentifier.builder(NetworkTopology.class).child(Topology.class, new TopologyKey(TOPOLOGY_ID)).build(); + private static final InstanceIdentifier TOPO_IID = InstanceIdentifier.builder(NetworkTopology.class) + .child(Topology.class, new TopologyKey(TOPOLOGY_ID)).build(); private static final String NODE1_IPV4 = "127.0.0.1"; private static final NodeId NODE1_ID = new NodeId("pcc://" + NODE1_IPV4); @@ -120,6 +125,12 @@ public class TunnelProgrammingTest extends AbstractConcurrentDataBrokerTest { private ListenableFuture instructionFuture; @Mock private Instruction instruction; + @Mock + private ClusterSingletonServiceProvider cssp; + @Mock + private RpcProviderRegistry rpr; + @Mock + private BundleContext bundleContext; private TunnelProgramming tunnelProgramming; @@ -134,8 +145,39 @@ public class TunnelProgrammingTest extends AbstractConcurrentDataBrokerTest { @Mock private ListenableFuture> futureRemoveLspOutput; + private static Node createNode(final NodeId nodeId, final TpId tpId, final String ipv4Address) { + final TerminationPointBuilder tpBuilder = new TerminationPointBuilder(); + tpBuilder.setTpId(tpId); + tpBuilder.setKey(new TerminationPointKey(tpId)); + tpBuilder.addAugmentation(TerminationPoint1.class, new TerminationPoint1Builder() + .setIgpTerminationPointAttributes(new IgpTerminationPointAttributesBuilder() + .setTerminationPointType(new IpBuilder() + .setIpAddress(Collections.singletonList(new IpAddress(new Ipv4Address(ipv4Address)))) + .build()).build()).build()); + final NodeBuilder nodeBuilder = new NodeBuilder(); + nodeBuilder.setNodeId(nodeId); + nodeBuilder.setKey(new NodeKey(nodeId)); + nodeBuilder.setTerminationPoint(Lists.newArrayList(tpBuilder.build())); + final SupportingNode supportingNode = new SupportingNodeBuilder() + .setKey(new SupportingNodeKey(nodeId, new TopologyId("dummy"))) + .addAugmentation(SupportingNode1.class, new SupportingNode1Builder() + .setPathComputationClient(new PathComputationClientBuilder() + .setControlling(true).build()).build()).build(); + nodeBuilder.setSupportingNode(Lists.newArrayList(supportingNode)); + return nodeBuilder.build(); + } + + private static ExplicitHops createExplicitHop(final String ipv4Prefix) { + final ExplicitHopsBuilder explcitHopsBuilder = new ExplicitHopsBuilder(); + explcitHopsBuilder.addAugmentation(ExplicitHops1.class, new ExplicitHops1Builder() + .setSubobjectType(new IpPrefixCaseBuilder().setIpPrefix(new IpPrefixBuilder() + .setIpPrefix(new IpPrefix(new Ipv4Prefix(ipv4Prefix))).build()).build()).build()); + return explcitHopsBuilder.build(); + } + @Before - public void setUp() throws SchedulerException, InterruptedException, ExecutionException, TransactionCommitFailedException { + public void setUp() throws SchedulerException, InterruptedException, ExecutionException, + TransactionCommitFailedException { MockitoAnnotations.initMocks(this); Mockito.doReturn(true).when(this.instruction).checkedExecutionStart(); Mockito.doNothing().when(this.instruction).executionCompleted(InstructionStatus.Failed, null); @@ -173,15 +215,21 @@ public class TunnelProgrammingTest extends AbstractConcurrentDataBrokerTest { }).when(this.topologyService).removeLsp(Mockito.any(RemoveLspInput.class)); Mockito.doReturn(this.instruction).when(this.instructionFuture).get(); Mockito.doReturn(true).when(this.instructionFuture).isDone(); - Mockito.doReturn(this.instructionFuture).when(this.scheduler).scheduleInstruction(Mockito.any(SubmitInstructionInput.class)); + Mockito.doReturn(this.instructionFuture).when(this.scheduler) + .scheduleInstruction(Mockito.any(SubmitInstructionInput.class)); + + Mockito.doReturn(this.topologyService).when(this.rpr) + .getRpcService(NetworkTopologyPcepService.class); createInitialTopology(); - this.tunnelProgramming = new TunnelProgramming(this.scheduler, getDataBroker(), this.topologyService); + final TunnelProviderDependencies dependencies = new TunnelProviderDependencies(getDataBroker(), this.cssp, + this.rpr, this.bundleContext); + this.tunnelProgramming = new TunnelProgramming(this.scheduler, dependencies); } @Test public void testTunnelProgramming() throws TransactionCommitFailedException { - final Bandwidth bwd = new Bandwidth(new byte[] {0x00, 0x00, 0x00, (byte) 0xff}); + final Bandwidth bwd = new Bandwidth(new byte[]{0x00, 0x00, 0x00, (byte) 0xff}); final ClassType classType = new ClassType((short) 1); final String tunnelName = "create-tunnel"; final NetworkTopologyRef topologyRef = new NetworkTopologyRef(TOPO_IID); @@ -194,7 +242,8 @@ public class TunnelProgrammingTest extends AbstractConcurrentDataBrokerTest { createInputBuilder.setClassType(classType); createInputBuilder.setSymbolicPathName(tunnelName); createInputBuilder.setExplicitHops(Lists.newArrayList()); - createInputBuilder.addAugmentation(PcepCreateP2pTunnelInput1.class, new PcepCreateP2pTunnelInput1Builder().setAdministrativeStatus(AdministrativeStatus.Active).build()); + createInputBuilder.addAugmentation(PcepCreateP2pTunnelInput1.class, new PcepCreateP2pTunnelInput1Builder() + .setAdministrativeStatus(AdministrativeStatus.Active).build()); this.tunnelProgramming.pcepCreateP2pTunnel(createInputBuilder.build()); //check add-lsp input Assert.assertNotNull(this.addLspInput); @@ -214,18 +263,21 @@ public class TunnelProgrammingTest extends AbstractConcurrentDataBrokerTest { updateInputBuilder.setNetworkTopologyRef(topologyRef); updateInputBuilder.setBandwidth(bwd); updateInputBuilder.setClassType(classType); - updateInputBuilder.setExplicitHops(Lists.newArrayList(createExplicitHop(IPV4_PREFIX1), createExplicitHop(IPV4_PREFIX2))); + updateInputBuilder.setExplicitHops(Lists.newArrayList(createExplicitHop(IPV4_PREFIX1), + createExplicitHop(IPV4_PREFIX2))); updateInputBuilder.setLinkId(LINK1_ID); - updateInputBuilder.addAugmentation(PcepUpdateTunnelInput1.class, new PcepUpdateTunnelInput1Builder().setAdministrativeStatus(AdministrativeStatus.Active).build()); + updateInputBuilder.addAugmentation(PcepUpdateTunnelInput1.class, new PcepUpdateTunnelInput1Builder() + .setAdministrativeStatus(AdministrativeStatus.Active).build()); this.tunnelProgramming.pcepUpdateTunnel(updateInputBuilder.build()); //check update-lsp input Assert.assertNotNull(this.updateLspInput); Assert.assertEquals(LINK1_ID.getValue(), this.updateLspInput.getName()); - final org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.topology.pcep.rev171025.update.lsp.args.Arguments updArgs = this.updateLspInput.getArguments(); + final org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.topology.pcep.rev171025.update.lsp + .args.Arguments updArgs = this.updateLspInput.getArguments(); Assert.assertEquals(2, updArgs.getEro().getSubobject().size()); final List subObjects = updArgs.getEro().getSubobject(); - final IpPrefixCase prefix1 = (IpPrefixCase)subObjects.get(0).getSubobjectType(); - final IpPrefixCase prefix2 = (IpPrefixCase)subObjects.get(1).getSubobjectType(); + final IpPrefixCase prefix1 = (IpPrefixCase) subObjects.get(0).getSubobjectType(); + final IpPrefixCase prefix2 = (IpPrefixCase) subObjects.get(1).getSubobjectType(); Assert.assertEquals(IPV4_PREFIX1, prefix1.getIpPrefix().getIpPrefix().getIpv4Prefix().getValue()); Assert.assertEquals(IPV4_PREFIX2, prefix2.getIpPrefix().getIpPrefix().getIpv4Prefix().getValue()); @@ -244,41 +296,25 @@ public class TunnelProgrammingTest extends AbstractConcurrentDataBrokerTest { topologyBuilder.setKey(new TopologyKey(TOPOLOGY_ID)); topologyBuilder.setServerProvided(true); topologyBuilder.setTopologyId(TOPOLOGY_ID); - topologyBuilder.setNode(Lists.newArrayList(createNode(NODE1_ID, TP1_ID, NODE1_IPV4), createNode(NODE2_ID, TP2_ID, NODE2_IPV4))); + topologyBuilder.setNode(Lists.newArrayList(createNode(NODE1_ID, TP1_ID, NODE1_IPV4), + createNode(NODE2_ID, TP2_ID, NODE2_IPV4))); final WriteTransaction wTx = getDataBroker().newWriteOnlyTransaction(); wTx.put(LogicalDatastoreType.OPERATIONAL, TOPO_IID, topologyBuilder.build(), true); wTx.submit().checkedGet(); } - private static Node createNode(final NodeId nodeId, final TpId tpId, final String ipv4Address) { - final TerminationPointBuilder tpBuilder = new TerminationPointBuilder(); - tpBuilder.setTpId(tpId); - tpBuilder.setKey(new TerminationPointKey(tpId)); - tpBuilder.addAugmentation(TerminationPoint1.class, new TerminationPoint1Builder().setIgpTerminationPointAttributes(new IgpTerminationPointAttributesBuilder().setTerminationPointType(new IpBuilder().setIpAddress(Lists.newArrayList(new IpAddress(new Ipv4Address(ipv4Address)))).build()).build()).build()); - final NodeBuilder nodeBuilder = new NodeBuilder(); - nodeBuilder.setNodeId(nodeId); - nodeBuilder.setKey(new NodeKey(nodeId)); - nodeBuilder.setTerminationPoint(Lists.newArrayList(tpBuilder.build())); - final SupportingNode supportingNode = new SupportingNodeBuilder().setKey(new SupportingNodeKey(nodeId, new TopologyId("dummy"))).addAugmentation(SupportingNode1.class, new SupportingNode1Builder().setPathComputationClient(new PathComputationClientBuilder().setControlling(true).build()).build()).build(); - nodeBuilder.setSupportingNode(Lists.newArrayList(supportingNode)); - return nodeBuilder.build(); - } - - private static ExplicitHops createExplicitHop(final String ipv4Prefix) { - final ExplicitHopsBuilder explcitHopsBuilder = new ExplicitHopsBuilder(); - explcitHopsBuilder.addAugmentation(ExplicitHops1.class, new ExplicitHops1Builder().setSubobjectType(new IpPrefixCaseBuilder().setIpPrefix(new IpPrefixBuilder().setIpPrefix(new IpPrefix(new Ipv4Prefix(ipv4Prefix))).build()).build()).build()); - return explcitHopsBuilder.build(); - } - private void createLink() throws TransactionCommitFailedException { final LinkBuilder linkBuilder = new LinkBuilder(); - linkBuilder.setSource(new org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.link.attributes.SourceBuilder().setSourceNode(NODE1_ID).setSourceTp(TP1_ID).build()); - linkBuilder.setDestination(new org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.link.attributes.DestinationBuilder().setDestNode(NODE2_ID).setDestTp(TP2_ID).build()); + linkBuilder.setSource(new org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology + .rev131021.link.attributes.SourceBuilder().setSourceNode(NODE1_ID).setSourceTp(TP1_ID).build()); + linkBuilder.setDestination(new org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology + .rev131021.link.attributes.DestinationBuilder().setDestNode(NODE2_ID).setDestTp(TP2_ID).build()); linkBuilder.setLinkId(LINK1_ID); linkBuilder.setKey(new LinkKey(LINK1_ID)); linkBuilder.addAugmentation(Link1.class, new Link1Builder().setSymbolicPathName(LINK1_ID.getValue()).build()); final WriteTransaction wTx = getDataBroker().newWriteOnlyTransaction(); - wTx.put(LogicalDatastoreType.OPERATIONAL, TOPO_IID.builder().child(Link.class, new LinkKey(LINK1_ID)).build(), linkBuilder.build(), true); + wTx.put(LogicalDatastoreType.OPERATIONAL, TOPO_IID.builder().child(Link.class, new LinkKey(LINK1_ID)).build(), + linkBuilder.build(), true); wTx.submit().checkedGet(); }