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