TAPI topology Service RPCs impl 49/95049/41
authorJavier Errea <errea@eurecom.fr>
Fri, 5 Feb 2021 11:22:44 +0000 (12:22 +0100)
committererrea <errea@eurecom.fr>
Fri, 30 Apr 2021 12:38:24 +0000 (14:38 +0200)
- getNodeDetails
- getTopologyDetails
- getNodeEdgePointDetails
- getLinkDetails
- getTopologyList

JIRA: TRNSPRTPCE-427
Change-Id: I2a0afc32c9815f43cbd6982a4b3b1b19b0914303
Signed-off-by: errea <errea@eurecom.fr>
tapi/src/main/java/org/opendaylight/transportpce/tapi/topology/TapiTopologyImpl.java
tapi/src/main/java/org/opendaylight/transportpce/tapi/utils/TapiContext.java
tapi/src/test/java/org/opendaylight/transportpce/tapi/topology/TapiTopologyImplExceptionTest.java

index 46e618d671f9212ff93a72d0d8b3d93b29462077..20cc23de6de794143b0c3ac4f6a6238835afe8a7 100644 (file)
@@ -57,17 +57,23 @@ import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.topology.rev181210.Co
 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.topology.rev181210.ForwardingRule;
 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.topology.rev181210.GetLinkDetailsInput;
 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.topology.rev181210.GetLinkDetailsOutput;
+import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.topology.rev181210.GetLinkDetailsOutputBuilder;
 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.topology.rev181210.GetNodeDetailsInput;
 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.topology.rev181210.GetNodeDetailsOutput;
+import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.topology.rev181210.GetNodeDetailsOutputBuilder;
 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.topology.rev181210.GetNodeEdgePointDetailsInput;
 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.topology.rev181210.GetNodeEdgePointDetailsOutput;
+import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.topology.rev181210.GetNodeEdgePointDetailsOutputBuilder;
 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.topology.rev181210.GetTopologyDetailsInput;
 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.topology.rev181210.GetTopologyDetailsOutput;
 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.topology.rev181210.GetTopologyDetailsOutputBuilder;
 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.topology.rev181210.GetTopologyListInput;
 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.topology.rev181210.GetTopologyListOutput;
+import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.topology.rev181210.GetTopologyListOutputBuilder;
 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.topology.rev181210.RuleType;
 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.topology.rev181210.TapiTopologyService;
+import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.topology.rev181210.get.link.details.output.LinkBuilder;
+import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.topology.rev181210.get.node.edge.point.details.output.NodeEdgePointBuilder;
 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.topology.rev181210.get.topology.details.output.Topology;
 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.topology.rev181210.get.topology.details.output.TopologyBuilder;
 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.topology.rev181210.node.NodeRuleGroup;
@@ -84,6 +90,7 @@ import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.topology.rev181210.to
 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.topology.rev181210.topology.context.TopologyKey;
 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
 import org.opendaylight.yangtools.yang.binding.KeyedInstanceIdentifier;
+import org.opendaylight.yangtools.yang.common.RpcError;
 import org.opendaylight.yangtools.yang.common.RpcResult;
 import org.opendaylight.yangtools.yang.common.RpcResultBuilder;
 import org.slf4j.Logger;
