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