Stores and gets IP address of a flow capable node 16/9616/8
authorMartin Sunal <msunal@cisco.com>
Sat, 2 Aug 2014 17:28:40 +0000 (19:28 +0200)
committerMartin Sunal <msunal@cisco.com>
Wed, 27 Aug 2014 13:51:56 +0000 (13:51 +0000)
- implements RPCs get-node-ip-address from flow-node-inventory.yang
depends on https://git.opendaylight.org/gerrit/#/c/9612/
- impelementation is done by using switch IP address from OFJava
depends on https://git.opendaylight.org/gerrit/#/c/9615/
- stores IP address of OF capable switch to data store (depends on Bug 1585)

Change-Id: I5b46106cf94109ddddd8cf5353d749e40c43b0ec
Signed-off-by: Martin Sunal <msunal@cisco.com>
openflowplugin/src/main/java/org/opendaylight/openflowplugin/openflow/md/ModelDrivenSwitch.java
openflowplugin/src/main/java/org/opendaylight/openflowplugin/openflow/md/core/sal/AbstractModelDrivenSwitch.java
openflowplugin/src/main/java/org/opendaylight/openflowplugin/openflow/md/core/sal/ModelDrivenSwitchImpl.java
openflowplugin/src/main/java/org/opendaylight/openflowplugin/openflow/md/core/sal/SalRegistrationManager.java
openflowplugin/src/test/java/org/opendaylight/openflowplugin/openflow/md/core/plan/ConnectionAdapterStackImpl.java
openflowplugin/src/test/java/org/opendaylight/openflowplugin/openflow/md/core/session/MessageDispatchServiceImplTest.java

index 06350308b4de6155d356c02204179c2dc55bc012..2a06cd88cd1a60b8dcf78f1d41666ffc89888c9c 100644 (file)
@@ -9,6 +9,7 @@ package org.opendaylight.openflowplugin.openflow.md;
 
 import org.opendaylight.controller.sal.binding.api.BindingAwareBroker.ProviderContext;
 import org.opendaylight.openflowplugin.openflow.md.core.session.SessionContext;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowNodeInventoryService;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.SalFlowService;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.OpendaylightFlowStatisticsService;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.table.statistics.rev131215.OpendaylightFlowTableStatisticsService;
@@ -43,6 +44,7 @@ public interface ModelDrivenSwitch extends //
         OpendaylightPortStatisticsService, //
         OpendaylightFlowTableStatisticsService, //
         OpendaylightQueueStatisticsService, //
