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