Stores and gets IP address of a flow capable node
[openflowplugin.git] / openflowplugin / src / main / java / org / opendaylight / openflowplugin / openflow / md / core / sal / ModelDrivenSwitchImpl.java
index feb383b8638d53510a36ed5da3db72694fa17891..8c7e0633f891283548a6103627874691cf997942 100644 (file)
@@ -1,26 +1,64 @@
+/**
+ * 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
+ */
 package org.opendaylight.openflowplugin.openflow.md.core.sal;
 
-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;
 
-import org.apache.log4j.spi.LoggerFactory;
-import org.opendaylight.openflowplugin.openflow.md.ModelDrivenSwitch;
-import org.opendaylight.openflowplugin.openflow.md.core.ConnectionConductor;
+import org.opendaylight.controller.sal.binding.api.NotificationProviderService;
+import org.opendaylight.openflowplugin.openflow.md.core.SwitchConnectionDistinguisher;
+import org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.PacketOutConvertor;
+import org.opendaylight.openflowplugin.openflow.md.core.session.IMessageDispatchService;
+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.NodeFlow;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.AddFlowOutput;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.RemoveFlowInput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.RemoveFlowOutput;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.UpdateFlowInput;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.group.service.rev130918.AddGroupOutput;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.Flow;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.group.service.rev130918.AddGroupOutput;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.FlowModFlags;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.UpdateFlowOutput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.GetAggregateFlowStatisticsFromFlowTableForAllFlowsInput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.GetAggregateFlowStatisticsFromFlowTableForAllFlowsOutput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.GetAggregateFlowStatisticsFromFlowTableForGivenMatchInput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.GetAggregateFlowStatisticsFromFlowTableForGivenMatchOutput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.GetAllFlowStatisticsFromFlowTableInput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.GetAllFlowStatisticsFromFlowTableOutput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.GetAllFlowsStatisticsFromAllFlowTablesInput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.GetAllFlowsStatisticsFromAllFlowTablesOutput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.GetFlowStatisticsFromFlowTableInput;
+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.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;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.service.rev130918.RemoveGroupOutput;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.service.rev130918.UpdateGroupInput;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.service.rev130918.UpdateGroupOutput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.group.statistics.rev131111.GetAllGroupStatisticsInput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.group.statistics.rev131111.GetAllGroupStatisticsOutput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.group.statistics.rev131111.GetGroupDescriptionInput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.group.statistics.rev131111.GetGroupDescriptionOutput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.group.statistics.rev131111.GetGroupFeaturesInput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.group.statistics.rev131111.GetGroupFeaturesOutput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.group.statistics.rev131111.GetGroupStatisticsInput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.group.statistics.rev131111.GetGroupStatisticsOutput;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeId;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.service.rev130918.AddMeterInput;
@@ -29,120 +67,500 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.service.rev130918.Rem
 import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.service.rev130918.RemoveMeterOutput;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.service.rev130918.UpdateMeterInput;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.service.rev130918.UpdateMeterOutput;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev130731.oxm.fields.MatchEntries;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.FlowMod;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.FlowModInputBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.flow.mod.Match;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.flow.mod.MatchBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.statistics.rev131111.GetAllMeterConfigStatisticsInput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.statistics.rev131111.GetAllMeterConfigStatisticsOutput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.statistics.rev131111.GetAllMeterStatisticsInput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.statistics.rev131111.GetAllMeterStatisticsOutput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.statistics.rev131111.GetMeterFeaturesInput;
