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