+        FlowNodeInventoryService,
         Identifiable<InstanceIdentifier<Node>> {
 
     /**
index e3db0982a122a5d1e0e797a5f30254bc16b2f5e5..5dada33e6805e2e0da6ed26759dd863c4919888c 100644 (file)
@@ -11,6 +11,7 @@ import org.opendaylight.controller.sal.binding.api.BindingAwareBroker.ProviderCo
 import org.opendaylight.controller.sal.binding.api.BindingAwareBroker.RoutedRpcRegistration;
 import org.opendaylight.openflowplugin.openflow.md.ModelDrivenSwitch;
 import org.opendaylight.openflowplugin.openflow.md.core.session.SessionContext;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowNodeInventoryService;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.SalFlowService;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.OpendaylightFlowStatisticsService;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.table.statistics.rev131215.OpendaylightFlowTableStatisticsService;
@@ -60,6 +61,8 @@ public abstract class AbstractModelDrivenSwitch implements ModelDrivenSwitch {
 
     private RoutedRpcRegistration<OpendaylightQueueStatisticsService> queueStatisticsRegistration;
 
+    private RoutedRpcRegistration<FlowNodeInventoryService> flowNodeInventoryRegistration;
+
     protected final SessionContext sessionContext;
 
     protected AbstractModelDrivenSwitch(InstanceIdentifier<Node> identifier,SessionContext conductor) {
@@ -125,6 +128,10 @@ public abstract class AbstractModelDrivenSwitch implements ModelDrivenSwitch {
         queueStatisticsRegistration.registerPath(NodeContext.class, getIdentifier());
         builder.add(queueStatisticsRegistration);
 
+        flowNodeInventoryRegistration = ctx.addRoutedRpcImplementation(FlowNodeInventoryService.class, this);
+        flowNodeInventoryRegistration.registerPath(NodeContext.class, getIdentifier());
+        builder.add(flowNodeInventoryRegistration);
+
         return builder.toInstance();
     }
 
index d579187ffd666c0d414bcca75faa11f647b3703a..8c7e0633f891283548a6103627874691cf997942 100644 (file)
@@ -7,9 +7,10 @@
  */
 package org.opendaylight.openflowplugin.openflow.md.core.sal;
 
-import java.math.BigInteger;
-import java.util.ArrayList;
-import java.util.List;
+import java.net.Inet4Address;
+import java.net.Inet6Address;
+import java.net.InetAddress;
+import java.net.InetSocketAddress;
 import java.util.concurrent.Future;
 import java.util.concurrent.TimeUnit;
 
@@ -20,6 +21,12 @@ import org.opendaylight.openflowplugin.openflow.md.core.session.IMessageDispatch
 import org.opendaylight.openflowplugin.openflow.md.core.session.OFSessionUtil;
 import org.opendaylight.openflowplugin.openflow.md.core.session.SessionContext;
 import org.opendaylight.openflowplugin.openflow.md.core.session.SwitchConnectionCookieOFImpl;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.IpAddress;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Ipv4Address;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Ipv6Address;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.GetNodeIpAddressInput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.GetNodeIpAddressOutput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.GetNodeIpAddressOutputBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.AddFlowInput;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.AddFlowOutput;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.RemoveFlowInput;
@@ -38,8 +45,6 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.G
 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.GetFlowStatisticsFromFlowTableOutput;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.table.statistics.rev131215.GetFlowTablesStatisticsInput;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.table.statistics.rev131215.GetFlowTablesStatisticsOutput;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.transaction.rev131103.TransactionId;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.Flow;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.service.rev130918.AddGroupInput;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.service.rev130918.AddGroupOutput;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.service.rev130918.RemoveGroupInput;
@@ -70,10 +75,6 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.statistics.rev131111.
 import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.statistics.rev131111.GetMeterFeaturesOutput;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.statistics.rev131111.GetMeterStatisticsInput;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.statistics.rev131111.GetMeterStatisticsOutput;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev130731.match.grouping.Match;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev130731.match.grouping.MatchBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev130731.oxm.fields.grouping.MatchEntries;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.FlowModInputBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.PacketOutInput;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.packet.service.rev130709.ConnectionCookie;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.packet.service.rev130709.TransmitPacketInput;
@@ -93,10 +94,10 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.table.service.rev131026.Upd
 import org.opendaylight.yang.gen.v1.urn.opendaylight.table.service.rev131026.UpdateTableOutput;
 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
 import org.opendaylight.yangtools.yang.common.RpcResult;
+import org.opendaylight.yangtools.yang.common.RpcResultBuilder;
 import org.slf4j.Logger;
 
 import com.google.common.util.concurrent.Futures;
-import com.google.common.util.concurrent.JdkFutureAdapters;
 import com.google.common.util.concurrent.ListenableFuture;
 
 /**
@@ -530,4 +531,36 @@ public class ModelDrivenSwitchImpl extends AbstractModelDrivenSwitch {
         ListenableFuture<RpcResult<GetQueueStatisticsFromGivenPortOutput>> result = task.submit();
         return result;
     }
+
+    @Override
+    public Future<RpcResult<GetNodeIpAddressOutput>> getNodeIpAddress(GetNodeIpAddressInput input) {
+        if (!sessionContext.isValid()) {
+            return Futures.immediateFuture(RpcResultBuilder
+                    .<GetNodeIpAddressOutput> failed()
+                    .withError(org.opendaylight.yangtools.yang.common.RpcError.ErrorType.TRANSPORT,
+                            "Session is not valid.").build());
+        }
+        InetSocketAddress remoteAddress = sessionContext.getPrimaryConductor().getConnectionAdapter()
+                .getRemoteAddress();
+        if (remoteAddress == null) {
+            return Futures.immediateFuture(RpcResultBuilder
+                    .<GetNodeIpAddressOutput> failed()
+                    .withError(org.opendaylight.yangtools.yang.common.RpcError.ErrorType.TRANSPORT,
+                            "No connection with switch.").build());
+        }
+        IpAddress ipAddress = resolveIpAddress(remoteAddress.getAddress());
+        GetNodeIpAddressOutput result = new GetNodeIpAddressOutputBuilder().setIpAddress(ipAddress).build();
+        return Futures.immediateFuture(RpcResultBuilder.<GetNodeIpAddressOutput> success(result).build());
+    }
+
+    private static IpAddress resolveIpAddress(InetAddress address) {
+        String hostAddress = address.getHostAddress();
+        if (address instanceof Inet4Address) {
+            return new IpAddress(new Ipv4Address(hostAddress));
+        }
+        if (address instanceof Inet6Address) {
+            return new IpAddress(new Ipv6Address(hostAddress));
+        }
+        throw new IllegalArgumentException("Unsupported IP address type!");
+    }
 }
index e949d9998e86c3b9d08321be9b0c5aa98b3b6f9b..27cc0bdb748268688498c7c433ea44a40fa290ab 100644 (file)
@@ -8,6 +8,7 @@
 package org.opendaylight.openflowplugin.openflow.md.core.sal;
 
 import java.math.BigInteger;
+import java.util.Collection;
 
 import org.opendaylight.controller.sal.binding.api.BindingAwareBroker.ProviderContext;
 import org.opendaylight.controller.sal.binding.api.NotificationProviderService;
@@ -21,6 +22,9 @@ import org.opendaylight.openflowplugin.openflow.md.core.session.SwitchSessionKey
 import org.opendaylight.openflowplugin.openflow.md.lldp.LLDPSpeaker;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNodeUpdated;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNodeUpdatedBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.GetNodeIpAddressInput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.GetNodeIpAddressInputBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.GetNodeIpAddressOutput;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeId;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeRef;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeRemoved;
@@ -34,9 +38,13 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731
 import org.opendaylight.yangtools.concepts.CompositeObjectRegistration;
 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier.InstanceIdentifierBuilder;
+import org.opendaylight.yangtools.yang.common.RpcError;
+import org.opendaylight.yangtools.yang.common.RpcResult;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
+import com.google.common.util.concurrent.Futures;
+
 /**
  * session and inventory listener implementation
  */
@@ -116,14 +124,32 @@ public class SalRegistrationManager implements SessionListener, AutoCloseable {
         NodeUpdatedBuilder builder = new NodeUpdatedBuilder();
         builder.setId(sw.getNodeId());
         builder.setNodeRef(nodeRef);
-        
         FlowCapableNodeUpdatedBuilder builder2 = new FlowCapableNodeUpdatedBuilder();
+        setIpAddressToBuilder(builder2, sw, nodeRef);
         builder2.setSwitchFeatures(swFeaturesUtil.buildSwitchFeatures(features));
         builder.addAugmentation(FlowCapableNodeUpdated.class, builder2.build());
-        
         return builder.build();
     }
 
+    private void setIpAddressToBuilder(FlowCapableNodeUpdatedBuilder builder, ModelDrivenSwitch sw, NodeRef nodeRef) {
+        GetNodeIpAddressInput rpcInputGetIpAddress = new GetNodeIpAddressInputBuilder().setNode(nodeRef).build();
+        RpcResult<GetNodeIpAddressOutput> rpcResultGetIpAddress = Futures.getUnchecked(sw
+                .getNodeIpAddress(rpcInputGetIpAddress));
+        if (rpcResultGetIpAddress.isSuccessful()) {
+            builder.setIpAddress(rpcResultGetIpAddress.getResult().getIpAddress());
+        } else {
+            printRpcErrors(rpcResultGetIpAddress.getErrors());
+        }
+    }
+
+    private static void printRpcErrors(Collection<RpcError> rpcErrors) {
+        if (rpcErrors != null) {
+            for (RpcError error : rpcErrors) {
+                LOG.warn("{}", error);
+            }
+        }
+    }
+
     private NodeRemoved nodeRemoved(NodeRef nodeRef) {
         NodeRemovedBuilder builder = new NodeRemovedBuilder();
         builder.setNodeRef(nodeRef);
index 69d498d999ab75717cdc8d7c1c8e012b7826b5c8..296bdeccaa9daf073788c85c3c97def83b712b51 100644 (file)
@@ -8,6 +8,7 @@
 
 package org.opendaylight.openflowplugin.openflow.md.core.plan;
 
+import java.net.InetSocketAddress;
 import java.util.ArrayList;
 import java.util.Collection;
 import java.util.Collections;
@@ -612,4 +613,11 @@ public class ConnectionAdapterStackImpl implements ConnectionAdapter, Runnable {
         SettableFuture<RpcResult<Void>> result = createOneWayRpcResult();
         return result;
     }
+
+    @Override
+    public InetSocketAddress getRemoteAddress() {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
 }
index 456a3a77bd1a2b76a89285c41da14353d53e7f9f..1dfa06d713f03d6721d3444ee4d2fc3d96915625 100644 (file)
@@ -25,6 +25,7 @@ import org.opendaylight.yangtools.yang.binding.DataObject;
 import org.opendaylight.yangtools.yang.common.RpcError;
 import org.opendaylight.yangtools.yang.common.RpcResult;
 
+import java.net.InetSocketAddress;
 import java.util.*;
 import java.util.Map.Entry;
 import java.util.concurrent.Future;
@@ -569,4 +570,13 @@ class MockConnectionAdapter implements ConnectionAdapter {
         // TODO Auto-generated method stub
         return null;
     }
+
+    /* (non-Javadoc)
+     * @see org.opendaylight.openflowjava.protocol.api.connection.ConnectionAdapter#getRemoteAddress()
+     */
+    @Override
+    public InetSocketAddress getRemoteAddress() {
+        // TODO Auto-generated method stub
+        return null;
+    }
 }