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