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