ddfbaaeceb5d96ea2bc74b852ebb821403be2893
[openflowplugin.git] / openflowplugin / src / main / java / org / opendaylight / openflowplugin / openflow / md / core / sal / ModelDrivenSwitchImpl.java
1 /**
2  * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
3  *
4  * This program and the accompanying materials are made available under the
5  * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6  * and is available at http://www.eclipse.org/legal/epl-v10.html
7  */
8 package org.opendaylight.openflowplugin.openflow.md.core.sal;
9
10 import com.google.common.base.Objects;
11 import com.google.common.util.concurrent.Futures;
12 import com.google.common.util.concurrent.JdkFutureAdapters;
13 import com.google.common.util.concurrent.ListenableFuture;
14 import org.opendaylight.controller.sal.binding.api.NotificationProviderService;
15 import org.opendaylight.controller.sal.common.util.Rpcs;
16 import org.opendaylight.openflowjava.protocol.api.util.BinContent;
17 import org.opendaylight.openflowplugin.openflow.md.OFConstants;
18 import org.opendaylight.openflowplugin.openflow.md.core.SwitchConnectionDistinguisher;
19 import org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.FlowConvertor;
20 import org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.GroupConvertor;
21 import org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.MeterConvertor;
22 import org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.PacketOutConvertor;
23 import org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.PortConvertor;
24 import org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.TableFeaturesConvertor;
25 import org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.match.MatchReactor;
26 import org.opendaylight.openflowplugin.openflow.md.core.session.IMessageDispatchService;
27 import org.opendaylight.openflowplugin.openflow.md.core.session.OFSessionUtil;
28 import org.opendaylight.openflowplugin.openflow.md.core.session.SessionContext;
29 import org.opendaylight.openflowplugin.openflow.md.core.session.SwitchConnectionCookieOFImpl;
30 import org.opendaylight.openflowplugin.openflow.md.util.FlowCreatorUtil;
31 import org.opendaylight.openflowplugin.openflow.md.util.InventoryDataServiceUtil;
32 import org.opendaylight.openflowplugin.openflow.md.util.OpenflowVersion;
33 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.AddFlowInput;
34 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.AddFlowOutput;
35 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.FlowRemovedBuilder;
36 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.RemoveFlowInput;
37 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.RemoveFlowOutput;
38 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.RemoveFlowOutputBuilder;
39 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.UpdateFlowInput;
40 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.UpdateFlowOutput;
41 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.GetAggregateFlowStatisticsFromFlowTableForAllFlowsInput;
42 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.GetAggregateFlowStatisticsFromFlowTableForAllFlowsOutput;
43 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.GetAggregateFlowStatisticsFromFlowTableForAllFlowsOutputBuilder;
44 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.GetAggregateFlowStatisticsFromFlowTableForGivenMatchInput;
45 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.GetAggregateFlowStatisticsFromFlowTableForGivenMatchOutput;
46 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.GetAggregateFlowStatisticsFromFlowTableForGivenMatchOutputBuilder;
47 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.GetAllFlowStatisticsFromFlowTableInput;
48 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.GetAllFlowStatisticsFromFlowTableOutput;
49 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.GetAllFlowStatisticsFromFlowTableOutputBuilder;
50 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.GetAllFlowsStatisticsFromAllFlowTablesInput;
51 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.GetAllFlowsStatisticsFromAllFlowTablesOutput;
52 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.GetAllFlowsStatisticsFromAllFlowTablesOutputBuilder;
53 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.GetFlowStatisticsFromFlowTableInput;
54 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.GetFlowStatisticsFromFlowTableOutput;
55 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.GetFlowStatisticsFromFlowTableOutputBuilder;
56 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.table.statistics.rev131215.GetFlowTablesStatisticsInput;
57 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.table.statistics.rev131215.GetFlowTablesStatisticsOutput;
58 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.table.statistics.rev131215.GetFlowTablesStatisticsOutputBuilder;
59 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.transaction.rev131103.TransactionId;
60 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.port.rev130925.port.mod.port.Port;
61 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.Flow;
62 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.service.rev130918.AddGroupInput;
63 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.service.rev130918.AddGroupOutput;
64 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.service.rev130918.GroupRemovedBuilder;
65 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.service.rev130918.RemoveGroupInput;
66 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.service.rev130918.RemoveGroupOutput;
67 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.service.rev130918.RemoveGroupOutputBuilder;
68 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.service.rev130918.UpdateGroupInput;
69 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.service.rev130918.UpdateGroupOutput;
70 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.statistics.rev131111.GetAllGroupStatisticsInput;
71 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.statistics.rev131111.GetAllGroupStatisticsOutput;
72 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.statistics.rev131111.GetAllGroupStatisticsOutputBuilder;
73 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.statistics.rev131111.GetGroupDescriptionInput;
74 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.statistics.rev131111.GetGroupDescriptionOutput;
75 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.statistics.rev131111.GetGroupDescriptionOutputBuilder;
76 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.statistics.rev131111.GetGroupFeaturesInput;
77 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.statistics.rev131111.GetGroupFeaturesOutput;
78 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.statistics.rev131111.GetGroupFeaturesOutputBuilder;
79 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.statistics.rev131111.GetGroupStatisticsInput;
80 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.statistics.rev131111.GetGroupStatisticsOutput;
81 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.statistics.rev131111.GetGroupStatisticsOutputBuilder;
82 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeId;
83 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node;
84 import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.service.rev130918.AddMeterInput;
85 import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.service.rev130918.AddMeterOutput;
86 import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.service.rev130918.MeterRemovedBuilder;
87 import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.service.rev130918.RemoveMeterInput;
88 import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.service.rev130918.RemoveMeterOutput;
89 import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.service.rev130918.RemoveMeterOutputBuilder;
90 import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.service.rev130918.UpdateMeterInput;
91 import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.service.rev130918.UpdateMeterOutput;
92 import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.statistics.rev131111.GetAllMeterConfigStatisticsInput;
93 import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.statistics.rev131111.GetAllMeterConfigStatisticsOutput;
94 import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.statistics.rev131111.GetAllMeterConfigStatisticsOutputBuilder;
95 import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.statistics.rev131111.GetAllMeterStatisticsInput;
96 import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.statistics.rev131111.GetAllMeterStatisticsOutput;
97 import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.statistics.rev131111.GetAllMeterStatisticsOutputBuilder;
98 import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.statistics.rev131111.GetMeterFeaturesInput;
99 import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.statistics.rev131111.GetMeterFeaturesOutput;
100 import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.statistics.rev131111.GetMeterFeaturesOutputBuilder;
101 import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.statistics.rev131111.GetMeterStatisticsInput;
102 import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.statistics.rev131111.GetMeterStatisticsOutput;
103 import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.statistics.rev131111.GetMeterStatisticsOutputBuilder;
104 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.Group;
105 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.GroupId;
106 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.Meter;
107 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.MeterId;
108 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.MultipartRequestFlags;
109 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.MultipartType;
110 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev130731.match.grouping.Match;
111 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev130731.match.grouping.MatchBuilder;
112 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev130731.oxm.fields.grouping.MatchEntries;
113 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.BarrierInputBuilder;
114 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.BarrierOutput;
115 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.FlowModInputBuilder;
116 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.GroupModInputBuilder;
117 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.MeterModInputBuilder;
118 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.MultipartRequestInputBuilder;
119 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.PacketOutInput;
120 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.PortModInput;
121 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.PortModInputBuilder;
122 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.MultipartRequestAggregateCaseBuilder;
123 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.MultipartRequestFlowCaseBuilder;
124 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.MultipartRequestGroupCaseBuilder;
125 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.MultipartRequestGroupDescCaseBuilder;
126 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.MultipartRequestGroupFeaturesCaseBuilder;
127 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.MultipartRequestMeterCaseBuilder;
128 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.MultipartRequestMeterConfigCaseBuilder;
129 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.MultipartRequestMeterFeaturesCaseBuilder;
130 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.MultipartRequestPortStatsCaseBuilder;
131 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.MultipartRequestQueueCaseBuilder;
132 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.MultipartRequestTableCaseBuilder;
133 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.MultipartRequestTableFeaturesCaseBuilder;
134 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.multipart.request.aggregate._case.MultipartRequestAggregateBuilder;
135 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.multipart.request.flow._case.MultipartRequestFlowBuilder;
136 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.multipart.request.group._case.MultipartRequestGroupBuilder;
137 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.multipart.request.meter._case.MultipartRequestMeterBuilder;
138 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.multipart.request.meter.config._case.MultipartRequestMeterConfigBuilder;
139 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.multipart.request.port.stats._case.MultipartRequestPortStatsBuilder;
140 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.multipart.request.queue._case.MultipartRequestQueueBuilder;
141 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.multipart.request.table._case.MultipartRequestTableBuilder;
142 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.multipart.request.table.features._case.MultipartRequestTableFeaturesBuilder;
143 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.multipart.request.table.features._case.multipart.request.table.features.TableFeatures;
144 import org.opendaylight.yang.gen.v1.urn.opendaylight.packet.service.rev130709.ConnectionCookie;
145 import org.opendaylight.yang.gen.v1.urn.opendaylight.packet.service.rev130709.TransmitPacketInput;
146 import org.opendaylight.yang.gen.v1.urn.opendaylight.port.service.rev131107.UpdatePortInput;
147 import org.opendaylight.yang.gen.v1.urn.opendaylight.port.service.rev131107.UpdatePortOutput;
148 import org.opendaylight.yang.gen.v1.urn.opendaylight.port.service.rev131107.UpdatePortOutputBuilder;
149 import org.opendaylight.yang.gen.v1.urn.opendaylight.port.statistics.rev131214.GetAllNodeConnectorsStatisticsInput;
150 import org.opendaylight.yang.gen.v1.urn.opendaylight.port.statistics.rev131214.GetAllNodeConnectorsStatisticsOutput;
151 import org.opendaylight.yang.gen.v1.urn.opendaylight.port.statistics.rev131214.GetAllNodeConnectorsStatisticsOutputBuilder;
152 import org.opendaylight.yang.gen.v1.urn.opendaylight.port.statistics.rev131214.GetNodeConnectorStatisticsInput;
153 import org.opendaylight.yang.gen.v1.urn.opendaylight.port.statistics.rev131214.GetNodeConnectorStatisticsOutput;
154 import org.opendaylight.yang.gen.v1.urn.opendaylight.port.statistics.rev131214.GetNodeConnectorStatisticsOutputBuilder;
155 import org.opendaylight.yang.gen.v1.urn.opendaylight.queue.statistics.rev131216.GetAllQueuesStatisticsFromAllPortsInput;
156 import org.opendaylight.yang.gen.v1.urn.opendaylight.queue.statistics.rev131216.GetAllQueuesStatisticsFromAllPortsOutput;
157 import org.opendaylight.yang.gen.v1.urn.opendaylight.queue.statistics.rev131216.GetAllQueuesStatisticsFromAllPortsOutputBuilder;
158 import org.opendaylight.yang.gen.v1.urn.opendaylight.queue.statistics.rev131216.GetAllQueuesStatisticsFromGivenPortInput;
159 import org.opendaylight.yang.gen.v1.urn.opendaylight.queue.statistics.rev131216.GetAllQueuesStatisticsFromGivenPortOutput;
160 import org.opendaylight.yang.gen.v1.urn.opendaylight.queue.statistics.rev131216.GetAllQueuesStatisticsFromGivenPortOutputBuilder;
161 import org.opendaylight.yang.gen.v1.urn.opendaylight.queue.statistics.rev131216.GetQueueStatisticsFromGivenPortInput;
162 import org.opendaylight.yang.gen.v1.urn.opendaylight.queue.statistics.rev131216.GetQueueStatisticsFromGivenPortOutput;
163 import org.opendaylight.yang.gen.v1.urn.opendaylight.queue.statistics.rev131216.GetQueueStatisticsFromGivenPortOutputBuilder;
164 import org.opendaylight.yang.gen.v1.urn.opendaylight.table.service.rev131026.UpdateTableInput;
165 import org.opendaylight.yang.gen.v1.urn.opendaylight.table.service.rev131026.UpdateTableOutput;
166 import org.opendaylight.yang.gen.v1.urn.opendaylight.table.service.rev131026.UpdateTableOutputBuilder;
167 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
168 import org.opendaylight.yangtools.yang.common.RpcError;
169 import org.opendaylight.yangtools.yang.common.RpcResult;
170 import org.slf4j.Logger;
171
172 import java.math.BigInteger;
173 import java.util.ArrayList;
174 import java.util.Collection;
175 import java.util.Collections;
176 import java.util.List;
177 import java.util.concurrent.Future;
178 import java.util.concurrent.TimeUnit;
179
180 /**
181  * RPC implementation of MD-switch
182  */
183 public class ModelDrivenSwitchImpl extends AbstractModelDrivenSwitch {
184
185     private static final Logger LOG = org.slf4j.LoggerFactory.getLogger(ModelDrivenSwitchImpl.class);
186     private final NodeId nodeId;
187     private final IMessageDispatchService messageService;
188     private short version = 0;
189     private NotificationProviderService rpcNotificationProviderService;
190     private OFRpcTaskContext rpcTaskContext;
191     
192     // TODO:read timeout from configSubsystem
193     protected long maxTimeout = 1000;
194     protected TimeUnit maxTimeoutUnit = TimeUnit.MILLISECONDS;
195     
196     protected ModelDrivenSwitchImpl(final NodeId nodeId, final InstanceIdentifier<Node> identifier, 
197             final SessionContext sessionContext) {
198         super(identifier, sessionContext);
199         this.nodeId = nodeId;
200         messageService = sessionContext.getMessageDispatchService();
201         version = sessionContext.getPrimaryConductor().getVersion();
202         rpcNotificationProviderService = OFSessionUtil.getSessionManager().getNotificationProviderService();
203         
204         rpcTaskContext = new OFRpcTaskContext();
205         rpcTaskContext.setSession(sessionContext);
206         rpcTaskContext.setMessageService(messageService);
207         rpcTaskContext.setRpcNotificationProviderService(rpcNotificationProviderService);
208         rpcTaskContext.setMaxTimeout(maxTimeout);
209         rpcTaskContext.setMaxTimeoutUnit(maxTimeoutUnit);
210         rpcTaskContext.setRpcPool(OFSessionUtil.getSessionManager().getRpcPool());
211         rpcTaskContext.setMessageSpy(OFSessionUtil.getSessionManager().getMessageSpy());
212     }
213
214     @Override
215     public Future<RpcResult<AddFlowOutput>> addFlow(final AddFlowInput input) {
216         LOG.debug("Calling the FlowMod RPC method on MessageDispatchService");
217         // use primary connection
218         SwitchConnectionDistinguisher cookie = null;
219         
220         OFRpcTask<AddFlowInput, RpcResult<UpdateFlowOutput>> task = 
221                 OFRpcTaskFactory.createAddFlowTask(rpcTaskContext, input, cookie);
222         ListenableFuture<RpcResult<UpdateFlowOutput>> result = task.submit();
223         
224         return Futures.transform(JdkFutureAdapters.listenInPoolThread(result), 
225                 OFRpcFutureResultTransformFactory.createForAddFlowOutput());
226     }
227
228
229     @Override
230     public Future<RpcResult<AddGroupOutput>> addGroup(final AddGroupInput input) {
231         LOG.debug("Calling the GroupMod RPC method on MessageDispatchService");
232         
233         // use primary connection
234         SwitchConnectionDistinguisher cookie = null;
235         
236         OFRpcTask<AddGroupInput, RpcResult<UpdateGroupOutput>> task = 
237                 OFRpcTaskFactory.createAddGroupTask(rpcTaskContext, input, cookie);
238         ListenableFuture<RpcResult<UpdateGroupOutput>> result = task.submit();
239         
240         return Futures.transform(JdkFutureAdapters.listenInPoolThread(result), 
241                 OFRpcFutureResultTransformFactory.createForAddGroupOutput());
242     }
243
244     @Override
245     public Future<RpcResult<AddMeterOutput>> addMeter(final AddMeterInput input) {
246         LOG.debug("Calling the MeterMod RPC method on MessageDispatchService");
247         
248         // use primary connection
249         SwitchConnectionDistinguisher cookie = null;
250         
251         OFRpcTask<AddMeterInput, RpcResult<UpdateMeterOutput>> task = 
252                 OFRpcTaskFactory.createAddMeterTask(rpcTaskContext, input, cookie);
253         ListenableFuture<RpcResult<UpdateMeterOutput>> result = task.submit();
254         
255         return Futures.transform(JdkFutureAdapters.listenInPoolThread(result), 
256                 OFRpcFutureResultTransformFactory.createForAddMeterOutput());
257     }
258
259     @Override
260     public Future<RpcResult<RemoveFlowOutput>> removeFlow(final RemoveFlowInput input) {
261         LOG.debug("Calling the removeFlow RPC method on MessageDispatchService");
262         Long xId = null;
263         // For Flow provisioning, the SwitchConnectionDistinguisher is set to
264         // null so
265         // the request can be routed through any connection to the switch
266
267         SwitchConnectionDistinguisher cookie = null;
268         if (Objects.firstNonNull(input.isBarrier(), Boolean.FALSE)) {
269             BarrierInputBuilder barrierInput = new BarrierInputBuilder();
270             xId = sessionContext.getNextXid();
271             barrierInput.setXid(xId);
272             barrierInput.setVersion(version);
273             @SuppressWarnings("unused")
274             Future<RpcResult<BarrierOutput>> barrierOFLib = messageService.barrier(barrierInput.build(), cookie);
275         }
276
277         // Convert the RemoveFlowInput to FlowModInput
278         FlowModInputBuilder ofFlowModInput = FlowConvertor.toFlowModInput(input, version, sessionContext
279                 .getFeatures().getDatapathId());
280         xId = sessionContext.getNextXid();
281         ofFlowModInput.setXid(xId);
282
283         if (null != rpcNotificationProviderService) {
284             FlowRemovedBuilder removeFlow = new FlowRemovedBuilder(
285                     (org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.Flow) input);
286             removeFlow.setTransactionId(new TransactionId(BigInteger.valueOf(xId.intValue())));
287             removeFlow.setFlowRef(input.getFlowRef());
288             rpcNotificationProviderService.publish(removeFlow.build());
289         }
290
291         Future<RpcResult<UpdateFlowOutput>> resultFromOFLib = messageService.flowMod(ofFlowModInput.build(), cookie);
292
293         RpcResult<UpdateFlowOutput> rpcResultFromOFLib = null;
294
295         try {
296             rpcResultFromOFLib = resultFromOFLib.get();
297         } catch (Exception ex) {
298             LOG.error(" Error while getting result for remove Flow RPC" + ex.getMessage());
299         }
300
301         UpdateFlowOutput updateFlowOutput = rpcResultFromOFLib.getResult();
302
303         RemoveFlowOutputBuilder removeFlowOutput = new RemoveFlowOutputBuilder();
304         removeFlowOutput.setTransactionId(updateFlowOutput.getTransactionId());
305         RemoveFlowOutput result = removeFlowOutput.build();
306
307         Collection<RpcError> errors = rpcResultFromOFLib.getErrors();
308         RpcResult<RemoveFlowOutput> rpcResult = Rpcs.getRpcResult(true, result, errors);
309
310         LOG.debug("Returning the Remove Flow RPC result to MD-SAL");
311         return Futures.immediateFuture(rpcResult);
312     }
313
314     @Override
315     public Future<RpcResult<RemoveGroupOutput>> removeGroup(final RemoveGroupInput input) {
316         LOG.debug("Calling the Remove Group RPC method on MessageDispatchService");
317         Long xId = null;
318
319         // For Flow provisioning, the SwitchConnectionDistinguisher is set to
320         // null so
321         // the request can be routed through any connection to the switch
322
323         SwitchConnectionDistinguisher cookie = null;
324         if (Objects.firstNonNull(input.isBarrier(), Boolean.FALSE)) {
325             xId = sessionContext.getNextXid();
326             BarrierInputBuilder barrierInput = new BarrierInputBuilder();
327             barrierInput.setVersion(version);
328             barrierInput.setXid(xId);
329             @SuppressWarnings("unused")
330             Future<RpcResult<BarrierOutput>> barrierOFLib = messageService.barrier(barrierInput.build(), cookie);
331         }
332
333         // Convert the RemoveGroupInput to GroupModInput
334         GroupModInputBuilder ofGroupModInput = GroupConvertor.toGroupModInput(input, version, this.getSessionContext()
335                 .getFeatures().getDatapathId());
336         xId = sessionContext.getNextXid();
337         ofGroupModInput.setXid(xId);
338
339         if (null != rpcNotificationProviderService) {
340             GroupRemovedBuilder groupMod = new GroupRemovedBuilder(
341                     (org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.Group) input);
342             groupMod.setTransactionId(new TransactionId(BigInteger.valueOf(xId.intValue())));
343             groupMod.setGroupRef(input.getGroupRef());
344             rpcNotificationProviderService.publish(groupMod.build());
345         }
346
347         Future<RpcResult<UpdateGroupOutput>> resultFromOFLib = messageService.groupMod(ofGroupModInput.build(), cookie);
348
349         RpcResult<UpdateGroupOutput> rpcResultFromOFLib = null;
350
351         try {
352             rpcResultFromOFLib = resultFromOFLib.get();
353         } catch (Exception ex) {
354             LOG.error(" Error while getting result for RemoveGroup RPC" + ex.getMessage());
355         }
356
357         UpdateGroupOutput updateGroupOutput = rpcResultFromOFLib.getResult();
358
359         RemoveGroupOutputBuilder removeGroupOutput = new RemoveGroupOutputBuilder();
360         removeGroupOutput.setTransactionId(updateGroupOutput.getTransactionId());
361         RemoveGroupOutput result = removeGroupOutput.build();
362
363         Collection<RpcError> errors = rpcResultFromOFLib.getErrors();
364         RpcResult<RemoveGroupOutput> rpcResult = Rpcs.getRpcResult(true, result, errors);
365
366         LOG.debug("Returning the Remove Group RPC result to MD-SAL");
367         return Futures.immediateFuture(rpcResult);
368     }
369
370     @Override
371     public Future<RpcResult<RemoveMeterOutput>> removeMeter(final RemoveMeterInput input) {
372         LOG.debug("Calling the Remove MeterMod RPC method on MessageDispatchService");
373         Long xId = null;
374
375         // For Meter provisioning, the SwitchConnectionDistinguisher is set to
376         // null so
377         // the request can be routed through any connection to the switch
378         SwitchConnectionDistinguisher cookie = null;
379         if (Objects.firstNonNull(input.isBarrier(), Boolean.FALSE)) {
380             xId = sessionContext.getNextXid();
381             BarrierInputBuilder barrierInput = new BarrierInputBuilder();
382             barrierInput.setVersion(version);
383             barrierInput.setXid(xId);
384             @SuppressWarnings("unused")
385             Future<RpcResult<BarrierOutput>> barrierOFLib = messageService.barrier(barrierInput.build(), cookie);
386         }
387
388         // Convert the RemoveMeterInput to MeterModInput
389         MeterModInputBuilder ofMeterModInput = MeterConvertor.toMeterModInput(input, version);
390         xId = sessionContext.getNextXid();
391         ofMeterModInput.setXid(xId);
392
393         if (null != rpcNotificationProviderService) {
394             MeterRemovedBuilder meterMod = new MeterRemovedBuilder(
395                     (org.opendaylight.yang.gen.v1.urn.opendaylight.meter.types.rev130918.Meter) input);
396             meterMod.setTransactionId(new TransactionId(BigInteger.valueOf(xId.intValue())));
397             meterMod.setMeterRef(input.getMeterRef());
398             rpcNotificationProviderService.publish(meterMod.build());
399         }
400
401         Future<RpcResult<UpdateMeterOutput>> resultFromOFLib = messageService.meterMod(ofMeterModInput.build(), cookie);
402
403         RpcResult<UpdateMeterOutput> rpcResultFromOFLib = null;
404
405         try {
406             rpcResultFromOFLib = resultFromOFLib.get();
407         } catch (Exception ex) {
408             LOG.error(" Error while getting result for RemoveMeter RPC" + ex.getMessage());
409         }
410
411         UpdateMeterOutput updatemeterOutput = rpcResultFromOFLib.getResult();
412
413         RemoveMeterOutputBuilder removeMeterOutput = new RemoveMeterOutputBuilder();
414         removeMeterOutput.setTransactionId(updatemeterOutput.getTransactionId());
415         RemoveMeterOutput result = removeMeterOutput.build();
416
417         Collection<RpcError> errors = rpcResultFromOFLib.getErrors();
418         RpcResult<RemoveMeterOutput> rpcResult = Rpcs.getRpcResult(true, result, errors);
419
420         LOG.debug("Returning the Remove Meter RPC result to MD-SAL");
421         return Futures.immediateFuture(rpcResult);
422     }
423
424     @Override
425     public Future<RpcResult<Void>> transmitPacket(final TransmitPacketInput input) {
426         LOG.debug("TransmitPacket - {}", input);
427         // Convert TransmitPacket to PacketOutInput
428         PacketOutInput message = PacketOutConvertor.toPacketOutInput(input, version, sessionContext.getNextXid(),
429                 sessionContext.getFeatures().getDatapathId());
430
431         SwitchConnectionDistinguisher cookie = null;
432         ConnectionCookie connectionCookie = input.getConnectionCookie();
433         if (connectionCookie != null && connectionCookie.getValue() != null) {
434             cookie = new SwitchConnectionCookieOFImpl(connectionCookie.getValue());
435         }
436
437         LOG.debug("Calling the transmitPacket RPC method");
438         return messageService.packetOut(message, cookie);
439     }
440
441     private FlowModInputBuilder toFlowModInputBuilder(final Flow source) {
442         FlowModInputBuilder target = new FlowModInputBuilder();
443         target.setCookie(source.getCookie().getValue());
444         target.setIdleTimeout(source.getIdleTimeout());
445         target.setHardTimeout(source.getHardTimeout());
446         target.setMatch(toMatch(source.getMatch()));
447
448         return target;
449     }
450
451     private Match toMatch(final org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.Match match) {
452         MatchBuilder target = new MatchBuilder();
453
454         target.setMatchEntries(toMatchEntries(match));
455
456         return null;
457     }
458
459     private List<MatchEntries> toMatchEntries(
460             final org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.Match match) {
461         List<MatchEntries> entries = new ArrayList<>();
462
463         return null;
464     }
465
466     @Override
467     public Future<RpcResult<UpdateFlowOutput>> updateFlow(final UpdateFlowInput input) {
468         LOG.debug("Calling the updateFlow RPC method on MessageDispatchService");
469         
470         // use primary connection
471         SwitchConnectionDistinguisher cookie = null;
472         
473         OFRpcTask<UpdateFlowInput, RpcResult<UpdateFlowOutput>> task = 
474                 OFRpcTaskFactory.createUpdateFlowTask(rpcTaskContext, input, cookie);
475         ListenableFuture<RpcResult<UpdateFlowOutput>> result = task.submit();
476         
477         return result;
478     }
479
480     @Override
481     public Future<RpcResult<UpdateGroupOutput>> updateGroup(final UpdateGroupInput input) {
482         LOG.debug("Calling the update Group Mod RPC method on MessageDispatchService");
483         
484         // use primary connection
485         SwitchConnectionDistinguisher cookie = null;
486         
487         OFRpcTask<UpdateGroupInput, RpcResult<UpdateGroupOutput>> task = 
488                 OFRpcTaskFactory.createUpdateGroupTask(rpcTaskContext, input, cookie);
489         ListenableFuture<RpcResult<UpdateGroupOutput>> result = task.submit();
490         
491         return result;
492     }
493
494     @Override
495     public Future<RpcResult<UpdateMeterOutput>> updateMeter(final UpdateMeterInput input) {
496         LOG.debug("Calling the MeterMod RPC method on MessageDispatchService");
497         
498         // use primary connection
499         SwitchConnectionDistinguisher cookie = null;
500         
501         OFRpcTask<UpdateMeterInput, RpcResult<UpdateMeterOutput>> task = 
502                 OFRpcTaskFactory.createUpdateMeterTask(rpcTaskContext, input, cookie);
503         ListenableFuture<RpcResult<UpdateMeterOutput>> result = task.submit();
504         
505         return result;
506     }
507
508     @Override
509     public NodeId getNodeId() {
510         return nodeId;
511     }
512
513     /*
514      * Methods for requesting statistics from switch
515      */
516     @Override
517     public Future<RpcResult<GetAllGroupStatisticsOutput>> getAllGroupStatistics(final GetAllGroupStatisticsInput input) {
518
519         GetAllGroupStatisticsOutputBuilder output = new GetAllGroupStatisticsOutputBuilder();
520         Collection<RpcError> errors = Collections.emptyList();
521
522         if (version == OFConstants.OFP_VERSION_1_0) {
523             output.setTransactionId(null);
524             output.setGroupStats(null);
525
526             RpcResult<GetAllGroupStatisticsOutput> rpcResult = Rpcs.getRpcResult(true, output.build(), errors);
527             return Futures.immediateFuture(rpcResult);
528         }
529         // Generate xid to associate it with the request
530         Long xid = this.getSessionContext().getNextXid();
531
532         LOG.debug("Prepare statistics request for all the groups - Transaction id - {}", xid);
533
534         // Create multipart request header
535         MultipartRequestInputBuilder mprInput = new MultipartRequestInputBuilder();
536         mprInput.setType(MultipartType.OFPMPGROUP);
537         mprInput.setVersion(version);
538         mprInput.setXid(xid);
539         mprInput.setFlags(new MultipartRequestFlags(false));
540
541         // Create multipart request body for fetch all the group stats
542         MultipartRequestGroupCaseBuilder caseBuilder = new MultipartRequestGroupCaseBuilder();
543         MultipartRequestGroupBuilder mprGroupBuild = new MultipartRequestGroupBuilder();
544         mprGroupBuild.setGroupId(new GroupId(BinContent.intToUnsignedLong(Group.OFPGALL.getIntValue())));
545         caseBuilder.setMultipartRequestGroup(mprGroupBuild.build());
546
547         // Set request body to main multipart request
548         mprInput.setMultipartRequestBody(caseBuilder.build());
549
550         // Send the request, no cookies associated, use any connection
551         LOG.debug("Send group statistics request to the switch :{}", mprGroupBuild);
552         this.messageService.multipartRequest(mprInput.build(), null);
553
554         // Prepare rpc return output. Set xid and send it back.
555         LOG.debug("Return results and transaction id back to caller");
556         output.setTransactionId(generateTransactionId(xid));
557         output.setGroupStats(null);
558
559         RpcResult<GetAllGroupStatisticsOutput> rpcResult = Rpcs.getRpcResult(true, output.build(), errors);
560         return Futures.immediateFuture(rpcResult);
561
562     }
563
564     @Override
565     public Future<RpcResult<GetGroupDescriptionOutput>> getGroupDescription(final GetGroupDescriptionInput input) {
566
567         GetGroupDescriptionOutputBuilder output = new GetGroupDescriptionOutputBuilder();
568         Collection<RpcError> errors = Collections.emptyList();
569
570         if (version == OFConstants.OFP_VERSION_1_0) {
571             output.setTransactionId(null);
572             output.setGroupDescStats(null);
573
574             RpcResult<GetGroupDescriptionOutput> rpcResult = Rpcs.getRpcResult(true, output.build(), errors);
575             return Futures.immediateFuture(rpcResult);
576         }
577         // Generate xid to associate it with the request
578         Long xid = this.getSessionContext().getNextXid();
579
580         LOG.debug("Prepare group description statistics request - Transaction id - {}", xid);
581
582         // Create multipart request header
583         MultipartRequestInputBuilder mprInput = new MultipartRequestInputBuilder();
584         mprInput.setType(MultipartType.OFPMPGROUPDESC);
585         mprInput.setVersion(version);
586         mprInput.setXid(xid);
587         mprInput.setFlags(new MultipartRequestFlags(false));
588
589         // Create multipart request body for fetch all the group description
590         // stats
591         MultipartRequestGroupDescCaseBuilder mprGroupDescBuild = new MultipartRequestGroupDescCaseBuilder();
592
593         // Set request body to main multipart request
594         mprInput.setMultipartRequestBody(mprGroupDescBuild.build());
595
596         // Send the request, no cookies associated, use any connection
597         LOG.debug("Send group desciption statistics request to switch : {}", mprGroupDescBuild);
598         this.messageService.multipartRequest(mprInput.build(), null);
599
600         // Prepare rpc return output. Set xid and send it back.
601         LOG.debug("Return results and transaction id back to caller");
602         output.setTransactionId(generateTransactionId(xid));
603         output.setGroupDescStats(null);
604
605         RpcResult<GetGroupDescriptionOutput> rpcResult = Rpcs.getRpcResult(true, output.build(), errors);
606         return Futures.immediateFuture(rpcResult);
607
608     }
609
610     @Override
611     public Future<RpcResult<GetGroupFeaturesOutput>> getGroupFeatures(final GetGroupFeaturesInput input) {
612
613         GetGroupFeaturesOutputBuilder output = new GetGroupFeaturesOutputBuilder();
614         Collection<RpcError> errors = Collections.emptyList();
615
616         if (version == OFConstants.OFP_VERSION_1_0) {
617             output.setTransactionId(null);
618
619             RpcResult<GetGroupFeaturesOutput> rpcResult = Rpcs.getRpcResult(true, output.build(), errors);
620             return Futures.immediateFuture(rpcResult);
621         }
622         // Generate xid to associate it with the request
623         Long xid = this.getSessionContext().getNextXid();
624
625         LOG.debug("Prepare group features statistics request - Transaction id - {}", xid);
626
627         // Create multipart request header
628         MultipartRequestInputBuilder mprInput = new MultipartRequestInputBuilder();
629         mprInput.setType(MultipartType.OFPMPGROUPFEATURES);
630         mprInput.setVersion(version);
631         mprInput.setXid(xid);
632         mprInput.setFlags(new MultipartRequestFlags(false));
633
634         // Create multipart request body for fetch all the group description
635         // stats
636         MultipartRequestGroupFeaturesCaseBuilder mprGroupFeaturesBuild = new MultipartRequestGroupFeaturesCaseBuilder();
637
638         // Set request body to main multipart request
639         mprInput.setMultipartRequestBody(mprGroupFeaturesBuild.build());
640
641         // Send the request, no cookies associated, use any connection
642         LOG.debug("Send group features statistics request :{}", mprGroupFeaturesBuild);
643         this.messageService.multipartRequest(mprInput.build(), null);
644
645         // Prepare rpc return output. Set xid and send it back.
646         LOG.debug("Return results and transaction id back to caller");
647         output.setTransactionId(generateTransactionId(xid));
648
649         RpcResult<GetGroupFeaturesOutput> rpcResult = Rpcs.getRpcResult(true, output.build(), errors);
650         return Futures.immediateFuture(rpcResult);
651     }
652
653     @Override
654     public Future<RpcResult<GetGroupStatisticsOutput>> getGroupStatistics(final GetGroupStatisticsInput input) {
655
656         GetGroupStatisticsOutputBuilder output = new GetGroupStatisticsOutputBuilder();
657         Collection<RpcError> errors = Collections.emptyList();
658
659         if (version == OFConstants.OFP_VERSION_1_0) {
660             output.setTransactionId(null);
661             output.setGroupStats(null);
662
663             RpcResult<GetGroupStatisticsOutput> rpcResult = Rpcs.getRpcResult(true, output.build(), errors);
664             return Futures.immediateFuture(rpcResult);
665         }
666         // Generate xid to associate it with the request
667         Long xid = this.getSessionContext().getNextXid();
668
669         LOG.debug("Prepare statistics request for node {} group ({}) - Transaction id - {}", input.getNode(),
670                 input.getGroupId(), xid);
671
672         // Create multipart request header
673         MultipartRequestInputBuilder mprInput = new MultipartRequestInputBuilder();
674         mprInput.setType(MultipartType.OFPMPGROUP);
675         mprInput.setVersion(version);
676         mprInput.setXid(xid);
677         mprInput.setFlags(new MultipartRequestFlags(false));
678
679         // Create multipart request body for fetch all the group stats
680         MultipartRequestGroupCaseBuilder caseBuilder = new MultipartRequestGroupCaseBuilder();
681         MultipartRequestGroupBuilder mprGroupBuild = new MultipartRequestGroupBuilder();
682         mprGroupBuild.setGroupId(new GroupId(input.getGroupId().getValue()));
683         caseBuilder.setMultipartRequestGroup(mprGroupBuild.build());
684
685         // Set request body to main multipart request
686         mprInput.setMultipartRequestBody(caseBuilder.build());
687
688         // Send the request, no cookies associated, use any connection
689         LOG.debug("Send group statistics request :{}", mprGroupBuild);
690         this.messageService.multipartRequest(mprInput.build(), null);
691
692         // Prepare rpc return output. Set xid and send it back.
693         LOG.debug("Return results and transaction id back to caller");
694         output.setTransactionId(generateTransactionId(xid));
695         output.setGroupStats(null);
696
697         RpcResult<GetGroupStatisticsOutput> rpcResult = Rpcs.getRpcResult(true, output.build(), errors);
698         return Futures.immediateFuture(rpcResult);
699     }
700
701     @Override
702     public Future<RpcResult<GetAllMeterConfigStatisticsOutput>> getAllMeterConfigStatistics(
703             final GetAllMeterConfigStatisticsInput input) {
704
705         GetAllMeterConfigStatisticsOutputBuilder output = new GetAllMeterConfigStatisticsOutputBuilder();
706         Collection<RpcError> errors = Collections.emptyList();
707
708         if (version == OFConstants.OFP_VERSION_1_0) {
709             output.setTransactionId(null);
710             output.setMeterConfigStats(null);
711
712             RpcResult<GetAllMeterConfigStatisticsOutput> rpcResult = Rpcs.getRpcResult(true, output.build(), errors);
713             return Futures.immediateFuture(rpcResult);
714
715         }
716         // Generate xid to associate it with the request
717         Long xid = this.getSessionContext().getNextXid();
718
719         LOG.debug("Prepare config request for all the meters - Transaction id - {}", xid);
720
721         // Create multipart request header
722         MultipartRequestInputBuilder mprInput = new MultipartRequestInputBuilder();
723         mprInput.setType(MultipartType.OFPMPMETERCONFIG);
724         mprInput.setVersion(version);
725         mprInput.setXid(xid);
726         mprInput.setFlags(new MultipartRequestFlags(false));
727
728         // Create multipart request body for fetch all the meter stats
729         MultipartRequestMeterConfigCaseBuilder caseBuilder = new MultipartRequestMeterConfigCaseBuilder();
730         MultipartRequestMeterConfigBuilder mprMeterConfigBuild = new MultipartRequestMeterConfigBuilder();
731         mprMeterConfigBuild.setMeterId(new MeterId(BinContent.intToUnsignedLong(Meter.OFPMALL.getIntValue())));
732         caseBuilder.setMultipartRequestMeterConfig(mprMeterConfigBuild.build());
733
734         // Set request body to main multipart request
735         mprInput.setMultipartRequestBody(caseBuilder.build());
736
737         // Send the request, no cookies associated, use any connection
738         LOG.debug("Send meter statistics request :{}", mprMeterConfigBuild);
739         this.messageService.multipartRequest(mprInput.build(), null);
740
741         // Prepare rpc return output. Set xid and send it back.
742         LOG.debug("Return results and transaction id back to caller");
743         output.setTransactionId(generateTransactionId(xid));
744         output.setMeterConfigStats(null);
745
746         RpcResult<GetAllMeterConfigStatisticsOutput> rpcResult = Rpcs.getRpcResult(true, output.build(), errors);
747         return Futures.immediateFuture(rpcResult);
748     }
749
750     @Override
751     public Future<RpcResult<GetAllMeterStatisticsOutput>> getAllMeterStatistics(final GetAllMeterStatisticsInput input) {
752
753         GetAllMeterStatisticsOutputBuilder output = new GetAllMeterStatisticsOutputBuilder();
754         Collection<RpcError> errors = Collections.emptyList();
755
756         if (version == OFConstants.OFP_VERSION_1_0) {
757             output.setTransactionId(null);
758             output.setMeterStats(null);
759
760             RpcResult<GetAllMeterStatisticsOutput> rpcResult = Rpcs.getRpcResult(true, output.build(), errors);
761             return Futures.immediateFuture(rpcResult);
762         }
763         // Generate xid to associate it with the request
764         Long xid = this.getSessionContext().getNextXid();
765
766         LOG.debug("Prepare statistics request for all the meters - Transaction id - {}", xid);
767
768         // Create multipart request header
769         MultipartRequestInputBuilder mprInput = new MultipartRequestInputBuilder();
770         mprInput.setType(MultipartType.OFPMPMETER);
771         mprInput.setVersion(version);
772         mprInput.setXid(xid);
773         mprInput.setFlags(new MultipartRequestFlags(false));
774
775         // Create multipart request body for fetch all the meter stats
776         MultipartRequestMeterCaseBuilder caseBuilder = new MultipartRequestMeterCaseBuilder();
777         MultipartRequestMeterBuilder mprMeterBuild = new MultipartRequestMeterBuilder();
778         mprMeterBuild.setMeterId(new MeterId(BinContent.intToUnsignedLong(Meter.OFPMALL.getIntValue())));
779         caseBuilder.setMultipartRequestMeter(mprMeterBuild.build());
780
781         // Set request body to main multipart request
782         mprInput.setMultipartRequestBody(caseBuilder.build());
783
784         // Send the request, no cookies associated, use any connection
785         LOG.debug("Send meter statistics request :{}", mprMeterBuild);
786         this.messageService.multipartRequest(mprInput.build(), null);
787
788         // Prepare rpc return output. Set xid and send it back.
789         LOG.debug("Return results and transaction id back to caller");
790         output.setTransactionId(generateTransactionId(xid));
791         output.setMeterStats(null);
792
793         RpcResult<GetAllMeterStatisticsOutput> rpcResult = Rpcs.getRpcResult(true, output.build(), errors);
794         return Futures.immediateFuture(rpcResult);
795     }
796
797     @Override
798     public Future<RpcResult<GetMeterFeaturesOutput>> getMeterFeatures(final GetMeterFeaturesInput input) {
799
800         GetMeterFeaturesOutputBuilder output = new GetMeterFeaturesOutputBuilder();
801         Collection<RpcError> errors = Collections.emptyList();
802
803         if (version == OFConstants.OFP_VERSION_1_0) {
804             output.setTransactionId(null);
805
806             RpcResult<GetMeterFeaturesOutput> rpcResult = Rpcs.getRpcResult(true, output.build(), errors);
807             return Futures.immediateFuture(rpcResult);
808         }
809         // Generate xid to associate it with the request
810         Long xid = this.getSessionContext().getNextXid();
811
812         LOG.debug("Prepare features statistics request for all the meters - Transaction id - {}", xid);
813
814         // Create multipart request header
815         MultipartRequestInputBuilder mprInput = new MultipartRequestInputBuilder();
816         mprInput.setType(MultipartType.OFPMPMETERFEATURES);
817         mprInput.setVersion(version);
818         mprInput.setXid(xid);
819         mprInput.setFlags(new MultipartRequestFlags(false));
820
821         // Create multipart request body for fetch all the group description
822         // stats
823         MultipartRequestMeterFeaturesCaseBuilder mprMeterFeaturesBuild = new MultipartRequestMeterFeaturesCaseBuilder();
824
825         // Set request body to main multipart request
826         mprInput.setMultipartRequestBody(mprMeterFeaturesBuild.build());
827
828         // Send the request, no cookies associated, use any connection
829         LOG.debug("Send meter features statistics request :{}", mprMeterFeaturesBuild);
830         this.messageService.multipartRequest(mprInput.build(), null);
831
832         // Prepare rpc return output. Set xid and send it back.
833         LOG.debug("Return results and transaction id back to caller");
834         output.setTransactionId(generateTransactionId(xid));
835
836         RpcResult<GetMeterFeaturesOutput> rpcResult = Rpcs.getRpcResult(true, output.build(), errors);
837         return Futures.immediateFuture(rpcResult);
838     }
839
840     @Override
841     public Future<RpcResult<GetMeterStatisticsOutput>> getMeterStatistics(final GetMeterStatisticsInput input) {
842
843         GetMeterStatisticsOutputBuilder output = new GetMeterStatisticsOutputBuilder();
844         Collection<RpcError> errors = Collections.emptyList();
845
846         if (version == OFConstants.OFP_VERSION_1_0) {
847             output.setTransactionId(null);
848             output.setMeterStats(null);
849
850             RpcResult<GetMeterStatisticsOutput> rpcResult = Rpcs.getRpcResult(true, output.build(), errors);
851             return Futures.immediateFuture(rpcResult);
852
853         }
854         // Generate xid to associate it with the request
855         Long xid = this.getSessionContext().getNextXid();
856
857         LOG.debug("Preprae statistics request for Meter ({}) - Transaction id - {}", input.getMeterId().getValue(), xid);
858
859         // Create multipart request header
860         MultipartRequestInputBuilder mprInput = new MultipartRequestInputBuilder();
861         mprInput.setType(MultipartType.OFPMPMETER);
862         mprInput.setVersion(version);
863         mprInput.setXid(xid);
864         mprInput.setFlags(new MultipartRequestFlags(false));
865
866         // Create multipart request body for fetch all the meter stats
867         MultipartRequestMeterCaseBuilder caseBuilder = new MultipartRequestMeterCaseBuilder();
868         MultipartRequestMeterBuilder mprMeterBuild = new MultipartRequestMeterBuilder();
869         // Select specific meter
870         mprMeterBuild.setMeterId(new MeterId(input.getMeterId().getValue()));
871         caseBuilder.setMultipartRequestMeter(mprMeterBuild.build());
872
873         // Set request body to main multipart request
874         mprInput.setMultipartRequestBody(caseBuilder.build());
875
876         // Send the request, no cookies associated, use any connection
877         LOG.debug("Send meter statistics request :{}", mprMeterBuild);
878         this.messageService.multipartRequest(mprInput.build(), null);
879
880         // Prepare rpc return output. Set xid and send it back.
881         LOG.debug("Return results and transaction id back to caller");
882         output.setTransactionId(generateTransactionId(xid));
883         output.setMeterStats(null);
884
885         RpcResult<GetMeterStatisticsOutput> rpcResult = Rpcs.getRpcResult(true, output.build(), errors);
886         return Futures.immediateFuture(rpcResult);
887     }
888
889     @Override
890     public Future<RpcResult<GetAllNodeConnectorsStatisticsOutput>> getAllNodeConnectorsStatistics(
891             final GetAllNodeConnectorsStatisticsInput arg0) {
892
893         // Generate xid to associate it with the request
894         Long xid = this.getSessionContext().getNextXid();
895
896         LOG.debug("Prepare port statistics request for all ports of node {} - TrasactionId - {}", arg0.getNode()
897                 .getValue(), xid);
898
899         // Create multipart request header
900         MultipartRequestInputBuilder mprInput = new MultipartRequestInputBuilder();
901         mprInput.setType(MultipartType.OFPMPPORTSTATS);
902         mprInput.setVersion(version);
903         mprInput.setXid(xid);
904         mprInput.setFlags(new MultipartRequestFlags(false));
905
906         // Create multipart request body to fetch stats for all the port of the
907         // node
908         MultipartRequestPortStatsCaseBuilder caseBuilder = new MultipartRequestPortStatsCaseBuilder();
909         MultipartRequestPortStatsBuilder mprPortStatsBuilder = new MultipartRequestPortStatsBuilder();
910         // Select all ports
911         mprPortStatsBuilder.setPortNo(OFConstants.OFPP_ANY);
912         caseBuilder.setMultipartRequestPortStats(mprPortStatsBuilder.build());
913
914         // Set request body to main multipart request
915         mprInput.setMultipartRequestBody(caseBuilder.build());
916
917         // Send the request, no cookies associated, use any connection
918         LOG.debug("Send port statistics request :{}", mprPortStatsBuilder.build().toString());
919         this.messageService.multipartRequest(mprInput.build(), null);
920
921         // Prepare rpc return output. Set xid and send it back.
922         GetAllNodeConnectorsStatisticsOutputBuilder output = new GetAllNodeConnectorsStatisticsOutputBuilder();
923         output.setTransactionId(generateTransactionId(xid));
924
925         Collection<RpcError> errors = Collections.emptyList();
926         RpcResult<GetAllNodeConnectorsStatisticsOutput> rpcResult = Rpcs.getRpcResult(true, output.build(), errors);
927         return Futures.immediateFuture(rpcResult);
928     }
929
930     @Override
931     public Future<RpcResult<GetNodeConnectorStatisticsOutput>> getNodeConnectorStatistics(
932             final GetNodeConnectorStatisticsInput arg0) {
933         // Generate xid to associate it with the request
934         Long xid = this.getSessionContext().getNextXid();
935
936         LOG.debug("Prepare port statistics request for port {} of node {} - TrasactionId - {}",
937                 arg0.getNodeConnectorId(), arg0.getNode().getValue(), xid);
938
939         // Create multipart request header
940         MultipartRequestInputBuilder mprInput = new MultipartRequestInputBuilder();
941         mprInput.setType(MultipartType.OFPMPPORTSTATS);
942         mprInput.setVersion(version);
943         mprInput.setXid(xid);
944         mprInput.setFlags(new MultipartRequestFlags(false));
945
946         // Create multipart request body to fetch stats for all the port of the
947         // node
948         MultipartRequestPortStatsCaseBuilder caseBuilder = new MultipartRequestPortStatsCaseBuilder();
949         MultipartRequestPortStatsBuilder mprPortStatsBuilder = new MultipartRequestPortStatsBuilder();
950
951         // Set specific port
952         mprPortStatsBuilder
953                 .setPortNo(InventoryDataServiceUtil.portNumberfromNodeConnectorId(
954                         OpenflowVersion.get(version), arg0.getNodeConnectorId()));
955         caseBuilder.setMultipartRequestPortStats(mprPortStatsBuilder.build());
956
957         // Set request body to main multipart request
958         mprInput.setMultipartRequestBody(caseBuilder.build());
959
960         // Send the request, no cookies associated, use any connection
961         LOG.debug("Send port statistics request :{}", mprPortStatsBuilder.build().toString());
962         this.messageService.multipartRequest(mprInput.build(), null);
963
964         // Prepare rpc return output. Set xid and send it back.
965         GetNodeConnectorStatisticsOutputBuilder output = new GetNodeConnectorStatisticsOutputBuilder();
966         output.setTransactionId(generateTransactionId(xid));
967
968         Collection<RpcError> errors = Collections.emptyList();
969         RpcResult<GetNodeConnectorStatisticsOutput> rpcResult = Rpcs.getRpcResult(true, output.build(), errors);
970         return Futures.immediateFuture(rpcResult);
971     }
972
973     private static TransactionId generateTransactionId(final Long xid) {
974         BigInteger bigIntXid = BigInteger.valueOf(xid);
975         return new TransactionId(bigIntXid);
976
977     }
978
979     @Override
980     public Future<RpcResult<UpdatePortOutput>> updatePort(final UpdatePortInput input) {
981         PortModInput ofPortModInput = null;
982         RpcResult<UpdatePortOutput> rpcResultFromOFLib = null;
983
984         // For Flow provisioning, the SwitchConnectionDistinguisher is set to
985         // null so
986         // the request can be routed through any connection to the switch
987
988         SwitchConnectionDistinguisher cookie = null;
989
990         // NSF sends a list of port and the ModelDrivenSwitch will
991         // send one port at a time towards the switch ( mutiple RPCs calls)
992         List<Port> inputPorts = input.getUpdatedPort().getPort().getPort();
993
994         // Get the Xid. The same Xid has to be sent in all the RPCs
995         Long Xid = sessionContext.getNextXid();
996
997         for (Port inputPort : inputPorts) {
998
999             // Convert the UpdateGroupInput to GroupModInput
1000             ofPortModInput = PortConvertor.toPortModInput(inputPort, version);
1001
1002             // Insert the Xid ( transaction Id) before calling the RPC on the
1003             // OFLibrary
1004
1005             PortModInputBuilder mdInput = new PortModInputBuilder(ofPortModInput);
1006             mdInput.setXid(Xid);
1007
1008             LOG.debug("Calling the PortMod RPC method on MessageDispatchService");
1009             Future<RpcResult<UpdatePortOutput>> resultFromOFLib = messageService.portMod(mdInput.build(), cookie);
1010
1011             try {
1012                 rpcResultFromOFLib = resultFromOFLib.get();
1013             } catch (Exception ex) {
1014                 LOG.error(" Error while getting result for updatePort RPC" + ex.getMessage());
1015             }
1016
1017             // The Future response value for all the RPCs except the last one is
1018             // ignored
1019
1020         }
1021         // Extract the Xid only from the Future for the last RPC and
1022         // send it back to the NSF
1023         UpdatePortOutput updatePortOutputOFLib = rpcResultFromOFLib.getResult();
1024
1025         UpdatePortOutputBuilder updatePortOutput = new UpdatePortOutputBuilder();
1026         updatePortOutput.setTransactionId(updatePortOutputOFLib.getTransactionId());
1027         UpdatePortOutput result = updatePortOutput.build();
1028
1029         Collection<RpcError> errors = rpcResultFromOFLib.getErrors();
1030         RpcResult<UpdatePortOutput> rpcResult = Rpcs.getRpcResult(true, result, errors);
1031
1032         LOG.debug("Returning the Update Group RPC result to MD-SAL");
1033         return Futures.immediateFuture(rpcResult);
1034
1035     }
1036
1037     @Override
1038     public Future<RpcResult<UpdateTableOutput>> updateTable(final UpdateTableInput input) {
1039
1040         // Get the Xid. The same Xid has to be sent in all the Multipart
1041         // requests
1042         Long xid = this.getSessionContext().getNextXid();
1043
1044         LOG.debug("Prepare the Multipart Table Mod requests for Transaction Id {} ", xid);
1045
1046         // Create multipart request header
1047         MultipartRequestInputBuilder mprInput = new MultipartRequestInputBuilder();
1048         mprInput.setType(MultipartType.OFPMPTABLEFEATURES);
1049         mprInput.setVersion((short) 0x04);
1050         mprInput.setXid(xid);
1051
1052         // Convert the list of all MD-SAL table feature object into OF library
1053         // object
1054         List<TableFeatures> ofTableFeatureList = TableFeaturesConvertor.toTableFeaturesRequest(input.getUpdatedTable());
1055
1056         MultipartRequestTableFeaturesCaseBuilder caseRequest = new MultipartRequestTableFeaturesCaseBuilder();
1057         MultipartRequestTableFeaturesBuilder tableFeaturesRequest = new MultipartRequestTableFeaturesBuilder();
1058
1059         mprInput.setFlags(new MultipartRequestFlags(false));
1060
1061         tableFeaturesRequest.setTableFeatures(ofTableFeatureList);
1062
1063         // Set request body to main multipart request
1064         caseRequest.setMultipartRequestTableFeatures(tableFeaturesRequest.build());
1065         mprInput.setMultipartRequestBody(caseRequest.build());
1066
1067         // Send the request, no cookies associated, use any connection
1068         LOG.debug("Send Table Feature request :{}", ofTableFeatureList);
1069         this.messageService.multipartRequest(mprInput.build(), null);
1070
1071         // Extract the Xid only from the Future for the last RPC and
1072         // send it back to the NSF
1073         LOG.debug("Returning the result and transaction id to NSF");
1074         LOG.debug("Return results and transaction id back to caller");
1075         UpdateTableOutputBuilder output = new UpdateTableOutputBuilder();
1076         output.setTransactionId(generateTransactionId(xid));
1077
1078         Collection<RpcError> errors = Collections.emptyList();
1079         RpcResult<UpdateTableOutput> rpcResult = Rpcs.getRpcResult(true, output.build(), errors);
1080         return Futures.immediateFuture(rpcResult);
1081     }
1082
1083     @Override
1084     public Future<RpcResult<GetAllFlowStatisticsFromFlowTableOutput>> getAllFlowStatisticsFromFlowTable(
1085             final GetAllFlowStatisticsFromFlowTableInput arg0) {
1086
1087         // Generate xid to associate it with the request
1088         Long xid = this.getSessionContext().getNextXid();
1089
1090         LOG.debug("Prepare statistics request to get flow stats for switch tables {} - Transaction id - {}", arg0
1091                 .getTableId().getValue(), xid);
1092
1093         // Create multipart request header
1094         MultipartRequestInputBuilder mprInput = new MultipartRequestInputBuilder();
1095         mprInput.setType(MultipartType.OFPMPFLOW);
1096         mprInput.setVersion(version);
1097         mprInput.setXid(xid);
1098         mprInput.setFlags(new MultipartRequestFlags(false));
1099
1100         // Create multipart request body for fetch all the group stats
1101         MultipartRequestFlowCaseBuilder multipartRequestFlowCaseBuilder = new MultipartRequestFlowCaseBuilder();
1102         MultipartRequestFlowBuilder mprFlowRequestBuilder = new MultipartRequestFlowBuilder();
1103         mprFlowRequestBuilder.setTableId(arg0.getTableId().getValue());
1104         mprFlowRequestBuilder.setOutPort(OFConstants.OFPP_ANY);
1105         mprFlowRequestBuilder.setOutGroup(OFConstants.OFPG_ANY);
1106         mprFlowRequestBuilder.setCookie(OFConstants.DEFAULT_COOKIE);
1107         mprFlowRequestBuilder.setCookieMask(OFConstants.DEFAULT_COOKIE_MASK);
1108         FlowCreatorUtil.setWildcardedFlowMatch(version, mprFlowRequestBuilder);
1109
1110         // Set request body to main multipart request
1111         multipartRequestFlowCaseBuilder.setMultipartRequestFlow(mprFlowRequestBuilder.build());
1112         mprInput.setMultipartRequestBody(multipartRequestFlowCaseBuilder.build());
1113
1114         // Send the request, no cookies associated, use any connection
1115         LOG.debug("Send flow statistics request to the switch :{}", mprFlowRequestBuilder);
1116         this.messageService.multipartRequest(mprInput.build(), null);
1117
1118         // Prepare rpc return output. Set xid and send it back.
1119         LOG.debug("Return results and transaction id back to caller");
1120         GetAllFlowStatisticsFromFlowTableOutputBuilder output = new GetAllFlowStatisticsFromFlowTableOutputBuilder();
1121         output.setTransactionId(generateTransactionId(xid));
1122         output.setFlowAndStatisticsMapList(null);
1123
1124         Collection<RpcError> errors = Collections.emptyList();
1125         RpcResult<GetAllFlowStatisticsFromFlowTableOutput> rpcResult = Rpcs.getRpcResult(true, output.build(), errors);
1126         return Futures.immediateFuture(rpcResult);
1127     }
1128
1129     @Override
1130     public Future<RpcResult<GetAllFlowsStatisticsFromAllFlowTablesOutput>> getAllFlowsStatisticsFromAllFlowTables(
1131             final GetAllFlowsStatisticsFromAllFlowTablesInput arg0) {
1132
1133         // Generate xid to associate it with the request
1134         Long xid = this.getSessionContext().getNextXid();
1135
1136         LOG.debug("Prepare statistics request to get flow stats of all switch tables - Transaction id - {}", xid);
1137
1138         // Create multipart request header
1139         MultipartRequestInputBuilder mprInput = new MultipartRequestInputBuilder();
1140         mprInput.setType(MultipartType.OFPMPFLOW);
1141         mprInput.setVersion(version);
1142         mprInput.setXid(xid);
1143         mprInput.setFlags(new MultipartRequestFlags(false));
1144
1145         // Create multipart request body for fetch all the group stats
1146         MultipartRequestFlowCaseBuilder multipartRequestFlowCaseBuilder = new MultipartRequestFlowCaseBuilder();
1147         MultipartRequestFlowBuilder mprFlowRequestBuilder = new MultipartRequestFlowBuilder();
1148         mprFlowRequestBuilder.setTableId(OFConstants.OFPTT_ALL);
1149         mprFlowRequestBuilder.setOutPort(OFConstants.OFPP_ANY);
1150         mprFlowRequestBuilder.setOutGroup(OFConstants.OFPG_ANY);
1151         mprFlowRequestBuilder.setCookie(OFConstants.DEFAULT_COOKIE);
1152         mprFlowRequestBuilder.setCookieMask(OFConstants.DEFAULT_COOKIE_MASK);
1153         mprFlowRequestBuilder.setCookieMask(OFConstants.DEFAULT_COOKIE_MASK);
1154
1155         FlowCreatorUtil.setWildcardedFlowMatch(version, mprFlowRequestBuilder);
1156
1157         // Set request body to main multipart request
1158         multipartRequestFlowCaseBuilder.setMultipartRequestFlow(mprFlowRequestBuilder.build());
1159         mprInput.setMultipartRequestBody(multipartRequestFlowCaseBuilder.build());
1160
1161         // Send the request, no cookies associated, use any connection
1162         LOG.debug("Send flow statistics request to the switch :{}", mprFlowRequestBuilder);
1163         this.messageService.multipartRequest(mprInput.build(), null);
1164
1165         // Prepare rpc return output. Set xid and send it back.
1166         GetAllFlowsStatisticsFromAllFlowTablesOutputBuilder output = new GetAllFlowsStatisticsFromAllFlowTablesOutputBuilder();
1167         output.setTransactionId(generateTransactionId(xid));
1168         output.setFlowAndStatisticsMapList(null);
1169
1170         Collection<RpcError> errors = Collections.emptyList();
1171         RpcResult<GetAllFlowsStatisticsFromAllFlowTablesOutput> rpcResult = Rpcs.getRpcResult(true, output.build(),
1172                 errors);
1173         return Futures.immediateFuture(rpcResult);
1174
1175     }
1176
1177     @Override
1178     public Future<RpcResult<GetFlowStatisticsFromFlowTableOutput>> getFlowStatisticsFromFlowTable(
1179             final GetFlowStatisticsFromFlowTableInput arg0) {
1180         // Generate xid to associate it with the request
1181         Long xid = this.getSessionContext().getNextXid();
1182
1183         LOG.debug("Prepare statistics request to get stats for flow {} for switch tables {} - Transaction id - {}",
1184                   arg0.getMatch() == null ? null : arg0.getMatch().toString(), arg0.getTableId(), xid);
1185
1186         // Create multipart request header
1187         MultipartRequestInputBuilder mprInput = new MultipartRequestInputBuilder();
1188         mprInput.setType(MultipartType.OFPMPFLOW);
1189         mprInput.setVersion(version);
1190         mprInput.setXid(xid);
1191         mprInput.setFlags(new MultipartRequestFlags(false));
1192
1193         // Create multipart request body for fetch all the group stats
1194         MultipartRequestFlowCaseBuilder multipartRequestFlowCaseBuilder = new MultipartRequestFlowCaseBuilder();
1195         MultipartRequestFlowBuilder mprFlowRequestBuilder = new MultipartRequestFlowBuilder();
1196         mprFlowRequestBuilder.setTableId(arg0.getTableId());
1197
1198         if (arg0.getOutPort() != null)
1199             mprFlowRequestBuilder.setOutPort(arg0.getOutPort().longValue());
1200         else
1201             mprFlowRequestBuilder.setOutPort(OFConstants.OFPP_ANY);
1202
1203         if (arg0.getOutGroup() != null)
1204             mprFlowRequestBuilder.setOutGroup(arg0.getOutGroup());
1205         else
1206             mprFlowRequestBuilder.setOutGroup(OFConstants.OFPG_ANY);
1207
1208         if (arg0.getCookie() != null)
1209             mprFlowRequestBuilder.setCookie(arg0.getCookie().getValue());
1210         else
1211             mprFlowRequestBuilder.setCookie(OFConstants.DEFAULT_COOKIE);
1212
1213         if (arg0.getCookieMask() != null)
1214             mprFlowRequestBuilder.setCookieMask(arg0.getCookieMask().getValue());
1215         else
1216             mprFlowRequestBuilder.setCookieMask(OFConstants.DEFAULT_COOKIE_MASK);
1217
1218         // convert and inject match
1219         MatchReactor.getInstance().convert(arg0.getMatch(), version, mprFlowRequestBuilder,
1220                 this.getSessionContext().getFeatures().getDatapathId());
1221
1222         // Set request body to main multipart request
1223         multipartRequestFlowCaseBuilder.setMultipartRequestFlow(mprFlowRequestBuilder.build());
1224         mprInput.setMultipartRequestBody(multipartRequestFlowCaseBuilder.build());
1225
1226         // Send the request, no cookies associated, use any connection
1227         LOG.debug("Send flow statistics request to the switch :{}", mprFlowRequestBuilder);
1228         this.messageService.multipartRequest(mprInput.build(), null);
1229
1230         // Prepare rpc return output. Set xid and send it back.
1231         GetFlowStatisticsFromFlowTableOutputBuilder output = new GetFlowStatisticsFromFlowTableOutputBuilder();
1232         output.setTransactionId(generateTransactionId(xid));
1233         output.setFlowAndStatisticsMapList(null);
1234
1235         Collection<RpcError> errors = Collections.emptyList();
1236         RpcResult<GetFlowStatisticsFromFlowTableOutput> rpcResult = Rpcs.getRpcResult(true, output.build(), errors);
1237         return Futures.immediateFuture(rpcResult);
1238     }
1239
1240     @Override
1241     public Future<RpcResult<GetAggregateFlowStatisticsFromFlowTableForAllFlowsOutput>> getAggregateFlowStatisticsFromFlowTableForAllFlows(
1242             final GetAggregateFlowStatisticsFromFlowTableForAllFlowsInput arg0) {
1243         // Generate xid to associate it with the request
1244         Long xid = this.getSessionContext().getNextXid();
1245
1246         LOG.debug(
1247                 "Prepare aggregate flow statistics request to get aggregate flow stats for all the flow installed on switch table {} - Transaction id - {}",
1248                 arg0.getTableId().getValue(), xid);
1249
1250         // Create multipart request header
1251         MultipartRequestInputBuilder mprInput = new MultipartRequestInputBuilder();
1252         mprInput.setType(MultipartType.OFPMPAGGREGATE);
1253         mprInput.setVersion(version);
1254         mprInput.setXid(xid);
1255         mprInput.setFlags(new MultipartRequestFlags(false));
1256
1257         // Create multipart request body for fetch all the group stats
1258         MultipartRequestAggregateCaseBuilder multipartRequestAggregateCaseBuilder = new MultipartRequestAggregateCaseBuilder();
1259         MultipartRequestAggregateBuilder mprAggregateRequestBuilder = new MultipartRequestAggregateBuilder();
1260         mprAggregateRequestBuilder.setTableId(arg0.getTableId().getValue());
1261         mprAggregateRequestBuilder.setOutPort(OFConstants.OFPP_ANY);
1262         mprAggregateRequestBuilder.setOutGroup(OFConstants.OFPG_ANY);
1263         mprAggregateRequestBuilder.setCookie(OFConstants.DEFAULT_COOKIE);
1264         mprAggregateRequestBuilder.setCookieMask(OFConstants.DEFAULT_COOKIE_MASK);
1265
1266         FlowCreatorUtil.setWildcardedFlowMatch(version, mprAggregateRequestBuilder);
1267
1268         // Set request body to main multipart request
1269         multipartRequestAggregateCaseBuilder.setMultipartRequestAggregate(mprAggregateRequestBuilder.build());
1270         mprInput.setMultipartRequestBody(multipartRequestAggregateCaseBuilder.build());
1271
1272         // Send the request, no cookies associated, use any connection
1273         LOG.debug("Send request to the switch :{}", multipartRequestAggregateCaseBuilder.build().toString());
1274         this.messageService.multipartRequest(mprInput.build(), null);
1275
1276         // Prepare rpc return output. Set xid and send it back.
1277         GetAggregateFlowStatisticsFromFlowTableForAllFlowsOutputBuilder output = new GetAggregateFlowStatisticsFromFlowTableForAllFlowsOutputBuilder();
1278         output.setTransactionId(generateTransactionId(xid));
1279
1280         Collection<RpcError> errors = Collections.emptyList();
1281         RpcResult<GetAggregateFlowStatisticsFromFlowTableForAllFlowsOutput> rpcResult = Rpcs.getRpcResult(true,
1282                 output.build(), errors);
1283         return Futures.immediateFuture(rpcResult);
1284     }
1285
1286     @Override
1287     public Future<RpcResult<GetAggregateFlowStatisticsFromFlowTableForGivenMatchOutput>> getAggregateFlowStatisticsFromFlowTableForGivenMatch(
1288             final GetAggregateFlowStatisticsFromFlowTableForGivenMatchInput arg0) {
1289
1290         // Generate xid to associate it with the request
1291         Long xid = this.getSessionContext().getNextXid();
1292
1293         LOG.debug(
1294                 "Prepare aggregate statistics request to get aggregate stats for flows matching {} and installed in flow tables {} - Transaction id - {}",
1295                 arg0.getMatch().toString(), arg0.getTableId(), xid);
1296
1297         // Create multipart request header
1298         MultipartRequestInputBuilder mprInput = new MultipartRequestInputBuilder();
1299         mprInput.setType(MultipartType.OFPMPAGGREGATE);
1300         mprInput.setVersion(version);
1301         mprInput.setXid(xid);
1302         mprInput.setFlags(new MultipartRequestFlags(false));
1303
1304         // Create multipart request body for fetch all the group stats
1305         MultipartRequestAggregateCaseBuilder multipartRequestAggregateCaseBuilder = new MultipartRequestAggregateCaseBuilder();
1306         MultipartRequestAggregateBuilder mprAggregateRequestBuilder = new MultipartRequestAggregateBuilder();
1307         mprAggregateRequestBuilder.setTableId(arg0.getTableId());
1308         mprAggregateRequestBuilder.setOutPort(arg0.getOutPort().longValue());
1309         mprAggregateRequestBuilder.setOutGroup(OFConstants.OFPG_ANY);
1310         mprAggregateRequestBuilder.setCookie(OFConstants.DEFAULT_COOKIE);
1311         mprAggregateRequestBuilder.setCookieMask(OFConstants.DEFAULT_COOKIE_MASK);
1312
1313         MatchReactor.getInstance().convert(arg0.getMatch(), version, mprAggregateRequestBuilder,
1314                 this.getSessionContext().getFeatures().getDatapathId());
1315         // TODO: repeating code
1316         if (version == OFConstants.OFP_VERSION_1_3) {
1317             mprAggregateRequestBuilder.setCookie(arg0.getCookie().getValue());
1318             mprAggregateRequestBuilder.setCookieMask(arg0.getCookieMask().getValue());
1319             mprAggregateRequestBuilder.setOutGroup(arg0.getOutGroup());
1320         }
1321
1322         // Set request body to main multipart request
1323         multipartRequestAggregateCaseBuilder.setMultipartRequestAggregate(mprAggregateRequestBuilder.build());
1324         mprInput.setMultipartRequestBody(multipartRequestAggregateCaseBuilder.build());
1325
1326         // Send the request, no cookies associated, use any connection
1327         LOG.debug("Send request to the switch :{}", multipartRequestAggregateCaseBuilder.build().toString());
1328         this.messageService.multipartRequest(mprInput.build(), null);
1329
1330         // Prepare rpc return output. Set xid and send it back.
1331         GetAggregateFlowStatisticsFromFlowTableForGivenMatchOutputBuilder output = new GetAggregateFlowStatisticsFromFlowTableForGivenMatchOutputBuilder();
1332         output.setTransactionId(generateTransactionId(xid));
1333
1334         Collection<RpcError> errors = Collections.emptyList();
1335         RpcResult<GetAggregateFlowStatisticsFromFlowTableForGivenMatchOutput> rpcResult = Rpcs.getRpcResult(true,
1336                 output.build(), errors);
1337         return Futures.immediateFuture(rpcResult);
1338     }
1339
1340     @Override
1341     public Future<RpcResult<GetFlowTablesStatisticsOutput>> getFlowTablesStatistics(final GetFlowTablesStatisticsInput arg0) {
1342         // Generate xid to associate it with the request
1343         Long xid = this.getSessionContext().getNextXid();
1344
1345         LOG.debug("Prepare flow table statistics request to get flow table stats for all tables "
1346                 + "from node {}- Transaction id - {}", arg0.getNode(), xid);
1347
1348         // Create multipart request header
1349         MultipartRequestInputBuilder mprInput = new MultipartRequestInputBuilder();
1350         mprInput.setType(MultipartType.OFPMPTABLE);
1351         mprInput.setVersion(version);
1352         mprInput.setXid(xid);
1353         mprInput.setFlags(new MultipartRequestFlags(false));
1354
1355         // Create multipart request body for fetch all the group stats
1356         MultipartRequestTableCaseBuilder multipartRequestTableCaseBuilder = new MultipartRequestTableCaseBuilder();
1357         MultipartRequestTableBuilder multipartRequestTableBuilder = new MultipartRequestTableBuilder();
1358         multipartRequestTableBuilder.setEmpty(true);
1359         multipartRequestTableCaseBuilder.setMultipartRequestTable(multipartRequestTableBuilder.build());
1360
1361         // Set request body to main multipart request
1362         mprInput.setMultipartRequestBody(multipartRequestTableCaseBuilder.build());
1363
1364         // Send the request, no cookies associated, use any connection
1365         LOG.debug("Send request to the switch :{}", multipartRequestTableCaseBuilder.build().toString());
1366         this.messageService.multipartRequest(mprInput.build(), null);
1367
1368         // Prepare rpc return output. Set xid and send it back.
1369         GetFlowTablesStatisticsOutputBuilder output = new GetFlowTablesStatisticsOutputBuilder();
1370         output.setTransactionId(generateTransactionId(xid));
1371
1372         Collection<RpcError> errors = Collections.emptyList();
1373         RpcResult<GetFlowTablesStatisticsOutput> rpcResult = Rpcs.getRpcResult(true, output.build(), errors);
1374         return Futures.immediateFuture(rpcResult);
1375     }
1376
1377     @Override
1378     public Future<RpcResult<GetAllQueuesStatisticsFromAllPortsOutput>> getAllQueuesStatisticsFromAllPorts(
1379             final GetAllQueuesStatisticsFromAllPortsInput arg0) {
1380         // Generate xid to associate it with the request
1381         Long xid = this.getSessionContext().getNextXid();
1382
1383         LOG.debug(
1384                 "Prepare queue statistics request to collect stats for all queues attached to all the ports of node {} - TrasactionId - {}",
1385                 arg0.getNode().getValue(), xid);
1386
1387         // Create multipart request header
1388         MultipartRequestInputBuilder mprInput = new MultipartRequestInputBuilder();
1389         mprInput.setType(MultipartType.OFPMPQUEUE);
1390         mprInput.setVersion(version);
1391         mprInput.setXid(xid);
1392         mprInput.setFlags(new MultipartRequestFlags(false));
1393
1394         // Create multipart request body to fetch stats for all the port of the
1395         // node
1396         MultipartRequestQueueCaseBuilder caseBuilder = new MultipartRequestQueueCaseBuilder();
1397         MultipartRequestQueueBuilder mprQueueBuilder = new MultipartRequestQueueBuilder();
1398         // Select all ports
1399         mprQueueBuilder.setPortNo(OFConstants.OFPP_ANY);
1400         // Select all the ports
1401         mprQueueBuilder.setQueueId(OFConstants.OFPQ_ANY);
1402
1403         caseBuilder.setMultipartRequestQueue(mprQueueBuilder.build());
1404
1405         // Set request body to main multipart request
1406         mprInput.setMultipartRequestBody(caseBuilder.build());
1407
1408         // Send the request, no cookies associated, use any connection
1409         LOG.debug("Send queue statistics request :{}", mprQueueBuilder.build().toString());
1410         this.messageService.multipartRequest(mprInput.build(), null);
1411
1412         // Prepare rpc return output. Set xid and send it back.
1413         GetAllQueuesStatisticsFromAllPortsOutputBuilder output = new GetAllQueuesStatisticsFromAllPortsOutputBuilder();
1414         output.setTransactionId(generateTransactionId(xid));
1415         output.setQueueIdAndStatisticsMap(null);
1416
1417         Collection<RpcError> errors = Collections.emptyList();
1418         RpcResult<GetAllQueuesStatisticsFromAllPortsOutput> rpcResult = Rpcs.getRpcResult(true, output.build(), errors);
1419         return Futures.immediateFuture(rpcResult);
1420     }
1421
1422     @Override
1423     public Future<RpcResult<GetAllQueuesStatisticsFromGivenPortOutput>> getAllQueuesStatisticsFromGivenPort(
1424             final GetAllQueuesStatisticsFromGivenPortInput arg0) {
1425         // Generate xid to associate it with the request
1426         Long xid = this.getSessionContext().getNextXid();
1427
1428         LOG.debug("Prepare queue statistics request to collect stats for "
1429                 + "all queues attached to given port {} of node {} - TrasactionId - {}", arg0.getNodeConnectorId()
1430                 .toString(), arg0.getNode().getValue(), xid);
1431
1432         // Create multipart request header
1433         MultipartRequestInputBuilder mprInput = new MultipartRequestInputBuilder();
1434         mprInput.setType(MultipartType.OFPMPQUEUE);
1435         mprInput.setVersion(version);
1436         mprInput.setXid(xid);
1437         mprInput.setFlags(new MultipartRequestFlags(false));
1438
1439         // Create multipart request body to fetch stats for all the port of the
1440         // node
1441         MultipartRequestQueueCaseBuilder caseBuilder = new MultipartRequestQueueCaseBuilder();
1442         MultipartRequestQueueBuilder mprQueueBuilder = new MultipartRequestQueueBuilder();
1443         // Select all queues
1444         mprQueueBuilder.setQueueId(OFConstants.OFPQ_ANY);
1445         // Select specific port
1446         mprQueueBuilder.setPortNo(InventoryDataServiceUtil.portNumberfromNodeConnectorId(
1447                 OpenflowVersion.get(version),
1448                 arg0.getNodeConnectorId()));
1449
1450         caseBuilder.setMultipartRequestQueue(mprQueueBuilder.build());
1451
1452         // Set request body to main multipart request
1453         mprInput.setMultipartRequestBody(caseBuilder.build());
1454
1455         // Send the request, no cookies associated, use any connection
1456         LOG.debug("Send queue statistics request :{}", mprQueueBuilder.build().toString());
1457         this.messageService.multipartRequest(mprInput.build(), null);
1458
1459         // Prepare rpc return output. Set xid and send it back.
1460         GetAllQueuesStatisticsFromGivenPortOutputBuilder output = new GetAllQueuesStatisticsFromGivenPortOutputBuilder();
1461         output.setTransactionId(generateTransactionId(xid));
1462         output.setQueueIdAndStatisticsMap(null);
1463
1464         Collection<RpcError> errors = Collections.emptyList();
1465         RpcResult<GetAllQueuesStatisticsFromGivenPortOutput> rpcResult = Rpcs
1466                 .getRpcResult(true, output.build(), errors);
1467         return Futures.immediateFuture(rpcResult);
1468     }
1469
1470     @Override
1471     public Future<RpcResult<GetQueueStatisticsFromGivenPortOutput>> getQueueStatisticsFromGivenPort(
1472             final GetQueueStatisticsFromGivenPortInput arg0) {
1473         // Generate xid to associate it with the request
1474         Long xid = this.getSessionContext().getNextXid();
1475
1476         LOG.debug("Prepare queue statistics request to collect stats for "
1477                 + "given queue attached to given port {} of node {} - TrasactionId - {}", arg0.getQueueId().toString(),
1478                 arg0.getNodeConnectorId().toString(), arg0.getNode().getValue(), xid);
1479
1480         // Create multipart request header
1481         MultipartRequestInputBuilder mprInput = new MultipartRequestInputBuilder();
1482         mprInput.setType(MultipartType.OFPMPQUEUE);
1483         mprInput.setVersion(version);
1484         mprInput.setXid(xid);
1485         mprInput.setFlags(new MultipartRequestFlags(false));
1486
1487         // Create multipart request body to fetch stats for all the port of the
1488         // node
1489         MultipartRequestQueueCaseBuilder caseBuilder = new MultipartRequestQueueCaseBuilder();
1490         MultipartRequestQueueBuilder mprQueueBuilder = new MultipartRequestQueueBuilder();
1491         // Select specific queue
1492         mprQueueBuilder.setQueueId(arg0.getQueueId().getValue());
1493         // Select specific port
1494         mprQueueBuilder.setPortNo(InventoryDataServiceUtil.portNumberfromNodeConnectorId(OpenflowVersion.get(version),
1495                 arg0.getNodeConnectorId()));
1496
1497         caseBuilder.setMultipartRequestQueue(mprQueueBuilder.build());
1498
1499         // Set request body to main multipart request
1500         mprInput.setMultipartRequestBody(caseBuilder.build());
1501
1502         // Send the request, no cookies associated, use any connection
1503         LOG.debug("Send queue statistics request :{}", mprQueueBuilder.build().toString());
1504         this.messageService.multipartRequest(mprInput.build(), null);
1505
1506         // Prepare rpc return output. Set xid and send it back.
1507         GetQueueStatisticsFromGivenPortOutputBuilder output = new GetQueueStatisticsFromGivenPortOutputBuilder();
1508         output.setTransactionId(generateTransactionId(xid));
1509         output.setQueueIdAndStatisticsMap(null);
1510
1511         Collection<RpcError> errors = Collections.emptyList();
1512         RpcResult<GetQueueStatisticsFromGivenPortOutput> rpcResult = Rpcs.getRpcResult(true, output.build(), errors);
1513         return Futures.immediateFuture(rpcResult);
1514     }
1515 }