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