+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.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;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.port.service.rev131107.UpdatePortInput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.port.service.rev131107.UpdatePortOutput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.port.statistics.rev131214.GetAllNodeConnectorsStatisticsInput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.port.statistics.rev131214.GetAllNodeConnectorsStatisticsOutput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.port.statistics.rev131214.GetNodeConnectorStatisticsInput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.port.statistics.rev131214.GetNodeConnectorStatisticsOutput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.queue.statistics.rev131216.GetAllQueuesStatisticsFromAllPortsInput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.queue.statistics.rev131216.GetAllQueuesStatisticsFromAllPortsOutput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.queue.statistics.rev131216.GetAllQueuesStatisticsFromGivenPortInput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.queue.statistics.rev131216.GetAllQueuesStatisticsFromGivenPortOutput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.queue.statistics.rev131216.GetQueueStatisticsFromGivenPortInput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.queue.statistics.rev131216.GetQueueStatisticsFromGivenPortOutput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.table.service.rev131026.UpdateTableInput;
+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.ListenableFuture;
+
+/**
+ * RPC implementation of MD-switch
+ */
 public class ModelDrivenSwitchImpl extends AbstractModelDrivenSwitch {
 
-    public static final Logger LOG = org.slf4j.LoggerFactory
-            .getLogger(ModelDrivenSwitchImpl.class);
+    private static final Logger LOG = org.slf4j.LoggerFactory.getLogger(ModelDrivenSwitchImpl.class);
     private final NodeId nodeId;
-
-    protected ModelDrivenSwitchImpl(NodeId nodeId,
-            InstanceIdentifier<Node> identifier, SessionContext context) {
-        super(identifier, context);
+    private final IMessageDispatchService messageService;
+    private short version = 0;
+    private NotificationProviderService rpcNotificationProviderService;
+    private OFRpcTaskContext rpcTaskContext;
+    
+    // TODO:read timeout from configSubsystem
+    protected long maxTimeout = 1000;
+    protected TimeUnit maxTimeoutUnit = TimeUnit.MILLISECONDS;
+    
+    protected ModelDrivenSwitchImpl(final NodeId nodeId, final InstanceIdentifier<Node> identifier, 
+            final SessionContext sessionContext) {
+        super(identifier, sessionContext);
         this.nodeId = nodeId;
+        messageService = sessionContext.getMessageDispatchService();
+        version = sessionContext.getPrimaryConductor().getVersion();
+        rpcNotificationProviderService = OFSessionUtil.getSessionManager().getNotificationProviderService();
+        
+        rpcTaskContext = new OFRpcTaskContext();
+        rpcTaskContext.setSession(sessionContext);
+        rpcTaskContext.setMessageService(messageService);
+        rpcTaskContext.setRpcNotificationProviderService(rpcNotificationProviderService);
+        rpcTaskContext.setMaxTimeout(maxTimeout);
+        rpcTaskContext.setMaxTimeoutUnit(maxTimeoutUnit);
+        rpcTaskContext.setRpcPool(OFSessionUtil.getSessionManager().getRpcPool());
+        rpcTaskContext.setMessageSpy(OFSessionUtil.getSessionManager().getMessageSpy());
     }
 
     @Override
-    public Future<RpcResult<Void>> addFlow(AddFlowInput input) {
-        // TODO Auto-generated method stub
+    public Future<RpcResult<AddFlowOutput>> addFlow(final AddFlowInput input) {
+        LOG.debug("Calling the FlowMod RPC method on MessageDispatchService");
+        // use primary connection
+        SwitchConnectionDistinguisher cookie = null;
+        
+        OFRpcTask<AddFlowInput, RpcResult<UpdateFlowOutput>> task = 
+                OFRpcTaskFactory.createAddFlowTask(rpcTaskContext, input, cookie);
+        ListenableFuture<RpcResult<UpdateFlowOutput>> result = task.submit();
+        
+        return Futures.transform(result, OFRpcFutureResultTransformFactory.createForAddFlowOutput());
+    }
 
-        return null;
+
+    @Override
+    public Future<RpcResult<AddGroupOutput>> addGroup(final AddGroupInput input) {
+        LOG.debug("Calling the GroupMod RPC method on MessageDispatchService");
+        
+        // use primary connection
+        SwitchConnectionDistinguisher cookie = null;
+        
+        OFRpcTask<AddGroupInput, RpcResult<UpdateGroupOutput>> task = 
+                OFRpcTaskFactory.createAddGroupTask(rpcTaskContext, input, cookie);
+        ListenableFuture<RpcResult<UpdateGroupOutput>> result = task.submit();
+        
+        return Futures.transform(result, OFRpcFutureResultTransformFactory.createForAddGroupOutput());
     }
 
     @Override
-    public Future<RpcResult<AddGroupOutput>> addGroup(AddGroupInput input) {
-        // TODO Auto-generated method stub
-        return null;
+    public Future<RpcResult<AddMeterOutput>> addMeter(final AddMeterInput input) {
+        LOG.debug("Calling the MeterMod RPC method on MessageDispatchService");
+        
+        // use primary connection
+        SwitchConnectionDistinguisher cookie = null;
+        
+        OFRpcTask<AddMeterInput, RpcResult<UpdateMeterOutput>> task = 
+                OFRpcTaskFactory.createAddMeterTask(rpcTaskContext, input, cookie);
+        ListenableFuture<RpcResult<UpdateMeterOutput>> result = task.submit();
+        
+        return Futures.transform(result, OFRpcFutureResultTransformFactory.createForAddMeterOutput());
     }
 
     @Override
-    public Future<RpcResult<AddMeterOutput>> addMeter(AddMeterInput input) {
-        // TODO Auto-generated method stub
-        return null;
+    public Future<RpcResult<RemoveFlowOutput>> removeFlow(final RemoveFlowInput input) {
+        LOG.debug("Calling the removeFlow RPC method on MessageDispatchService");
+        
+        // use primary connection
+        SwitchConnectionDistinguisher cookie = null;
+        OFRpcTask<RemoveFlowInput, RpcResult<UpdateFlowOutput>> task = 
+                OFRpcTaskFactory.createRemoveFlowTask(rpcTaskContext, input, cookie);
+        ListenableFuture<RpcResult<UpdateFlowOutput>> result = task.submit();
+
+        return Futures.transform(result, OFRpcFutureResultTransformFactory.createForRemoveFlowOutput());
     }
 
     @Override
-    public Future<RpcResult<Void>> removeFlow(RemoveFlowInput input) {
-        // TODO Auto-generated method stub
-        return null;
+    public Future<RpcResult<RemoveGroupOutput>> removeGroup(final RemoveGroupInput input) {
+        LOG.debug("Calling the Remove Group RPC method on MessageDispatchService");
+
+        SwitchConnectionDistinguisher cookie = null;
+        OFRpcTask<RemoveGroupInput, RpcResult<UpdateGroupOutput>> task = 
+                OFRpcTaskFactory.createRemoveGroupTask(rpcTaskContext, input, cookie);
+        ListenableFuture<RpcResult<UpdateGroupOutput>> result = task.submit();
+        
+        return Futures.transform(result, OFRpcFutureResultTransformFactory.createForRemoveGroupOutput());
     }
 
     @Override
-    public Future<RpcResult<RemoveGroupOutput>> removeGroup(
-            RemoveGroupInput input) {
-        // TODO Auto-generated method stub
-        return null;
+    public Future<RpcResult<RemoveMeterOutput>> removeMeter(final RemoveMeterInput input) {
+        LOG.debug("Calling the Remove MeterMod RPC method on MessageDispatchService");
+
+        SwitchConnectionDistinguisher cookie = null;
+        OFRpcTask<RemoveMeterInput, RpcResult<UpdateMeterOutput>> task = 
+                OFRpcTaskFactory.createRemoveMeterTask(rpcTaskContext, input, cookie);
+        ListenableFuture<RpcResult<UpdateMeterOutput>> result = task.submit();
+        
+        return Futures.transform(result, OFRpcFutureResultTransformFactory.createForRemoveMeterOutput());
     }
 
     @Override
-    public Future<RpcResult<RemoveMeterOutput>> removeMeter(
-            RemoveMeterInput input) {
-        // TODO Auto-generated method stub
-        return null;
+    public Future<RpcResult<Void>> transmitPacket(final TransmitPacketInput input) {
+        LOG.debug("TransmitPacket - {}", input);
+        // Convert TransmitPacket to PacketOutInput
+        PacketOutInput message = PacketOutConvertor.toPacketOutInput(input, version, sessionContext.getNextXid(),
+                sessionContext.getFeatures().getDatapathId());
+
+        SwitchConnectionDistinguisher cookie = null;
+        ConnectionCookie connectionCookie = input.getConnectionCookie();
+        if (connectionCookie != null && connectionCookie.getValue() != null) {
+            cookie = new SwitchConnectionCookieOFImpl(connectionCookie.getValue());
+        }
+
+        LOG.debug("Calling the transmitPacket RPC method");
+        return messageService.packetOut(message, cookie);
     }
 
     @Override
-    public Future<RpcResult<Void>> transmitPacket(TransmitPacketInput input) {
-        // TODO Auto-generated method stub
-        return null;
+    public Future<RpcResult<UpdateFlowOutput>> updateFlow(final UpdateFlowInput input) {
+        LOG.debug("Calling the updateFlow RPC method on MessageDispatchService");
+        
+        // use primary connection
+        SwitchConnectionDistinguisher cookie = null;
+        
+        OFRpcTask<UpdateFlowInput, RpcResult<UpdateFlowOutput>> task = 
+                OFRpcTaskFactory.createUpdateFlowTask(rpcTaskContext, input, cookie);
+        ListenableFuture<RpcResult<UpdateFlowOutput>> result = task.submit();
+        
+        return result;
     }
 
-    private FlowModInputBuilder toFlowModInputBuilder(Flow source) {
-        FlowModInputBuilder target = new FlowModInputBuilder();
-        target.setCookie(source.getCookie());
-        target.setIdleTimeout(source.getIdleTimeout());
-        target.setHardTimeout(source.getHardTimeout());
-        target.setMatch(toMatch(source.getMatch()));
+    @Override
+    public Future<RpcResult<UpdateGroupOutput>> updateGroup(final UpdateGroupInput input) {
+        LOG.debug("Calling the update Group Mod RPC method on MessageDispatchService");
+        
+        // use primary connection
+        SwitchConnectionDistinguisher cookie = null;
+        
+        OFRpcTask<UpdateGroupInput, RpcResult<UpdateGroupOutput>> task = 
+                OFRpcTaskFactory.createUpdateGroupTask(rpcTaskContext, input, cookie);
+        ListenableFuture<RpcResult<UpdateGroupOutput>> result = task.submit();
+        
+        return result;
+    }
 
-        return target;
+    @Override
+    public Future<RpcResult<UpdateMeterOutput>> updateMeter(final UpdateMeterInput input) {
+        LOG.debug("Calling the MeterMod RPC method on MessageDispatchService");
+        
+        // use primary connection
+        SwitchConnectionDistinguisher cookie = null;
+        
+        OFRpcTask<UpdateMeterInput, RpcResult<UpdateMeterOutput>> task = 
+                OFRpcTaskFactory.createUpdateMeterTask(rpcTaskContext, input, cookie);
+        ListenableFuture<RpcResult<UpdateMeterOutput>> result = task.submit();
+        
+        return result;
     }
 
-    private Match toMatch(
-            org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.Match match) {
-        MatchBuilder target = new MatchBuilder();
+    @Override
+    public NodeId getNodeId() {
+        return nodeId;
+    }
 
-        target.setMatchEntries(toMatchEntries(match));
+    
+    @Override
+    public Future<RpcResult<GetAllGroupStatisticsOutput>> getAllGroupStatistics(final GetAllGroupStatisticsInput input) {
+     // use primary connection
+        LOG.debug("Calling the getAllGroupStatistics RPC method on MessageDispatchService");
+        SwitchConnectionDistinguisher cookie = null;
+        
+        OFRpcTask<GetAllGroupStatisticsInput, RpcResult<GetAllGroupStatisticsOutput>> task = 
+                OFRpcTaskFactory.createGetAllGroupStatisticsTask(rpcTaskContext, input, cookie);
+        ListenableFuture<RpcResult<GetAllGroupStatisticsOutput>> result = task.submit();
+        
+        return result;
 
-        return null;
     }
 
-    private List<MatchEntries> toMatchEntries(
-            org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.Match match) {
-        List<MatchEntries> entries = new ArrayList<>();
+    @Override
+    public Future<RpcResult<GetGroupDescriptionOutput>> getGroupDescription(final GetGroupDescriptionInput input) {
+        LOG.debug("Calling the getGroupDescription RPC method on MessageDispatchService");
+        SwitchConnectionDistinguisher cookie = null;
+        
+        OFRpcTask<GetGroupDescriptionInput, RpcResult<GetGroupDescriptionOutput>> task = 
+                OFRpcTaskFactory.createGetGroupDescriptionTask(rpcTaskContext, input, cookie);
+        ListenableFuture<RpcResult<GetGroupDescriptionOutput>> result = task.submit();
+        return result;
+    }
+    
+    @Override
+    public Future<RpcResult<GetGroupFeaturesOutput>> getGroupFeatures(final GetGroupFeaturesInput input) {
+        LOG.debug("Calling the getGroupFeatures RPC method on MessageDispatchService");
+        SwitchConnectionDistinguisher cookie = null;
+        
+        OFRpcTask<GetGroupFeaturesInput, RpcResult<GetGroupFeaturesOutput>> task = 
+                OFRpcTaskFactory.createGetGroupFeaturesTask(rpcTaskContext, input, cookie);
+        ListenableFuture<RpcResult<GetGroupFeaturesOutput>> result = task.submit();
+        return result;
+    }
+    
+    @Override
+    public Future<RpcResult<GetGroupStatisticsOutput>> getGroupStatistics(final GetGroupStatisticsInput input) {
+        LOG.debug("Calling the getGroupStatistics RPC method on MessageDispatchService");
+        SwitchConnectionDistinguisher cookie = null;
+        
+        OFRpcTask<GetGroupStatisticsInput, RpcResult<GetGroupStatisticsOutput>> task = 
+                OFRpcTaskFactory.createGetGroupStatisticsTask(rpcTaskContext, input, cookie);
+        ListenableFuture<RpcResult<GetGroupStatisticsOutput>> result = task.submit();
+        return result;
+    }
 
-        return null;
+    @Override
+    public Future<RpcResult<GetAllMeterConfigStatisticsOutput>> getAllMeterConfigStatistics(
+            final GetAllMeterConfigStatisticsInput input) {
+        LOG.debug("Calling the getAllMeterConfigStatistics RPC method on MessageDispatchService");
+        SwitchConnectionDistinguisher cookie = null;
+        
+        OFRpcTask<GetAllMeterConfigStatisticsInput, RpcResult<GetAllMeterConfigStatisticsOutput>> task = 
+                OFRpcTaskFactory.createGetAllMeterConfigStatisticsTask(rpcTaskContext, input, cookie);
+        ListenableFuture<RpcResult<GetAllMeterConfigStatisticsOutput>> result = task.submit();
+        return result;
+    }
+    
+    @Override
+    public Future<RpcResult<GetAllMeterStatisticsOutput>> getAllMeterStatistics(
+            final GetAllMeterStatisticsInput input) {
+        LOG.debug("Calling the getAllMeterStatistics RPC method on MessageDispatchService");
+        SwitchConnectionDistinguisher cookie = null;
+        
+        OFRpcTask<GetAllMeterStatisticsInput, RpcResult<GetAllMeterStatisticsOutput>> task = 
+                OFRpcTaskFactory.createGetAllMeterStatisticsTask(rpcTaskContext, input, cookie);
+        ListenableFuture<RpcResult<GetAllMeterStatisticsOutput>> result = task.submit();
+        return result;
+    }
+    
+    @Override
+    public Future<RpcResult<GetMeterFeaturesOutput>> getMeterFeatures(
+            final GetMeterFeaturesInput input) {
+        LOG.debug("Calling the getMeterFeatures RPC method on MessageDispatchService");
+        SwitchConnectionDistinguisher cookie = null;
+        
+        OFRpcTask<GetMeterFeaturesInput, RpcResult<GetMeterFeaturesOutput>> task = 
+                OFRpcTaskFactory.createGetMeterFeaturesTask(rpcTaskContext, input, cookie);
+        ListenableFuture<RpcResult<GetMeterFeaturesOutput>> result = task.submit();
+        return result;
+    }
+    
+    @Override
+    public Future<RpcResult<GetMeterStatisticsOutput>> getMeterStatistics(
+            final GetMeterStatisticsInput input) {
+        LOG.debug("Calling the getMeterStatistics RPC method on MessageDispatchService");
+        SwitchConnectionDistinguisher cookie = null;
+        
+        OFRpcTask<GetMeterStatisticsInput, RpcResult<GetMeterStatisticsOutput>> task = 
+                OFRpcTaskFactory.createGetMeterStatisticsTask(rpcTaskContext, input, cookie);
+        ListenableFuture<RpcResult<GetMeterStatisticsOutput>> result = task.submit();
+        return result;
+    }
+    
+    @Override
+    public Future<RpcResult<GetAllNodeConnectorsStatisticsOutput>> getAllNodeConnectorsStatistics(
+            final GetAllNodeConnectorsStatisticsInput input) {
+        LOG.debug("Calling the getAllNodeConnectorsStatistics RPC method on MessageDispatchService");
+        SwitchConnectionDistinguisher cookie = null;
+        
+        OFRpcTask<GetAllNodeConnectorsStatisticsInput, RpcResult<GetAllNodeConnectorsStatisticsOutput>> task = 
+                OFRpcTaskFactory.createGetAllNodeConnectorsStatisticsTask(rpcTaskContext, input, cookie);
+        ListenableFuture<RpcResult<GetAllNodeConnectorsStatisticsOutput>> result = task.submit();
+        return result;
+    }
+    
+    @Override
+    public Future<RpcResult<GetNodeConnectorStatisticsOutput>> getNodeConnectorStatistics(
+            final GetNodeConnectorStatisticsInput input) {
+        LOG.debug("Calling the getNodeConnectorStatistics RPC method on MessageDispatchService");
+        SwitchConnectionDistinguisher cookie = null;
+        
+        OFRpcTask<GetNodeConnectorStatisticsInput, RpcResult<GetNodeConnectorStatisticsOutput>> task = 
+                OFRpcTaskFactory.createGetNodeConnectorStatisticsTask(rpcTaskContext, input, cookie);
+        ListenableFuture<RpcResult<GetNodeConnectorStatisticsOutput>> result = task.submit();
+        return result;
+    }
+    
+    @Override
+    public Future<RpcResult<UpdatePortOutput>> updatePort(final UpdatePortInput input) {
+        LOG.debug("Calling the updatePort RPC method on MessageDispatchService");
+        
+        // use primary connection
+        SwitchConnectionDistinguisher cookie = null;
+        
+        OFRpcTask<UpdatePortInput, RpcResult<UpdatePortOutput>> task = 
+                OFRpcTaskFactory.createUpdatePortTask(rpcTaskContext, input, cookie);
+        ListenableFuture<RpcResult<UpdatePortOutput>> result = task.submit();
+        
+        return result;
     }
 
     @Override
-    public Future<RpcResult<Void>> updateFlow(UpdateFlowInput input) {
-        // TODO Auto-generated method stub
-        return null;
+    public Future<RpcResult<UpdateTableOutput>> updateTable(final UpdateTableInput input) {
+        LOG.debug("Calling the updateTable RPC method on MessageDispatchService");
+        
+        SwitchConnectionDistinguisher cookie = null;
+        
+        OFRpcTask<UpdateTableInput, RpcResult<UpdateTableOutput>> task = 
+                OFRpcTaskFactory.createUpdateTableTask(rpcTaskContext, input, cookie);
+        ListenableFuture<RpcResult<UpdateTableOutput>> result = task.submit();
+        
+        return result;
     }
 
     @Override
-    public Future<RpcResult<UpdateGroupOutput>> updateGroup(
-            UpdateGroupInput input) {
-        // TODO Auto-generated method stub
-        return null;
+    public Future<RpcResult<GetAllFlowStatisticsFromFlowTableOutput>> getAllFlowStatisticsFromFlowTable(
+            final GetAllFlowStatisticsFromFlowTableInput input) {
+        LOG.debug("Calling the getAllFlowStatisticsFromFlowTable RPC method on MessageDispatchService");
+        SwitchConnectionDistinguisher cookie = null;
+        
+        OFRpcTask<GetAllFlowStatisticsFromFlowTableInput, RpcResult<GetAllFlowStatisticsFromFlowTableOutput>> task = 
+                OFRpcTaskFactory.createGetAllFlowStatisticsFromFlowTableTask(rpcTaskContext, input, cookie);
+        ListenableFuture<RpcResult<GetAllFlowStatisticsFromFlowTableOutput>> result = task.submit();
+        return result;
+    }
+    
+    @Override
+    public Future<RpcResult<GetAllFlowsStatisticsFromAllFlowTablesOutput>> getAllFlowsStatisticsFromAllFlowTables(
+            final GetAllFlowsStatisticsFromAllFlowTablesInput input) {
+        LOG.debug("Calling the getAllFlowsStatisticsFromAllFlowTables RPC method on MessageDispatchService");
+        SwitchConnectionDistinguisher cookie = null;
+        
+        OFRpcTask<GetAllFlowsStatisticsFromAllFlowTablesInput, RpcResult<GetAllFlowsStatisticsFromAllFlowTablesOutput>> task = 
+                OFRpcTaskFactory.createGetAllFlowsStatisticsFromAllFlowTablesTask(rpcTaskContext, input, cookie);
+        ListenableFuture<RpcResult<GetAllFlowsStatisticsFromAllFlowTablesOutput>> result = task.submit();
+        return result;
+    }
+    
+    @Override
+    public Future<RpcResult<GetFlowStatisticsFromFlowTableOutput>> getFlowStatisticsFromFlowTable(
+            final GetFlowStatisticsFromFlowTableInput input) {
+        LOG.debug("Calling the getFlowStatisticsFromFlowTable RPC method on MessageDispatchService");
+        SwitchConnectionDistinguisher cookie = null;
+        
+        OFRpcTask<GetFlowStatisticsFromFlowTableInput, RpcResult<GetFlowStatisticsFromFlowTableOutput>> task = 
+                OFRpcTaskFactory.createGetFlowStatisticsFromFlowTableTask(rpcTaskContext, input, cookie);
+        ListenableFuture<RpcResult<GetFlowStatisticsFromFlowTableOutput>> result = task.submit();
+        return result;
+    }
+    
+    @Override
+    public Future<RpcResult<GetAggregateFlowStatisticsFromFlowTableForAllFlowsOutput>> getAggregateFlowStatisticsFromFlowTableForAllFlows(
+            final GetAggregateFlowStatisticsFromFlowTableForAllFlowsInput input) {
+        LOG.debug("Calling the getAggregateFlowStatisticsFromFlowTableForAllFlows RPC method on MessageDispatchService");
+        SwitchConnectionDistinguisher cookie = null;
+        
+        OFRpcTask<GetAggregateFlowStatisticsFromFlowTableForAllFlowsInput, RpcResult<GetAggregateFlowStatisticsFromFlowTableForAllFlowsOutput>> task = 
+                OFRpcTaskFactory.createGetAggregateFlowStatisticsFromFlowTableForAllFlowsTask(rpcTaskContext, input, cookie);
+        ListenableFuture<RpcResult<GetAggregateFlowStatisticsFromFlowTableForAllFlowsOutput>> result = task.submit();
+        return result;
+    }
+    
+    @Override
+    public Future<RpcResult<GetAggregateFlowStatisticsFromFlowTableForGivenMatchOutput>> getAggregateFlowStatisticsFromFlowTableForGivenMatch(
+            final GetAggregateFlowStatisticsFromFlowTableForGivenMatchInput input) {
+        LOG.debug("Calling the getAggregateFlowStatisticsFromFlowTableForGivenMatch RPC method on MessageDispatchService");
+        SwitchConnectionDistinguisher cookie = null;
+        
+        OFRpcTask<GetAggregateFlowStatisticsFromFlowTableForGivenMatchInput, RpcResult<GetAggregateFlowStatisticsFromFlowTableForGivenMatchOutput>> task = 
+                OFRpcTaskFactory.createGetAggregateFlowStatisticsFromFlowTableForGivenMatchTask(rpcTaskContext, input, cookie);
+        ListenableFuture<RpcResult<GetAggregateFlowStatisticsFromFlowTableForGivenMatchOutput>> result = task.submit();
+        return result;
+    }
+    
+    @Override
+    public Future<RpcResult<GetFlowTablesStatisticsOutput>> getFlowTablesStatistics(
+            final GetFlowTablesStatisticsInput input) {
+        LOG.debug("Calling the getFlowTablesStatistics RPC method on MessageDispatchService");
+        SwitchConnectionDistinguisher cookie = null;
+        
+        OFRpcTask<GetFlowTablesStatisticsInput, RpcResult<GetFlowTablesStatisticsOutput>> task = 
+                OFRpcTaskFactory.createGetFlowTablesStatisticsTask(rpcTaskContext, input, cookie);
+        ListenableFuture<RpcResult<GetFlowTablesStatisticsOutput>> result = task.submit();
+        return result;
+    }
+    
+    @Override
+    public Future<RpcResult<GetAllQueuesStatisticsFromAllPortsOutput>> getAllQueuesStatisticsFromAllPorts(
+            final GetAllQueuesStatisticsFromAllPortsInput input) {
+        LOG.debug("Calling the getAllQueuesStatisticsFromAllPorts RPC method on MessageDispatchService");
+        SwitchConnectionDistinguisher cookie = null;
+        
+        OFRpcTask<GetAllQueuesStatisticsFromAllPortsInput, RpcResult<GetAllQueuesStatisticsFromAllPortsOutput>> task = 
+                OFRpcTaskFactory.createGetAllQueuesStatisticsFromAllPortsTask(rpcTaskContext, input, cookie);
+        ListenableFuture<RpcResult<GetAllQueuesStatisticsFromAllPortsOutput>> result = task.submit();
+        return result;
+    }
+    
+    @Override
+    public Future<RpcResult<GetAllQueuesStatisticsFromGivenPortOutput>> getAllQueuesStatisticsFromGivenPort(
+            final GetAllQueuesStatisticsFromGivenPortInput input) {
+        LOG.debug("Calling the getAllQueuesStatisticsFromGivenPort RPC method on MessageDispatchService");
+        SwitchConnectionDistinguisher cookie = null;
+        
+        OFRpcTask<GetAllQueuesStatisticsFromGivenPortInput, RpcResult<GetAllQueuesStatisticsFromGivenPortOutput>> task = 
+                OFRpcTaskFactory.createGetAllQueuesStatisticsFromGivenPortTask(rpcTaskContext, input, cookie);
+        ListenableFuture<RpcResult<GetAllQueuesStatisticsFromGivenPortOutput>> result = task.submit();
+        return result;
+    }
+    
+    @Override
+    public Future<RpcResult<GetQueueStatisticsFromGivenPortOutput>> getQueueStatisticsFromGivenPort(
+            final GetQueueStatisticsFromGivenPortInput input) {
+        LOG.debug("Calling the getQueueStatisticsFromGivenPort RPC method on MessageDispatchService");
+        SwitchConnectionDistinguisher cookie = null;
+        
+        OFRpcTask<GetQueueStatisticsFromGivenPortInput, RpcResult<GetQueueStatisticsFromGivenPortOutput>> task = 
+                OFRpcTaskFactory.createGetQueueStatisticsFromGivenPortTask(rpcTaskContext, input, cookie);
+        ListenableFuture<RpcResult<GetQueueStatisticsFromGivenPortOutput>> result = task.submit();
+        return result;
     }
 
     @Override
-    public Future<RpcResult<UpdateMeterOutput>> updateMeter(
-            UpdateMeterInput input) {
-        // TODO Auto-generated method stub
-        return null;
+    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());
     }
 
-    public NodeId getNodeId() {
-        return nodeId;
+    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!");
     }
 }