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