BUG-670: enable reporting of PCEP errors 67/8367/10
authorRobert Varga <rovarga@cisco.com>
Thu, 26 Jun 2014 12:26:07 +0000 (14:26 +0200)
committerDana Kutenicsova <dkutenic@cisco.com>
Tue, 15 Jul 2014 09:46:25 +0000 (11:46 +0200)
Adds a place where errors reported by a PCC can be stored and fills it
when a PCUpd request results in a failure.

Change-Id: Id235effcf6069b66b9f3f3cae19d0cb495ee332f
Signed-off-by: Robert Varga <rovarga@cisco.com>
pcep/topology-api/src/main/yang/network-topology-pcep.yang
pcep/topology-provider/src/main/java/org/opendaylight/bgpcep/pcep/topology/provider/OperationResults.java
pcep/topology-provider/src/main/java/org/opendaylight/bgpcep/pcep/topology/provider/Stateful07TopologySessionListener.java

index 3971daf7c0328eb0576292e52c7d3544216af510..07270940201123f86bb54aefea77d914cf2c87cd 100644 (file)
@@ -119,10 +119,38 @@ module network-topology-pcep {
     }
 
     typedef failure-type {
+        description
+            "Enumeration of all the distinct failure modes that can
+            happen while servicing a request towards the PCC.";
+
         type enumeration {
-            enum unsent;
-            enum no-ack;
-            enum failed;
+            enum unsent {
+                description
+                    "The request failed before it was sent to the PCC.
+                    PCC's state is guaranteed not to reflect state
+                    transition implied by the request. This typically
+                    happens if the request is syntactically invalid,
+                    the target PCC is not connected or disconnects
+                    while the request is enqueued.";
+            }
+            enum no-ack {
+                description
+                    "The request has been sent to the PCC, but the session
+                    went down before we have received confirmation of the
+                    request being received by the PCC. PCC's state is
+                    unknown -- the request may or may not be reflected
+                    in its internal state. The caller should not make
+                    any hard assumptions about PCC state until it reconnects
+                    and state synchronization completes.";
+            }
+            enum failed {
+                description
+                    "The request has been seen by the PCC, where it failed
+                    for some external reason. The caller can assume the
+                    state transition has not taken place, but is advised
+                    to examine the attached error list to gain a deeper
+                    understanding of the failure cause.";
+            }
         }
     }
 
@@ -142,6 +170,11 @@ module network-topology-pcep {
         leaf failure {
             type failure-type;
         }
+
+        list error {
+            when "../failure = failed";
+            uses pcep:pcep-error-object;
+        }
     }
 
     grouping lsp-metadata {
index d9d84cb2a352eae272e24de21fb08885ecb363d6..65a8002830fb234f5a6ec2d62971fd75666d715e 100644 (file)
@@ -7,43 +7,70 @@
  */
 package org.opendaylight.bgpcep.pcep.topology.provider;
 
+import com.google.common.base.Function;
+import com.google.common.collect.Lists;
 import com.google.common.util.concurrent.Futures;
 import com.google.common.util.concurrent.ListenableFuture;
 
+import java.util.Collections;
+import java.util.List;
+
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.pcerr.message.pcerr.message.Errors;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.topology.pcep.rev131024.FailureType;
 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.operation.result.Error;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.topology.pcep.rev131024.operation.result.ErrorBuilder;
 import org.opendaylight.yangtools.yang.binding.DataContainer;
 
 /**
  *
  */
-enum OperationResults implements OperationResult {
-    NOACK {
-        @Override
-        public FailureType getFailure() {
-            return FailureType.NoAck;
-        }
+final class OperationResults implements OperationResult {
+    static final OperationResults NOACK = new OperationResults(FailureType.NoAck);
+    static final OperationResults SUCCESS = new OperationResults((FailureType)null);
+    static final OperationResults UNSENT = new OperationResults(FailureType.Unsent);
 
-    },
-    SUCCESS {
+    private static final Function<Errors, Error> CONVERT_ERRORS = new Function<Errors, Error>() {
         @Override
-        public FailureType getFailure() {
-            return null;
-        }
-    },
-    UNSENT {
-        @Override
-        public FailureType getFailure() {
-            return FailureType.Unsent;
+        public Error apply(final Errors input) {
+            return new ErrorBuilder(input).build();
         }
     };
 
-    @Override
-    public Class<? extends DataContainer> getImplementedInterface() {
-        return OperationResult.class;
+    private final FailureType failure;
+    private final List<Error> error;
+
+    private OperationResults(final FailureType failure) {
+        this.failure = failure;
+        this.error = null;
+    }
+
+    private OperationResults(final List<Error> error) {
+        this.failure = FailureType.Failed;
+        this.error = error;
     }
 
     ListenableFuture<OperationResult> future() {
         return Futures.<OperationResult> immediateFuture(this);
     }
+
+    public static OperationResults createFailed(final List<Errors> errors) {
+        final List<Errors> e = errors != null ? errors : Collections.<Errors>emptyList();
+        return new OperationResults(Lists.transform(e, CONVERT_ERRORS));
+    }
+
+    @Override
+    public FailureType getFailure() {
+        return failure;
+    }
+
+    @Override
+    public List<Error> getError() {
+        return error;
+
+    }
+    @Override
+    public Class<? extends DataContainer> getImplementedInterface() {
+        return OperationResult.class;
+    }
 }
index b4e8e75f2acd315333e6df190c8168b1ff6f7f41..ef2fa3b0ce7fcadebf73848ac3f34e4b74b54b10 100644 (file)
@@ -115,7 +115,7 @@ final class Stateful07TopologySessionListener extends AbstractTopologySessionLis
                     if (id.getValue() != 0) {
                         final PCEPRequest req = removeRequest(id);
                         if (req != null) {
-                            req.setResult(OperationResults.SUCCESS);
+                            req.setResult(OperationResults.createFailed(errMsg.getErrors()));
                         } else {
                             LOG.warn("Request ID {} not found in outstanding DB", id);
                         }