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