@@ -105,7 +112,23 @@ public class TapiTopologyImpl implements TapiTopologyService {
     @Override
     public ListenableFuture<RpcResult<GetNodeDetailsOutput>> getNodeDetails(GetNodeDetailsInput input) {
         // TODO Auto-generated method stub
-        return null;
+        // TODO -> maybe we get errors when having CEPs?
+        Uuid topoUuid = new Uuid(UUID.nameUUIDFromBytes(input.getTopologyIdOrName().getBytes(Charset.forName("UTF-8")))
+                .toString());
+        // Node id: if roadm -> ROADM+PHOTONIC_MEDIA. if xpdr -> XPDR-XPDR+DSR/OTSi
+        Uuid nodeUuid = new Uuid(UUID.nameUUIDFromBytes(input.getNodeIdOrName().getBytes(Charset.forName("UTF-8")))
+                .toString());
+        org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.topology.rev181210.topology.Node node = this.tapiContext
+                .getTapiNode(topoUuid, nodeUuid);
+        if (node == null) {
+            LOG.error("Invalid TAPI node name");
+            return RpcResultBuilder.<GetNodeDetailsOutput>failed().withError(RpcError.ErrorType.RPC,
+                "Invalid Tapi Node name").buildFuture();
+        }
+        return RpcResultBuilder.success(new GetNodeDetailsOutputBuilder()
+                .setNode(new org.opendaylight.yang.gen.v1.urn
+                        .onf.otcc.yang.tapi.topology.rev181210.get.node.details.output.NodeBuilder(node).build())
+                .build()).buildFuture();
     }
 
     @Override
@@ -122,7 +145,8 @@ public class TapiTopologyImpl implements TapiTopologyService {
                     topologyMap = context.augmentation(Context1.class).getTopologyContext().getTopology();
                 if (!(topologyMap != null && topologyMap.containsKey(new TopologyKey(topoUuid)))) {
                     LOG.error("Topology {} not found in datastore", input.getTopologyIdOrName());
-                    return RpcResultBuilder.success(new GetTopologyDetailsOutputBuilder().build()).buildFuture();
+                    return RpcResultBuilder.<GetTopologyDetailsOutput>failed()
+                        .withError(RpcError.ErrorType.RPC, "Invalid Topology name").buildFuture();
                 }
                 org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.topology.rev181210.topology.context.Topology
                     topology = topologyMap.get(new TopologyKey(topoUuid));
@@ -132,7 +156,8 @@ public class TapiTopologyImpl implements TapiTopologyService {
                     .buildFuture();
             }
             LOG.error("Invalid TAPI topology name");
-            return RpcResultBuilder.success(new GetTopologyDetailsOutputBuilder().build()).buildFuture();
+            return RpcResultBuilder.<GetTopologyDetailsOutput>failed()
+                .withError(RpcError.ErrorType.RPC, "Invalid Topology name").buildFuture();
         }
         try {
             LOG.info("Building TAPI Topology abstraction for {}", input.getTopologyIdOrName());
@@ -144,7 +169,8 @@ public class TapiTopologyImpl implements TapiTopologyService {
                 .buildFuture();
         } catch (TapiTopologyException e) {
             LOG.error("error building TAPI topology");
-            return RpcResultBuilder.success(new GetTopologyDetailsOutputBuilder().build()).buildFuture();
+            return RpcResultBuilder.<GetTopologyDetailsOutput>failed()
+                .withError(RpcError.ErrorType.RPC, "Error building topology").buildFuture();
         }
     }
 
@@ -171,8 +197,7 @@ public class TapiTopologyImpl implements TapiTopologyService {
             .build();
     }
 
-    private Network readTopology(InstanceIdentifier<Network> networkIID)
-        throws TapiTopologyException {
+    private Network readTopology(InstanceIdentifier<Network> networkIID) throws TapiTopologyException {
         Network topology = null;
         FluentFuture<Optional<Network>> topologyFuture = dataBroker.newReadOnlyTransaction()
             .read(LogicalDatastoreType.CONFIGURATION, networkIID);
@@ -267,21 +292,71 @@ public class TapiTopologyImpl implements TapiTopologyService {
 
     @Override
     public ListenableFuture<RpcResult<GetNodeEdgePointDetailsOutput>> getNodeEdgePointDetails(
-        GetNodeEdgePointDetailsInput input) {
+            GetNodeEdgePointDetailsInput input) {
         // TODO Auto-generated method stub
-        return null;
+        // TODO -> maybe we get errors when having CEPs?
+        Uuid topoUuid = new Uuid(UUID.nameUUIDFromBytes(input.getTopologyIdOrName().getBytes(Charset.forName("UTF-8")))
+                .toString());
+        // Node id: if roadm -> ROADMid+PHOTONIC_MEDIA. if xpdr -> XPDRid-XPDRnbr+DSR/OTSi
+        Uuid nodeUuid = new Uuid(UUID.nameUUIDFromBytes(input.getNodeIdOrName().getBytes(Charset.forName("UTF-8")))
+                .toString());
+        // NEP id: if roadm -> ROADMid+PHOTONIC_MEDIA/MC/OTSiMC+TPid.
+        // if xpdr -> XPDRid-XPDRnbr+DSR/eODU/iODU/iOTSi/eOTSi/PHOTONIC_MEDIA+TPid
+        Uuid nepUuid = new Uuid(UUID.nameUUIDFromBytes(input.getEpIdOrName().getBytes(Charset.forName("UTF-8")))
+                .toString());
+        OwnedNodeEdgePoint nep = this.tapiContext.getTapiNEP(topoUuid, nodeUuid, nepUuid);
+        if (nep == null) {
+            LOG.error("Invalid TAPI nep name");
+            return RpcResultBuilder.<GetNodeEdgePointDetailsOutput>failed().withError(RpcError.ErrorType.RPC,
+                "Invalid NEP name").buildFuture();
+        }
+        return RpcResultBuilder.success(new GetNodeEdgePointDetailsOutputBuilder()
+                .setNodeEdgePoint(new NodeEdgePointBuilder(nep).build()).build()).buildFuture();
     }
 
     @Override
     public ListenableFuture<RpcResult<GetLinkDetailsOutput>> getLinkDetails(GetLinkDetailsInput input) {
         // TODO Auto-generated method stub
-        return null;
+        Uuid topoUuid = new Uuid(UUID.nameUUIDFromBytes(input.getTopologyIdOrName().getBytes(Charset.forName("UTF-8")))
+                .toString());
+        // Link id: same as OR link id
+        Uuid linkUuid = new Uuid(UUID.nameUUIDFromBytes(input.getLinkIdOrName().getBytes(Charset.forName("UTF-8")))
+                .toString());
+        org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.topology.rev181210.topology.Link link = this.tapiContext
+                .getTapiLink(topoUuid, linkUuid);
+        if (link == null) {
+            LOG.error("Invalid TAPI link name");
+            return RpcResultBuilder.<GetLinkDetailsOutput>failed().withError(RpcError.ErrorType.RPC,
+                "Invalid Link name").buildFuture();
+        }
+        return RpcResultBuilder.success(new GetLinkDetailsOutputBuilder().setLink(new LinkBuilder(link).build())
+                .build()).buildFuture();
     }
 
     @Override
     public ListenableFuture<RpcResult<GetTopologyListOutput>> getTopologyList(GetTopologyListInput input) {
         // TODO Auto-generated method stub
-        return null;
+        // TODO -> maybe we get errors when having CEPs?
+        Map<TopologyKey,
+                org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.topology.rev181210.topology.context.Topology>
+                topologyMap = this.tapiContext.getTopologyContext();
+        if (topologyMap.isEmpty()) {
+            LOG.error("No topologies exist in tapi context");
+            return RpcResultBuilder.<GetTopologyListOutput>failed().withError(RpcError.ErrorType.APPLICATION,
+                "No topologies exist in tapi context").buildFuture();
+        }
+        Map<org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.topology.rev181210.get.topology.list.output.TopologyKey,
+            org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.topology.rev181210.get.topology.list.output.Topology>
+                newTopoMap = new HashMap<>();
+        for (org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.topology.rev181210.topology.context.Topology
+                topo:topologyMap.values()) {
+            org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.topology.rev181210.get.topology.list.output.Topology
+                newTopo = new org.opendaylight.yang.gen.v1.urn
+                    .onf.otcc.yang.tapi.topology.rev181210.get.topology.list.output.TopologyBuilder(topo).build();
+            newTopoMap.put(newTopo.key(), newTopo);
+        }
+        return RpcResultBuilder.success(new GetTopologyListOutputBuilder().setTopology(newTopoMap).build())
+                .buildFuture();
     }
 
     private org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.topology.rev181210.topology.Node
index 521857d6a125e0c6ce1a50649296ca3ad7e5c6e0..1fc8c5c50c0b905db4ecdc00b22d3fe63ad32cce 100644 (file)
@@ -35,10 +35,15 @@ import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.connectivity.rev18121
 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.connectivity.rev181210.context.ConnectivityContextBuilder;
 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.connectivity.rev181210.context.topology.context.topology.node.owned.node.edge.point.CepList;
 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.connectivity.rev181210.context.topology.context.topology.node.owned.node.edge.point.CepListBuilder;
+import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.topology.rev181210.context.TopologyContext;
 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.topology.rev181210.context.TopologyContextBuilder;
 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.topology.rev181210.node.OwnedNodeEdgePoint;
 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.topology.rev181210.node.OwnedNodeEdgePointBuilder;
 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.topology.rev181210.node.OwnedNodeEdgePointKey;
+import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.topology.rev181210.topology.Link;
+import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.topology.rev181210.topology.LinkKey;
+import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.topology.rev181210.topology.Node;
+import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.topology.rev181210.topology.NodeBuilder;
 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.topology.rev181210.topology.NodeKey;
 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.topology.rev181210.topology.context.NwTopologyServiceBuilder;
 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.topology.rev181210.topology.context.Topology;
@@ -138,17 +143,14 @@ public class TapiContext {
         // TODO: solve error when merging: Topology is not a valid child of topology context?
         // TODO: verify this is correct. Should we identify the context IID with the context UUID??
         try {
-            org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.topology.rev181210.context.TopologyContext
-                    topologyContext = new TopologyContextBuilder()
+            TopologyContext topologyContext = new TopologyContextBuilder()
                     //.setNwTopologyService(new NwTopologyServiceBuilder().build())
                     .setTopology(topologyMap)
                     .build();
-            InstanceIdentifier<org.opendaylight.yang.gen.v1.urn
-                    .onf.otcc.yang.tapi.topology.rev181210.context.TopologyContext> topologycontextIID =
+            InstanceIdentifier<TopologyContext> topologycontextIID =
                     InstanceIdentifier.builder(Context.class).augmentation(org.opendaylight.yang.gen.v1.urn
                             .onf.otcc.yang.tapi.topology.rev181210.Context1.class)
-                            .child(org.opendaylight.yang.gen.v1.urn
-                                    .onf.otcc.yang.tapi.topology.rev181210.context.TopologyContext.class)
+                            .child(TopologyContext.class)
                             .build();
             // merge in datastore
             this.networkTransactionService.merge(LogicalDatastoreType.OPERATIONAL, topologycontextIID,
@@ -242,4 +244,114 @@ public class TapiContext {
             LOG.error("Couldnt update cep in topology", e);
         }
     }
+
+    public Node getTapiNode(Uuid topoUuid, Uuid nodeUuid) {
+        InstanceIdentifier<Node> nodeIID = InstanceIdentifier.builder(Context.class)
+            .augmentation(org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.topology.rev181210.Context1.class)
+            .child(org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.topology.rev181210.context.TopologyContext.class)
+            .child(Topology.class, new TopologyKey(topoUuid))
+            .child(org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.topology.rev181210.topology.Node.class,
+                        new NodeKey(nodeUuid)).build();
+        try {
+            Optional<Node> optNode = this.networkTransactionService.read(LogicalDatastoreType.OPERATIONAL, nodeIID)
+                    .get();
+            if (!optNode.isPresent()) {
+                LOG.error("Node is not present in datastore");
+                return null;
+            }
+            // TODO -> Need to remove CEPs from NEPs. If not error from get Topology details output
+            Node node = optNode.get();
+            Map<OwnedNodeEdgePointKey, OwnedNodeEdgePoint> onepMap = new HashMap<>();
+            for (OwnedNodeEdgePoint onep: node.getOwnedNodeEdgePoint().values()) {
+                if (onep.augmentation(OwnedNodeEdgePoint1.class) == null) {
+                    onepMap.put(onep.key(), onep);
+                    continue;
+                }
+                OwnedNodeEdgePointBuilder newOnepBuilder = new OwnedNodeEdgePointBuilder()
+                    .setUuid(onep.getUuid())
+                    .setLayerProtocolName(onep.getLayerProtocolName())
+                    .setName(onep.getName())
+                    .setSupportedCepLayerProtocolQualifier(onep.getSupportedCepLayerProtocolQualifier())
+                    .setAdministrativeState(onep.getAdministrativeState())
+                    .setOperationalState(onep.getOperationalState())
+                    .setLifecycleState(onep.getLifecycleState())
+                    .setTerminationDirection(onep.getTerminationDirection())
+                    .setTerminationState(onep.getTerminationState())
+                    .setLinkPortDirection(onep.getLinkPortDirection())
+                    .setLinkPortRole(onep.getLinkPortRole());
+                if (onep.getMappedServiceInterfacePoint() != null) {
+                    newOnepBuilder.setMappedServiceInterfacePoint(onep.getMappedServiceInterfacePoint());
+                }
+                onepMap.put(newOnepBuilder.key(), newOnepBuilder.build());
+            }
+            return new NodeBuilder(node)
+                .setOwnedNodeEdgePoint(onepMap)
+                .build();
+        } catch (InterruptedException | ExecutionException e) {
+            LOG.error("Couldnt read node in topology", e);
+            return null;
+        }
+    }
+
+    public OwnedNodeEdgePoint getTapiNEP(Uuid topoUuid, Uuid nodeUuid, Uuid nepUuid) {
+        InstanceIdentifier<OwnedNodeEdgePoint> nepIID = InstanceIdentifier.builder(Context.class)
+            .augmentation(org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.topology.rev181210.Context1.class)
+            .child(org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.topology.rev181210.context.TopologyContext.class)
+            .child(Topology.class, new TopologyKey(topoUuid))
+            .child(org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.topology.rev181210.topology.Node.class,
+                new NodeKey(nodeUuid)).child(OwnedNodeEdgePoint.class, new OwnedNodeEdgePointKey(nepUuid)).build();
+        try {
+            Optional<OwnedNodeEdgePoint> optNode = this.networkTransactionService
+                    .read(LogicalDatastoreType.OPERATIONAL, nepIID)
+                    .get();
+            if (!optNode.isPresent()) {
+                LOG.error("Node is not present in datastore");
+                return null;
+            }
+            return optNode.get();
+        } catch (InterruptedException | ExecutionException e) {
+            LOG.error("Couldnt read NEP in topology", e);
+            return null;
+        }
+    }
+
+    public Link getTapiLink(Uuid topoUuid, Uuid linkUuid) {
+        InstanceIdentifier<Link> linkIID = InstanceIdentifier.builder(Context.class)
+            .augmentation(org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.topology.rev181210.Context1.class)
+            .child(org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.topology.rev181210.context.TopologyContext.class)
+            .child(Topology.class, new TopologyKey(topoUuid))
+            .child(Link.class, new LinkKey(linkUuid)).build();
+        try {
+            Optional<Link> optLink = this.networkTransactionService.read(LogicalDatastoreType.OPERATIONAL, linkIID)
+                    .get();
+            if (!optLink.isPresent()) {
+                LOG.error("Node is not present in datastore");
+                return null;
+            }
+            return optLink.get();
+        } catch (InterruptedException | ExecutionException e) {
+            LOG.error("Couldnt read link in topology", e);
+            return null;
+        }
+    }
+
+    public Map<TopologyKey, Topology> getTopologyContext() {
+        InstanceIdentifier<TopologyContext> topologycontextIID =
+                InstanceIdentifier.builder(Context.class).augmentation(org.opendaylight.yang.gen.v1.urn
+                        .onf.otcc.yang.tapi.topology.rev181210.Context1.class)
+                        .child(TopologyContext.class)
+                        .build();
+        try {
+            Optional<TopologyContext> optTopoContext = this.networkTransactionService.read(
+                    LogicalDatastoreType.OPERATIONAL, topologycontextIID).get();
+            if (!optTopoContext.isPresent()) {
+                LOG.error("Topology context is not present in datastore");
+                return null;
+            }
+            return optTopoContext.get().getTopology();
+        } catch (InterruptedException | ExecutionException e) {
+            LOG.error("Couldnt read topology context", e);
+            return null;
+        }
+    }
 }
index a130d44c6b85e5a2cc11818753ae2be5e60265ee..35cfb96896d1169aa4c894d0692f43aacb7c4f65 100644 (file)
@@ -62,8 +62,12 @@ public class TapiTopologyImplExceptionTest {
         TapiTopologyImpl tapiTopoImpl = new TapiTopologyImpl(dataBroker, tapiContext, topologyUtils);
         ListenableFuture<RpcResult<GetTopologyDetailsOutput>> result = tapiTopoImpl.getTopologyDetails(input);
         RpcResult<GetTopologyDetailsOutput> rpcResult = result.get();
-        Topology topology = rpcResult.getResult().getTopology();
-        assertNull("Topology should be null", topology);
+        if (rpcResult.isSuccessful()) {
+            Topology topology = rpcResult.getResult().getTopology();
+            assertNull("Topology should be null", topology);
+        } else {
+            assertNull("Topology should be null", null);
+        }
     }
 
     private class ReadTransactionMock implements ReadTransaction {