Updated topology provider for stateful02. 32/4732/6
authorDana Kutenicsova <dkutenic@cisco.com>
Fri, 24 Jan 2014 18:17:18 +0000 (19:17 +0100)
committerGerrit Code Review <gerrit@opendaylight.org>
Sun, 26 Jan 2014 12:08:04 +0000 (12:08 +0000)
Change-Id: Ia77cf420a272cbcf64c925c899102a818cbc6485
Signed-off-by: Dana Kutenicsova <dkutenic@cisco.com>
pcep/ietf-stateful02/pom.xml
pcep/ietf-stateful02/src/main/yang/odl-pcep-ietf-stateful02.yang
pcep/topology-provider/src/main/java/org/opendaylight/bgpcep/pcep/topology/provider/Stateful02TopologySessionListener.java [new file with mode: 0644]
pcep/topology-provider/src/main/java/org/opendaylight/bgpcep/pcep/topology/provider/Stateful07TopologySessionListener.java

index e0b90af416c43efbd7b4c8d249027b1f49b231e7..fcd12aa851044be2cc4471642aab8fcc6369cd90 100644 (file)
             <groupId>${project.groupId}</groupId>
             <artifactId>pcep-topology-api</artifactId>
         </dependency>
+        <dependency>
+            <groupId>${project.groupId}</groupId>
+            <artifactId>pcep-tunnel-api</artifactId>
+        </dependency>
 
         <!--
             FIXME: this is in support of the generated code. This should not
