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