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