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