index d1d2967e34caea5e6d19586eb7d721b9bebb031f..539f10d5f5995df70184e1664b81395862995e16 100644 (file)
@@ -7,6 +7,11 @@ module odl-pcep-ietf-stateful02 {
        import pcep-types { prefix pcep; revision-date 2013-10-05; }
        import pcep-message { prefix msg; revision-date 2013-10-07; }
        import rsvp { prefix rsvp; revision-date 2013-08-20; }
+       import network-topology { prefix nt; revision-date 2013-10-21; }
+       import network-topology-pcep { prefix topo; revision-date 2013-10-24; }
+       import topology-tunnel { prefix tt; revision-date 2013-08-19; }
+       import topology-tunnel-pcep { prefix tun; revision-date 2013-08-20; }
+       import topology-tunnel-pcep-programming { prefix ttpp; revision-date 2013-10-30; }
 
        organization "Cisco Systems, Inc.";
        contact "Dana Kutenicsova <dkutenic@cisco.com>";
@@ -228,4 +233,61 @@ module odl-pcep-ietf-stateful02 {
        augment "/msg:pcrep/msg:pcrep-message/msg:replies" {
                uses lsp-object;
        }
+       
+       augment "/nt:network-topology/nt:topology/nt:node/topo:path-computation-client/topo:reported-lsp" {
+               uses lsp-object;
+       }
+
+       augment "/nt:network-topology/nt:topology/nt:node/topo:path-computation-client/topo:stateful-tlv" {
+               uses stateful-capability-tlv;
+       }
+
+       augment "/topo:ensure-lsp-operational/topo:input/topo:arguments" {
+               leaf operational {
+                       type boolean;
+               }
+       }
+
+       typedef administrative-status {
+               type enumeration {
+                       enum active;
+                       enum inactive;
+               }
+               reference "https://tools.ietf.org/html/draft-ietf-pce-stateful-pce-07#section-7.3";
+       }
+
+       grouping cfg-attributes {
+               leaf administrative-status {
+                       type administrative-status;
+               }
+       }
+
+       grouping oper-attributes {
+               leaf operational-status {
+                       type boolean;
+                       config false;
+               }
+       }
+
+       augment "/nt:network-topology/nt:topology/nt:link" {
+               when "../../tunnel-types/pcep-tunnel";
+
+               uses cfg-attributes;
+               uses oper-attributes;
+       }
+
+       augment "/nt:network-topology/nt:topology/tt:paths" {
+               when "../../tunnel-types/pcep-tunnel";
+
+               uses cfg-attributes;
+               uses oper-attributes;
+       }
+
+       augment "/ttpp:pcep-create-p2p-tunnel/ttpp:input" {
+               uses cfg-attributes;
+       }
+
+       augment "/ttpp:pcep-update-tunnel/ttpp:input" {
+               uses cfg-attributes;
+       }
 }
diff --git a/pcep/topology-provider/src/main/java/org/opendaylight/bgpcep/pcep/topology/provider/Stateful02TopologySessionListener.java b/pcep/topology-provider/src/main/java/org/opendaylight/bgpcep/pcep/topology/provider/Stateful02TopologySessionListener.java
new file mode 100644 (file)
index 0000000..34ae634
--- /dev/null
@@ -0,0 +1,249 @@
+/*
+ * Copyright (c) 2014 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
+ */
+package org.opendaylight.bgpcep.pcep.topology.provider;
+
+import java.net.InetAddress;
+import java.nio.ByteBuffer;
+import java.util.Collections;
+
+import javax.annotation.concurrent.GuardedBy;
+
+import org.opendaylight.controller.sal.binding.api.data.DataModificationTransaction;
+import org.opendaylight.protocol.pcep.PCEPSession;
+import org.opendaylight.protocol.pcep.PCEPSessionListener;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.crabbe.initiated._00.rev140113.PcinitiateBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.crabbe.initiated._00.rev140113.pcinitiate.message.PcinitiateMessageBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.crabbe.initiated._00.rev140113.pcinitiate.message.pcinitiate.message.RequestsBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.crabbe.stateful._02.rev140110.Arguments1;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.crabbe.stateful._02.rev140110.PcrptMessage;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.crabbe.stateful._02.rev140110.PcupdBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.crabbe.stateful._02.rev140110.PlspId;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.crabbe.stateful._02.rev140110.ReportedLsp1;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.crabbe.stateful._02.rev140110.ReportedLsp1Builder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.crabbe.stateful._02.rev140110.StatefulTlv1;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.crabbe.stateful._02.rev140110.StatefulTlv1Builder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.crabbe.stateful._02.rev140110.Tlvs2;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.crabbe.stateful._02.rev140110.lsp.object.Lsp;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.crabbe.stateful._02.rev140110.lsp.object.LspBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.crabbe.stateful._02.rev140110.pcrpt.message.pcrpt.message.Reports;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.crabbe.stateful._02.rev140110.pcupd.message.PcupdMessageBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.crabbe.stateful._02.rev140110.pcupd.message.pcupd.message.UpdatesBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.crabbe.stateful._02.rev140110.pcupd.message.pcupd.message.updates.PathBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.crabbe.stateful._02.rev140110.stateful.capability.tlv.Stateful;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.Message;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.open.object.open.Tlvs;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.topology.pcep.rev131024.AddLspArgs;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.topology.pcep.rev131024.EnsureLspOperationalInput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.topology.pcep.rev131024.OperationResult;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.topology.pcep.rev131024.PccSyncState;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.topology.pcep.rev131024.RemoveLspArgs;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.topology.pcep.rev131024.UpdateLspArgs;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.topology.pcep.rev131024.pcep.client.attributes.PathComputationClientBuilder;
+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.ReportedLspBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.topology.pcep.rev131024.pcep.client.attributes.path.computation.client.StatefulTlvBuilder;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.common.base.Charsets;
+import com.google.common.base.Preconditions;
+import com.google.common.collect.ImmutableList;
+import com.google.common.util.concurrent.ListenableFuture;
+
+public class Stateful02TopologySessionListener extends AbstractTopologySessionListener<PlspId, PlspId> implements PCEPSessionListener {
+       private static final Logger LOG = LoggerFactory.getLogger(Stateful07TopologySessionListener.class);
+
+       /**
+        * @param serverSessionManager
+        */
+       Stateful02TopologySessionListener(final ServerSessionManager serverSessionManager) {
+               super(serverSessionManager);
+       }
+
+       @GuardedBy("this")
+       private long requestId = 1;
+
+       @Override
+       protected void onSessionUp(final PCEPSession session, final PathComputationClientBuilder pccBuilder) {
+               final InetAddress peerAddress = session.getRemoteAddress();
+
+               final Tlvs tlvs = session.getRemoteTlvs();
+               final Tlvs2 tlv = tlvs.getAugmentation(Tlvs2.class);
+               if (tlv != null) {
+                       final Stateful stateful = tlv.getStateful();
+                       if (stateful != null) {
+                               pccBuilder.setReportedLsp(Collections.<ReportedLsp> emptyList());
+                               pccBuilder.setStateSync(PccSyncState.InitialResync);
+                               pccBuilder.setStatefulTlv(new StatefulTlvBuilder().addAugmentation(StatefulTlv1.class, new StatefulTlv1Builder(tlv).build()).build());
+                       } else {
+                               LOG.debug("Peer {} does not advertise stateful TLV", peerAddress);
+                       }
+               } else {
+                       LOG.debug("Peer {} does not advertise stateful TLV", peerAddress);
+               }
+       }
+
+       @Override
+       protected synchronized boolean onMessage(final DataModificationTransaction trans, final Message message) {
+               if (!(message instanceof PcrptMessage)) {
+                       return true;
+               }
+
+               final org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.crabbe.stateful._02.rev140110.pcrpt.message.PcrptMessage rpt = ((PcrptMessage) message).getPcrptMessage();
+               for (final Reports r : rpt.getReports()) {
+                       final Lsp lsp = r.getLsp();
+
+                       if (!lsp.isSync()) {
+                               stateSynchronizationAchieved(trans);
+                               continue;
+                       }
+
+                       final ReportedLspBuilder rlb = new ReportedLspBuilder();
+                       rlb.addAugmentation(ReportedLsp1.class, new ReportedLsp1Builder().setLsp(r.getLsp()).build());
+                       boolean solicited = false;
+
+                       final PlspId id = lsp.getPlspId();
+                       if (id.getValue() != 0) {
+                               solicited = true;
+
+                               if (lsp.isOperational()) {
+                                       final PCEPRequest req = removeRequest(id);
+                                       if (req != null) {
+                                               LOG.debug("Request {} resulted in LSP operational state {}", id, lsp.isOperational());
+                                               rlb.setMetadata(req.getMetadata());
+                                               req.setResult(OperationResults.SUCCESS);
+                                       } else {
+                                               LOG.warn("Request ID {} not found in outstanding DB", id);
+                                       }
+                               }
+                       }
+
+                       if (!lsp.isRemove()) {
+                               final org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.crabbe.stateful._02.rev140110.lsp.object.lsp.Tlvs tlvs = r.getLsp().getTlvs();
+                               final String name;
+                               if (tlvs != null && tlvs.getSymbolicPathName() != null) {
+                                       name = Charsets.UTF_8.decode(ByteBuffer.wrap(tlvs.getSymbolicPathName().getPathName().getValue())).toString();
+                               } else {
+                                       name = null;
+                               }
+
+                               updateLsp(trans, id, name, rlb, solicited);
+                               LOG.debug("LSP {} updated", lsp);
+                       } else {
+                               removeLsp(trans, id);
+                               LOG.debug("LSP {} removed", lsp);
+                       }
+               }
+
+               return false;
+       }
+
+       @GuardedBy("this")
+       private PlspId nextRequest() {
+               return new PlspId(this.requestId++);
+       }
+
+       @Override
+       public synchronized ListenableFuture<OperationResult> addLsp(final AddLspArgs input) {
+               // Make sure there is no such LSP
+               final InstanceIdentifier<ReportedLsp> lsp = lspIdentifier(input.getName()).build();
+               if (this.serverSessionManager.readOperationalData(lsp) != null) {
+                       LOG.debug("Node {} already contains lsp {} at {}", input.getNode(), input.getName(), lsp);
+                       return OperationResults.UNSENT.future();
+               }
+
+               // Build the request
+               final RequestsBuilder rb = new RequestsBuilder();
+               rb.fieldsFrom(input.getArguments());
+
+               final PcinitiateMessageBuilder ib = new PcinitiateMessageBuilder(MESSAGE_HEADER);
+               ib.setRequests(ImmutableList.of(rb.build()));
+
+               // Send the message
+               return sendMessage(new PcinitiateBuilder().setPcinitiateMessage(ib.build()).build(), new PlspId(0L),
+                               input.getArguments().getMetadata());
+       }
+
+       @Override
+       public synchronized ListenableFuture<OperationResult> removeLsp(final RemoveLspArgs input) {
+               // Make sure the LSP exists, we need it for PLSP-ID
+               final InstanceIdentifier<ReportedLsp> lsp = lspIdentifier(input.getName()).build();
+               final ReportedLsp rep = this.serverSessionManager.readOperationalData(lsp);
+               if (rep == null) {
+                       LOG.debug("Node {} does not contain LSP {}", input.getNode(), input.getName());
+                       return OperationResults.UNSENT.future();
+               }
+
+               final ReportedLsp1 ra = rep.getAugmentation(ReportedLsp1.class);
+               Preconditions.checkState(ra != null);
+
+               // Build the request and send it
+               final UpdatesBuilder rb = new UpdatesBuilder();
+               rb.setLsp(new LspBuilder().setRemove(Boolean.TRUE).setPlspId(ra.getLsp().getPlspId()).setDelegate(Boolean.TRUE).build());
+
+               final PcupdMessageBuilder ib = new PcupdMessageBuilder(MESSAGE_HEADER);
+               ib.setUpdates(ImmutableList.of(rb.build()));
+               return sendMessage(new PcupdBuilder().setPcupdMessage(ib.build()).build(), ra.getLsp().getPlspId(), null);
+       }
+
+       @Override
+       public synchronized ListenableFuture<OperationResult> updateLsp(final UpdateLspArgs input) {
+               // Make sure the LSP exists
+               final InstanceIdentifier<ReportedLsp> lsp = lspIdentifier(input.getName()).build();
+               final ReportedLsp rep = this.serverSessionManager.readOperationalData(lsp);
+               if (rep == null) {
+                       LOG.debug("Node {} does not contain LSP {}", input.getNode(), input.getName());
+                       return OperationResults.UNSENT.future();
+               }
+
+               final ReportedLsp1 ra = rep.getAugmentation(ReportedLsp1.class);
+               Preconditions.checkState(ra != null);
+
+               // Build the PCUpd request and send it
+               final UpdatesBuilder rb = new UpdatesBuilder();
+               rb.setLsp(new LspBuilder().setPlspId(ra.getLsp().getPlspId()).setDelegate(Boolean.TRUE).build());
+               final PathBuilder pb = new PathBuilder();
+               rb.setPath(pb.setEro(input.getArguments().getEro()).build());
+
+               final PcupdMessageBuilder ub = new PcupdMessageBuilder(MESSAGE_HEADER);
+               ub.setUpdates(ImmutableList.of(rb.build()));
+               return sendMessage(new PcupdBuilder().setPcupdMessage(ub.build()).build(), ra.getLsp().getPlspId(),
+                               input.getArguments().getMetadata());
+       }
+
+       @Override
+       public synchronized ListenableFuture<OperationResult> ensureLspOperational(final EnsureLspOperationalInput input) {
+               Boolean op = null;
+               final Arguments1 aa = input.getArguments().getAugmentation(Arguments1.class);
+               if (aa != null) {
+                       op = aa.isOperational();
+               }
+
+               // Make sure the LSP exists
+               final InstanceIdentifier<ReportedLsp> lsp = lspIdentifier(input.getName()).build();
+               LOG.debug("Checking if LSP {} has operational state {}", lsp, op);
+               final ReportedLsp rep = this.serverSessionManager.readOperationalData(lsp);
+               if (rep == null) {
+                       LOG.debug("Node {} does not contain LSP {}", input.getNode(), input.getName());
+                       return OperationResults.UNSENT.future();
+               }
+
+               final ReportedLsp1 ra = rep.getAugmentation(ReportedLsp1.class);
+               if (ra == null) {
+                       LOG.warn("Node {} LSP {} does not contain data", input.getNode(), input.getName());
+                       return OperationResults.UNSENT.future();
+               }
+
+               if (ra.getLsp().isOperational().equals(op)) {
+                       return OperationResults.SUCCESS.future();
+               } else {
+                       return OperationResults.UNSENT.future();
+               }
+       }
+}
index fa729fcd801a30bb5d9c06bae782ec82182c0f8f..0c47d8350492e1e99f9b227c2e3f6f7b5078d9de 100644 (file)
@@ -87,8 +87,7 @@ final class Stateful07TopologySessionListener extends AbstractTopologySessionLis
                        if (stateful != null) {
                                pccBuilder.setReportedLsp(Collections.<ReportedLsp> emptyList());
                                pccBuilder.setStateSync(PccSyncState.InitialResync);
-                               pccBuilder.setStatefulTlv(
-                                               new StatefulTlvBuilder().addAugmentation(StatefulTlv1.class, new StatefulTlv1Builder(tlv).build()).build());
+                               pccBuilder.setStatefulTlv(new StatefulTlvBuilder().addAugmentation(StatefulTlv1.class, new StatefulTlv1Builder(tlv).build()).build());
                        } else {
                                LOG.debug("Peer {} does not advertise stateful TLV", peerAddress);
                        }
@@ -174,7 +173,7 @@ final class Stateful07TopologySessionListener extends AbstractTopologySessionLis
        public synchronized ListenableFuture<OperationResult> addLsp(final AddLspArgs input) {
                // Make sure there is no such LSP
                final InstanceIdentifier<ReportedLsp> lsp = lspIdentifier(input.getName()).build();
-               if (serverSessionManager.readOperationalData(lsp) != null) {
+               if (this.serverSessionManager.readOperationalData(lsp) != null) {
                        LOG.debug("Node {} already contains lsp {} at {}", input.getNode(), input.getName(), lsp);
                        return OperationResults.UNSENT.future();
                }
@@ -184,7 +183,8 @@ final class Stateful07TopologySessionListener extends AbstractTopologySessionLis
                rb.fieldsFrom(input.getArguments());
                rb.setSrp(new SrpBuilder().setOperationId(nextRequest()).setProcessingRule(Boolean.TRUE).build());
                rb.setLsp(new LspBuilder().setAdministrative(input.getArguments().isAdministrative()).setDelegate(Boolean.TRUE).setTlvs(
-                               new TlvsBuilder().setSymbolicPathName(new SymbolicPathNameBuilder().setPathName(new SymbolicPathName(input.getName().getBytes(Charsets.UTF_8))).build()).build()).build());
+                               new TlvsBuilder().setSymbolicPathName(
+                                               new SymbolicPathNameBuilder().setPathName(new SymbolicPathName(input.getName().getBytes(Charsets.UTF_8))).build()).build()).build());
 
                final PcinitiateMessageBuilder ib = new PcinitiateMessageBuilder(MESSAGE_HEADER);
                ib.setRequests(ImmutableList.of(rb.build()));
@@ -198,7 +198,7 @@ final class Stateful07TopologySessionListener extends AbstractTopologySessionLis
        public synchronized ListenableFuture<OperationResult> removeLsp(final RemoveLspArgs input) {
                // Make sure the LSP exists, we need it for PLSP-ID
                final InstanceIdentifier<ReportedLsp> lsp = lspIdentifier(input.getName()).build();
-               final ReportedLsp rep = serverSessionManager.readOperationalData(lsp);
+               final ReportedLsp rep = this.serverSessionManager.readOperationalData(lsp);
                if (rep == null) {
                        LOG.debug("Node {} does not contain LSP {}", input.getNode(), input.getName());
                        return OperationResults.UNSENT.future();
@@ -221,7 +221,7 @@ final class Stateful07TopologySessionListener extends AbstractTopologySessionLis
        public synchronized ListenableFuture<OperationResult> updateLsp(final UpdateLspArgs input) {
                // Make sure the LSP exists
                final InstanceIdentifier<ReportedLsp> lsp = lspIdentifier(input.getName()).build();
-               final ReportedLsp rep = serverSessionManager.readOperationalData(lsp);
+               final ReportedLsp rep = this.serverSessionManager.readOperationalData(lsp);
                if (rep == null) {
                        LOG.debug("Node {} does not contain LSP {}", input.getNode(), input.getName());
                        return OperationResults.UNSENT.future();
@@ -254,7 +254,7 @@ final class Stateful07TopologySessionListener extends AbstractTopologySessionLis
                // Make sure the LSP exists
                final InstanceIdentifier<ReportedLsp> lsp = lspIdentifier(input.getName()).build();
                LOG.debug("Checking if LSP {} has operational state {}", lsp, op);
-               final ReportedLsp rep = serverSessionManager.readOperationalData(lsp);
+               final ReportedLsp rep = this.serverSessionManager.readOperationalData(lsp);
                if (rep == null) {
                        LOG.debug("Node {} does not contain LSP {}", input.getNode(), input.getName());
                        return OperationResults.UNSENT.future();