59affaf88a6aaa4f080ba87b219aebd372da5e29
[openflowplugin.git] / openflowplugin / src / main / java / org / opendaylight / openflowplugin / openflow / md / core / sal / ModelDrivenSwitchImpl.java
1 /**
2  * Copyright (c) 2013 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 java.math.BigInteger;
11 import java.util.ArrayList;
12 import java.util.Collection;
13 import java.util.Collections;
14 import java.util.List;
15 import java.util.concurrent.Future;
16 import java.util.concurrent.TimeUnit;
17
18 import org.opendaylight.controller.sal.binding.api.NotificationProviderService;
19 import org.opendaylight.controller.sal.common.util.Rpcs;
20 import org.opendaylight.openflowjava.protocol.api.util.BinContent;
21 import org.opendaylight.openflowplugin.openflow.md.OFConstants;
22 import org.opendaylight.openflowplugin.openflow.md.core.SwitchConnectionDistinguisher;
23 import org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.FlowConvertor;
24 import org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.GroupConvertor;
25 import org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.MeterConvertor;
26 import org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.PacketOutConvertor;
27 import org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.PortConvertor;
28 import org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.TableFeaturesConvertor;
29 import org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.match.MatchReactor;
30 import org.opendaylight.openflowplugin.openflow.md.core.session.IMessageDispatchService;
31 import org.opendaylight.openflowplugin.openflow.md.core.session.OFSessionUtil;
32 import org.opendaylight.openflowplugin.openflow.md.core.session.SessionContext;
33 import org.opendaylight.openflowplugin.openflow.md.core.session.SwitchConnectionCookieOFImpl;
34 import org.opendaylight.openflowplugin.openflow.md.util.FlowCreatorUtil;
35 import org.opendaylight.openflowplugin.openflow.md.util.InventoryDataServiceUtil;
36 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.AddFlowInput;
37 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.AddFlowOutput;
38 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.FlowRemovedBuilder;
39 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.RemoveFlowInput;
40 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.RemoveFlowOutput;
41 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.RemoveFlowOutputBuilder;
42 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.UpdateFlowInput;
43 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.UpdateFlowOutput;
44 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.GetAggregateFlowStatisticsFromFlowTableForAllFlowsInput;
45 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.GetAggregateFlowStatisticsFromFlowTableForAllFlowsOutput;
46 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.GetAggregateFlowStatisticsFromFlowTableForAllFlowsOutputBuilder;
47 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.GetAggregateFlowStatisticsFromFlowTableForGivenMatchInput;
48 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.GetAggregateFlowStatisticsFromFlowTableForGivenMatchOutput;
49 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.GetAggregateFlowStatisticsFromFlowTableForGivenMatchOutputBuilder;
50 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.GetAllFlowStatisticsFromFlowTableInput;
51 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.GetAllFlowStatisticsFromFlowTableOutput;
52 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.GetAllFlowStatisticsFromFlowTableOutputBuilder;
53 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.GetAllFlowsStatisticsFromAllFlowTablesInput;
54 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.GetAllFlowsStatisticsFromAllFlowTablesOutput;
55 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.GetAllFlowsStatisticsFromAllFlowTablesOutputBuilder;
56 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.GetFlowStatisticsFromFlowTableInput;
57 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.GetFlowStatisticsFromFlowTableOutput;
58 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.GetFlowStatisticsFromFlowTableOutputBuilder;
59 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.table.statistics.rev131215.GetFlowTablesStatisticsInput;
60 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.table.statistics.rev131215.GetFlowTablesStatisticsOutput;
61 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.table.statistics.rev131215.GetFlowTablesStatisticsOutputBuilder;
62 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.transaction.rev131103.TransactionId;
63 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.port.rev130925.port.mod.port.Port;
64 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.Flow;
65 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.service.rev130918.AddGroupInput;
66 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.service.rev130918.AddGroupOutput;
67 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.service.rev130918.GroupRemovedBuilder;
68 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.service.rev130918.RemoveGroupInput;
69 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.service.rev130918.RemoveGroupOutput;
70 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.service.rev130918.RemoveGroupOutputBuilder;
71 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.service.rev130918.UpdateGroupInput;
72 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.service.rev130918.UpdateGroupOutput;
73 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.statistics.rev131111.GetAllGroupStatisticsInput;
74 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.statistics.rev131111.GetAllGroupStatisticsOutput;
75 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.statistics.rev131111.GetAllGroupStatisticsOutputBuilder;
76 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.statistics.rev131111.GetGroupDescriptionInput;
77 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.statistics.rev131111.GetGroupDescriptionOutput;
78 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.statistics.rev131111.GetGroupDescriptionOutputBuilder;
79 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.statistics.rev131111.GetGroupFeaturesInput;
80 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.statistics.rev131111.GetGroupFeaturesOutput;
81 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.statistics.rev131111.GetGroupFeaturesOutputBuilder;
82 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.statistics.rev131111.GetGroupStatisticsInput;
83 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.statistics.rev131111.GetGroupStatisticsOutput;
84 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.statistics.rev131111.GetGroupStatisticsOutputBuilder;
85 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeId;
86 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node;
87 import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.service.rev130918.AddMeterInput;
88 import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.service.rev130918.AddMeterOutput;
89 import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.service.rev130918.MeterRemovedBuilder;
90 import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.service.rev130918.RemoveMeterInput;
91 import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.service.rev130918.RemoveMeterOutput;
92 import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.service.rev130918.RemoveMeterOutputBuilder;
93 import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.service.rev130918.UpdateMeterInput;
94 import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.service.rev130918.UpdateMeterOutput;
95 import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.statistics.rev131111.GetAllMeterConfigStatisticsInput;
96 import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.statistics.rev131111.GetAllMeterConfigStatisticsOutput;
97 import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.statistics.rev131111.GetAllMeterConfigStatisticsOutputBuilder;
98 import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.statistics.rev131111.GetAllMeterStatisticsInput;
99 import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.statistics.rev131111.GetAllMeterStatisticsOutput;
100 import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.statistics.rev131111.GetAllMeterStatisticsOutputBuilder;
101 import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.statistics.rev131111.GetMeterFeaturesInput;
102 import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.statistics.rev131111.GetMeterFeaturesOutput;
103 import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.statistics.rev131111.GetMeterFeaturesOutputBuilder;
104 import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.statistics.rev131111.GetMeterStatisticsInput;
105 import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.statistics.rev131111.GetMeterStatisticsOutput;
106 import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.statistics.rev131111.GetMeterStatisticsOutputBuilder;
107 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.Group;
108 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.GroupId;
109 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.Meter;
110 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.MeterId;
111 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.MultipartRequestFlags;
112 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.MultipartType;
113 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev130731.match.grouping.Match;
114 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev130731.match.grouping.MatchBuilder;
115 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev130731.oxm.fields.grouping.MatchEntries;
116 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.BarrierInputBuilder;
117 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.BarrierOutput;
118 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.FlowModInputBuilder;
119 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.GroupModInputBuilder;
120 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.MeterModInputBuilder;
121 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.MultipartRequestInputBuilder;
122 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.PacketOutInput;
123 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.PortModInput;
124 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.PortModInputBuilder;
125 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.MultipartRequestAggregateCaseBuilder;
126 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.MultipartRequestFlowCaseBuilder;
127 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.MultipartRequestGroupCaseBuilder;
128 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.MultipartRequestGroupDescCaseBuilder;
129 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.MultipartRequestGroupFeaturesCaseBuilder;
130 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.MultipartRequestMeterCaseBuilder;
131 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.MultipartRequestMeterConfigCaseBuilder;
132 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.MultipartRequestMeterFeaturesCaseBuilder;
133 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.MultipartRequestPortStatsCaseBuilder;
134 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.MultipartRequestQueueCaseBuilder;
135 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.MultipartRequestTableCaseBuilder;
136 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.MultipartRequestTableFeaturesCaseBuilder;
137 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.multipart.request.aggregate._case.MultipartRequestAggregateBuilder;
138 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.multipart.request.flow._case.MultipartRequestFlowBuilder;
139 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.multipart.request.group._case.MultipartRequestGroupBuilder;
140 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.multipart.request.meter._case.MultipartRequestMeterBuilder;
141 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.multipart.request.meter.config._case.MultipartRequestMeterConfigBuilder;
142 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.multipart.request.port.stats._case.MultipartRequestPortStatsBuilder;
143 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.multipart.request.queue._case.MultipartRequestQueueBuilder;
144 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.multipart.request.table._case.MultipartRequestTableBuilder;
145 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.multipart.request.table.features._case.MultipartRequestTableFeaturesBuilder;
146 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;
147 import org.opendaylight.yang.gen.v1.urn.opendaylight.packet.service.rev130709.ConnectionCookie;
148 import org.opendaylight.yang.gen.v1.urn.opendaylight.packet.service.rev130709.TransmitPacketInput;
149 import org.opendaylight.yang.gen.v1.urn.opendaylight.port.service.rev131107.UpdatePortInput;
150 import org.opendaylight.yang.gen.v1.urn.opendaylight.port.service.rev131107.UpdatePortOutput;
151 import org.opendaylight.yang.gen.v1.urn.opendaylight.port.service.rev131107.UpdatePortOutputBuilder;
152 import org.opendaylight.yang.gen.v1.urn.opendaylight.port.statistics.rev131214.GetAllNodeConnectorsStatisticsInput;
153 import org.opendaylight.yang.gen.v1.urn.opendaylight.port.statistics.rev131214.GetAllNodeConnectorsStatisticsOutput;
154 import org.opendaylight.yang.gen.v1.urn.opendaylight.port.statistics.rev131214.GetAllNodeConnectorsStatisticsOutputBuilder;
155 import org.opendaylight.yang.gen.v1.urn.opendaylight.port.statistics.rev131214.GetNodeConnectorStatisticsInput;
156 import org.opendaylight.yang.gen.v1.urn.opendaylight.port.statistics.rev131214.GetNodeConnectorStatisticsOutput;
157 import org.opendaylight.yang.gen.v1.urn.opendaylight.port.statistics.rev131214.GetNodeConnectorStatisticsOutputBuilder;
158 import org.opendaylight.yang.gen.v1.urn.opendaylight.queue.statistics.rev131216.GetAllQueuesStatisticsFromAllPortsInput;
159 import org.opendaylight.yang.gen.v1.urn.opendaylight.queue.statistics.rev131216.GetAllQueuesStatisticsFromAllPortsOutput;
160 import org.opendaylight.yang.gen.v1.urn.opendaylight.queue.statistics.rev131216.GetAllQueuesStatisticsFromAllPortsOutputBuilder;
161 import org.opendaylight.yang.gen.v1.urn.opendaylight.queue.statistics.rev131216.GetAllQueuesStatisticsFromGivenPortInput;
162 import org.opendaylight.yang.gen.v1.urn.opendaylight.queue.statistics.rev131216.GetAllQueuesStatisticsFromGivenPortOutput;
163 import org.opendaylight.yang.gen.v1.urn.opendaylight.queue.statistics.rev131216.GetAllQueuesStatisticsFromGivenPortOutputBuilder;
164 import org.opendaylight.yang.gen.v1.urn.opendaylight.queue.statistics.rev131216.GetQueueStatisticsFromGivenPortInput;
165 import org.opendaylight.yang.gen.v1.urn.opendaylight.queue.statistics.rev131216.GetQueueStatisticsFromGivenPortOutput;
166 import org.opendaylight.yang.gen.v1.urn.opendaylight.queue.statistics.rev131216.GetQueueStatisticsFromGivenPortOutputBuilder;
167 import org.opendaylight.yang.gen.v1.urn.opendaylight.table.service.rev131026.UpdateTableInput;
168 import org.opendaylight.yang.gen.v1.urn.opendaylight.table.service.rev131026.UpdateTableOutput;
169 import org.opendaylight.yang.gen.v1.urn.opendaylight.table.service.rev131026.UpdateTableOutputBuilder;
170 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
171 import org.opendaylight.yangtools.yang.common.RpcError;
172 import org.opendaylight.yangtools.yang.common.RpcResult;
173 import org.slf4j.Logger;
174
175 import com.google.common.base.Objects;
176 import com.google.common.util.concurrent.Futures;
177 import com.google.common.util.concurrent.JdkFutureAdapters;
178 import com.google.common.util.concurrent.ListenableFuture;
179
180 /**
181  * RPC implementation of MD-switch
182  */
183 public class ModelDrivenSwitchImpl extends AbstractModelDrivenSwitch {
184
185     private static final Logger LOG = org.slf4j.LoggerFactory.getLogger(ModelDrivenSwitchImpl.class);
186     private final NodeId nodeId;
187     private final IMessageDispatchService messageService;
188     private short version = 0;
189     private NotificationProviderService rpcNotificationProviderService;
190     private OFRpcTaskContext rpcTaskContext;
191     
192     // TODO:read timeout from configSubsystem
193     protected long maxTimeout = 1000;
194     protected TimeUnit maxTimeoutUnit = TimeUnit.MILLISECONDS;
195     
196     protected ModelDrivenSwitchImpl(final NodeId nodeId, final InstanceIdentifier<Node> identifier, 
197             final SessionContext sessionContext) {
198         super(identifier, sessionContext);
199         this.nodeId = nodeId;
200         messageService = sessionContext.getMessageDispatchService();
201         version = sessionContext.getPrimaryConductor().getVersion();
202         rpcNotificationProviderService = OFSessionUtil.getSessionManager().getNotificationProviderService();
203         
204         rpcTaskContext = new OFRpcTaskContext();
205         rpcTaskContext.setSession(sessionContext);
206         rpcTaskContext.setMessageService(messageService);
207         rpcTaskContext.setRpcNotificationProviderService(rpcNotificationProviderService);
208         rpcTaskContext.setMaxTimeout(maxTimeout);
209         rpcTaskContext.setMaxTimeoutUnit(maxTimeoutUnit);
210         rpcTaskContext.setRpcPool(OFSessionUtil.getSessionManager().getRpcPool());
211         rpcTaskContext.setMessageSpy(OFSessionUtil.getSessionManager().getMessageSpy());
212     }
213
214     @Override
215     public Future<RpcResult<AddFlowOutput>> addFlow(final AddFlowInput input) {
216         LOG.debug("Calling the FlowMod RPC method on MessageDispatchService");
217         // use primary connection
218         SwitchConnectionDistinguisher cookie = null;
219         
220         OFRpcTask<AddFlowInput, RpcResult<UpdateFlowOutput>> task = 
221                 OFRpcTaskFactory.createAddFlowTask(rpcTaskContext, input, cookie);
222         ListenableFuture<RpcResult<UpdateFlowOutput>> result = task.submit();
223         
224         return Futures.transform(JdkFutureAdapters.listenInPoolThread(result), 
225                 OFRpcFutureResultTransformFactory.createForAddFlowOutput());
226     }
227
228
229     @Override
230     public Future<RpcResult<AddGroupOutput>> addGroup(final AddGroupInput input) {
231         LOG.debug("Calling the GroupMod RPC method on MessageDispatchService");
232         
233         // use primary connection
234         SwitchConnectionDistinguisher cookie = null;
235         
236         OFRpcTask<AddGroupInput, RpcResult<UpdateGroupOutput>> task = 
237                 OFRpcTaskFactory.createAddGroupTask(rpcTaskContext, input, cookie);
238         ListenableFuture<RpcResult<UpdateGroupOutput>> result = task.submit();
239         
240         return Futures.transform(JdkFutureAdapters.listenInPoolThread(result), 
241                 OFRpcFutureResultTransformFactory.createForAddGroupOutput());
242     }
243
244     @Override
245     public Future<RpcResult<AddMeterOutput>> addMeter(final AddMeterInput input) {
246         LOG.debug("Calling the MeterMod RPC method on MessageDispatchService");
247         
248         // use primary connection
249         SwitchConnectionDistinguisher cookie = null;
250         
251         OFRpcTask<AddMeterInput, RpcResult<UpdateMeterOutput>> task = 
252                 OFRpcTaskFactory.createAddMeterTask(rpcTaskContext, input, cookie);
253         ListenableFuture<RpcResult<UpdateMeterOutput>> result = task.submit();
254         
255         return Futures.transform(JdkFutureAdapters.listenInPoolThread(result), 
256                 OFRpcFutureResultTransformFactory.createForAddMeterOutput());
257     }
258
259     @Override
260     public Future<RpcResult<RemoveFlowOutput>> removeFlow(final RemoveFlowInput input) {
261         LOG.debug("Calling the removeFlow RPC method on MessageDispatchService");
262         Long xId = null;
263         // For Flow provisioning, the SwitchConnectionDistinguisher is set to
264         // null so
265         // the request can be routed through any connection to the switch
266
267         SwitchConnectionDistinguisher cookie = null;
268         if (Objects.firstNonNull(input.isBarrier(), Boolean.FALSE)) {
269             BarrierInputBuilder barrierInput = new BarrierInputBuilder();
270             xId = sessionContext.getNextXid();
271             barrierInput.setXid(xId);
272             barrierInput.setVersion(version);
273             @SuppressWarnings("unused")
274             Future<RpcResult<BarrierOutput>> barrierOFLib = messageService.barrier(barrierInput.build(), cookie);
275         }
276
277         // Convert the RemoveFlowInput to FlowModInput
278         FlowModInputBuilder ofFlowModInput = FlowConvertor.toFlowModInput(input, version, sessionContext
279                 .getFeatures().getDatapathId());
280         xId = sessionContext.getNextXid();
281         ofFlowModInput.setXid(xId);
282
283         if (null != rpcNotificationProviderService) {
284             FlowRemovedBuilder removeFlow = new FlowRemovedBuilder(
285                     (org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.Flow) input);
286             removeFlow.setTransactionId(new TransactionId(BigInteger.valueOf(xId.intValue())));
287             removeFlow.setFlowRef(input.getFlowRef());
288             rpcNotificationProviderService.publish(removeFlow.build());
289         }
290
291         Future<RpcResult<UpdateFlowOutput>> resultFromOFLib = messageService.flowMod(ofFlowModInput.build(), cookie);
292
293         RpcResult<UpdateFlowOutput> rpcResultFromOFLib = null;
294
295         try {
296             rpcResultFromOFLib = resultFromOFLib.get();
297         } catch (Exception ex) {
298             LOG.error(" Error while getting result for remove Flow RPC" + ex.getMessage());
299         }
300
301         UpdateFlowOutput updateFlowOutput = rpcResultFromOFLib.getResult();
302
303         RemoveFlowOutputBuilder removeFlowOutput = new RemoveFlowOutputBuilder();
304         removeFlowOutput.setTransactionId(updateFlowOutput.getTransactionId());
305         RemoveFlowOutput result = removeFlowOutput.build();
306
307         Collection<RpcError> errors = rpcResultFromOFLib.getErrors();
308         RpcResult<RemoveFlowOutput> rpcResult = Rpcs.getRpcResult(true, result, errors);
309
310         LOG.debug("Returning the Remove Flow RPC result to MD-SAL");
311         return Futures.immediateFuture(rpcResult);
312     }
313
314     @Override
315     public Future<RpcResult<RemoveGroupOutput>> removeGroup(final RemoveGroupInput input) {
316         LOG.debug("Calling the Remove Group RPC method on MessageDispatchService");
317         Long xId = null;
318
319         // For Flow provisioning, the SwitchConnectionDistinguisher is set to
320         // null so
321         // the request can be routed through any connection to the switch
322
323         SwitchConnectionDistinguisher cookie = null;
324         if (Objects.firstNonNull(input.isBarrier(), Boolean.FALSE)) {
325             xId = sessionContext.getNextXid();
326             BarrierInputBuilder barrierInput = new BarrierInputBuilder();
327             barrierInput.setVersion(version);
328             barrierInput.setXid(xId);
329             @SuppressWarnings("unused")
330             Future<RpcResult<BarrierOutput>> barrierOFLib = messageService.barrier(barrierInput.build(), cookie);
331         }
332
333         // Convert the RemoveGroupInput to GroupModInput
334         GroupModInputBuilder ofGroupModInput = GroupConvertor.toGroupModInput(input, version, this.getSessionContext()
335                 .getFeatures().getDatapathId());
336         xId = sessionContext.getNextXid();
337         ofGroupModInput.setXid(xId);
338
339         if (null != rpcNotificationProviderService) {
340             GroupRemovedBuilder groupMod = new GroupRemovedBuilder(
341                     (org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.Group) input);
342             groupMod.setTransactionId(new TransactionId(BigInteger.valueOf(xId.intValue())));
343             groupMod.setGroupRef(input.getGroupRef());
344             rpcNotificationProviderService.publish(groupMod.build());
345         }
346
347         Future<RpcResult<UpdateGroupOutput>> resultFromOFLib = messageService.groupMod(ofGroupModInput.build(), cookie);
348
349         RpcResult<UpdateGroupOutput> rpcResultFromOFLib = null;
350
351         try {
352             rpcResultFromOFLib = resultFromOFLib.get();
353         } catch (Exception ex) {
354             LOG.error(" Error while getting result for RemoveGroup RPC" + ex.getMessage());
355         }
356
357         UpdateGroupOutput updateGroupOutput = rpcResultFromOFLib.getResult();
358
359         RemoveGroupOutputBuilder removeGroupOutput = new RemoveGroupOutputBuilder();
360         removeGroupOutput.setTransactionId(updateGroupOutput.getTransactionId());
361         RemoveGroupOutput result = removeGroupOutput.build();
362
363         Collection<RpcError> errors = rpcResultFromOFLib.getErrors();
364         RpcResult<RemoveGroupOutput> rpcResult = Rpcs.getRpcResult(true, result, errors);
365
366         LOG.debug("Returning the Remove Group RPC result to MD-SAL");
367         return Futures.immediateFuture(rpcResult);
368     }
369
370     @Override
371     public Future<RpcResult<RemoveMeterOutput>> removeMeter(final RemoveMeterInput input) {
372         LOG.debug("Calling the Remove MeterMod RPC method on MessageDispatchService");
373         Long xId = null;
374
375         // For Meter provisioning, the SwitchConnectionDistinguisher is set to
376         // null so
377         // the request can be routed through any connection to the switch
378         SwitchConnectionDistinguisher cookie = null;
379         if (Objects.firstNonNull(input.isBarrier(), Boolean.FALSE)) {
380             xId = sessionContext.getNextXid();
381             BarrierInputBuilder barrierInput = new BarrierInputBuilder();
382             barrierInput.setVersion(version);
383             barrierInput.setXid(xId);
384             @SuppressWarnings("unused")
385             Future<RpcResult<BarrierOutput>> barrierOFLib = messageService.barrier(barrierInput.build(), cookie);
386         }
387
388         // Convert the RemoveMeterInput to MeterModInput
389         MeterModInputBuilder ofMeterModInput = MeterConvertor.toMeterModInput(input, version);
390         xId = sessionContext.getNextXid();
391         ofMeterModInput.setXid(xId);
392
393         if (null != rpcNotificationProviderService) {
394             MeterRemovedBuilder meterMod = new MeterRemovedBuilder(
395                     (org.opendaylight.yang.gen.v1.urn.opendaylight.meter.types.rev130918.Meter) input);
396             meterMod.setTransactionId(new TransactionId(BigInteger.valueOf(xId.intValue())));
397             meterMod.setMeterRef(input.getMeterRef());
398             rpcNotificationProviderService.publish(meterMod.build());
399         }
400
401         Future<RpcResult<UpdateMeterOutput>> resultFromOFLib = messageService.meterMod(ofMeterModInput.build(), cookie);
402
403         RpcResult<UpdateMeterOutput> rpcResultFromOFLib = null;
404
405         try {
406             rpcResultFromOFLib = resultFromOFLib.get();
407         } catch (Exception ex) {
408             LOG.error(" Error while getting result for RemoveMeter RPC" + ex.getMessage());
409         }
410
411         UpdateMeterOutput updatemeterOutput = rpcResultFromOFLib.getResult();
412
413         RemoveMeterOutputBuilder removeMeterOutput = new RemoveMeterOutputBuilder();
414         removeMeterOutput.setTransactionId(updatemeterOutput.getTransactionId());
415         RemoveMeterOutput result = removeMeterOutput.build();
416
417         Collection<RpcError> errors = rpcResultFromOFLib.getErrors();
418         RpcResult<RemoveMeterOutput> rpcResult = Rpcs.getRpcResult(true, result, errors);
419
420         LOG.debug("Returning the Remove Meter RPC result to MD-SAL");
421         return Futures.immediateFuture(rpcResult);
422     }
423
424     @Override
425     public Future<RpcResult<Void>> transmitPacket(final TransmitPacketInput input) {
426         LOG.debug("TransmitPacket - {}", input);
427         // Convert TransmitPacket to PacketOutInput
428         PacketOutInput message = PacketOutConvertor.toPacketOutInput(input, version, sessionContext.getNextXid(),
429                 sessionContext.getFeatures().getDatapathId());
430
431         SwitchConnectionDistinguisher cookie = null;
432         ConnectionCookie connectionCookie = input.getConnectionCookie();
433         if (connectionCookie != null && connectionCookie.getValue() != null) {
434             cookie = new SwitchConnectionCookieOFImpl(connectionCookie.getValue());
435         }
436
437         LOG.debug("Calling the transmitPacket RPC method");
438         return messageService.packetOut(message, cookie);
439     }
440
441     private FlowModInputBuilder toFlowModInputBuilder(final Flow source) {
442         FlowModInputBuilder target = new FlowModInputBuilder();
443         target.setCookie(source.getCookie().getValue());
444         target.setIdleTimeout(source.getIdleTimeout());
445         target.setHardTimeout(source.getHardTimeout());
446         target.setMatch(toMatch(source.getMatch()));
447
448         return target;
449     }
450
451     private Match toMatch(final org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.Match match) {
452         MatchBuilder target = new MatchBuilder();
453
454         target.setMatchEntries(toMatchEntries(match));
455
456         return null;
457     }
458
459     private List<MatchEntries> toMatchEntries(
460             final org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.Match match) {
461         List<MatchEntries> entries = new ArrayList<>();
462
463         return null;
464     }
465
466     @Override
467     public Future<RpcResult<UpdateFlowOutput>> updateFlow(final UpdateFlowInput input) {
468         LOG.debug("Calling the updateFlow RPC method on MessageDispatchService");
469         
470         // use primary connection
471         SwitchConnectionDistinguisher cookie = null;
472         
473         OFRpcTask<UpdateFlowInput, RpcResult<UpdateFlowOutput>> task = 
474                 OFRpcTaskFactory.createUpdateFlowTask(rpcTaskContext, input, cookie);
475         ListenableFuture<RpcResult<UpdateFlowOutput>> result = task.submit();
476         
477         return result;
478     }
479
480     @Override
481     public Future<RpcResult<UpdateGroupOutput>> updateGroup(final UpdateGroupInput input) {
482         LOG.debug("Calling the update Group Mod RPC method on MessageDispatchService");
483         
484         // use primary connection
485         SwitchConnectionDistinguisher cookie = null;
486         
487         OFRpcTask<UpdateGroupInput, RpcResult<UpdateGroupOutput>> task = 
488                 OFRpcTaskFactory.createUpdateGroupTask(rpcTaskContext, input, cookie);
489         ListenableFuture<RpcResult<UpdateGroupOutput>> result = task.submit();
490         
491         return result;
492     }
493
494     @Override
495     public Future<RpcResult<UpdateMeterOutput>> updateMeter(final UpdateMeterInput input) {
496         LOG.debug("Calling the MeterMod RPC method on MessageDispatchService");
497         
498         // use primary connection
499         SwitchConnectionDistinguisher cookie = null;
500         
501         OFRpcTask<UpdateMeterInput, RpcResult<UpdateMeterOutput>> task = 
502                 OFRpcTaskFactory.createUpdateMeterTask(rpcTaskContext, input, cookie);
503         ListenableFuture<RpcResult<UpdateMeterOutput>> result = task.submit();
504         
505         return result;
506     }
507
508     @Override
509     public NodeId getNodeId() {
510         return nodeId;
511     }
512
513     /*
514      * Methods for requesting statistics from switch
515      */
516     @Override
517     public Future<RpcResult<GetAllGroupStatisticsOutput>> getAllGroupStatistics(final GetAllGroupStatisticsInput input) {
518
519         GetAllGroupStatisticsOutputBuilder output = new GetAllGroupStatisticsOutputBuilder();
520         Collection<RpcError> errors = Collections.emptyList();
521
522         if (version == OFConstants.OFP_VERSION_1_0) {
523             output.setTransactionId(null);
524             output.setGroupStats(null);
525
526             RpcResult<GetAllGroupStatisticsOutput> rpcResult = Rpcs.getRpcResult(true, output.build(), errors);
527             return Futures.immediateFuture(rpcResult);
528         }
529         // Generate xid to associate it with the request
530         Long xid = this.getSessionContext().getNextXid();
531
532         LOG.debug("Prepare statistics request for all the groups - Transaction id - {}", xid);
533
534         // Create multipart request header
535         MultipartRequestInputBuilder mprInput = new MultipartRequestInputBuilder();
536         mprInput.setType(MultipartType.OFPMPGROUP);
537         mprInput.setVersion(version);
538         mprInput.setXid(xid);
539         mprInput.setFlags(new MultipartRequestFlags(false));
540
541         // Create multipart request body for fetch all the group stats
542         MultipartRequestGroupCaseBuilder caseBuilder = new MultipartRequestGroupCaseBuilder();
543         MultipartRequestGroupBuilder mprGroupBuild = new MultipartRequestGroupBuilder();
544         mprGroupBuild.setGroupId(new GroupId(BinContent.intToUnsignedLong(Group.OFPGALL.getIntValue())));
545         caseBuilder.setMultipartRequestGroup(mprGroupBuild.build());
546
547         // Set request body to main multipart request
548         mprInput.setMultipartRequestBody(caseBuilder.build());
549
550         // Send the request, no cookies associated, use any connection
551         LOG.debug("Send group statistics request to the switch :{}", mprGroupBuild);
552         this.messageService.multipartRequest(mprInput.build(), null);
553
554         // Prepare rpc return output. Set xid and send it back.
555         LOG.debug("Return results and transaction id back to caller");
556         output.setTransactionId(generateTransactionId(xid));
557         output.setGroupStats(null);
558
559         RpcResult<GetAllGroupStatisticsOutput> rpcResult = Rpcs.getRpcResult(true, output.build(), errors);
560         return Futures.immediateFuture(rpcResult);
561
562     }
563
564     @Override
565     public Future<RpcResult<GetGroupDescriptionOutput>> getGroupDescription(final GetGroupDescriptionInput input) {
566
567         GetGroupDescriptionOutputBuilder output = new GetGroupDescriptionOutputBuilder();
568         Collection<RpcError> errors = Collections.emptyList();
569
570         if (version == OFConstants.OFP_VERSION_1_0) {
571             output.setTransactionId(null);
572             output.setGroupDescStats(null);
573
574             RpcResult<GetGroupDescriptionOutput> rpcResult = Rpcs.getRpcResult(true, output.build(), errors);
575             return Futures.immediateFuture(rpcResult);
576         }
577         // Generate xid to associate it with the request
578         Long xid = this.getSessionContext().getNextXid();
579
580         LOG.debug("Prepare group description statistics request - Transaction id - {}", xid);
581
582         // Create multipart request header
583         MultipartRequestInputBuilder mprInput = new MultipartRequestInputBuilder();
584         mprInput.setType(MultipartType.OFPMPGROUPDESC);
585         mprInput.setVersion(version);
586         mprInput.setXid(xid);
587         mprInput.setFlags(new MultipartRequestFlags(false));
588
589         // Create multipart request body for fetch all the group description
590         // stats
591         MultipartRequestGroupDescCaseBuilder mprGroupDescBuild = new MultipartRequestGroupDescCaseBuilder();
592
593         // Set request body to main multipart request
594         mprInput.setMultipartRequestBody(mprGroupDescBuild.build());
595
596         // Send the request, no cookies associated, use any connection
597         LOG.debug("Send group desciption statistics request to switch : {}", mprGroupDescBuild);
598         this.messageService.multipartRequest(mprInput.build(), null);
599
600         // Prepare rpc return output. Set xid and send it back.
601         LOG.debug("Return results and transaction id back to caller");
602         output.setTransactionId(generateTransactionId(xid));
603         output.setGroupDescStats(null);
604
605         RpcResult<GetGroupDescriptionOutput> rpcResult = Rpcs.getRpcResult(true, output.build(), errors);
606         return Futures.immediateFuture(rpcResult);
607
608     }
609
610     @Override
611     public Future<RpcResult<GetGroupFeaturesOutput>> getGroupFeatures(final GetGroupFeaturesInput input) {
612
613         GetGroupFeaturesOutputBuilder output = new GetGroupFeaturesOutputBuilder();
614         Collection<RpcError> errors = Collections.emptyList();
615
616         if (version == OFConstants.OFP_VERSION_1_0) {
617             output.setTransactionId(null);
618
619             RpcResult<GetGroupFeaturesOutput> rpcResult = Rpcs.getRpcResult(true, output.build(), errors);
620             return Futures.immediateFuture(rpcResult);
621         }
622         // Generate xid to associate it with the request
623         Long xid = this.getSessionContext().getNextXid();
624
625         LOG.debug("Prepare group features statistics request - Transaction id - {}", xid);
626
627         // Create multipart request header
628         MultipartRequestInputBuilder mprInput = new MultipartRequestInputBuilder();
629         mprInput.setType(MultipartType.OFPMPGROUPFEATURES);
630         mprInput.setVersion(version);
631         mprInput.setXid(xid);
632         mprInput.setFlags(new MultipartRequestFlags(false));
633
634         // Create multipart request body for fetch all the group description
635         // stats
636         MultipartRequestGroupFeaturesCaseBuilder mprGroupFeaturesBuild = new MultipartRequestGroupFeaturesCaseBuilder();
637
638         // Set request body to main multipart request
639         mprInput.setMultipartRequestBody(mprGroupFeaturesBuild.build());
640
641         // Send the request, no cookies associated, use any connection
642         LOG.debug("Send group features statistics request :{}", mprGroupFeaturesBuild);
643         this.messageService.multipartRequest(mprInput.build(), null);
644
645         // Prepare rpc return output. Set xid and send it back.
646         LOG.debug("Return results and transaction id back to caller");
647         output.setTransactionId(generateTransactionId(xid));
648
649         RpcResult<GetGroupFeaturesOutput> rpcResult = Rpcs.getRpcResult(true, output.build(), errors);
650         return Futures.immediateFuture(rpcResult);
651     }
652
653     @Override
654     public Future<RpcResult<GetGroupStatisticsOutput>> getGroupStatistics(final GetGroupStatisticsInput input) {
655
656         GetGroupStatisticsOutputBuilder output = new GetGroupStatisticsOutputBuilder();
657         Collection<RpcError> errors = Collections.emptyList();
658
659         if (version == OFConstants.OFP_VERSION_1_0) {
660             output.setTransactionId(null);
661             output.setGroupStats(null);
662
663             RpcResult<GetGroupStatisticsOutput> rpcResult = Rpcs.getRpcResult(true, output.build(), errors);
664             return Futures.immediateFuture(rpcResult);
665         }
666         // Generate xid to associate it with the request
667         Long xid = this.getSessionContext().getNextXid();
668
669         LOG.debug("Prepare statistics request for node {} group ({}) - Transaction id - {}", input.getNode(),
670                 input.getGroupId(), xid);
671
672         // Create multipart request header
673         MultipartRequestInputBuilder mprInput = new MultipartRequestInputBuilder();
674         mprInput.setType(MultipartType.OFPMPGROUP);
675         mprInput.setVersion(version);
676         mprInput.setXid(xid);
677         mprInput.setFlags(new MultipartRequestFlags(false));
678
679         // Create multipart request body for fetch all the group stats
680         MultipartRequestGroupCaseBuilder caseBuilder = new MultipartRequestGroupCaseBuilder();
681         MultipartRequestGroupBuilder mprGroupBuild = new MultipartRequestGroupBuilder();
682         mprGroupBuild.setGroupId(new GroupId(input.getGroupId().getValue()));
683         caseBuilder.setMultipartRequestGroup(mprGroupBuild.build());
684
685         // Set request body to main multipart request
686         mprInput.setMultipartRequestBody(caseBuilder.build());
687
688         // Send the request, no cookies associated, use any connection
689         LOG.debug("Send group statistics request :{}", mprGroupBuild);
690         this.messageService.multipartRequest(mprInput.build(), null);
691
692         // Prepare rpc return output. Set xid and send it back.
693         LOG.debug("Return results and transaction id back to caller");
694         output.setTransactionId(generateTransactionId(xid));
695         output.setGroupStats(null);
696
697         RpcResult<GetGroupStatisticsOutput> rpcResult = Rpcs.getRpcResult(true, output.build(), errors);
698         return Futures.immediateFuture(rpcResult);
699     }
700
701     @Override
702     public Future<RpcResult<GetAllMeterConfigStatisticsOutput>> getAllMeterConfigStatistics(
703             final GetAllMeterConfigStatisticsInput input) {
704
705         GetAllMeterConfigStatisticsOutputBuilder output = new GetAllMeterConfigStatisticsOutputBuilder();
706         Collection<RpcError> errors = Collections.emptyList();
707
708         if (version == OFConstants.OFP_VERSION_1_0) {
709             output.setTransactionId(null);
710             output.setMeterConfigStats(null);
711
712             RpcResult<GetAllMeterConfigStatisticsOutput> rpcResult = Rpcs.getRpcResult(true, output.build(), errors);
713             return Futures.immediateFuture(rpcResult);
714
715         }
716         // Generate xid to associate it with the request
717         Long xid = this.getSessionContext().getNextXid();
718
719         LOG.debug("Prepare config request for all the meters - Transaction id - {}", xid);
720
721         // Create multipart request header
722         MultipartRequestInputBuilder mprInput = new MultipartRequestInputBuilder();
723         mprInput.setType(MultipartType.OFPMPMETERCONFIG);
724         mprInput.setVersion(version);
725         mprInput.setXid(xid);
726         mprInput.setFlags(new MultipartRequestFlags(false));
727
728         // Create multipart request body for fetch all the meter stats
729         MultipartRequestMeterConfigCaseBuilder caseBuilder = new MultipartRequestMeterConfigCaseBuilder();
730         MultipartRequestMeterConfigBuilder mprMeterConfigBuild = new MultipartRequestMeterConfigBuilder();
731         mprMeterConfigBuild.setMeterId(new MeterId(BinContent.intToUnsignedLong(Meter.OFPMALL.getIntValue())));
732         caseBuilder.setMultipartRequestMeterConfig(mprMeterConfigBuild.build());
733
734         // Set request body to main multipart request
735         mprInput.setMultipartRequestBody(caseBuilder.build());
736
737         // Send the request, no cookies associated, use any connection
738         LOG.debug("Send meter statistics request :{}", mprMeterConfigBuild);
739         this.messageService.multipartRequest(mprInput.build(), null);
740
741         // Prepare rpc return output. Set xid and send it back.
742         LOG.debug("Return results and transaction id back to caller");
743         output.setTransactionId(generateTransactionId(xid));
744         output.setMeterConfigStats(null);
745
746         RpcResult<GetAllMeterConfigStatisticsOutput> rpcResult = Rpcs.getRpcResult(true, output.build(), errors);
747         return Futures.immediateFuture(rpcResult);
748     }
749
750     @Override
751     public Future<RpcResult<GetAllMeterStatisticsOutput>> getAllMeterStatistics(final GetAllMeterStatisticsInput input) {
752
753         GetAllMeterStatisticsOutputBuilder output = new GetAllMeterStatisticsOutputBuilder();
754         Collection<RpcError> errors = Collections.emptyList();
755
756         if (version == OFConstants.OFP_VERSION_1_0) {
757             output.setTransactionId(null);
758             output.setMeterStats(null);
759
760             RpcResult<GetAllMeterStatisticsOutput> rpcResult = Rpcs.getRpcResult(true, output.build(), errors);
761             return Futures.immediateFuture(rpcResult);
762         }
763         // Generate xid to associate it with the request
764         Long xid = this.getSessionContext().getNextXid();
765
766         LOG.debug("Prepare statistics request for all the meters - Transaction id - {}", xid);
767
768         // Create multipart request header
769         MultipartRequestInputBuilder mprInput = new MultipartRequestInputBuilder();
770         mprInput.setType(MultipartType.OFPMPMETER);
771         mprInput.setVersion(version);
772         mprInput.setXid(xid);
773         mprInput.setFlags(new MultipartRequestFlags(false));
774
775         // Create multipart request body for fetch all the meter stats
776         MultipartRequestMeterCaseBuilder caseBuilder = new MultipartRequestMeterCaseBuilder();
777         MultipartRequestMeterBuilder mprMeterBuild = new MultipartRequestMeterBuilder();
778         mprMeterBuild.setMeterId(new MeterId(BinContent.intToUnsignedLong(Meter.OFPMALL.getIntValue())));
779         caseBuilder.setMultipartRequestMeter(mprMeterBuild.build());
780
781         // Set request body to main multipart request
782         mprInput.setMultipartRequestBody(caseBuilder.build());
783
784         // Send the request, no cookies associated, use any connection
785         LOG.debug("Send meter statistics request :{}", mprMeterBuild);
786         this.messageService.multipartRequest(mprInput.build(), null);
787
788         // Prepare rpc return output. Set xid and send it back.
789         LOG.debug("Return results and transaction id back to caller");
790         output.setTransactionId(generateTransactionId(xid));
791         output.setMeterStats(null);
792
793         RpcResult<GetAllMeterStatisticsOutput> rpcResult = Rpcs.getRpcResult(true, output.build(), errors);
794         return Futures.immediateFuture(rpcResult);
795     }
796
797     @Override
798     public Future<RpcResult<GetMeterFeaturesOutput>> getMeterFeatures(final GetMeterFeaturesInput input) {
799
800         GetMeterFeaturesOutputBuilder output = new GetMeterFeaturesOutputBuilder();
801         Collection<RpcError> errors = Collections.emptyList();
802
803         if (version == OFConstants.OFP_VERSION_1_0) {
804             output.setTransactionId(null);
805
806             RpcResult<GetMeterFeaturesOutput> rpcResult = Rpcs.getRpcResult(true, output.build(), errors);
807             return Futures.immediateFuture(rpcResult);
808         }
809         // Generate xid to associate it with the request
810         Long xid = this.getSessionContext().getNextXid();
811
812         LOG.debug("Prepare features statistics request for all the meters - Transaction id - {}", xid);
813
814         // Create multipart request header
815         MultipartRequestInputBuilder mprInput = new MultipartRequestInputBuilder();
816         mprInput.setType(MultipartType.OFPMPMETERFEATURES);
817         mprInput.setVersion(version);
818         mprInput.setXid(xid);
819         mprInput.setFlags(new MultipartRequestFlags(false));
820
821         // Create multipart request body for fetch all the group description
822         // stats
823         MultipartRequestMeterFeaturesCaseBuilder mprMeterFeaturesBuild = new MultipartRequestMeterFeaturesCaseBuilder();
824
825         // Set request body to main multipart request
826         mprInput.setMultipartRequestBody(mprMeterFeaturesBuild.build());
827
828         // Send the request, no cookies associated, use any connection
829         LOG.debug("Send meter features statistics request :{}", mprMeterFeaturesBuild);
830         this.messageService.multipartRequest(mprInput.build(), null);
831
832         // Prepare rpc return output. Set xid and send it back.
833         LOG.debug("Return results and transaction id back to caller");
834         output.setTransactionId(generateTransactionId(xid));
835
836         RpcResult<GetMeterFeaturesOutput> rpcResult = Rpcs.getRpcResult(true, output.build(), errors);
837         return Futures.immediateFuture(rpcResult);
838     }
839
840     @Override
841     public Future<RpcResult<GetMeterStatisticsOutput>> getMeterStatistics(final GetMeterStatisticsInput input) {
842
843         GetMeterStatisticsOutputBuilder output = new GetMeterStatisticsOutputBuilder();
844         Collection<RpcError> errors = Collections.emptyList();
845
846         if (version == OFConstants.OFP_VERSION_1_0) {
847             output.setTransactionId(null);
848             output.setMeterStats(null);
849
850             RpcResult<GetMeterStatisticsOutput> rpcResult = Rpcs.getRpcResult(true, output.build(), errors);
851             return Futures.immediateFuture(rpcResult);
852
853         }
854         // Generate xid to associate it with the request
855         Long xid = this.getSessionContext().getNextXid();
856
857         LOG.debug("Preprae statistics request for Meter ({}) - Transaction id - {}", input.getMeterId().getValue(), xid);
858
859         // Create multipart request header
860         MultipartRequestInputBuilder mprInput = new MultipartRequestInputBuilder();
861         mprInput.setType(MultipartType.OFPMPMETER);
862         mprInput.setVersion(version);
863         mprInput.setXid(xid);
864         mprInput.setFlags(new MultipartRequestFlags(false));
865
866         // Create multipart request body for fetch all the meter stats
867         MultipartRequestMeterCaseBuilder caseBuilder = new MultipartRequestMeterCaseBuilder();
868         MultipartRequestMeterBuilder mprMeterBuild = new MultipartRequestMeterBuilder();
869         // Select specific meter
870         mprMeterBuild.setMeterId(new MeterId(input.getMeterId().getValue()));
871         caseBuilder.setMultipartRequestMeter(mprMeterBuild.build());
872
873         // Set request body to main multipart request
874         mprInput.setMultipartRequestBody(caseBuilder.build());
875
876         // Send the request, no cookies associated, use any connection
877         LOG.debug("Send meter statistics request :{}", mprMeterBuild);
878         this.messageService.multipartRequest(mprInput.build(), null);
879
880         // Prepare rpc return output. Set xid and send it back.
881         LOG.debug("Return results and transaction id back to caller");
882         output.setTransactionId(generateTransactionId(xid));
883         output.setMeterStats(null);
884
885         RpcResult<GetMeterStatisticsOutput> rpcResult = Rpcs.getRpcResult(true, output.build(), errors);
886         return Futures.immediateFuture(rpcResult);
887     }
888
889     @Override
890     public Future<RpcResult<GetAllNodeConnectorsStatisticsOutput>> getAllNodeConnectorsStatistics(
891             final GetAllNodeConnectorsStatisticsInput arg0) {
892
893         // Generate xid to associate it with the request
894         Long xid = this.getSessionContext().getNextXid();
895
896         LOG.debug("Prepare port statistics request for all ports of node {} - TrasactionId - {}", arg0.getNode()
897                 .getValue(), xid);
898
899         // Create multipart request header
900         MultipartRequestInputBuilder mprInput = new MultipartRequestInputBuilder();
901         mprInput.setType(MultipartType.OFPMPPORTSTATS);
902         mprInput.setVersion(version);
903         mprInput.setXid(xid);
904         mprInput.setFlags(new MultipartRequestFlags(false));
905
906         // Create multipart request body to fetch stats for all the port of the
907         // node
908         MultipartRequestPortStatsCaseBuilder caseBuilder = new MultipartRequestPortStatsCaseBuilder();
909         MultipartRequestPortStatsBuilder mprPortStatsBuilder = new MultipartRequestPortStatsBuilder();
910         // Select all ports
911         mprPortStatsBuilder.setPortNo(OFConstants.OFPP_ANY);
912         caseBuilder.setMultipartRequestPortStats(mprPortStatsBuilder.build());
913
914         // Set request body to main multipart request
915         mprInput.setMultipartRequestBody(caseBuilder.build());
916
917         // Send the request, no cookies associated, use any connection
918         LOG.debug("Send port statistics request :{}", mprPortStatsBuilder.build().toString());
919         this.messageService.multipartRequest(mprInput.build(), null);
920
921         // Prepare rpc return output. Set xid and send it back.
922         GetAllNodeConnectorsStatisticsOutputBuilder output = new GetAllNodeConnectorsStatisticsOutputBuilder();
923         output.setTransactionId(generateTransactionId(xid));
924
925         Collection<RpcError> errors = Collections.emptyList();
926         RpcResult<GetAllNodeConnectorsStatisticsOutput> rpcResult = Rpcs.getRpcResult(true, output.build(), errors);
927         return Futures.immediateFuture(rpcResult);
928     }
929
930     @Override
931     public Future<RpcResult<GetNodeConnectorStatisticsOutput>> getNodeConnectorStatistics(
932             final GetNodeConnectorStatisticsInput arg0) {
933         // Generate xid to associate it with the request
934         Long xid = this.getSessionContext().getNextXid();
935
936         LOG.debug("Prepare port statistics request for port {} of node {} - TrasactionId - {}",
937                 arg0.getNodeConnectorId(), arg0.getNode().getValue(), xid);
938
939         // Create multipart request header
940         MultipartRequestInputBuilder mprInput = new MultipartRequestInputBuilder();
941         mprInput.setType(MultipartType.OFPMPPORTSTATS);
942         mprInput.setVersion(version);
943         mprInput.setXid(xid);
944         mprInput.setFlags(new MultipartRequestFlags(false));
945
946         // Create multipart request body to fetch stats for all the port of the
947         // node
948         MultipartRequestPortStatsCaseBuilder caseBuilder = new MultipartRequestPortStatsCaseBuilder();
949         MultipartRequestPortStatsBuilder mprPortStatsBuilder = new MultipartRequestPortStatsBuilder();
950
951         // Set specific port
952         mprPortStatsBuilder
953                 .setPortNo(InventoryDataServiceUtil.portNumberfromNodeConnectorId(arg0.getNodeConnectorId()));
954         caseBuilder.setMultipartRequestPortStats(mprPortStatsBuilder.build());
955
956         // Set request body to main multipart request
957         mprInput.setMultipartRequestBody(caseBuilder.build());
958
959         // Send the request, no cookies associated, use any connection
960         LOG.debug("Send port statistics request :{}", mprPortStatsBuilder.build().toString());
961         this.messageService.multipartRequest(mprInput.build(), null);
962
963         // Prepare rpc return output. Set xid and send it back.
964         GetNodeConnectorStatisticsOutputBuilder output = new GetNodeConnectorStatisticsOutputBuilder();
965         output.setTransactionId(generateTransactionId(xid));
966
967         Collection<RpcError> errors = Collections.emptyList();
968         RpcResult<GetNodeConnectorStatisticsOutput> rpcResult = Rpcs.getRpcResult(true, output.build(), errors);
969         return Futures.immediateFuture(rpcResult);
970     }
971
972     private static TransactionId generateTransactionId(final Long xid) {
973         BigInteger bigIntXid = BigInteger.valueOf(xid);
974         return new TransactionId(bigIntXid);
975
976     }
977
978     @Override
979     public Future<RpcResult<UpdatePortOutput>> updatePort(final UpdatePortInput input) {
980         PortModInput ofPortModInput = null;
981         RpcResult<UpdatePortOutput> rpcResultFromOFLib = null;
982
983         // For Flow provisioning, the SwitchConnectionDistinguisher is set to
984         // null so
985         // the request can be routed through any connection to the switch
986
987         SwitchConnectionDistinguisher cookie = null;
988
989         // NSF sends a list of port and the ModelDrivenSwitch will
990         // send one port at a time towards the switch ( mutiple RPCs calls)
991         List<Port> inputPorts = input.getUpdatedPort().getPort().getPort();
992
993         // Get the Xid. The same Xid has to be sent in all the RPCs
994         Long Xid = sessionContext.getNextXid();
995
996         for (Port inputPort : inputPorts) {
997
998             // Convert the UpdateGroupInput to GroupModInput
999             ofPortModInput = PortConvertor.toPortModInput(inputPort, version);
1000
1001             // Insert the Xid ( transaction Id) before calling the RPC on the
1002             // OFLibrary
1003
1004             PortModInputBuilder mdInput = new PortModInputBuilder(ofPortModInput);
1005             mdInput.setXid(Xid);
1006
1007             LOG.debug("Calling the PortMod RPC method on MessageDispatchService");
1008             Future<RpcResult<UpdatePortOutput>> resultFromOFLib = messageService.portMod(mdInput.build(), cookie);
1009
1010             try {
1011                 rpcResultFromOFLib = resultFromOFLib.get();
1012             } catch (Exception ex) {
1013                 LOG.error(" Error while getting result for updatePort RPC" + ex.getMessage());
1014             }
1015
1016             // The Future response value for all the RPCs except the last one is
1017             // ignored
1018
1019         }
1020         // Extract the Xid only from the Future for the last RPC and
1021         // send it back to the NSF
1022         UpdatePortOutput updatePortOutputOFLib = rpcResultFromOFLib.getResult();
1023
1024         UpdatePortOutputBuilder updatePortOutput = new UpdatePortOutputBuilder();
1025         updatePortOutput.setTransactionId(updatePortOutputOFLib.getTransactionId());
1026         UpdatePortOutput result = updatePortOutput.build();
1027
1028         Collection<RpcError> errors = rpcResultFromOFLib.getErrors();
1029         RpcResult<UpdatePortOutput> rpcResult = Rpcs.getRpcResult(true, result, errors);
1030
1031         LOG.debug("Returning the Update Group RPC result to MD-SAL");
1032         return Futures.immediateFuture(rpcResult);
1033
1034     }
1035
1036     @Override
1037     public Future<RpcResult<UpdateTableOutput>> updateTable(final UpdateTableInput input) {
1038
1039         // Get the Xid. The same Xid has to be sent in all the Multipart
1040         // requests
1041         Long xid = this.getSessionContext().getNextXid();
1042
1043         LOG.debug("Prepare the Multipart Table Mod requests for Transaction Id {} ", xid);
1044
1045         // Create multipart request header
1046         MultipartRequestInputBuilder mprInput = new MultipartRequestInputBuilder();
1047         mprInput.setType(MultipartType.OFPMPTABLEFEATURES);
1048         mprInput.setVersion((short) 0x04);
1049         mprInput.setXid(xid);
1050
1051         // Convert the list of all MD-SAL table feature object into OF library
1052         // object
1053         List<TableFeatures> ofTableFeatureList = TableFeaturesConvertor.toTableFeaturesRequest(input.getUpdatedTable());
1054
1055         MultipartRequestTableFeaturesCaseBuilder caseRequest = new MultipartRequestTableFeaturesCaseBuilder();
1056         MultipartRequestTableFeaturesBuilder tableFeaturesRequest = new MultipartRequestTableFeaturesBuilder();
1057
1058         mprInput.setFlags(new MultipartRequestFlags(false));
1059
1060         tableFeaturesRequest.setTableFeatures(ofTableFeatureList);
1061
1062         // Set request body to main multipart request
1063         caseRequest.setMultipartRequestTableFeatures(tableFeaturesRequest.build());
1064         mprInput.setMultipartRequestBody(caseRequest.build());
1065
1066         // Send the request, no cookies associated, use any connection
1067         LOG.debug("Send Table Feature request :{}", ofTableFeatureList);
1068         this.messageService.multipartRequest(mprInput.build(), null);
1069
1070         // Extract the Xid only from the Future for the last RPC and
1071         // send it back to the NSF
1072         LOG.debug("Returning the result and transaction id to NSF");
1073         LOG.debug("Return results and transaction id back to caller");
1074         UpdateTableOutputBuilder output = new UpdateTableOutputBuilder();
1075         output.setTransactionId(generateTransactionId(xid));
1076
1077         Collection<RpcError> errors = Collections.emptyList();
1078         RpcResult<UpdateTableOutput> rpcResult = Rpcs.getRpcResult(true, output.build(), errors);
1079         return Futures.immediateFuture(rpcResult);
1080     }
1081
1082     @Override
1083     public Future<RpcResult<GetAllFlowStatisticsFromFlowTableOutput>> getAllFlowStatisticsFromFlowTable(
1084             final GetAllFlowStatisticsFromFlowTableInput arg0) {
1085
1086         // Generate xid to associate it with the request
1087         Long xid = this.getSessionContext().getNextXid();
1088
1089         LOG.debug("Prepare statistics request to get flow stats for switch tables {} - Transaction id - {}", arg0
1090                 .getTableId().getValue(), xid);
1091
1092         // Create multipart request header
1093         MultipartRequestInputBuilder mprInput = new MultipartRequestInputBuilder();
1094         mprInput.setType(MultipartType.OFPMPFLOW);
1095         mprInput.setVersion(version);
1096         mprInput.setXid(xid);
1097         mprInput.setFlags(new MultipartRequestFlags(false));
1098
1099         // Create multipart request body for fetch all the group stats
1100         MultipartRequestFlowCaseBuilder multipartRequestFlowCaseBuilder = new MultipartRequestFlowCaseBuilder();
1101         MultipartRequestFlowBuilder mprFlowRequestBuilder = new MultipartRequestFlowBuilder();
1102         mprFlowRequestBuilder.setTableId(arg0.getTableId().getValue());
1103         mprFlowRequestBuilder.setOutPort(OFConstants.OFPP_ANY);
1104         mprFlowRequestBuilder.setOutGroup(OFConstants.OFPG_ANY);
1105         mprFlowRequestBuilder.setCookie(OFConstants.DEFAULT_COOKIE);
1106         mprFlowRequestBuilder.setCookieMask(OFConstants.DEFAULT_COOKIE_MASK);
1107         FlowCreatorUtil.setWildcardedFlowMatch(version, mprFlowRequestBuilder);
1108
1109         // Set request body to main multipart request
1110         multipartRequestFlowCaseBuilder.setMultipartRequestFlow(mprFlowRequestBuilder.build());
1111         mprInput.setMultipartRequestBody(multipartRequestFlowCaseBuilder.build());
1112
1113         // Send the request, no cookies associated, use any connection
1114         LOG.debug("Send flow statistics request to the switch :{}", mprFlowRequestBuilder);
1115         this.messageService.multipartRequest(mprInput.build(), null);
1116
1117         // Prepare rpc return output. Set xid and send it back.
1118         LOG.debug("Return results and transaction id back to caller");
1119         GetAllFlowStatisticsFromFlowTableOutputBuilder output = new GetAllFlowStatisticsFromFlowTableOutputBuilder();
1120         output.setTransactionId(generateTransactionId(xid));
1121         output.setFlowAndStatisticsMapList(null);
1122
1123         Collection<RpcError> errors = Collections.emptyList();
1124         RpcResult<GetAllFlowStatisticsFromFlowTableOutput> rpcResult = Rpcs.getRpcResult(true, output.build(), errors);
1125         return Futures.immediateFuture(rpcResult);
1126     }
1127
1128     @Override
1129     public Future<RpcResult<GetAllFlowsStatisticsFromAllFlowTablesOutput>> getAllFlowsStatisticsFromAllFlowTables(
1130             final GetAllFlowsStatisticsFromAllFlowTablesInput arg0) {
1131
1132         // Generate xid to associate it with the request
1133         Long xid = this.getSessionContext().getNextXid();
1134
1135         LOG.debug("Prepare statistics request to get flow stats of all switch tables - Transaction id - {}", xid);
1136
1137         // Create multipart request header
1138         MultipartRequestInputBuilder mprInput = new MultipartRequestInputBuilder();
1139         mprInput.setType(MultipartType.OFPMPFLOW);
1140         mprInput.setVersion(version);
1141         mprInput.setXid(xid);
1142         mprInput.setFlags(new MultipartRequestFlags(false));
1143
1144         // Create multipart request body for fetch all the group stats
1145         MultipartRequestFlowCaseBuilder multipartRequestFlowCaseBuilder = new MultipartRequestFlowCaseBuilder();
1146         MultipartRequestFlowBuilder mprFlowRequestBuilder = new MultipartRequestFlowBuilder();
1147         mprFlowRequestBuilder.setTableId(OFConstants.OFPTT_ALL);
1148         mprFlowRequestBuilder.setOutPort(OFConstants.OFPP_ANY);
1149         mprFlowRequestBuilder.setOutGroup(OFConstants.OFPG_ANY);
1150         mprFlowRequestBuilder.setCookie(OFConstants.DEFAULT_COOKIE);
1151         mprFlowRequestBuilder.setCookieMask(OFConstants.DEFAULT_COOKIE_MASK);
1152         mprFlowRequestBuilder.setCookieMask(OFConstants.DEFAULT_COOKIE_MASK);
1153
1154         FlowCreatorUtil.setWildcardedFlowMatch(version, mprFlowRequestBuilder);
1155
1156         // Set request body to main multipart request
1157         multipartRequestFlowCaseBuilder.setMultipartRequestFlow(mprFlowRequestBuilder.build());
1158         mprInput.setMultipartRequestBody(multipartRequestFlowCaseBuilder.build());
1159
1160         // Send the request, no cookies associated, use any connection
1161         LOG.debug("Send flow statistics request to the switch :{}", mprFlowRequestBuilder);
1162         this.messageService.multipartRequest(mprInput.build(), null);
1163
1164         // Prepare rpc return output. Set xid and send it back.
1165         GetAllFlowsStatisticsFromAllFlowTablesOutputBuilder output = new GetAllFlowsStatisticsFromAllFlowTablesOutputBuilder();
1166         output.setTransactionId(generateTransactionId(xid));
1167         output.setFlowAndStatisticsMapList(null);
1168
1169         Collection<RpcError> errors = Collections.emptyList();
1170         RpcResult<GetAllFlowsStatisticsFromAllFlowTablesOutput> rpcResult = Rpcs.getRpcResult(true, output.build(),
1171                 errors);
1172         return Futures.immediateFuture(rpcResult);
1173
1174     }
1175
1176     @Override
1177     public Future<RpcResult<GetFlowStatisticsFromFlowTableOutput>> getFlowStatisticsFromFlowTable(
1178             final GetFlowStatisticsFromFlowTableInput arg0) {
1179         // Generate xid to associate it with the request
1180         Long xid = this.getSessionContext().getNextXid();
1181
1182         LOG.debug("Prepare statistics request to get stats for flow {} for switch tables {} - Transaction id - {}",
1183                 arg0.getMatch().toString(), arg0.getTableId(), xid);
1184
1185         // Create multipart request header
1186         MultipartRequestInputBuilder mprInput = new MultipartRequestInputBuilder();
1187         mprInput.setType(MultipartType.OFPMPFLOW);
1188         mprInput.setVersion(version);
1189         mprInput.setXid(xid);
1190         mprInput.setFlags(new MultipartRequestFlags(false));
1191
1192         // Create multipart request body for fetch all the group stats
1193         MultipartRequestFlowCaseBuilder multipartRequestFlowCaseBuilder = new MultipartRequestFlowCaseBuilder();
1194         MultipartRequestFlowBuilder mprFlowRequestBuilder = new MultipartRequestFlowBuilder();
1195         mprFlowRequestBuilder.setTableId(arg0.getTableId());
1196
1197         if (arg0.getOutPort() != null)
1198             mprFlowRequestBuilder.setOutPort(arg0.getOutPort().longValue());
1199         else
1200             mprFlowRequestBuilder.setOutPort(OFConstants.OFPP_ANY);
1201
1202         if (arg0.getOutGroup() != null)
1203             mprFlowRequestBuilder.setOutGroup(arg0.getOutGroup());
1204         else
1205             mprFlowRequestBuilder.setOutGroup(OFConstants.OFPG_ANY);
1206
1207         if (arg0.getCookie() != null)
1208             mprFlowRequestBuilder.setCookie(arg0.getCookie().getValue());
1209         else
1210             mprFlowRequestBuilder.setCookie(OFConstants.DEFAULT_COOKIE);
1211
1212         if (arg0.getCookieMask() != null)
1213             mprFlowRequestBuilder.setCookieMask(arg0.getCookieMask().getValue());
1214         else
1215             mprFlowRequestBuilder.setCookieMask(OFConstants.DEFAULT_COOKIE_MASK);
1216
1217         // convert and inject match
1218         MatchReactor.getInstance().convert(arg0.getMatch(), version, mprFlowRequestBuilder,
1219                 this.getSessionContext().getFeatures().getDatapathId());
1220
1221         // Set request body to main multipart request
1222         multipartRequestFlowCaseBuilder.setMultipartRequestFlow(mprFlowRequestBuilder.build());
1223         mprInput.setMultipartRequestBody(multipartRequestFlowCaseBuilder.build());
1224
1225         // Send the request, no cookies associated, use any connection
1226         LOG.debug("Send flow statistics request to the switch :{}", mprFlowRequestBuilder);
1227         this.messageService.multipartRequest(mprInput.build(), null);
1228
1229         // Prepare rpc return output. Set xid and send it back.
1230         GetFlowStatisticsFromFlowTableOutputBuilder output = new GetFlowStatisticsFromFlowTableOutputBuilder();
1231         output.setTransactionId(generateTransactionId(xid));
1232         output.setFlowAndStatisticsMapList(null);
1233
1234         Collection<RpcError> errors = Collections.emptyList();
1235         RpcResult<GetFlowStatisticsFromFlowTableOutput> rpcResult = Rpcs.getRpcResult(true, output.build(), errors);
1236         return Futures.immediateFuture(rpcResult);
1237     }
1238
1239     @Override
1240     public Future<RpcResult<GetAggregateFlowStatisticsFromFlowTableForAllFlowsOutput>> getAggregateFlowStatisticsFromFlowTableForAllFlows(
1241             final GetAggregateFlowStatisticsFromFlowTableForAllFlowsInput arg0) {
1242         // Generate xid to associate it with the request
1243         Long xid = this.getSessionContext().getNextXid();
1244
1245         LOG.debug(
1246                 "Prepare aggregate flow statistics request to get aggregate flow stats for all the flow installed on switch table {} - Transaction id - {}",
1247                 arg0.getTableId().getValue(), xid);
1248
1249         // Create multipart request header
1250         MultipartRequestInputBuilder mprInput = new MultipartRequestInputBuilder();
1251         mprInput.setType(MultipartType.OFPMPAGGREGATE);
1252         mprInput.setVersion(version);
1253         mprInput.setXid(xid);
1254         mprInput.setFlags(new MultipartRequestFlags(false));
1255
1256         // Create multipart request body for fetch all the group stats
1257         MultipartRequestAggregateCaseBuilder multipartRequestAggregateCaseBuilder = new MultipartRequestAggregateCaseBuilder();
1258         MultipartRequestAggregateBuilder mprAggregateRequestBuilder = new MultipartRequestAggregateBuilder();
1259         mprAggregateRequestBuilder.setTableId(arg0.getTableId().getValue());
1260         mprAggregateRequestBuilder.setOutPort(OFConstants.OFPP_ANY);
1261         mprAggregateRequestBuilder.setOutGroup(OFConstants.OFPG_ANY);
1262         mprAggregateRequestBuilder.setCookie(OFConstants.DEFAULT_COOKIE);
1263         mprAggregateRequestBuilder.setCookieMask(OFConstants.DEFAULT_COOKIE_MASK);
1264
1265         FlowCreatorUtil.setWildcardedFlowMatch(version, mprAggregateRequestBuilder);
1266
1267         // Set request body to main multipart request
1268         multipartRequestAggregateCaseBuilder.setMultipartRequestAggregate(mprAggregateRequestBuilder.build());
1269         mprInput.setMultipartRequestBody(multipartRequestAggregateCaseBuilder.build());
1270
1271         // Send the request, no cookies associated, use any connection
1272         LOG.debug("Send request to the switch :{}", multipartRequestAggregateCaseBuilder.build().toString());
1273         this.messageService.multipartRequest(mprInput.build(), null);
1274
1275         // Prepare rpc return output. Set xid and send it back.
1276         GetAggregateFlowStatisticsFromFlowTableForAllFlowsOutputBuilder output = new GetAggregateFlowStatisticsFromFlowTableForAllFlowsOutputBuilder();
1277         output.setTransactionId(generateTransactionId(xid));
1278
1279         Collection<RpcError> errors = Collections.emptyList();
1280         RpcResult<GetAggregateFlowStatisticsFromFlowTableForAllFlowsOutput> rpcResult = Rpcs.getRpcResult(true,
1281                 output.build(), errors);
1282         return Futures.immediateFuture(rpcResult);
1283     }
1284
1285     @Override
1286     public Future<RpcResult<GetAggregateFlowStatisticsFromFlowTableForGivenMatchOutput>> getAggregateFlowStatisticsFromFlowTableForGivenMatch(
1287             final GetAggregateFlowStatisticsFromFlowTableForGivenMatchInput arg0) {
1288
1289         // Generate xid to associate it with the request
1290         Long xid = this.getSessionContext().getNextXid();
1291
1292         LOG.debug(
1293                 "Prepare aggregate statistics request to get aggregate stats for flows matching {} and installed in flow tables {} - Transaction id - {}",
1294                 arg0.getMatch().toString(), arg0.getTableId(), xid);
1295
1296         // Create multipart request header
1297         MultipartRequestInputBuilder mprInput = new MultipartRequestInputBuilder();
1298         mprInput.setType(MultipartType.OFPMPAGGREGATE);
1299         mprInput.setVersion(version);
1300         mprInput.setXid(xid);
1301         mprInput.setFlags(new MultipartRequestFlags(false));
1302
1303         // Create multipart request body for fetch all the group stats
1304         MultipartRequestAggregateCaseBuilder multipartRequestAggregateCaseBuilder = new MultipartRequestAggregateCaseBuilder();
1305         MultipartRequestAggregateBuilder mprAggregateRequestBuilder = new MultipartRequestAggregateBuilder();
1306         mprAggregateRequestBuilder.setTableId(arg0.getTableId());
1307         mprAggregateRequestBuilder.setOutPort(arg0.getOutPort().longValue());
1308         mprAggregateRequestBuilder.setOutGroup(OFConstants.OFPG_ANY);
1309         mprAggregateRequestBuilder.setCookie(OFConstants.DEFAULT_COOKIE);
1310         mprAggregateRequestBuilder.setCookieMask(OFConstants.DEFAULT_COOKIE_MASK);
1311
1312         MatchReactor.getInstance().convert(arg0.getMatch(), version, mprAggregateRequestBuilder,
1313                 this.getSessionContext().getFeatures().getDatapathId());
1314         // TODO: repeating code
1315         if (version == OFConstants.OFP_VERSION_1_3) {
1316             mprAggregateRequestBuilder.setCookie(arg0.getCookie().getValue());
1317             mprAggregateRequestBuilder.setCookieMask(arg0.getCookieMask().getValue());
1318             mprAggregateRequestBuilder.setOutGroup(arg0.getOutGroup());
1319         }
1320
1321         // Set request body to main multipart request
1322         multipartRequestAggregateCaseBuilder.setMultipartRequestAggregate(mprAggregateRequestBuilder.build());
1323         mprInput.setMultipartRequestBody(multipartRequestAggregateCaseBuilder.build());
1324
1325         // Send the request, no cookies associated, use any connection
1326         LOG.debug("Send request to the switch :{}", multipartRequestAggregateCaseBuilder.build().toString());
1327         this.messageService.multipartRequest(mprInput.build(), null);
1328
1329         // Prepare rpc return output. Set xid and send it back.
1330         GetAggregateFlowStatisticsFromFlowTableForGivenMatchOutputBuilder output = new GetAggregateFlowStatisticsFromFlowTableForGivenMatchOutputBuilder();
1331         output.setTransactionId(generateTransactionId(xid));
1332
1333         Collection<RpcError> errors = Collections.emptyList();
1334         RpcResult<GetAggregateFlowStatisticsFromFlowTableForGivenMatchOutput> rpcResult = Rpcs.getRpcResult(true,
1335                 output.build(), errors);
1336         return Futures.immediateFuture(rpcResult);
1337     }
1338
1339     @Override
1340     public Future<RpcResult<GetFlowTablesStatisticsOutput>> getFlowTablesStatistics(final GetFlowTablesStatisticsInput arg0) {
1341         // Generate xid to associate it with the request
1342         Long xid = this.getSessionContext().getNextXid();
1343
1344         LOG.debug("Prepare flow table statistics request to get flow table stats for all tables "
1345                 + "from node {}- Transaction id - {}", arg0.getNode(), xid);
1346
1347         // Create multipart request header
1348         MultipartRequestInputBuilder mprInput = new MultipartRequestInputBuilder();
1349         mprInput.setType(MultipartType.OFPMPTABLE);
1350         mprInput.setVersion(version);
1351         mprInput.setXid(xid);
1352         mprInput.setFlags(new MultipartRequestFlags(false));
1353
1354         // Create multipart request body for fetch all the group stats
1355         MultipartRequestTableCaseBuilder multipartRequestTableCaseBuilder = new MultipartRequestTableCaseBuilder();
1356         MultipartRequestTableBuilder multipartRequestTableBuilder = new MultipartRequestTableBuilder();
1357         multipartRequestTableBuilder.setEmpty(true);
1358         multipartRequestTableCaseBuilder.setMultipartRequestTable(multipartRequestTableBuilder.build());
1359
1360         // Set request body to main multipart request
1361         mprInput.setMultipartRequestBody(multipartRequestTableCaseBuilder.build());
1362
1363         // Send the request, no cookies associated, use any connection
1364         LOG.debug("Send request to the switch :{}", multipartRequestTableCaseBuilder.build().toString());
1365         this.messageService.multipartRequest(mprInput.build(), null);
1366
1367         // Prepare rpc return output. Set xid and send it back.
1368         GetFlowTablesStatisticsOutputBuilder output = new GetFlowTablesStatisticsOutputBuilder();
1369         output.setTransactionId(generateTransactionId(xid));
1370
1371         Collection<RpcError> errors = Collections.emptyList();
1372         RpcResult<GetFlowTablesStatisticsOutput> rpcResult = Rpcs.getRpcResult(true, output.build(), errors);
1373         return Futures.immediateFuture(rpcResult);
1374     }
1375
1376     @Override
1377     public Future<RpcResult<GetAllQueuesStatisticsFromAllPortsOutput>> getAllQueuesStatisticsFromAllPorts(
1378             final GetAllQueuesStatisticsFromAllPortsInput arg0) {
1379         // Generate xid to associate it with the request
1380         Long xid = this.getSessionContext().getNextXid();
1381
1382         LOG.debug(
1383                 "Prepare queue statistics request to collect stats for all queues attached to all the ports of node {} - TrasactionId - {}",
1384                 arg0.getNode().getValue(), xid);
1385
1386         // Create multipart request header
1387         MultipartRequestInputBuilder mprInput = new MultipartRequestInputBuilder();
1388         mprInput.setType(MultipartType.OFPMPQUEUE);
1389         mprInput.setVersion(version);
1390         mprInput.setXid(xid);
1391         mprInput.setFlags(new MultipartRequestFlags(false));
1392
1393         // Create multipart request body to fetch stats for all the port of the
1394         // node
1395         MultipartRequestQueueCaseBuilder caseBuilder = new MultipartRequestQueueCaseBuilder();
1396         MultipartRequestQueueBuilder mprQueueBuilder = new MultipartRequestQueueBuilder();
1397         // Select all ports
1398         mprQueueBuilder.setPortNo(OFConstants.OFPP_ANY);
1399         // Select all the ports
1400         mprQueueBuilder.setQueueId(OFConstants.OFPQ_ANY);
1401
1402         caseBuilder.setMultipartRequestQueue(mprQueueBuilder.build());
1403
1404         // Set request body to main multipart request
1405         mprInput.setMultipartRequestBody(caseBuilder.build());
1406
1407         // Send the request, no cookies associated, use any connection
1408         LOG.debug("Send queue statistics request :{}", mprQueueBuilder.build().toString());
1409         this.messageService.multipartRequest(mprInput.build(), null);
1410
1411         // Prepare rpc return output. Set xid and send it back.
1412         GetAllQueuesStatisticsFromAllPortsOutputBuilder output = new GetAllQueuesStatisticsFromAllPortsOutputBuilder();
1413         output.setTransactionId(generateTransactionId(xid));
1414         output.setQueueIdAndStatisticsMap(null);
1415
1416         Collection<RpcError> errors = Collections.emptyList();
1417         RpcResult<GetAllQueuesStatisticsFromAllPortsOutput> rpcResult = Rpcs.getRpcResult(true, output.build(), errors);
1418         return Futures.immediateFuture(rpcResult);
1419     }
1420
1421     @Override
1422     public Future<RpcResult<GetAllQueuesStatisticsFromGivenPortOutput>> getAllQueuesStatisticsFromGivenPort(
1423             final GetAllQueuesStatisticsFromGivenPortInput arg0) {
1424         // Generate xid to associate it with the request
1425         Long xid = this.getSessionContext().getNextXid();
1426
1427         LOG.debug("Prepare queue statistics request to collect stats for "
1428                 + "all queues attached to given port {} of node {} - TrasactionId - {}", arg0.getNodeConnectorId()
1429                 .toString(), arg0.getNode().getValue(), xid);
1430
1431         // Create multipart request header
1432         MultipartRequestInputBuilder mprInput = new MultipartRequestInputBuilder();
1433         mprInput.setType(MultipartType.OFPMPQUEUE);
1434         mprInput.setVersion(version);
1435         mprInput.setXid(xid);
1436         mprInput.setFlags(new MultipartRequestFlags(false));
1437
1438         // Create multipart request body to fetch stats for all the port of the
1439         // node
1440         MultipartRequestQueueCaseBuilder caseBuilder = new MultipartRequestQueueCaseBuilder();
1441         MultipartRequestQueueBuilder mprQueueBuilder = new MultipartRequestQueueBuilder();
1442         // Select all queues
1443         mprQueueBuilder.setQueueId(OFConstants.OFPQ_ANY);
1444         // Select specific port
1445         mprQueueBuilder.setPortNo(InventoryDataServiceUtil.portNumberfromNodeConnectorId(arg0.getNodeConnectorId()));
1446
1447         caseBuilder.setMultipartRequestQueue(mprQueueBuilder.build());
1448
1449         // Set request body to main multipart request
1450         mprInput.setMultipartRequestBody(caseBuilder.build());
1451
1452         // Send the request, no cookies associated, use any connection
1453         LOG.debug("Send queue statistics request :{}", mprQueueBuilder.build().toString());
1454         this.messageService.multipartRequest(mprInput.build(), null);
1455
1456         // Prepare rpc return output. Set xid and send it back.
1457         GetAllQueuesStatisticsFromGivenPortOutputBuilder output = new GetAllQueuesStatisticsFromGivenPortOutputBuilder();
1458         output.setTransactionId(generateTransactionId(xid));
1459         output.setQueueIdAndStatisticsMap(null);
1460
1461         Collection<RpcError> errors = Collections.emptyList();
1462         RpcResult<GetAllQueuesStatisticsFromGivenPortOutput> rpcResult = Rpcs
1463                 .getRpcResult(true, output.build(), errors);
1464         return Futures.immediateFuture(rpcResult);
1465     }
1466
1467     @Override
1468     public Future<RpcResult<GetQueueStatisticsFromGivenPortOutput>> getQueueStatisticsFromGivenPort(
1469             final GetQueueStatisticsFromGivenPortInput arg0) {
1470         // Generate xid to associate it with the request
1471         Long xid = this.getSessionContext().getNextXid();
1472
1473         LOG.debug("Prepare queue statistics request to collect stats for "
1474                 + "given queue attached to given port {} of node {} - TrasactionId - {}", arg0.getQueueId().toString(),
1475                 arg0.getNodeConnectorId().toString(), arg0.getNode().getValue(), xid);
1476
1477         // Create multipart request header
1478         MultipartRequestInputBuilder mprInput = new MultipartRequestInputBuilder();
1479         mprInput.setType(MultipartType.OFPMPQUEUE);
1480         mprInput.setVersion(version);
1481         mprInput.setXid(xid);
1482         mprInput.setFlags(new MultipartRequestFlags(false));
1483
1484         // Create multipart request body to fetch stats for all the port of the
1485         // node
1486         MultipartRequestQueueCaseBuilder caseBuilder = new MultipartRequestQueueCaseBuilder();
1487         MultipartRequestQueueBuilder mprQueueBuilder = new MultipartRequestQueueBuilder();
1488         // Select specific queue
1489         mprQueueBuilder.setQueueId(arg0.getQueueId().getValue());
1490         // Select specific port
1491         mprQueueBuilder.setPortNo(InventoryDataServiceUtil.portNumberfromNodeConnectorId(arg0.getNodeConnectorId()));
1492
1493         caseBuilder.setMultipartRequestQueue(mprQueueBuilder.build());
1494
1495         // Set request body to main multipart request
1496         mprInput.setMultipartRequestBody(caseBuilder.build());
1497
1498         // Send the request, no cookies associated, use any connection
1499         LOG.debug("Send queue statistics request :{}", mprQueueBuilder.build().toString());
1500         this.messageService.multipartRequest(mprInput.build(), null);
1501
1502         // Prepare rpc return output. Set xid and send it back.
1503         GetQueueStatisticsFromGivenPortOutputBuilder output = new GetQueueStatisticsFromGivenPortOutputBuilder();
1504         output.setTransactionId(generateTransactionId(xid));
1505         output.setQueueIdAndStatisticsMap(null);
1506
1507         Collection<RpcError> errors = Collections.emptyList();
1508         RpcResult<GetQueueStatisticsFromGivenPortOutput> rpcResult = Rpcs.getRpcResult(true, output.build(), errors);
1509         return Futures.immediateFuture(rpcResult);
1510     }
1511 }