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