5cbb4f9ea28e5bbe0b1b270e8d48563ed0e07a98
[openflowplugin.git] / openflowplugin / src / main / java / org / opendaylight / openflowplugin / openflow / md / core / sal / OFRpcTaskFactory.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.util.concurrent.AsyncFunction;
11 import com.google.common.util.concurrent.FutureCallback;
12 import com.google.common.util.concurrent.Futures;
13 import com.google.common.util.concurrent.JdkFutureAdapters;
14 import com.google.common.util.concurrent.ListenableFuture;
15 import com.google.common.util.concurrent.SettableFuture;
16 import org.opendaylight.controller.sal.common.util.RpcErrors;
17 import org.opendaylight.controller.sal.common.util.Rpcs;
18 import org.opendaylight.openflowjava.protocol.api.util.BinContent;
19 import org.opendaylight.openflowplugin.openflow.md.OFConstants;
20 import org.opendaylight.openflowplugin.openflow.md.core.SwitchConnectionDistinguisher;
21 import org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.FlowConvertor;
22 import org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.GroupConvertor;
23 import org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.MeterConvertor;
24 import org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.PortConvertor;
25 import org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.TableFeaturesConvertor;
26 import org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.match.MatchReactor;
27 import org.opendaylight.openflowplugin.openflow.md.util.FlowCreatorUtil;
28 import org.opendaylight.openflowplugin.openflow.md.util.InventoryDataServiceUtil;
29 import org.opendaylight.openflowplugin.openflow.md.util.OpenflowVersion;
30 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.AddFlowInput;
31 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.FlowAdded;
32 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.FlowAddedBuilder;
33 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.FlowRemoved;
34 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.FlowRemovedBuilder;
35 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.FlowUpdated;
36 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.FlowUpdatedBuilder;
37 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.RemoveFlowInput;
38 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.RemoveFlowInputBuilder;
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.GroupAdded;
64 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.service.rev130918.GroupAddedBuilder;
65 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.service.rev130918.GroupRemoved;
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.GroupUpdated;
68 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.service.rev130918.GroupUpdatedBuilder;
69 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.service.rev130918.RemoveGroupInput;
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.group.types.rev131018.Group;
85 import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.service.rev130918.AddMeterInput;
86 import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.service.rev130918.MeterAdded;
87 import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.service.rev130918.MeterAddedBuilder;
88 import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.service.rev130918.MeterRemoved;
89 import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.service.rev130918.MeterRemovedBuilder;
90 import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.service.rev130918.MeterUpdated;
91 import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.service.rev130918.MeterUpdatedBuilder;
92 import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.service.rev130918.RemoveMeterInput;
93 import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.service.rev130918.UpdateMeterInput;
94 import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.service.rev130918.UpdateMeterOutput;
95 import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.statistics.rev131111.GetAllMeterConfigStatisticsInput;
96 import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.statistics.rev131111.GetAllMeterConfigStatisticsOutput;
97 import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.statistics.rev131111.GetAllMeterConfigStatisticsOutputBuilder;
98 import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.statistics.rev131111.GetAllMeterStatisticsInput;
99 import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.statistics.rev131111.GetAllMeterStatisticsOutput;
100 import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.statistics.rev131111.GetAllMeterStatisticsOutputBuilder;
101 import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.statistics.rev131111.GetMeterFeaturesInput;
102 import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.statistics.rev131111.GetMeterFeaturesOutput;
103 import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.statistics.rev131111.GetMeterFeaturesOutputBuilder;
104 import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.statistics.rev131111.GetMeterStatisticsInput;
105 import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.statistics.rev131111.GetMeterStatisticsOutput;
106 import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.statistics.rev131111.GetMeterStatisticsOutputBuilder;
107 import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.types.rev130918.Meter;
108 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.GroupId;
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.protocol.rev130731.FlowModInputBuilder;
113 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.GroupModInputBuilder;
114 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.MeterModInputBuilder;
115 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.MultipartRequestInputBuilder;
116 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.PortModInput;
117 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.PortModInputBuilder;
118 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.MultipartRequestAggregateCaseBuilder;
119 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.MultipartRequestFlowCaseBuilder;
120 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.MultipartRequestGroupCaseBuilder;
121 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.MultipartRequestGroupDescCaseBuilder;
122 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.MultipartRequestGroupFeaturesCaseBuilder;
123 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.MultipartRequestMeterCaseBuilder;
124 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.MultipartRequestMeterConfigCaseBuilder;
125 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.MultipartRequestMeterFeaturesCaseBuilder;
126 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.MultipartRequestPortStatsCaseBuilder;
127 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.MultipartRequestQueueCaseBuilder;
128 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.MultipartRequestTableCaseBuilder;
129 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.MultipartRequestTableFeaturesCaseBuilder;
130 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.multipart.request.aggregate._case.MultipartRequestAggregateBuilder;
131 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.multipart.request.flow._case.MultipartRequestFlowBuilder;
132 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.multipart.request.group._case.MultipartRequestGroupBuilder;
133 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.multipart.request.meter._case.MultipartRequestMeterBuilder;
134 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.multipart.request.meter.config._case.MultipartRequestMeterConfigBuilder;
135 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.multipart.request.port.stats._case.MultipartRequestPortStatsBuilder;
136 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.multipart.request.queue._case.MultipartRequestQueueBuilder;
137 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.multipart.request.table._case.MultipartRequestTableBuilder;
138 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.multipart.request.table.features._case.MultipartRequestTableFeaturesBuilder;
139 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;
140 import org.opendaylight.yang.gen.v1.urn.opendaylight.port.service.rev131107.UpdatePortInput;
141 import org.opendaylight.yang.gen.v1.urn.opendaylight.port.service.rev131107.UpdatePortOutput;
142 import org.opendaylight.yang.gen.v1.urn.opendaylight.port.statistics.rev131214.GetAllNodeConnectorsStatisticsInput;
143 import org.opendaylight.yang.gen.v1.urn.opendaylight.port.statistics.rev131214.GetAllNodeConnectorsStatisticsOutput;
144 import org.opendaylight.yang.gen.v1.urn.opendaylight.port.statistics.rev131214.GetAllNodeConnectorsStatisticsOutputBuilder;
145 import org.opendaylight.yang.gen.v1.urn.opendaylight.port.statistics.rev131214.GetNodeConnectorStatisticsInput;
146 import org.opendaylight.yang.gen.v1.urn.opendaylight.port.statistics.rev131214.GetNodeConnectorStatisticsOutput;
147 import org.opendaylight.yang.gen.v1.urn.opendaylight.port.statistics.rev131214.GetNodeConnectorStatisticsOutputBuilder;
148 import org.opendaylight.yang.gen.v1.urn.opendaylight.queue.statistics.rev131216.GetAllQueuesStatisticsFromAllPortsInput;
149 import org.opendaylight.yang.gen.v1.urn.opendaylight.queue.statistics.rev131216.GetAllQueuesStatisticsFromAllPortsOutput;
150 import org.opendaylight.yang.gen.v1.urn.opendaylight.queue.statistics.rev131216.GetAllQueuesStatisticsFromAllPortsOutputBuilder;
151 import org.opendaylight.yang.gen.v1.urn.opendaylight.queue.statistics.rev131216.GetAllQueuesStatisticsFromGivenPortInput;
152 import org.opendaylight.yang.gen.v1.urn.opendaylight.queue.statistics.rev131216.GetAllQueuesStatisticsFromGivenPortOutput;
153 import org.opendaylight.yang.gen.v1.urn.opendaylight.queue.statistics.rev131216.GetAllQueuesStatisticsFromGivenPortOutputBuilder;
154 import org.opendaylight.yang.gen.v1.urn.opendaylight.queue.statistics.rev131216.GetQueueStatisticsFromGivenPortInput;
155 import org.opendaylight.yang.gen.v1.urn.opendaylight.queue.statistics.rev131216.GetQueueStatisticsFromGivenPortOutput;
156 import org.opendaylight.yang.gen.v1.urn.opendaylight.queue.statistics.rev131216.GetQueueStatisticsFromGivenPortOutputBuilder;
157 import org.opendaylight.yang.gen.v1.urn.opendaylight.table.service.rev131026.UpdateTableInput;
158 import org.opendaylight.yang.gen.v1.urn.opendaylight.table.service.rev131026.UpdateTableOutput;
159 import org.opendaylight.yang.gen.v1.urn.opendaylight.table.service.rev131026.UpdateTableOutputBuilder;
160 import org.opendaylight.yangtools.yang.common.RpcError;
161 import org.opendaylight.yangtools.yang.common.RpcError.ErrorSeverity;
162 import org.opendaylight.yangtools.yang.common.RpcError.ErrorType;
163 import org.opendaylight.yangtools.yang.common.RpcResult;
164 import org.slf4j.Logger;
165 import org.slf4j.LoggerFactory;
166
167 import java.math.BigInteger;
168 import java.util.ArrayList;
169 import java.util.Collection;
170 import java.util.Collections;
171 import java.util.List;
172 import java.util.concurrent.Future;
173
174 /**
175  *
176  */
177 public abstract class OFRpcTaskFactory {
178     private static final Logger logger = LoggerFactory.getLogger(OFRpcTaskFactory.class);
179
180     /**
181      * @param taskContext 
182      * @param input 
183      * @param cookie 
184      * @return UpdateFlow task
185      */
186     public static OFRpcTask<AddFlowInput, RpcResult<UpdateFlowOutput>> createAddFlowTask(
187             OFRpcTaskContext taskContext, AddFlowInput input, 
188             SwitchConnectionDistinguisher cookie) {
189         OFRpcTask<AddFlowInput, RpcResult<UpdateFlowOutput>> task = 
190                 new OFRpcTask<AddFlowInput, RpcResult<UpdateFlowOutput>>(taskContext, cookie, input) {
191             
192             @Override
193             public ListenableFuture<RpcResult<UpdateFlowOutput>> call() {
194                 ListenableFuture<RpcResult<UpdateFlowOutput>> result = SettableFuture.create();
195                 
196                 Collection<RpcError> barrierErrors = OFRpcTaskUtil.manageBarrier(getTaskContext(), getInput().isBarrier(), getCookie());
197                 if (!barrierErrors.isEmpty()) {
198                     OFRpcTaskUtil.wrapBarrierErrors(((SettableFuture<RpcResult<UpdateFlowOutput>>) result), barrierErrors);
199                 } else {
200                     // Convert the AddFlowInput to FlowModInput
201                     List<FlowModInputBuilder> ofFlowModInputs = FlowConvertor.toFlowModInputs(getInput(),
202                             getVersion(), getSession().getFeatures().getDatapathId());
203
204                     logger.debug("Number of flows to push to switch: {}", ofFlowModInputs.size());
205
206                     Long xId = getSession().getNextXid();
207
208                     result = chainFlowMods(ofFlowModInputs, 0, getTaskContext(), getCookie());
209
210                     OFRpcTaskUtil.hookFutureNotification(this, result,
211                         getRpcNotificationProviderService(),
212                         createFlowAddedNotification(xId, getInput()));
213                 }
214                 return result;
215             }
216         };
217         return task;
218     }
219
220     /**
221      * Recursive helper method for {@link OFRpcTaskFactory#createAddFlowTask()}
222      * and {@link OFRpcTaskFactory#createUpdateFlowTask()} to chain results
223      * of multiple flowmods.
224      * The next flowmod gets executed if the earlier one is successful.
225      * All the flowmods should have the same xid, in-order to cross-reference
226      * the notification
227      */
228     private static ListenableFuture<RpcResult<UpdateFlowOutput>> chainFlowMods(
229         final List<FlowModInputBuilder> ofFlowModInputs, final int index,
230         final OFRpcTaskContext taskContext, final SwitchConnectionDistinguisher cookie) {
231
232         Future<RpcResult<UpdateFlowOutput>> resultFromOFLib =
233             createResultForFlowMod(taskContext, ofFlowModInputs.get(index), cookie);
234
235         ListenableFuture<RpcResult<UpdateFlowOutput>> result  = JdkFutureAdapters.listenInPoolThread(resultFromOFLib);
236
237         if(ofFlowModInputs.size() > index + 1) {
238             // there are more flowmods to chain
239             return Futures.transform(result,
240                 new AsyncFunction<RpcResult<UpdateFlowOutput>, RpcResult<UpdateFlowOutput>>() {
241                     @Override
242                     public ListenableFuture<RpcResult<UpdateFlowOutput>> apply(RpcResult<UpdateFlowOutput> input) throws Exception {
243                         if (input.isSuccessful()) {
244                             return chainFlowMods(ofFlowModInputs, index + 1, taskContext, cookie);
245                         } else {
246                             logger.warn("Flowmod failed. Any chained flowmods are ignored. xid:{}",
247                                 taskContext.getSession().getFeatures().getXid());
248                             return Futures.immediateFuture(input);
249                         }
250                     }
251                 }
252             );
253         } else {
254             return result;
255         }
256     }
257
258     private static Future<RpcResult<UpdateFlowOutput>> createResultForFlowMod(
259         OFRpcTaskContext taskContext, FlowModInputBuilder flowModInput,
260         SwitchConnectionDistinguisher cookie) {
261         flowModInput.setXid(taskContext.getSession().getFeatures().getXid());
262         return taskContext.getMessageService().flowMod(flowModInput.build(), cookie);
263     }
264
265
266     /**
267      * @param xId
268      * @return
269      */
270     protected static NotificationComposer<FlowAdded> createFlowAddedNotification(
271             final Long xId, final AddFlowInput input) {
272         return new NotificationComposer<FlowAdded>() {
273             @Override
274             public FlowAdded compose() {
275                 FlowAddedBuilder newFlow = new FlowAddedBuilder((Flow) input);
276                 newFlow.setTransactionId(new TransactionId(BigInteger.valueOf(xId.intValue())));
277                 newFlow.setFlowRef(input.getFlowRef());
278                 return newFlow.build();
279             }
280         };
281     }
282
283     /**
284      * @param taskContext 
285      * @param input 
286      * @param cookie 
287      * @return UpdateFlow task
288      */
289     public static OFRpcTask<UpdateFlowInput, RpcResult<UpdateFlowOutput>> createUpdateFlowTask(
290             final OFRpcTaskContext taskContext, UpdateFlowInput input, 
291             SwitchConnectionDistinguisher cookie) {
292         
293         OFRpcTask<UpdateFlowInput, RpcResult<UpdateFlowOutput>> task = 
294                 new OFRpcTask<UpdateFlowInput, RpcResult<UpdateFlowOutput>>(taskContext, cookie, input) {
295             
296             @Override
297             public ListenableFuture<RpcResult<UpdateFlowOutput>> call() {
298                 ListenableFuture<RpcResult<UpdateFlowOutput>> result = null;
299                 Collection<RpcError> barrierErrors = OFRpcTaskUtil.manageBarrier(getTaskContext(), 
300                         getInput().getUpdatedFlow().isBarrier(), getCookie());
301                 if (!barrierErrors.isEmpty()) {
302                     OFRpcTaskUtil.wrapBarrierErrors(((SettableFuture<RpcResult<UpdateFlowOutput>>) result), barrierErrors);
303
304                 } else {
305                     Long xId = getSession().getNextXid();
306                     boolean updatedFlow = (getInput().getUpdatedFlow().getMatch().equals(getInput().getOriginalFlow().getMatch())) &&
307                             (getInput().getUpdatedFlow().getPriority().equals(getInput().getOriginalFlow().getPriority()));
308
309                     List<FlowModInputBuilder> allFlowMods = new ArrayList<>();
310                     List<FlowModInputBuilder> ofFlowModInputs =
311                         FlowConvertor.toFlowModInputs(getInput().getUpdatedFlow(),
312                             getVersion(), getSession().getFeatures().getDatapathId());
313
314                     if (updatedFlow == false) {
315                         // if neither match nor priority matches, then we would need to remove the flow and add it
316                         //remove flow
317                         RemoveFlowInputBuilder removeflow = new RemoveFlowInputBuilder(getInput().getOriginalFlow());
318                         FlowModInputBuilder ofFlowRemoveInput = FlowConvertor.toFlowModInput(removeflow.build(),
319                             getVersion(),getSession().getFeatures().getDatapathId());
320                         ofFlowRemoveInput.setXid(xId);
321                         // remove flow should be the first
322                         allFlowMods.add(ofFlowRemoveInput);
323                     }
324
325                     allFlowMods.addAll(ofFlowModInputs);
326                     logger.debug("Number of flows to push to switch: {}", allFlowMods.size());
327                     result = chainFlowMods(allFlowMods, 0, getTaskContext(), getCookie());
328
329                     OFRpcTaskUtil.hookFutureNotification(this, result,
330                         getRpcNotificationProviderService(),
331                         createFlowUpdatedNotification(xId, getInput()));
332                 }
333                 return result;
334             }
335         };
336         return task;
337     }
338     
339
340     /**
341      * @param xId
342      * @param input
343      * @return
344      */
345     protected static NotificationComposer<FlowUpdated> createFlowUpdatedNotification(
346             final Long xId, final UpdateFlowInput input) {
347         return new NotificationComposer<FlowUpdated>() {
348             @Override
349             public FlowUpdated compose() {
350                 FlowUpdatedBuilder updFlow = new FlowUpdatedBuilder(input.getUpdatedFlow());
351                 updFlow.setTransactionId(new TransactionId(BigInteger.valueOf(xId.intValue())));
352                 updFlow.setFlowRef(input.getFlowRef());
353                 return updFlow.build();
354             }
355         };
356     }
357     
358     /**
359      * @param taskContext
360      * @param input
361      * @param cookie
362      * @return update group task
363      */
364     public static OFRpcTask<AddGroupInput, RpcResult<UpdateGroupOutput>> createAddGroupTask(
365             final OFRpcTaskContext taskContext, AddGroupInput input, 
366             final SwitchConnectionDistinguisher cookie) {
367         OFRpcTask<AddGroupInput, RpcResult<UpdateGroupOutput>> task = 
368                 new OFRpcTask<AddGroupInput, RpcResult<UpdateGroupOutput>>(taskContext, cookie, input) {
369             
370             @Override
371             public ListenableFuture<RpcResult<UpdateGroupOutput>> call() {
372                 ListenableFuture<RpcResult<UpdateGroupOutput>> result = SettableFuture.create();
373                 
374                 Collection<RpcError> barrierErrors = OFRpcTaskUtil.manageBarrier(getTaskContext(), getInput().isBarrier(), getCookie());
375                 if (!barrierErrors.isEmpty()) {
376                     OFRpcTaskUtil.wrapBarrierErrors(((SettableFuture<RpcResult<UpdateGroupOutput>>) result), barrierErrors);
377                 } else {
378                     // Convert the AddGroupInput to GroupModInput
379                     GroupModInputBuilder ofGroupModInput = GroupConvertor.toGroupModInput(getInput(), 
380                             getVersion(), getSession().getFeatures().getDatapathId());
381                     final Long xId = getSession().getNextXid();
382                     ofGroupModInput.setXid(xId);
383                     
384                     Future<RpcResult<UpdateGroupOutput>> resultFromOFLib = getMessageService()
385                             .groupMod(ofGroupModInput.build(), getCookie());
386                     result = JdkFutureAdapters.listenInPoolThread(resultFromOFLib);
387                     
388                     OFRpcTaskUtil.hookFutureNotification(this, result, 
389                             getRpcNotificationProviderService(), createGroupAddedNotification(xId, getInput()));
390                 }
391
392                 return result;
393             }
394         };
395         
396         return task;
397     }
398     
399
400     /**
401      * @param xId
402      * @param input
403      * @return
404      */
405     protected static NotificationComposer<GroupAdded> createGroupAddedNotification(
406             final Long xId, final AddGroupInput input) {
407         return new NotificationComposer<GroupAdded>() {
408             @Override
409             public GroupAdded compose() {
410                 GroupAddedBuilder groupMod = new GroupAddedBuilder((Group) input);
411                 groupMod.setTransactionId(new TransactionId(BigInteger.valueOf(xId.intValue())));
412                 groupMod.setGroupRef(input.getGroupRef());
413                 return groupMod.build();
414             }
415         };
416     }
417
418     /**
419      * @param taskContext
420      * @param input
421      * @param cookie
422      * @return update meter task
423      */
424     public static OFRpcTask<AddMeterInput, RpcResult<UpdateMeterOutput>> createAddMeterTask(
425             OFRpcTaskContext taskContext, AddMeterInput input,
426             SwitchConnectionDistinguisher cookie) {
427         OFRpcTask<AddMeterInput, RpcResult<UpdateMeterOutput>> task = 
428                 new OFRpcTask<AddMeterInput, RpcResult<UpdateMeterOutput>>(taskContext, cookie, input) {
429             
430             @Override
431             public ListenableFuture<RpcResult<UpdateMeterOutput>> call() {
432                 ListenableFuture<RpcResult<UpdateMeterOutput>> result = SettableFuture.create();
433                 
434                 Collection<RpcError> barrierErrors = OFRpcTaskUtil.manageBarrier(getTaskContext(), getInput().isBarrier(), getCookie());
435                 if (!barrierErrors.isEmpty()) {
436                     OFRpcTaskUtil.wrapBarrierErrors(((SettableFuture<RpcResult<UpdateMeterOutput>>) result), barrierErrors);
437                 } else {
438                     // Convert the AddGroupInput to GroupModInput
439                     MeterModInputBuilder ofMeterModInput = MeterConvertor.toMeterModInput(getInput(), getVersion());
440                     final Long xId = getSession().getNextXid();
441                     ofMeterModInput.setXid(xId);
442                     
443                     Future<RpcResult<UpdateMeterOutput>> resultFromOFLib = getMessageService()
444                             .meterMod(ofMeterModInput.build(), getCookie());
445                     result = JdkFutureAdapters.listenInPoolThread(resultFromOFLib);
446                     
447                     OFRpcTaskUtil.hookFutureNotification(this, result, 
448                             getRpcNotificationProviderService(), createMeterAddedNotification(xId, getInput()));
449                 }
450
451                 return result;
452             }
453         };
454         
455         return task;
456         
457     }
458
459     /**
460      * @param xId
461      * @param input
462      * @return
463      */
464     protected static NotificationComposer<MeterAdded> createMeterAddedNotification(
465             final Long xId, final AddMeterInput input) {
466         return new NotificationComposer<MeterAdded>() {
467             @Override
468             public MeterAdded compose() {
469                 MeterAddedBuilder meterMod = new MeterAddedBuilder((Meter) input);
470                 meterMod.setTransactionId(new TransactionId(BigInteger.valueOf(xId.intValue())));
471                 meterMod.setMeterRef(input.getMeterRef());
472                 return meterMod.build();
473             }
474         };
475     }
476     
477     /**
478      * @param taskContext 
479      * @param input 
480      * @param cookie 
481      * @return UpdateFlow task
482      */
483     public static OFRpcTask<UpdateGroupInput, RpcResult<UpdateGroupOutput>> createUpdateGroupTask(
484             OFRpcTaskContext taskContext, UpdateGroupInput input, 
485             SwitchConnectionDistinguisher cookie) {
486         OFRpcTask<UpdateGroupInput, RpcResult<UpdateGroupOutput>> task = 
487                 new OFRpcTask<UpdateGroupInput, RpcResult<UpdateGroupOutput>>(taskContext, cookie, input) {
488             
489             @Override
490             public ListenableFuture<RpcResult<UpdateGroupOutput>> call() {
491                 ListenableFuture<RpcResult<UpdateGroupOutput>> result = null;
492                 Collection<RpcError> barrierErrors = OFRpcTaskUtil.manageBarrier(getTaskContext(), 
493                         getInput().getUpdatedGroup().isBarrier(), getCookie());
494                 if (!barrierErrors.isEmpty()) {
495                     OFRpcTaskUtil.wrapBarrierErrors(((SettableFuture<RpcResult<UpdateGroupOutput>>) result), barrierErrors);
496                 } else {
497                     // Convert the UpdateGroupInput to GroupModInput
498                     GroupModInputBuilder ofGroupModInput = GroupConvertor.toGroupModInput(
499                             getInput().getUpdatedGroup(), getVersion(),
500                             getSession().getFeatures().getDatapathId());
501                     final Long xId = getSession().getNextXid();
502                     ofGroupModInput.setXid(xId);
503     
504                     Future<RpcResult<UpdateGroupOutput>> resultFromOFLib = 
505                             getMessageService().groupMod(ofGroupModInput.build(), getCookie());
506                     result = JdkFutureAdapters.listenInPoolThread(resultFromOFLib);
507                     
508                     OFRpcTaskUtil.hookFutureNotification(this, result, 
509                             getRpcNotificationProviderService(), createGroupUpdatedNotification(xId, getInput()));
510                 }
511                 return result;
512             }
513         };
514         return task;
515     }
516     
517     /**
518      * @param xId
519      * @param input
520      * @return
521      */
522     protected static NotificationComposer<GroupUpdated> createGroupUpdatedNotification(
523             final Long xId, final UpdateGroupInput input) {
524         return new NotificationComposer<GroupUpdated>() {
525             @Override
526             public GroupUpdated compose() {
527                 GroupUpdatedBuilder groupMod = new GroupUpdatedBuilder(input.getUpdatedGroup());
528                 groupMod.setTransactionId(new TransactionId(BigInteger.valueOf(xId.intValue())));
529                 groupMod.setGroupRef(input.getGroupRef());
530                 return groupMod.build();
531             }
532         };
533     }
534
535     /**
536      * @param taskContext 
537      * @param input
538      * @param cookie
539      * @return update meter task 
540      */
541     public static OFRpcTask<UpdateMeterInput, RpcResult<UpdateMeterOutput>> createUpdateMeterTask(
542             OFRpcTaskContext taskContext, UpdateMeterInput input,
543             SwitchConnectionDistinguisher cookie) {
544         OFRpcTask<UpdateMeterInput, RpcResult<UpdateMeterOutput>> task = 
545                 new OFRpcTask<UpdateMeterInput, RpcResult<UpdateMeterOutput>>(taskContext, cookie, input) {
546             
547             @Override
548             public ListenableFuture<RpcResult<UpdateMeterOutput>> call() {
549                 ListenableFuture<RpcResult<UpdateMeterOutput>> result = null;
550                 Collection<RpcError> barrierErrors = OFRpcTaskUtil.manageBarrier(getTaskContext(), 
551                         getInput().getUpdatedMeter().isBarrier(), getCookie());
552                 if (!barrierErrors.isEmpty()) {
553                     OFRpcTaskUtil.wrapBarrierErrors(((SettableFuture<RpcResult<UpdateMeterOutput>>) result), barrierErrors);
554                 } else {
555                     // Convert the UpdateMeterInput to MeterModInput
556                     MeterModInputBuilder ofMeterModInput = MeterConvertor.toMeterModInput(
557                             getInput().getUpdatedMeter(), getVersion());
558                     final Long xId = getSession().getNextXid();
559                     ofMeterModInput.setXid(xId);
560     
561                     Future<RpcResult<UpdateMeterOutput>> resultFromOFLib = 
562                             getMessageService().meterMod(ofMeterModInput.build(), getCookie());
563                     result = JdkFutureAdapters.listenInPoolThread(resultFromOFLib);
564                     
565                     OFRpcTaskUtil.hookFutureNotification(this, result,
566                             getRpcNotificationProviderService(), createMeterUpdatedNotification(xId, getInput()));
567                 }
568                 return result;
569             }
570         };
571         return task;
572     }
573     
574     /**
575      * @param xId
576      * @param input
577      * @return
578      */
579     protected static NotificationComposer<MeterUpdated> createMeterUpdatedNotification(
580             final Long xId, final UpdateMeterInput input) {
581         return new NotificationComposer<MeterUpdated>() {
582             @Override
583             public MeterUpdated compose() {
584                 MeterUpdatedBuilder meterMod = new MeterUpdatedBuilder(input.getUpdatedMeter());
585                 meterMod.setTransactionId(new TransactionId(BigInteger.valueOf(xId.intValue())));
586                 meterMod.setMeterRef(input.getMeterRef());
587                 return meterMod.build();
588             }
589         };
590     }
591     
592     
593     /**
594      * @param taskContext
595      * @param input
596      * @param cookie
597      * @return task
598      */
599     public static OFRpcTask<RemoveFlowInput, RpcResult<UpdateFlowOutput>> createRemoveFlowTask(
600             OFRpcTaskContext taskContext, RemoveFlowInput input,
601             SwitchConnectionDistinguisher cookie) {
602         OFRpcTask<RemoveFlowInput, RpcResult<UpdateFlowOutput>> task = 
603                 new OFRpcTask<RemoveFlowInput, RpcResult<UpdateFlowOutput>>(taskContext, cookie, input) {
604             
605             @Override
606             public ListenableFuture<RpcResult<UpdateFlowOutput>> call() {
607                 ListenableFuture<RpcResult<UpdateFlowOutput>> result = SettableFuture.create();
608                 
609                 Collection<RpcError> barrierErrors = OFRpcTaskUtil.manageBarrier(getTaskContext(), getInput().isBarrier(), getCookie());
610                 if (!barrierErrors.isEmpty()) {
611                     OFRpcTaskUtil.wrapBarrierErrors(((SettableFuture<RpcResult<UpdateFlowOutput>>) result), barrierErrors);
612                 } else {
613                     // Convert the AddFlowInput to FlowModInput
614                     FlowModInputBuilder ofFlowModInput = FlowConvertor.toFlowModInput(getInput(), 
615                             getVersion(), getSession().getFeatures().getDatapathId());
616                     final Long xId = getSession().getNextXid();
617                     ofFlowModInput.setXid(xId);
618                     
619                     Future<RpcResult<UpdateFlowOutput>> resultFromOFLib = 
620                             getMessageService().flowMod(ofFlowModInput.build(), getCookie());
621                     result = JdkFutureAdapters.listenInPoolThread(resultFromOFLib);
622                     
623                     OFRpcTaskUtil.hookFutureNotification(this, result, 
624                             getRpcNotificationProviderService(), createFlowRemovedNotification(xId, getInput()));
625                 }
626
627                 return result;
628             }
629         };
630         
631         return task;
632     }
633     
634     /**
635      * @param xId
636      * @return
637      */
638     protected static NotificationComposer<FlowRemoved> createFlowRemovedNotification(
639             final Long xId, final RemoveFlowInput input) {
640         return new NotificationComposer<FlowRemoved>() {
641             @Override
642             public FlowRemoved compose() {
643                 FlowRemovedBuilder removedFlow = new FlowRemovedBuilder((Flow) input);
644                 removedFlow.setTransactionId(new TransactionId(BigInteger.valueOf(xId.intValue())));
645                 removedFlow.setFlowRef(input.getFlowRef());
646                 return removedFlow.build();
647             }
648         };
649     }
650     
651     
652     /**
653      * @param taskContext
654      * @param input
655      * @param cookie
656      * @return task
657      */
658     public static OFRpcTask<RemoveGroupInput, RpcResult<UpdateGroupOutput>> createRemoveGroupTask(
659             final OFRpcTaskContext taskContext, RemoveGroupInput input, 
660             final SwitchConnectionDistinguisher cookie) {
661         OFRpcTask<RemoveGroupInput, RpcResult<UpdateGroupOutput>> task = 
662                 new OFRpcTask<RemoveGroupInput, RpcResult<UpdateGroupOutput>>(taskContext, cookie, input) {
663             
664             @Override
665             public ListenableFuture<RpcResult<UpdateGroupOutput>> call() {
666                 ListenableFuture<RpcResult<UpdateGroupOutput>> result = SettableFuture.create();
667                 
668                 Collection<RpcError> barrierErrors = OFRpcTaskUtil.manageBarrier(getTaskContext(), getInput().isBarrier(), getCookie());
669                 if (!barrierErrors.isEmpty()) {
670                     OFRpcTaskUtil.wrapBarrierErrors(((SettableFuture<RpcResult<UpdateGroupOutput>>) result), barrierErrors);
671                 } else {
672                     // Convert the AddGroupInput to GroupModInput
673                     GroupModInputBuilder ofGroupModInput = GroupConvertor.toGroupModInput(getInput(), 
674                             getVersion(), getSession().getFeatures().getDatapathId());
675                     final Long xId = getSession().getNextXid();
676                     ofGroupModInput.setXid(xId);
677                     
678                     Future<RpcResult<UpdateGroupOutput>> resultFromOFLib = getMessageService()
679                             .groupMod(ofGroupModInput.build(), getCookie());
680                     result = JdkFutureAdapters.listenInPoolThread(resultFromOFLib);
681                     
682                     OFRpcTaskUtil.hookFutureNotification(this, result, 
683                             getRpcNotificationProviderService(), createGroupRemovedNotification(xId, getInput()));
684                 }
685
686                 return result;
687             }
688         };
689         
690         return task;
691     }
692     
693     /**
694      * @param xId
695      * @param input
696      * @return 
697      */
698     protected static NotificationComposer<GroupRemoved> createGroupRemovedNotification(
699             final Long xId, final RemoveGroupInput input) {
700         return new NotificationComposer<GroupRemoved>() {
701             @Override
702             public GroupRemoved compose() {
703                 GroupRemovedBuilder removedGroup = new GroupRemovedBuilder((Group) input);
704                 removedGroup.setTransactionId(new TransactionId(BigInteger.valueOf(xId.intValue())));
705                 removedGroup.setGroupRef(input.getGroupRef());
706                 return removedGroup.build();
707             }
708         };
709     }
710     
711     /**
712      * @param taskContext
713      * @param input
714      * @param cookie
715      * @return task
716      */
717     public static OFRpcTask<RemoveMeterInput, RpcResult<UpdateMeterOutput>> createRemoveMeterTask(
718             OFRpcTaskContext taskContext, RemoveMeterInput input,
719             SwitchConnectionDistinguisher cookie) {
720         OFRpcTask<RemoveMeterInput, RpcResult<UpdateMeterOutput>> task = 
721                 new OFRpcTask<RemoveMeterInput, RpcResult<UpdateMeterOutput>>(taskContext, cookie, input) {
722             
723             @Override
724             public ListenableFuture<RpcResult<UpdateMeterOutput>> call() {
725                 ListenableFuture<RpcResult<UpdateMeterOutput>> result = SettableFuture.create();
726                 
727                 Collection<RpcError> barrierErrors = OFRpcTaskUtil.manageBarrier(getTaskContext(), getInput().isBarrier(), getCookie());
728                 if (!barrierErrors.isEmpty()) {
729                     OFRpcTaskUtil.wrapBarrierErrors(((SettableFuture<RpcResult<UpdateMeterOutput>>) result), barrierErrors);
730                 } else {
731                     // Convert the AddGroupInput to GroupModInput
732                     MeterModInputBuilder ofMeterModInput = MeterConvertor.toMeterModInput(getInput(), getVersion());
733                     final Long xId = getSession().getNextXid();
734                     ofMeterModInput.setXid(xId);
735                     
736                     Future<RpcResult<UpdateMeterOutput>> resultFromOFLib = getMessageService()
737                             .meterMod(ofMeterModInput.build(), getCookie());
738                     result = JdkFutureAdapters.listenInPoolThread(resultFromOFLib);
739                     
740                     OFRpcTaskUtil.hookFutureNotification(this, result, 
741                             getRpcNotificationProviderService(), createMeterRemovedNotification(xId, getInput()));
742                 }
743
744                 return result;
745             }
746         };
747         
748         return task;
749         
750     }
751     
752     /**
753      * @param xId
754      * @param input
755      * @return
756      */
757     protected static NotificationComposer<MeterRemoved> createMeterRemovedNotification(
758             final Long xId, final RemoveMeterInput input) {
759         return new NotificationComposer<MeterRemoved>() {
760             @Override
761             public MeterRemoved compose() {
762                 MeterRemovedBuilder meterRemoved = new MeterRemovedBuilder((Meter) input);
763                 meterRemoved.setTransactionId(new TransactionId(BigInteger.valueOf(xId.intValue())));
764                 meterRemoved.setMeterRef(input.getMeterRef());
765                 return meterRemoved.build();
766             }
767         };
768     }
769     
770     /**
771      * @param taskContext
772      * @param input
773      * @param cookie
774      * @return task
775      */
776     public static OFRpcTask<GetAllGroupStatisticsInput, RpcResult<GetAllGroupStatisticsOutput>> createGetAllGroupStatisticsTask(
777             final OFRpcTaskContext taskContext, GetAllGroupStatisticsInput input,
778             SwitchConnectionDistinguisher cookie) {
779         OFRpcTask<GetAllGroupStatisticsInput, RpcResult<GetAllGroupStatisticsOutput>> task = 
780                 new OFRpcTask<GetAllGroupStatisticsInput, RpcResult<GetAllGroupStatisticsOutput>>(taskContext, cookie, input) {
781             
782             @Override
783             public ListenableFuture<RpcResult<GetAllGroupStatisticsOutput>> call() {
784                 final SettableFuture<RpcResult<GetAllGroupStatisticsOutput>> result = SettableFuture.create();
785              
786                 if (taskContext.getSession().getPrimaryConductor().getVersion() == OFConstants.OFP_VERSION_1_0) {
787                     Collection<RpcError> errors = Collections.emptyList();
788                     RpcResult<GetAllGroupStatisticsOutput> rpcResult = Rpcs.getRpcResult(true, 
789                             new GetAllGroupStatisticsOutputBuilder().build(), errors);
790                     
791                     return Futures.immediateFuture(rpcResult);
792                 } else {   
793                 
794                  // Generate xid to associate it with the request
795                     final Long xid = taskContext.getSession().getNextXid();
796     
797                  // Create multipart request body for fetch all the group stats
798                     MultipartRequestGroupCaseBuilder caseBuilder = new MultipartRequestGroupCaseBuilder();
799                     MultipartRequestGroupBuilder mprGroupBuild = new MultipartRequestGroupBuilder();
800                     mprGroupBuild.setGroupId(new GroupId(BinContent.intToUnsignedLong(
801                             org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731
802                             .Group.OFPGALL.getIntValue())));
803                     caseBuilder.setMultipartRequestGroup(mprGroupBuild.build());
804                     
805                     // Create multipart request header
806                     MultipartRequestInputBuilder mprInput = createMultipartHeader(MultipartType.OFPMPGROUP, 
807                             taskContext, xid);
808                     
809                     // Set request body to main multipart request
810                     mprInput.setMultipartRequestBody(caseBuilder.build());
811     
812                     // Send the request, no cookies associated, use any connection
813                     
814                     Future<RpcResult<Void>> resultFromOFLib = getMessageService()
815                             .multipartRequest(mprInput.build(), getCookie());
816                     ListenableFuture<RpcResult<Void>> resultLib = JdkFutureAdapters.listenInPoolThread(resultFromOFLib);
817                     
818                     Futures.addCallback(resultLib, new ResultCallback<GetAllGroupStatisticsOutput>(result) {
819                         @Override
820                         public GetAllGroupStatisticsOutput createResult() {
821                             GetAllGroupStatisticsOutputBuilder groupStatBuilder = new GetAllGroupStatisticsOutputBuilder()
822                             .setTransactionId(new TransactionId(BigInteger.valueOf(xid)));
823                             return groupStatBuilder.build();
824                         }
825                     });
826                         
827                     return result;
828                 }
829             }
830         };
831         return task;
832     }
833     
834     /**
835      * @param taskContext
836      * @param input
837      * @param cookie
838      * @return task
839      */
840     public static OFRpcTask<GetGroupDescriptionInput, RpcResult<GetGroupDescriptionOutput>> createGetGroupDescriptionTask(
841             final OFRpcTaskContext taskContext, GetGroupDescriptionInput input,
842             SwitchConnectionDistinguisher cookie) {
843         OFRpcTask<GetGroupDescriptionInput, RpcResult<GetGroupDescriptionOutput>> task = 
844                 new OFRpcTask<GetGroupDescriptionInput, RpcResult<GetGroupDescriptionOutput>>(taskContext, cookie, input) {
845
846                     @Override
847                     public ListenableFuture<RpcResult<GetGroupDescriptionOutput>> call()
848                             throws Exception {
849                         final SettableFuture<RpcResult<GetGroupDescriptionOutput>> result = SettableFuture.create();
850                         
851                         if (taskContext.getSession().getPrimaryConductor().getVersion() == OFConstants.OFP_VERSION_1_0) {
852                             Collection<RpcError> errors = Collections.emptyList();
853                             RpcResult<GetGroupDescriptionOutput> rpcResult = Rpcs.getRpcResult(true, 
854                                     new GetGroupDescriptionOutputBuilder().build(), errors);
855                             return Futures.immediateFuture(rpcResult);
856                         } else {
857                             final Long xid = taskContext.getSession().getNextXid();
858                             
859                             MultipartRequestGroupDescCaseBuilder mprGroupDescCaseBuild = 
860                                                   new MultipartRequestGroupDescCaseBuilder();
861                             MultipartRequestInputBuilder mprInput = 
862                                     createMultipartHeader(MultipartType.OFPMPGROUPDESC, taskContext, xid);
863                             mprInput.setMultipartRequestBody(mprGroupDescCaseBuild.build());
864                             Future<RpcResult<Void>> resultFromOFLib = getMessageService()
865                                     .multipartRequest(mprInput.build(), getCookie());
866                             ListenableFuture<RpcResult<Void>> resultLib = JdkFutureAdapters.listenInPoolThread(resultFromOFLib);
867                             
868                             Futures.addCallback(resultLib, new ResultCallback<GetGroupDescriptionOutput>(result) {
869                                 @Override
870                                 public GetGroupDescriptionOutput createResult() {
871                                     GetGroupDescriptionOutputBuilder groupStatBuilder = new GetGroupDescriptionOutputBuilder()
872                                     .setTransactionId(new TransactionId(BigInteger.valueOf(xid)));
873                                     return groupStatBuilder.build();
874                                 }
875                             });
876                             return result;
877                         }
878                     }  
879         };
880         return task;
881     }
882     
883     /**
884      * @param taskContext
885      * @param input
886      * @param cookie
887      * @return task
888      */
889     public static OFRpcTask<GetGroupFeaturesInput, RpcResult<GetGroupFeaturesOutput>> createGetGroupFeaturesTask(
890             final OFRpcTaskContext taskContext, GetGroupFeaturesInput input,
891             SwitchConnectionDistinguisher cookie) {
892         OFRpcTask<GetGroupFeaturesInput, RpcResult<GetGroupFeaturesOutput>> task = 
893                 new OFRpcTask<GetGroupFeaturesInput, RpcResult<GetGroupFeaturesOutput>>(taskContext, cookie, input) {
894
895                     @Override
896                     public ListenableFuture<RpcResult<GetGroupFeaturesOutput>> call()
897                             throws Exception {
898                         final SettableFuture<RpcResult<GetGroupFeaturesOutput>> result = SettableFuture.create();
899                         
900                         if (taskContext.getSession().getPrimaryConductor().getVersion() == OFConstants.OFP_VERSION_1_0) {
901                             Collection<RpcError> errors = Collections.emptyList();
902                             RpcResult<GetGroupFeaturesOutput> rpcResult = Rpcs.getRpcResult(true, 
903                                     new GetGroupFeaturesOutputBuilder().build(), errors);
904                             return Futures.immediateFuture(rpcResult);
905                         } else {
906                             final Long xid = taskContext.getSession().getNextXid();
907                             
908                             MultipartRequestGroupFeaturesCaseBuilder mprGroupFeaturesBuild = 
909                                                   new MultipartRequestGroupFeaturesCaseBuilder();
910                             MultipartRequestInputBuilder mprInput = 
911                                     createMultipartHeader(MultipartType.OFPMPGROUPFEATURES, taskContext, xid);
912                             mprInput.setMultipartRequestBody(mprGroupFeaturesBuild.build());
913                             Future<RpcResult<Void>> resultFromOFLib = getMessageService()
914                                     .multipartRequest(mprInput.build(), getCookie());
915                             ListenableFuture<RpcResult<Void>> resultLib = JdkFutureAdapters.listenInPoolThread(resultFromOFLib);
916                             
917                             Futures.addCallback(resultLib, new ResultCallback<GetGroupFeaturesOutput>(result) {
918                                 @Override
919                                 public GetGroupFeaturesOutput createResult() {
920                                     GetGroupFeaturesOutputBuilder groupFeatureBuilder = new GetGroupFeaturesOutputBuilder()
921                                     .setTransactionId(new TransactionId(BigInteger.valueOf(xid)));
922                                     return groupFeatureBuilder.build();
923                                 }
924                             });
925                             return result;
926                         }
927                     }  
928         };
929         return task;
930     }
931     
932     /**
933      * @param taskContext
934      * @param input
935      * @param cookie
936      * @return task
937      */
938     public static OFRpcTask<GetGroupStatisticsInput, RpcResult<GetGroupStatisticsOutput>> createGetGroupStatisticsTask(
939             final OFRpcTaskContext taskContext, final GetGroupStatisticsInput input,
940             SwitchConnectionDistinguisher cookie) {
941         OFRpcTask<GetGroupStatisticsInput, RpcResult<GetGroupStatisticsOutput>> task = 
942                 new OFRpcTask<GetGroupStatisticsInput, RpcResult<GetGroupStatisticsOutput>>(taskContext, cookie, input) {
943
944                     @Override
945                     public ListenableFuture<RpcResult<GetGroupStatisticsOutput>> call()
946                             throws Exception {
947                         final SettableFuture<RpcResult<GetGroupStatisticsOutput>> result = SettableFuture.create();
948                         
949                         if (taskContext.getSession().getPrimaryConductor().getVersion() == OFConstants.OFP_VERSION_1_0) {
950                             Collection<RpcError> errors = Collections.emptyList();
951                             RpcResult<GetGroupStatisticsOutput> rpcResult = Rpcs.getRpcResult(true, 
952                                     new GetGroupStatisticsOutputBuilder().build(), errors);
953                             return Futures.immediateFuture(rpcResult);
954                         } else {
955                             final Long xid = taskContext.getSession().getNextXid();
956                             
957                             MultipartRequestGroupCaseBuilder caseBuilder = new MultipartRequestGroupCaseBuilder();
958                             MultipartRequestGroupBuilder mprGroupBuild = new MultipartRequestGroupBuilder();
959                             mprGroupBuild.setGroupId(new GroupId(input.getGroupId().getValue()));
960                             caseBuilder.setMultipartRequestGroup(mprGroupBuild.build());
961                             
962                             MultipartRequestInputBuilder mprInput = 
963                                     createMultipartHeader(MultipartType.OFPMPGROUP, taskContext, xid);
964                             mprInput.setMultipartRequestBody(caseBuilder.build());
965                             Future<RpcResult<Void>> resultFromOFLib = getMessageService()
966                                     .multipartRequest(mprInput.build(), getCookie());
967                             ListenableFuture<RpcResult<Void>> resultLib = JdkFutureAdapters.listenInPoolThread(resultFromOFLib);
968                             
969                             Futures.addCallback(resultLib, new ResultCallback<GetGroupStatisticsOutput>(result) {
970                                 @Override
971                                 public GetGroupStatisticsOutput createResult() {
972                                     GetGroupStatisticsOutputBuilder groupStatisticsBuilder = 
973                                             new GetGroupStatisticsOutputBuilder()
974                                     .setTransactionId(new TransactionId(BigInteger.valueOf(xid)));
975                                     return groupStatisticsBuilder.build();
976                                 }
977                             });
978                             return result;
979                         }
980                     }  
981         };
982         return task;
983     }
984     
985     /**
986      * @param taskContext
987      * @param input
988      * @param cookie
989      * @return task
990      */
991     public static OFRpcTask<GetAllMeterConfigStatisticsInput, RpcResult<GetAllMeterConfigStatisticsOutput>> createGetAllMeterConfigStatisticsTask(
992             final OFRpcTaskContext taskContext, final GetAllMeterConfigStatisticsInput input,
993             SwitchConnectionDistinguisher cookie) {
994         OFRpcTask<GetAllMeterConfigStatisticsInput, RpcResult<GetAllMeterConfigStatisticsOutput>> task = 
995                 new OFRpcTask<GetAllMeterConfigStatisticsInput, RpcResult<GetAllMeterConfigStatisticsOutput>>(taskContext, cookie, input) {
996
997                     @Override
998                     public ListenableFuture<RpcResult<GetAllMeterConfigStatisticsOutput>> call()
999                             throws Exception {
1000                         final SettableFuture<RpcResult<GetAllMeterConfigStatisticsOutput>> result = SettableFuture.create();
1001                         
1002                         if (taskContext.getSession().getPrimaryConductor().getVersion() == OFConstants.OFP_VERSION_1_0) {
1003                             Collection<RpcError> errors = Collections.emptyList();
1004                             RpcResult<GetAllMeterConfigStatisticsOutput> rpcResult = Rpcs.getRpcResult(true, 
1005                                     new GetAllMeterConfigStatisticsOutputBuilder().build(), errors);
1006                             return Futures.immediateFuture(rpcResult);
1007                         } else {
1008                             final Long xid = taskContext.getSession().getNextXid();
1009                             
1010                             MultipartRequestMeterConfigCaseBuilder caseBuilder = 
1011                                     new MultipartRequestMeterConfigCaseBuilder();
1012                             MultipartRequestMeterConfigBuilder mprMeterConfigBuild = 
1013                                     new MultipartRequestMeterConfigBuilder();
1014                             mprMeterConfigBuild.setMeterId(new MeterId(BinContent.intToUnsignedLong(
1015                                     org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common
1016                                     .types.rev130731.Meter.OFPMALL.getIntValue())));
1017                             caseBuilder.setMultipartRequestMeterConfig(mprMeterConfigBuild.build());
1018                             
1019                             MultipartRequestInputBuilder mprInput = 
1020                                     createMultipartHeader(MultipartType.OFPMPMETERCONFIG, taskContext, xid);
1021                             mprInput.setMultipartRequestBody(caseBuilder.build());
1022                             Future<RpcResult<Void>> resultFromOFLib = getMessageService()
1023                                     .multipartRequest(mprInput.build(), getCookie());
1024                             ListenableFuture<RpcResult<Void>> resultLib = JdkFutureAdapters.listenInPoolThread(resultFromOFLib);
1025                             
1026                             Futures.addCallback(resultLib, new ResultCallback<GetAllMeterConfigStatisticsOutput>(result) {
1027                                 @Override
1028                                 public GetAllMeterConfigStatisticsOutput createResult() {
1029                                     GetAllMeterConfigStatisticsOutputBuilder allMeterConfStatBuilder = 
1030                                             new GetAllMeterConfigStatisticsOutputBuilder()
1031                                     .setTransactionId(new TransactionId(BigInteger.valueOf(xid)));
1032                                     return allMeterConfStatBuilder.build();
1033                                 }
1034                             });
1035                             return result;
1036                         }
1037                     }  
1038         };
1039         return task;
1040     }
1041     
1042     /**
1043      * @param taskContext
1044      * @param input
1045      * @param cookie
1046      * @return task
1047      */
1048     public static OFRpcTask<GetAllMeterStatisticsInput, RpcResult<GetAllMeterStatisticsOutput>> createGetAllMeterStatisticsTask(
1049             final OFRpcTaskContext taskContext, final GetAllMeterStatisticsInput input,
1050             SwitchConnectionDistinguisher cookie) {
1051         OFRpcTask<GetAllMeterStatisticsInput, RpcResult<GetAllMeterStatisticsOutput>> task = 
1052                 new OFRpcTask<GetAllMeterStatisticsInput, RpcResult<GetAllMeterStatisticsOutput>>(taskContext, cookie, input) {
1053
1054                     @Override
1055                     public ListenableFuture<RpcResult<GetAllMeterStatisticsOutput>> call()
1056                             throws Exception {
1057                         final SettableFuture<RpcResult<GetAllMeterStatisticsOutput>> result = SettableFuture.create();
1058                         
1059                         if (taskContext.getSession().getPrimaryConductor().getVersion() == OFConstants.OFP_VERSION_1_0) {
1060                             Collection<RpcError> errors = Collections.emptyList();
1061                             RpcResult<GetAllMeterStatisticsOutput> rpcResult = Rpcs.getRpcResult(true, 
1062                                     new GetAllMeterStatisticsOutputBuilder().build(), errors);
1063                             return Futures.immediateFuture(rpcResult);
1064                         } else {
1065                             final Long xid = taskContext.getSession().getNextXid();
1066                             
1067                             MultipartRequestMeterCaseBuilder caseBuilder = 
1068                                     new MultipartRequestMeterCaseBuilder();
1069                             MultipartRequestMeterBuilder mprMeterBuild = 
1070                                     new MultipartRequestMeterBuilder();
1071                             mprMeterBuild.setMeterId(new MeterId(BinContent.intToUnsignedLong(
1072                                     org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common
1073                                     .types.rev130731.Meter.OFPMALL.getIntValue())));
1074                             caseBuilder.setMultipartRequestMeter(mprMeterBuild.build());
1075                             
1076                             MultipartRequestInputBuilder mprInput = 
1077                                     createMultipartHeader(MultipartType.OFPMPMETER, taskContext, xid);
1078                             mprInput.setMultipartRequestBody(caseBuilder.build());
1079                             Future<RpcResult<Void>> resultFromOFLib = getMessageService()
1080                                     .multipartRequest(mprInput.build(), getCookie());
1081                             ListenableFuture<RpcResult<Void>> resultLib = JdkFutureAdapters.listenInPoolThread(resultFromOFLib);
1082                             
1083                             Futures.addCallback(resultLib, new ResultCallback<GetAllMeterStatisticsOutput>(result) {
1084                                 @Override
1085                                 public GetAllMeterStatisticsOutput createResult() {
1086                                     GetAllMeterStatisticsOutputBuilder allMeterStatBuilder = 
1087                                             new GetAllMeterStatisticsOutputBuilder()
1088                                     .setTransactionId(new TransactionId(BigInteger.valueOf(xid)));
1089                                     return allMeterStatBuilder.build();
1090                                 }
1091                             });
1092                             return result;
1093                         }
1094                     }  
1095         };
1096         return task;
1097     }
1098     
1099     /**
1100      * @param taskContext
1101      * @param input
1102      * @param cookie
1103      * @return task
1104      */
1105     public static OFRpcTask<GetMeterFeaturesInput, RpcResult<GetMeterFeaturesOutput>> createGetMeterFeaturesTask(
1106             final OFRpcTaskContext taskContext, final GetMeterFeaturesInput input,
1107             SwitchConnectionDistinguisher cookie) {
1108         OFRpcTask<GetMeterFeaturesInput, RpcResult<GetMeterFeaturesOutput>> task = 
1109                 new OFRpcTask<GetMeterFeaturesInput, RpcResult<GetMeterFeaturesOutput>>(taskContext, cookie, input) {
1110
1111                     @Override
1112                     public ListenableFuture<RpcResult<GetMeterFeaturesOutput>> call()
1113                             throws Exception {
1114                         final SettableFuture<RpcResult<GetMeterFeaturesOutput>> result = SettableFuture.create();
1115                         
1116                         if (taskContext.getSession().getPrimaryConductor().getVersion() == OFConstants.OFP_VERSION_1_0) {
1117                             Collection<RpcError> errors = Collections.emptyList();
1118                             RpcResult<GetMeterFeaturesOutput> rpcResult = Rpcs.getRpcResult(true, 
1119                                     new GetMeterFeaturesOutputBuilder().build(), errors);
1120                             return Futures.immediateFuture(rpcResult);
1121                         } else {
1122                             final Long xid = taskContext.getSession().getNextXid();
1123                             
1124                             MultipartRequestMeterFeaturesCaseBuilder mprMeterFeaturesBuild = 
1125                                     new MultipartRequestMeterFeaturesCaseBuilder();
1126                             
1127                             MultipartRequestInputBuilder mprInput = 
1128                                     createMultipartHeader(MultipartType.OFPMPMETERFEATURES, taskContext, xid);
1129                             mprInput.setMultipartRequestBody(mprMeterFeaturesBuild.build());
1130                             Future<RpcResult<Void>> resultFromOFLib = getMessageService()
1131                                     .multipartRequest(mprInput.build(), getCookie());
1132                             ListenableFuture<RpcResult<Void>> resultLib = JdkFutureAdapters.listenInPoolThread(resultFromOFLib);
1133                             
1134                             Futures.addCallback(resultLib, new ResultCallback<GetMeterFeaturesOutput>(result) {
1135                                 @Override
1136                                 public GetMeterFeaturesOutput createResult() {
1137                                     GetMeterFeaturesOutputBuilder meterFeaturesBuilder = 
1138                                             new GetMeterFeaturesOutputBuilder()
1139                                     .setTransactionId(new TransactionId(BigInteger.valueOf(xid)));
1140                                     return meterFeaturesBuilder.build();
1141                                 }
1142                             });
1143                             return result;
1144                         }
1145                     }  
1146         };
1147         return task;
1148     }
1149     
1150     /**
1151      * @param taskContext
1152      * @param input
1153      * @param cookie
1154      * @return task
1155      */
1156     public static OFRpcTask<GetMeterStatisticsInput, RpcResult<GetMeterStatisticsOutput>> createGetMeterStatisticsTask(
1157             final OFRpcTaskContext taskContext, final GetMeterStatisticsInput input,
1158             SwitchConnectionDistinguisher cookie) {
1159         OFRpcTask<GetMeterStatisticsInput, RpcResult<GetMeterStatisticsOutput>> task = 
1160                 new OFRpcTask<GetMeterStatisticsInput, RpcResult<GetMeterStatisticsOutput>>(taskContext, cookie, input) {
1161
1162                     @Override
1163                     public ListenableFuture<RpcResult<GetMeterStatisticsOutput>> call()
1164                             throws Exception {
1165                         final SettableFuture<RpcResult<GetMeterStatisticsOutput>> result = SettableFuture.create();
1166                         
1167                         if (taskContext.getSession().getPrimaryConductor().getVersion() == OFConstants.OFP_VERSION_1_0) {
1168                             Collection<RpcError> errors = Collections.emptyList();
1169                             RpcResult<GetMeterStatisticsOutput> rpcResult = Rpcs.getRpcResult(true, 
1170                                     new GetMeterStatisticsOutputBuilder().build(), errors);
1171                             return Futures.immediateFuture(rpcResult);
1172                         } else {
1173                             final Long xid = taskContext.getSession().getNextXid();
1174                             
1175                             MultipartRequestMeterCaseBuilder caseBuilder = 
1176                                     new MultipartRequestMeterCaseBuilder();
1177                             MultipartRequestMeterBuilder mprMeterBuild = 
1178                                     new MultipartRequestMeterBuilder();
1179                             mprMeterBuild.setMeterId(new MeterId(input.getMeterId().getValue()));
1180                             caseBuilder.setMultipartRequestMeter(mprMeterBuild.build());
1181                             
1182                             MultipartRequestInputBuilder mprInput = 
1183                                     createMultipartHeader(MultipartType.OFPMPMETER, taskContext, xid);
1184                             mprInput.setMultipartRequestBody(caseBuilder.build());
1185                             Future<RpcResult<Void>> resultFromOFLib = getMessageService()
1186                                     .multipartRequest(mprInput.build(), getCookie());
1187                             ListenableFuture<RpcResult<Void>> resultLib = JdkFutureAdapters.listenInPoolThread(resultFromOFLib);
1188                             
1189                             Futures.addCallback(resultLib, new ResultCallback<GetMeterStatisticsOutput>(result) {
1190                                 @Override
1191                                 public GetMeterStatisticsOutput createResult() {
1192                                     GetMeterStatisticsOutputBuilder meterStatBuilder = 
1193                                             new GetMeterStatisticsOutputBuilder()
1194                                     .setTransactionId(new TransactionId(BigInteger.valueOf(xid)));
1195                                     return meterStatBuilder.build();
1196                                 }
1197                             });
1198                             return result;
1199                         }
1200                     }  
1201         };
1202         return task;
1203     }
1204     
1205     /**
1206      * @param taskContext
1207      * @param input
1208      * @param cookie
1209      * @return task
1210      */
1211     public static OFRpcTask<GetAllNodeConnectorsStatisticsInput, RpcResult<GetAllNodeConnectorsStatisticsOutput>> 
1212                                                     createGetAllNodeConnectorsStatisticsTask(
1213             final OFRpcTaskContext taskContext, final GetAllNodeConnectorsStatisticsInput input,
1214             SwitchConnectionDistinguisher cookie) {
1215         OFRpcTask<GetAllNodeConnectorsStatisticsInput, RpcResult<GetAllNodeConnectorsStatisticsOutput>> task = 
1216                 new OFRpcTask<GetAllNodeConnectorsStatisticsInput, RpcResult<GetAllNodeConnectorsStatisticsOutput>>(taskContext, cookie, input) {
1217
1218                     @Override
1219                     public ListenableFuture<RpcResult<GetAllNodeConnectorsStatisticsOutput>> call()
1220                             throws Exception {
1221                         final SettableFuture<RpcResult<GetAllNodeConnectorsStatisticsOutput>> result = SettableFuture.create();
1222                         
1223                             final Long xid = taskContext.getSession().getNextXid();
1224                             
1225                             MultipartRequestPortStatsCaseBuilder caseBuilder = 
1226                                     new MultipartRequestPortStatsCaseBuilder();
1227                             MultipartRequestPortStatsBuilder mprPortStatsBuilder = 
1228                                     new MultipartRequestPortStatsBuilder();
1229                             // Select all ports
1230                             mprPortStatsBuilder.setPortNo(OFConstants.OFPP_ANY);
1231                             caseBuilder.setMultipartRequestPortStats(mprPortStatsBuilder.build());
1232                             
1233                             MultipartRequestInputBuilder mprInput = 
1234                                     createMultipartHeader(MultipartType.OFPMPPORTSTATS, taskContext, xid);
1235                             mprInput.setMultipartRequestBody(caseBuilder.build());
1236                             Future<RpcResult<Void>> resultFromOFLib = getMessageService()
1237                                     .multipartRequest(mprInput.build(), getCookie());
1238                             ListenableFuture<RpcResult<Void>> resultLib = JdkFutureAdapters.listenInPoolThread(resultFromOFLib);
1239                             
1240                             Futures.addCallback(resultLib, new ResultCallback<GetAllNodeConnectorsStatisticsOutput>(result) {
1241                                 @Override
1242                                 public GetAllNodeConnectorsStatisticsOutput createResult() {
1243                                     GetAllNodeConnectorsStatisticsOutputBuilder allNodeConnectorStatBuilder = 
1244                                             new GetAllNodeConnectorsStatisticsOutputBuilder()
1245                                     .setTransactionId(new TransactionId(BigInteger.valueOf(xid)));
1246                                     return allNodeConnectorStatBuilder.build();
1247                                 }
1248                             });
1249                             return result;
1250                         }
1251         };
1252         return task;
1253     }
1254     
1255     /**
1256      * @param taskContext
1257      * @param input
1258      * @param cookie
1259      * @return task
1260      */
1261     public static OFRpcTask<GetNodeConnectorStatisticsInput, RpcResult<GetNodeConnectorStatisticsOutput>> 
1262                                                     createGetNodeConnectorStatisticsTask(
1263             final OFRpcTaskContext taskContext, final GetNodeConnectorStatisticsInput input,
1264             SwitchConnectionDistinguisher cookie) {
1265         OFRpcTask<GetNodeConnectorStatisticsInput, RpcResult<GetNodeConnectorStatisticsOutput>> task = 
1266                 new OFRpcTask<GetNodeConnectorStatisticsInput, RpcResult<GetNodeConnectorStatisticsOutput>>(taskContext, cookie, input) {
1267
1268                 @Override
1269                 public ListenableFuture<RpcResult<GetNodeConnectorStatisticsOutput>> call()
1270                         throws Exception {
1271                     final SettableFuture<RpcResult<GetNodeConnectorStatisticsOutput>> result = SettableFuture.create();
1272                     
1273                         final Long xid = taskContext.getSession().getNextXid();
1274                         
1275                         MultipartRequestPortStatsCaseBuilder caseBuilder = 
1276                                 new MultipartRequestPortStatsCaseBuilder();
1277                         MultipartRequestPortStatsBuilder mprPortStatsBuilder = 
1278                                 new MultipartRequestPortStatsBuilder();
1279                         // Set specific port
1280                         mprPortStatsBuilder
1281                                 .setPortNo(InventoryDataServiceUtil.portNumberfromNodeConnectorId(
1282                                         OpenflowVersion.get(taskContext.getSession().getFeatures().getVersion()), 
1283                                         input.getNodeConnectorId()));
1284                         caseBuilder.setMultipartRequestPortStats(mprPortStatsBuilder.build());
1285                         
1286                         MultipartRequestInputBuilder mprInput = 
1287                                 createMultipartHeader(MultipartType.OFPMPPORTSTATS, taskContext, xid);
1288                         mprInput.setMultipartRequestBody(caseBuilder.build());
1289                         Future<RpcResult<Void>> resultFromOFLib = getMessageService()
1290                                 .multipartRequest(mprInput.build(), getCookie());
1291                         ListenableFuture<RpcResult<Void>> resultLib = JdkFutureAdapters.listenInPoolThread(resultFromOFLib);
1292                         
1293                         Futures.addCallback(resultLib, new ResultCallback<GetNodeConnectorStatisticsOutput>(result) {
1294                             @Override
1295                             public GetNodeConnectorStatisticsOutput createResult() {
1296                                 GetNodeConnectorStatisticsOutputBuilder allNodeConnectorStatBuilder = 
1297                                         new GetNodeConnectorStatisticsOutputBuilder()
1298                                 .setTransactionId(new TransactionId(BigInteger.valueOf(xid)));
1299                                 return allNodeConnectorStatBuilder.build();
1300                             }
1301                         });
1302                         return result;
1303                     }
1304         };
1305         return task;
1306     }
1307     
1308     /**
1309      * @param taskContext
1310      * @param input
1311      * @param cookie
1312      * @return task
1313      */
1314     public static OFRpcTask<GetAllFlowStatisticsFromFlowTableInput, RpcResult<GetAllFlowStatisticsFromFlowTableOutput>> 
1315                                                     createGetAllFlowStatisticsFromFlowTableTask(
1316             final OFRpcTaskContext taskContext, 
1317             final GetAllFlowStatisticsFromFlowTableInput input,
1318             SwitchConnectionDistinguisher cookie) {
1319         OFRpcTask<GetAllFlowStatisticsFromFlowTableInput, RpcResult<GetAllFlowStatisticsFromFlowTableOutput>> task = 
1320         new OFRpcTask<GetAllFlowStatisticsFromFlowTableInput, RpcResult<GetAllFlowStatisticsFromFlowTableOutput>>(taskContext, cookie, input) {
1321
1322                 @Override
1323                 public ListenableFuture<RpcResult<GetAllFlowStatisticsFromFlowTableOutput>> call() throws Exception {
1324                     final SettableFuture<RpcResult<GetAllFlowStatisticsFromFlowTableOutput>> result = SettableFuture.create();
1325                     
1326                         final Long xid = taskContext.getSession().getNextXid();
1327                         
1328                         MultipartRequestFlowCaseBuilder multipartRequestFlowCaseBuilder = new MultipartRequestFlowCaseBuilder();
1329                         MultipartRequestFlowBuilder mprFlowRequestBuilder = new MultipartRequestFlowBuilder();
1330                         mprFlowRequestBuilder.setTableId(input.getTableId().getValue());
1331                         mprFlowRequestBuilder.setOutPort(OFConstants.OFPP_ANY);
1332                         mprFlowRequestBuilder.setOutGroup(OFConstants.OFPG_ANY);
1333                         mprFlowRequestBuilder.setCookie(OFConstants.DEFAULT_COOKIE);
1334                         mprFlowRequestBuilder.setCookieMask(OFConstants.DEFAULT_COOKIE_MASK);
1335                         FlowCreatorUtil.setWildcardedFlowMatch(taskContext.getSession()
1336                                 .getPrimaryConductor().getVersion(), mprFlowRequestBuilder);
1337                         
1338                         MultipartRequestInputBuilder mprInput = 
1339                                 createMultipartHeader(MultipartType.OFPMPFLOW, taskContext, xid);
1340                         mprInput.setMultipartRequestBody(multipartRequestFlowCaseBuilder.build());
1341                         Future<RpcResult<Void>> resultFromOFLib = getMessageService()
1342                                 .multipartRequest(mprInput.build(), getCookie());
1343                         ListenableFuture<RpcResult<Void>> resultLib = JdkFutureAdapters.listenInPoolThread(resultFromOFLib);
1344                         
1345                         Futures.addCallback(resultLib, new ResultCallback<GetAllFlowStatisticsFromFlowTableOutput>(result) {
1346                             @Override
1347                             public GetAllFlowStatisticsFromFlowTableOutput createResult() {
1348                                 GetAllFlowStatisticsFromFlowTableOutputBuilder allFlowStatsFromFlowTableBuilder = 
1349                                         new GetAllFlowStatisticsFromFlowTableOutputBuilder()
1350                                 .setTransactionId(new TransactionId(BigInteger.valueOf(xid)));
1351                                 return allFlowStatsFromFlowTableBuilder.build();
1352                             }
1353                         });
1354                         return result;
1355                     }
1356         };
1357         return task;
1358     }
1359     
1360     /**
1361      * @param taskContext
1362      * @param input
1363      * @param cookie
1364      * @return task
1365      */
1366     public static OFRpcTask<GetAllFlowsStatisticsFromAllFlowTablesInput, RpcResult<GetAllFlowsStatisticsFromAllFlowTablesOutput>> 
1367                                                     createGetAllFlowsStatisticsFromAllFlowTablesTask(
1368             final OFRpcTaskContext taskContext, 
1369             final GetAllFlowsStatisticsFromAllFlowTablesInput input,
1370             SwitchConnectionDistinguisher cookie) {
1371         OFRpcTask<GetAllFlowsStatisticsFromAllFlowTablesInput, 
1372         RpcResult<GetAllFlowsStatisticsFromAllFlowTablesOutput>> task = 
1373         new OFRpcTask<GetAllFlowsStatisticsFromAllFlowTablesInput, 
1374         RpcResult<GetAllFlowsStatisticsFromAllFlowTablesOutput>>(taskContext, cookie, input) {
1375
1376             @Override
1377             public ListenableFuture<RpcResult<GetAllFlowsStatisticsFromAllFlowTablesOutput>> call() throws Exception {
1378                 final SettableFuture<RpcResult<GetAllFlowsStatisticsFromAllFlowTablesOutput>> result = SettableFuture.create();
1379                 
1380                     final Long xid = taskContext.getSession().getNextXid();
1381                     
1382                  // Create multipart request body for fetch all the group stats
1383                     MultipartRequestFlowCaseBuilder multipartRequestFlowCaseBuilder = 
1384                             new MultipartRequestFlowCaseBuilder();
1385                     MultipartRequestFlowBuilder mprFlowRequestBuilder = 
1386                             new MultipartRequestFlowBuilder();
1387                     mprFlowRequestBuilder.setTableId(OFConstants.OFPTT_ALL);
1388                     mprFlowRequestBuilder.setOutPort(OFConstants.OFPP_ANY);
1389                     mprFlowRequestBuilder.setOutGroup(OFConstants.OFPG_ANY);
1390                     mprFlowRequestBuilder.setCookie(OFConstants.DEFAULT_COOKIE);
1391                     mprFlowRequestBuilder.setCookieMask(OFConstants.DEFAULT_COOKIE_MASK);
1392                     FlowCreatorUtil.setWildcardedFlowMatch(taskContext.getSession()
1393                             .getPrimaryConductor().getVersion(), mprFlowRequestBuilder);
1394                     
1395                     MultipartRequestInputBuilder mprInput = 
1396                             createMultipartHeader(MultipartType.OFPMPFLOW, taskContext, xid);
1397                     multipartRequestFlowCaseBuilder.setMultipartRequestFlow(mprFlowRequestBuilder.build());
1398                     mprInput.setMultipartRequestBody(multipartRequestFlowCaseBuilder.build());
1399                     Future<RpcResult<Void>> resultFromOFLib = getMessageService()
1400                             .multipartRequest(mprInput.build(), getCookie());
1401                     ListenableFuture<RpcResult<Void>> resultLib = JdkFutureAdapters.listenInPoolThread(resultFromOFLib);
1402                     
1403                     Futures.addCallback(resultLib, new ResultCallback<GetAllFlowsStatisticsFromAllFlowTablesOutput>(result) {
1404                         @Override
1405                         public GetAllFlowsStatisticsFromAllFlowTablesOutput createResult() {
1406                             GetAllFlowsStatisticsFromAllFlowTablesOutputBuilder allFlowStatsFromAllFlowTableBuilder = 
1407                                     new GetAllFlowsStatisticsFromAllFlowTablesOutputBuilder()
1408                             .setTransactionId(new TransactionId(BigInteger.valueOf(xid)));
1409                             return allFlowStatsFromAllFlowTableBuilder.build();
1410                         }
1411                     });
1412                     return result;
1413                 }
1414         };
1415         return task;
1416     }
1417     
1418     /**
1419      * @param taskContext
1420      * @param input
1421      * @param cookie
1422      * @return task
1423      */
1424     public static OFRpcTask<GetFlowStatisticsFromFlowTableInput, RpcResult<GetFlowStatisticsFromFlowTableOutput>> 
1425                                                     createGetFlowStatisticsFromFlowTableTask(
1426             final OFRpcTaskContext taskContext, 
1427             final GetFlowStatisticsFromFlowTableInput input,SwitchConnectionDistinguisher cookie) {
1428         OFRpcTask<GetFlowStatisticsFromFlowTableInput, RpcResult<GetFlowStatisticsFromFlowTableOutput>> task = 
1429         new OFRpcTask<GetFlowStatisticsFromFlowTableInput, RpcResult<GetFlowStatisticsFromFlowTableOutput>>(taskContext, cookie, input) {
1430
1431             @Override
1432             public ListenableFuture<RpcResult<GetFlowStatisticsFromFlowTableOutput>> call() throws Exception {
1433                 final SettableFuture<RpcResult<GetFlowStatisticsFromFlowTableOutput>> result = SettableFuture.create();
1434                 
1435                     final Long xid = taskContext.getSession().getNextXid();
1436                     
1437                  // Create multipart request body for fetch all the group stats
1438                     MultipartRequestFlowCaseBuilder multipartRequestFlowCaseBuilder = new MultipartRequestFlowCaseBuilder();
1439                     MultipartRequestFlowBuilder mprFlowRequestBuilder = new MultipartRequestFlowBuilder();
1440                     mprFlowRequestBuilder.setTableId(input.getTableId());
1441
1442                     if (input.getOutPort() != null)
1443                         mprFlowRequestBuilder.setOutPort(input.getOutPort().longValue());
1444                     else
1445                         mprFlowRequestBuilder.setOutPort(OFConstants.OFPP_ANY);
1446
1447                     if (input.getOutGroup() != null)
1448                         mprFlowRequestBuilder.setOutGroup(input.getOutGroup());
1449                     else
1450                         mprFlowRequestBuilder.setOutGroup(OFConstants.OFPG_ANY);
1451
1452                     if (input.getCookie() != null)
1453                         mprFlowRequestBuilder.setCookie(input.getCookie().getValue());
1454                     else
1455                         mprFlowRequestBuilder.setCookie(OFConstants.DEFAULT_COOKIE);
1456
1457                     if (input.getCookieMask() != null)
1458                         mprFlowRequestBuilder.setCookieMask(input.getCookieMask().getValue());
1459                     else
1460                         mprFlowRequestBuilder.setCookieMask(OFConstants.DEFAULT_COOKIE_MASK);
1461
1462                     // convert and inject match
1463                     MatchReactor.getInstance().convert(input.getMatch(), taskContext.getSession()
1464                             .getPrimaryConductor().getVersion(), mprFlowRequestBuilder,
1465                             taskContext.getSession().getFeatures().getDatapathId());
1466
1467                     // Set request body to main multipart request
1468                     multipartRequestFlowCaseBuilder.setMultipartRequestFlow(mprFlowRequestBuilder.build());
1469                     MultipartRequestInputBuilder mprInput = 
1470                             createMultipartHeader(MultipartType.OFPMPFLOW, taskContext, xid);
1471                     mprInput.setMultipartRequestBody(multipartRequestFlowCaseBuilder.build());
1472                     Future<RpcResult<Void>> resultFromOFLib = getMessageService()
1473                             .multipartRequest(mprInput.build(), getCookie());
1474                     ListenableFuture<RpcResult<Void>> resultLib = JdkFutureAdapters.listenInPoolThread(resultFromOFLib);
1475                     
1476                     Futures.addCallback(resultLib, new ResultCallback<GetFlowStatisticsFromFlowTableOutput>(result) {
1477                         @Override
1478                         public GetFlowStatisticsFromFlowTableOutput createResult() {
1479                             GetFlowStatisticsFromFlowTableOutputBuilder flowStatsFromFlowTableBuilder = 
1480                                     new GetFlowStatisticsFromFlowTableOutputBuilder()
1481                             .setTransactionId(new TransactionId(BigInteger.valueOf(xid)));
1482                             return flowStatsFromFlowTableBuilder.build();
1483                         }
1484                     });
1485                     return result;
1486                 }
1487         };
1488         return task;
1489     }
1490     
1491     /**
1492      * @param taskContext
1493      * @param input
1494      * @param cookie
1495      * @return task
1496      */
1497     public static OFRpcTask<GetAggregateFlowStatisticsFromFlowTableForAllFlowsInput, RpcResult<GetAggregateFlowStatisticsFromFlowTableForAllFlowsOutput>> 
1498                                                     createGetAggregateFlowStatisticsFromFlowTableForAllFlowsTask(
1499             final OFRpcTaskContext taskContext, 
1500             final GetAggregateFlowStatisticsFromFlowTableForAllFlowsInput input,SwitchConnectionDistinguisher cookie) {
1501         OFRpcTask<GetAggregateFlowStatisticsFromFlowTableForAllFlowsInput, RpcResult<GetAggregateFlowStatisticsFromFlowTableForAllFlowsOutput>> task = 
1502         new OFRpcTask<GetAggregateFlowStatisticsFromFlowTableForAllFlowsInput, RpcResult<GetAggregateFlowStatisticsFromFlowTableForAllFlowsOutput>>(taskContext, cookie, input) {
1503
1504         @Override
1505         public ListenableFuture<RpcResult<GetAggregateFlowStatisticsFromFlowTableForAllFlowsOutput>> call() throws Exception {
1506             final SettableFuture<RpcResult<GetAggregateFlowStatisticsFromFlowTableForAllFlowsOutput>> result = SettableFuture.create();
1507             
1508                 final Long xid = taskContext.getSession().getNextXid();
1509                 
1510              // Create multipart request body for fetch all the group stats
1511                 MultipartRequestAggregateCaseBuilder multipartRequestAggregateCaseBuilder = new MultipartRequestAggregateCaseBuilder();
1512                 MultipartRequestAggregateBuilder mprAggregateRequestBuilder = new MultipartRequestAggregateBuilder();
1513                 mprAggregateRequestBuilder.setTableId(input.getTableId().getValue());
1514                 mprAggregateRequestBuilder.setOutPort(OFConstants.OFPP_ANY);
1515                 mprAggregateRequestBuilder.setOutGroup(OFConstants.OFPG_ANY);
1516                 mprAggregateRequestBuilder.setCookie(OFConstants.DEFAULT_COOKIE);
1517                 mprAggregateRequestBuilder.setCookieMask(OFConstants.DEFAULT_COOKIE_MASK);
1518
1519                 FlowCreatorUtil.setWildcardedFlowMatch(taskContext.getSession()
1520                         .getPrimaryConductor().getVersion(), mprAggregateRequestBuilder);
1521
1522                 // Set request body to main multipart request
1523                 multipartRequestAggregateCaseBuilder.setMultipartRequestAggregate(mprAggregateRequestBuilder.build());
1524                 MultipartRequestInputBuilder mprInput = 
1525                         createMultipartHeader(MultipartType.OFPMPAGGREGATE, taskContext, xid);
1526                 mprInput.setMultipartRequestBody(multipartRequestAggregateCaseBuilder.build());
1527                 Future<RpcResult<Void>> resultFromOFLib = getMessageService()
1528                         .multipartRequest(mprInput.build(), getCookie());
1529                 ListenableFuture<RpcResult<Void>> resultLib = JdkFutureAdapters.listenInPoolThread(resultFromOFLib);
1530                 
1531                 Futures.addCallback(resultLib, new ResultCallback<GetAggregateFlowStatisticsFromFlowTableForAllFlowsOutput>(result) {
1532                     @Override
1533                     public GetAggregateFlowStatisticsFromFlowTableForAllFlowsOutput createResult() {
1534                         GetAggregateFlowStatisticsFromFlowTableForAllFlowsOutputBuilder flowStatsFromFlowTableBuilder = 
1535                                 new GetAggregateFlowStatisticsFromFlowTableForAllFlowsOutputBuilder()
1536                         .setTransactionId(new TransactionId(BigInteger.valueOf(xid)));
1537                         return flowStatsFromFlowTableBuilder.build();
1538                     }
1539                 });
1540                 return result;
1541             }
1542         };
1543         return task;
1544     }
1545     
1546     /**
1547      * @param taskContext
1548      * @param input
1549      * @param cookie
1550      * @return task
1551      */
1552     public static OFRpcTask<GetAggregateFlowStatisticsFromFlowTableForGivenMatchInput, RpcResult<GetAggregateFlowStatisticsFromFlowTableForGivenMatchOutput>> 
1553                                                     createGetAggregateFlowStatisticsFromFlowTableForGivenMatchTask(
1554             final OFRpcTaskContext taskContext, 
1555             final GetAggregateFlowStatisticsFromFlowTableForGivenMatchInput input,SwitchConnectionDistinguisher cookie) {
1556         OFRpcTask<GetAggregateFlowStatisticsFromFlowTableForGivenMatchInput, RpcResult<GetAggregateFlowStatisticsFromFlowTableForGivenMatchOutput>> task = 
1557         new OFRpcTask<GetAggregateFlowStatisticsFromFlowTableForGivenMatchInput, RpcResult<GetAggregateFlowStatisticsFromFlowTableForGivenMatchOutput>>(taskContext, cookie, input) {
1558
1559         @Override
1560         public ListenableFuture<RpcResult<GetAggregateFlowStatisticsFromFlowTableForGivenMatchOutput>> call() throws Exception {
1561             final SettableFuture<RpcResult<GetAggregateFlowStatisticsFromFlowTableForGivenMatchOutput>> result = SettableFuture.create();
1562             
1563                 final Long xid = taskContext.getSession().getNextXid();
1564                 
1565                 MultipartRequestAggregateCaseBuilder multipartRequestAggregateCaseBuilder = new MultipartRequestAggregateCaseBuilder();
1566                 MultipartRequestAggregateBuilder mprAggregateRequestBuilder = new MultipartRequestAggregateBuilder();
1567                 mprAggregateRequestBuilder.setTableId(input.getTableId());
1568                 mprAggregateRequestBuilder.setOutPort(input.getOutPort().longValue());
1569              // TODO: repeating code
1570                 if (taskContext.getSession().getPrimaryConductor().getVersion() == 
1571                                                                 OFConstants.OFP_VERSION_1_3) {
1572                     mprAggregateRequestBuilder.setCookie(input.getCookie().getValue());
1573                     mprAggregateRequestBuilder.setCookieMask(input.getCookieMask().getValue());
1574                     mprAggregateRequestBuilder.setOutGroup(input.getOutGroup());
1575                 } else {
1576                     mprAggregateRequestBuilder.setOutGroup(OFConstants.OFPG_ANY);
1577                     mprAggregateRequestBuilder.setCookie(OFConstants.DEFAULT_COOKIE);
1578                     mprAggregateRequestBuilder.setCookieMask(OFConstants.DEFAULT_COOKIE_MASK);
1579                 }
1580                 
1581                 MatchReactor.getInstance().convert(input.getMatch(), taskContext.getSession()
1582                         .getPrimaryConductor().getVersion(), mprAggregateRequestBuilder,
1583                         taskContext.getSession().getFeatures().getDatapathId());
1584
1585                 FlowCreatorUtil.setWildcardedFlowMatch(taskContext.getSession()
1586                         .getPrimaryConductor().getVersion(), mprAggregateRequestBuilder);
1587
1588                 // Set request body to main multipart request
1589                 multipartRequestAggregateCaseBuilder.setMultipartRequestAggregate(mprAggregateRequestBuilder.build());
1590                 MultipartRequestInputBuilder mprInput = 
1591                         createMultipartHeader(MultipartType.OFPMPAGGREGATE, taskContext, xid);
1592                 mprInput.setMultipartRequestBody(multipartRequestAggregateCaseBuilder.build());
1593                 Future<RpcResult<Void>> resultFromOFLib = getMessageService()
1594                         .multipartRequest(mprInput.build(), getCookie());
1595                 ListenableFuture<RpcResult<Void>> resultLib = JdkFutureAdapters.listenInPoolThread(resultFromOFLib);
1596                 
1597                 Futures.addCallback(resultLib, new ResultCallback<GetAggregateFlowStatisticsFromFlowTableForGivenMatchOutput>(result) {
1598                     @Override
1599                     public GetAggregateFlowStatisticsFromFlowTableForGivenMatchOutput createResult() {
1600                         GetAggregateFlowStatisticsFromFlowTableForGivenMatchOutputBuilder aggregFlowStatsFromFlowTableBuilder = 
1601                                 new GetAggregateFlowStatisticsFromFlowTableForGivenMatchOutputBuilder()
1602                         .setTransactionId(new TransactionId(BigInteger.valueOf(xid)));
1603                         return aggregFlowStatsFromFlowTableBuilder.build();
1604                     }
1605                 });
1606                 return result;
1607             }
1608         };
1609         return task;
1610     }
1611     
1612     /**
1613      * @param taskContext
1614      * @param input
1615      * @param cookie
1616      * @return task
1617      */
1618     public static OFRpcTask<GetFlowTablesStatisticsInput, RpcResult<GetFlowTablesStatisticsOutput>> createGetFlowTablesStatisticsTask(
1619             final OFRpcTaskContext taskContext, final GetFlowTablesStatisticsInput input,SwitchConnectionDistinguisher cookie) {
1620         OFRpcTask<GetFlowTablesStatisticsInput, RpcResult<GetFlowTablesStatisticsOutput>> task = 
1621         new OFRpcTask<GetFlowTablesStatisticsInput, RpcResult<GetFlowTablesStatisticsOutput>>(taskContext, cookie, input) {
1622
1623         @Override
1624         public ListenableFuture<RpcResult<GetFlowTablesStatisticsOutput>> call() throws Exception {
1625             final SettableFuture<RpcResult<GetFlowTablesStatisticsOutput>> result = SettableFuture.create();
1626             
1627                 final Long xid = taskContext.getSession().getNextXid();
1628                 
1629              // Create multipart request body for fetch all the group stats
1630                 MultipartRequestTableCaseBuilder multipartRequestTableCaseBuilder = new MultipartRequestTableCaseBuilder();
1631                 MultipartRequestTableBuilder multipartRequestTableBuilder = new MultipartRequestTableBuilder();
1632                 multipartRequestTableBuilder.setEmpty(true);
1633                 multipartRequestTableCaseBuilder.setMultipartRequestTable(multipartRequestTableBuilder.build());
1634
1635                 // Set request body to main multipart request
1636                 MultipartRequestInputBuilder mprInput = 
1637                         createMultipartHeader(MultipartType.OFPMPTABLE, taskContext, xid);
1638                 mprInput.setMultipartRequestBody(multipartRequestTableCaseBuilder.build());
1639                 Future<RpcResult<Void>> resultFromOFLib = getMessageService()
1640                         .multipartRequest(mprInput.build(), getCookie());
1641                 ListenableFuture<RpcResult<Void>> resultLib = JdkFutureAdapters.listenInPoolThread(resultFromOFLib);
1642                 
1643                 Futures.addCallback(resultLib, new ResultCallback<GetFlowTablesStatisticsOutput>(result) {
1644                     @Override
1645                     public GetFlowTablesStatisticsOutput createResult() {
1646                         GetFlowTablesStatisticsOutputBuilder flowTableStatsBuilder = 
1647                                 new GetFlowTablesStatisticsOutputBuilder()
1648                         .setTransactionId(new TransactionId(BigInteger.valueOf(xid)));
1649                         return flowTableStatsBuilder.build();
1650                     }
1651                 });
1652                 return result;
1653             }
1654         };
1655         return task;
1656     }
1657     
1658     /**
1659      * @param taskContext
1660      * @param input
1661      * @param cookie
1662      * @return task
1663      */
1664     public static OFRpcTask<GetAllQueuesStatisticsFromAllPortsInput, RpcResult<GetAllQueuesStatisticsFromAllPortsOutput>> createGetAllQueuesStatisticsFromAllPortsTask(
1665             final OFRpcTaskContext taskContext, final GetAllQueuesStatisticsFromAllPortsInput input,SwitchConnectionDistinguisher cookie) {
1666         OFRpcTask<GetAllQueuesStatisticsFromAllPortsInput, RpcResult<GetAllQueuesStatisticsFromAllPortsOutput>> task = 
1667         new OFRpcTask<GetAllQueuesStatisticsFromAllPortsInput, RpcResult<GetAllQueuesStatisticsFromAllPortsOutput>>(taskContext, cookie, input) {
1668
1669         @Override
1670         public ListenableFuture<RpcResult<GetAllQueuesStatisticsFromAllPortsOutput>> call() throws Exception {
1671             final SettableFuture<RpcResult<GetAllQueuesStatisticsFromAllPortsOutput>> result = SettableFuture.create();
1672             
1673             final Long xid = taskContext.getSession().getNextXid();
1674             
1675             MultipartRequestQueueCaseBuilder caseBuilder = new MultipartRequestQueueCaseBuilder();
1676             MultipartRequestQueueBuilder mprQueueBuilder = new MultipartRequestQueueBuilder();
1677             // Select all ports
1678             mprQueueBuilder.setPortNo(OFConstants.OFPP_ANY);
1679             // Select all the ports
1680             mprQueueBuilder.setQueueId(OFConstants.OFPQ_ANY);
1681             caseBuilder.setMultipartRequestQueue(mprQueueBuilder.build());
1682
1683             // Set request body to main multipart request
1684             MultipartRequestInputBuilder mprInput = 
1685                     createMultipartHeader(MultipartType.OFPMPQUEUE, taskContext, xid);
1686             mprInput.setMultipartRequestBody(caseBuilder.build());
1687             Future<RpcResult<Void>> resultFromOFLib = getMessageService()
1688                     .multipartRequest(mprInput.build(), getCookie());
1689             ListenableFuture<RpcResult<Void>> resultLib = JdkFutureAdapters.listenInPoolThread(resultFromOFLib);
1690             
1691             Futures.addCallback(resultLib, new ResultCallback<GetAllQueuesStatisticsFromAllPortsOutput>(result) {
1692                 @Override
1693                 public GetAllQueuesStatisticsFromAllPortsOutput createResult() {
1694                     GetAllQueuesStatisticsFromAllPortsOutputBuilder allQueueStatsBuilder = 
1695                             new GetAllQueuesStatisticsFromAllPortsOutputBuilder()
1696                     .setTransactionId(new TransactionId(BigInteger.valueOf(xid)));
1697                     return allQueueStatsBuilder.build();
1698                 }
1699             });
1700             return result;
1701         }
1702        };
1703         return task;
1704     }
1705     
1706     /**
1707      * @param taskContext
1708      * @param input
1709      * @param cookie
1710      * @return task
1711      */
1712     public static OFRpcTask<GetAllQueuesStatisticsFromGivenPortInput, RpcResult<GetAllQueuesStatisticsFromGivenPortOutput>> createGetAllQueuesStatisticsFromGivenPortTask(
1713             final OFRpcTaskContext taskContext, final GetAllQueuesStatisticsFromGivenPortInput input,SwitchConnectionDistinguisher cookie) {
1714         OFRpcTask<GetAllQueuesStatisticsFromGivenPortInput, RpcResult<GetAllQueuesStatisticsFromGivenPortOutput>> task = 
1715         new OFRpcTask<GetAllQueuesStatisticsFromGivenPortInput, RpcResult<GetAllQueuesStatisticsFromGivenPortOutput>>(taskContext, cookie, input) {
1716
1717         @Override
1718         public ListenableFuture<RpcResult<GetAllQueuesStatisticsFromGivenPortOutput>> call() throws Exception {
1719             final SettableFuture<RpcResult<GetAllQueuesStatisticsFromGivenPortOutput>> result = SettableFuture.create();
1720             
1721             final Long xid = taskContext.getSession().getNextXid();
1722             
1723             MultipartRequestQueueCaseBuilder caseBuilder = new MultipartRequestQueueCaseBuilder();
1724             MultipartRequestQueueBuilder mprQueueBuilder = new MultipartRequestQueueBuilder();
1725             // Select all queues
1726             mprQueueBuilder.setQueueId(OFConstants.OFPQ_ANY);
1727             // Select specific port
1728             mprQueueBuilder.setPortNo(InventoryDataServiceUtil.portNumberfromNodeConnectorId(
1729                     OpenflowVersion.get(taskContext.getSession().getFeatures().getVersion()),
1730                     input.getNodeConnectorId()));
1731             caseBuilder.setMultipartRequestQueue(mprQueueBuilder.build());
1732
1733             // Set request body to main multipart request
1734             MultipartRequestInputBuilder mprInput = 
1735                     createMultipartHeader(MultipartType.OFPMPQUEUE, taskContext, xid);
1736             mprInput.setMultipartRequestBody(caseBuilder.build());
1737             Future<RpcResult<Void>> resultFromOFLib = getMessageService()
1738                     .multipartRequest(mprInput.build(), getCookie());
1739             ListenableFuture<RpcResult<Void>> resultLib = JdkFutureAdapters.listenInPoolThread(resultFromOFLib);
1740             
1741             Futures.addCallback(resultLib, new ResultCallback<GetAllQueuesStatisticsFromGivenPortOutput>(result) {
1742                 @Override
1743                 public GetAllQueuesStatisticsFromGivenPortOutput createResult() {
1744                     GetAllQueuesStatisticsFromGivenPortOutputBuilder allQueueStatsBuilder = 
1745                             new GetAllQueuesStatisticsFromGivenPortOutputBuilder()
1746                     .setTransactionId(new TransactionId(BigInteger.valueOf(xid)));
1747                     return allQueueStatsBuilder.build();
1748                 }
1749             });
1750             return result;
1751         }
1752        };
1753         return task;
1754     }
1755     
1756     /**
1757      * @param taskContext
1758      * @param input
1759      * @param cookie
1760      * @return task
1761      */
1762     public static OFRpcTask<GetQueueStatisticsFromGivenPortInput, RpcResult<GetQueueStatisticsFromGivenPortOutput>> createGetQueueStatisticsFromGivenPortTask(
1763             final OFRpcTaskContext taskContext, final GetQueueStatisticsFromGivenPortInput input,SwitchConnectionDistinguisher cookie) {
1764         OFRpcTask<GetQueueStatisticsFromGivenPortInput, RpcResult<GetQueueStatisticsFromGivenPortOutput>> task = 
1765         new OFRpcTask<GetQueueStatisticsFromGivenPortInput, RpcResult<GetQueueStatisticsFromGivenPortOutput>>(taskContext, cookie, input) {
1766
1767         @Override
1768         public ListenableFuture<RpcResult<GetQueueStatisticsFromGivenPortOutput>> call() throws Exception {
1769             final SettableFuture<RpcResult<GetQueueStatisticsFromGivenPortOutput>> result = SettableFuture.create();
1770             
1771             final Long xid = taskContext.getSession().getNextXid();
1772             
1773             MultipartRequestQueueCaseBuilder caseBuilder = new MultipartRequestQueueCaseBuilder();
1774             MultipartRequestQueueBuilder mprQueueBuilder = new MultipartRequestQueueBuilder();
1775             // Select specific queue
1776             mprQueueBuilder.setQueueId(input.getQueueId().getValue());
1777             // Select specific port
1778             mprQueueBuilder.setPortNo(InventoryDataServiceUtil.portNumberfromNodeConnectorId(
1779                     OpenflowVersion.get(taskContext.getSession().getFeatures().getVersion()),
1780                     input.getNodeConnectorId()));
1781             caseBuilder.setMultipartRequestQueue(mprQueueBuilder.build());
1782
1783             // Set request body to main multipart request
1784             MultipartRequestInputBuilder mprInput = 
1785                     createMultipartHeader(MultipartType.OFPMPQUEUE, taskContext, xid);
1786             mprInput.setMultipartRequestBody(caseBuilder.build());
1787             Future<RpcResult<Void>> resultFromOFLib = getMessageService()
1788                     .multipartRequest(mprInput.build(), getCookie());
1789             ListenableFuture<RpcResult<Void>> resultLib = JdkFutureAdapters.listenInPoolThread(resultFromOFLib);
1790             
1791             Futures.addCallback(resultLib, new ResultCallback<GetQueueStatisticsFromGivenPortOutput>(result) {
1792                 @Override
1793                 public GetQueueStatisticsFromGivenPortOutput createResult() {
1794                     GetQueueStatisticsFromGivenPortOutputBuilder queueStatsFromPortBuilder = 
1795                             new GetQueueStatisticsFromGivenPortOutputBuilder()
1796                     .setTransactionId(new TransactionId(BigInteger.valueOf(xid)));
1797                     return queueStatsFromPortBuilder.build();
1798                 }
1799             });
1800             return result;
1801         }
1802        };
1803         return task;
1804     }
1805     
1806     static MultipartRequestInputBuilder createMultipartHeader(MultipartType multipart, 
1807             OFRpcTaskContext taskContext, Long xid) {
1808         MultipartRequestInputBuilder mprInput = new MultipartRequestInputBuilder();
1809         mprInput.setType(multipart);
1810         mprInput.setVersion(taskContext.getSession().getPrimaryConductor().getVersion());
1811         mprInput.setXid(xid);
1812         mprInput.setFlags(new MultipartRequestFlags(false));
1813         return mprInput;
1814     }
1815     
1816     private static abstract class ResultCallback<T> implements FutureCallback<RpcResult<Void>> {
1817         
1818         private SettableFuture<RpcResult<T>> result;
1819
1820         /**
1821          * @param result
1822          */
1823         public ResultCallback(SettableFuture<RpcResult<T>> result) {
1824             this.result = result;
1825         }
1826
1827         public abstract T createResult();
1828
1829         @Override
1830         public void onSuccess(RpcResult<Void> resultArg) {
1831             Collection<RpcError> errors = Collections.emptyList();
1832             result.set(Rpcs.getRpcResult(true, createResult(), errors));
1833         }
1834
1835         @Override
1836         public void onFailure(Throwable t) {
1837             result.set(Rpcs.<T>getRpcResult(false, 
1838                     Collections.singletonList(RpcErrors.getRpcError(OFConstants.APPLICATION_TAG, 
1839                             OFConstants.ERROR_TAG_TIMEOUT, 
1840                             "something wrong happened", ErrorSeverity.WARNING, "", 
1841                             ErrorType.RPC, t))));
1842         }
1843     }
1844     
1845     /**
1846      * @param taskContext
1847      * @param input
1848      * @param cookie
1849      * @return task
1850      */
1851     public static OFRpcTask<UpdatePortInput, RpcResult<UpdatePortOutput>> createUpdatePortTask(
1852             final OFRpcTaskContext taskContext, final UpdatePortInput input,
1853             final SwitchConnectionDistinguisher cookie) {
1854         OFRpcTask<UpdatePortInput, RpcResult<UpdatePortOutput>> task = 
1855                 new OFRpcTask<UpdatePortInput, RpcResult<UpdatePortOutput>>(taskContext, cookie, input) {
1856             
1857             @Override
1858             public ListenableFuture<RpcResult<UpdatePortOutput>> call() {
1859                 ListenableFuture<RpcResult<UpdatePortOutput>> result = SettableFuture.create();
1860                 final Long xid = taskContext.getSession().getNextXid();
1861                 Port inputPort = input.getUpdatedPort().getPort().getPort().get(0);
1862                 
1863                     PortModInput ofPortModInput = PortConvertor.toPortModInput(inputPort, 
1864                             taskContext.getSession().getPrimaryConductor().getVersion());
1865
1866                     PortModInputBuilder mdInput = new PortModInputBuilder(ofPortModInput);
1867                     mdInput.setXid(xid);
1868
1869                     Future<RpcResult<UpdatePortOutput>> resultFromOFLib = getMessageService()
1870                             .portMod(mdInput.build(), cookie);
1871                     result = JdkFutureAdapters.listenInPoolThread(resultFromOFLib);
1872
1873                 return result;
1874             }
1875         };
1876         
1877         return task;
1878         
1879     }
1880     
1881     /**
1882      * @param taskContext
1883      * @param input
1884      * @param cookie
1885      * @return task
1886      */
1887     public static OFRpcTask<UpdateTableInput, RpcResult<UpdateTableOutput>> createUpdateTableTask(
1888             final OFRpcTaskContext taskContext, final UpdateTableInput input,
1889             final SwitchConnectionDistinguisher cookie) {
1890         OFRpcTask<UpdateTableInput, RpcResult<UpdateTableOutput>> task = 
1891                 new OFRpcTask<UpdateTableInput, RpcResult<UpdateTableOutput>>(taskContext, cookie, input) {
1892             
1893             @Override
1894             public ListenableFuture<RpcResult<UpdateTableOutput>> call() {
1895                 final SettableFuture<RpcResult<UpdateTableOutput>> result = SettableFuture.create();
1896                 
1897                 final Long xid = taskContext.getSession().getNextXid();
1898                 
1899                 MultipartRequestTableFeaturesCaseBuilder caseBuilder = new MultipartRequestTableFeaturesCaseBuilder();
1900                 MultipartRequestTableFeaturesBuilder requestBuilder = new MultipartRequestTableFeaturesBuilder();
1901                 List<TableFeatures> ofTableFeatureList = TableFeaturesConvertor
1902                         .toTableFeaturesRequest(input.getUpdatedTable());
1903                 requestBuilder.setTableFeatures(ofTableFeatureList);
1904                 caseBuilder.setMultipartRequestTableFeatures(requestBuilder.build());
1905                 
1906                 // Set request body to main multipart request
1907                 MultipartRequestInputBuilder mprInput = 
1908                         createMultipartHeader(MultipartType.OFPMPTABLEFEATURES, taskContext, xid);
1909                 mprInput.setMultipartRequestBody(caseBuilder.build());
1910                 
1911                 Future<RpcResult<Void>> resultFromOFLib = getMessageService()
1912                         .multipartRequest(mprInput.build(), getCookie());
1913                 ListenableFuture<RpcResult<Void>> resultLib = JdkFutureAdapters.listenInPoolThread(resultFromOFLib);
1914                 
1915                 Futures.addCallback(resultLib, new ResultCallback<UpdateTableOutput>(result) {
1916                     @Override
1917                     public UpdateTableOutput createResult() {
1918                         UpdateTableOutputBuilder queueStatsFromPortBuilder = 
1919                                 new UpdateTableOutputBuilder()
1920                         .setTransactionId(new TransactionId(BigInteger.valueOf(xid)));
1921                         return queueStatsFromPortBuilder.build();
1922                     }
1923                 });
1924                 return result;
1925             }
1926         };
1927         return task;
1928     }
1929     
1930 }