2 * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
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
8 package org.opendaylight.openflowplugin.openflow.md.core.sal;
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;
17 import org.opendaylight.controller.sal.common.util.Rpcs;
18 import org.opendaylight.openflowplugin.openflow.md.core.SwitchConnectionDistinguisher;
19 import org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.FlowConvertor;
20 import org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.GroupConvertor;
21 import org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.MeterConvertor;
22 import org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.PortConvertor;
23 import org.opendaylight.openflowplugin.openflow.md.core.session.IMessageDispatchService;
24 import org.opendaylight.openflowplugin.openflow.md.core.session.SessionContext;
25 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.AddFlowInput;
26 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.AddFlowOutput;
27 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.AddFlowOutputBuilder;
28 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.RemoveFlowInput;
29 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.RemoveFlowOutput;
30 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.RemoveFlowOutputBuilder;
31 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.UpdateFlowInput;
32 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.UpdateFlowOutput;
33 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.UpdateFlowOutputBuilder;
34 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.service.rev130918.AddGroupOutput;
35 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.transaction.rev131103.TransactionId;
36 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.port.rev130925.port.mod.port.Port;
37 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.Flow;
38 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.service.rev130918.AddGroupInput;
39 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.service.rev130918.AddGroupOutputBuilder;
40 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.service.rev130918.RemoveGroupInput;
41 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.service.rev130918.RemoveGroupOutput;
42 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.service.rev130918.RemoveGroupOutputBuilder;
43 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.service.rev130918.UpdateGroupInput;
44 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.service.rev130918.UpdateGroupOutput;
45 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.service.rev130918.UpdateGroupOutputBuilder;
46 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.statistics.rev131111.GetAllGroupStatisticsInput;
47 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.statistics.rev131111.GetAllGroupStatisticsOutput;
48 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.statistics.rev131111.GetAllGroupStatisticsOutputBuilder;
49 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.statistics.rev131111.GetGroupDescriptionInput;
50 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.statistics.rev131111.GetGroupDescriptionOutput;
51 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.statistics.rev131111.GetGroupDescriptionOutputBuilder;
52 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.statistics.rev131111.GetGroupFeaturesInput;
53 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.statistics.rev131111.GetGroupFeaturesOutput;
54 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.statistics.rev131111.GetGroupFeaturesOutputBuilder;
55 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.statistics.rev131111.GetGroupStatisticsInput;
56 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.statistics.rev131111.GetGroupStatisticsOutput;
57 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.statistics.rev131111.GetGroupStatisticsOutputBuilder;
58 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeId;
59 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node;
60 import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.service.rev130918.AddMeterInput;
61 import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.service.rev130918.AddMeterOutput;
62 import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.service.rev130918.AddMeterOutputBuilder;
63 import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.service.rev130918.RemoveMeterInput;
64 import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.service.rev130918.RemoveMeterOutput;
65 import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.service.rev130918.RemoveMeterOutputBuilder;
66 import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.service.rev130918.UpdateMeterInput;
67 import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.service.rev130918.UpdateMeterOutput;
68 import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.service.rev130918.UpdateMeterOutputBuilder;
69 import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.statistics.rev131111.GetAllMeterConfigStatisticsInput;
70 import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.statistics.rev131111.GetAllMeterConfigStatisticsOutput;
71 import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.statistics.rev131111.GetAllMeterConfigStatisticsOutputBuilder;
72 import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.statistics.rev131111.GetAllMeterStatisticsInput;
73 import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.statistics.rev131111.GetAllMeterStatisticsOutput;
74 import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.statistics.rev131111.GetAllMeterStatisticsOutputBuilder;
75 import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.statistics.rev131111.GetMeterFeaturesInput;
76 import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.statistics.rev131111.GetMeterFeaturesOutput;
77 import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.statistics.rev131111.GetMeterFeaturesOutputBuilder;
78 import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.statistics.rev131111.GetMeterStatisticsInput;
79 import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.statistics.rev131111.GetMeterStatisticsOutput;
80 import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.statistics.rev131111.GetMeterStatisticsOutputBuilder;
81 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.Group;
82 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.Meter;
83 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.MultipartRequestFlags;
84 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.MultipartType;
85 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev130731.oxm.fields.MatchEntries;
86 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.FlowModInput;
87 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.FlowModInputBuilder;
88 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.GroupModInput;
89 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.MeterModInput;
90 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.MultipartRequestInputBuilder;
91 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.PortModInput;
92 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.PortModInputBuilder;
93 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.match.grouping.Match;
94 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.match.grouping.MatchBuilder;
95 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.MultipartRequestGroupBuilder;
96 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.MultipartRequestGroupDescBuilder;
97 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.MultipartRequestGroupFeaturesBuilder;
98 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.MultipartRequestMeterBuilder;
99 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.MultipartRequestMeterConfigBuilder;
100 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.MultipartRequestMeterFeaturesBuilder;
101 import org.opendaylight.yang.gen.v1.urn.opendaylight.packet.service.rev130709.TransmitPacketInput;
102 import org.opendaylight.yang.gen.v1.urn.opendaylight.port.service.rev131107.GetPortOutput;
103 import org.opendaylight.yang.gen.v1.urn.opendaylight.port.service.rev131107.UpdatePortInput;
104 import org.opendaylight.yang.gen.v1.urn.opendaylight.port.service.rev131107.UpdatePortOutput;
105 import org.opendaylight.yang.gen.v1.urn.opendaylight.port.service.rev131107.UpdatePortOutputBuilder;
106 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
107 import org.opendaylight.yangtools.yang.common.RpcError;
108 import org.opendaylight.yangtools.yang.common.RpcResult;
109 import org.slf4j.Logger;
111 import com.google.common.util.concurrent.Futures;
114 * RPC implementation of MD-switch
116 public class ModelDrivenSwitchImpl extends AbstractModelDrivenSwitch {
118 private static final Logger LOG = org.slf4j.LoggerFactory
119 .getLogger(ModelDrivenSwitchImpl.class);
120 private final NodeId nodeId;
121 private final IMessageDispatchService messageService ;
122 private short version = 0;
124 protected ModelDrivenSwitchImpl(NodeId nodeId,
125 InstanceIdentifier<Node> identifier, SessionContext context) {
126 super(identifier, context);
127 this.nodeId = nodeId;
128 messageService = sessionContext.getMessageDispatchService() ;
129 version = context.getPrimaryConductor().getVersion();
133 public Future<RpcResult<AddFlowOutput>> addFlow(AddFlowInput input) {
134 // Convert the AddFlowInput to FlowModInput
135 FlowModInput ofFlowModInput = FlowConvertor.toFlowModInput(input, version);
137 // For Flow provisioning, the SwitchConnectionDistinguisher is set to null so
138 // the request can be routed through any connection to the switch
140 SwitchConnectionDistinguisher cookie = null ;
142 LOG.debug("Calling the FlowMod RPC method on MessageDispatchService");
143 Future<RpcResult<UpdateFlowOutput>> resultFromOFLib = messageService.flowMod(ofFlowModInput, cookie) ;
145 RpcResult<UpdateFlowOutput> rpcResultFromOFLib = null ;
148 rpcResultFromOFLib = resultFromOFLib.get();
149 } catch( Exception ex ) {
150 LOG.error( " Error while getting result for AddFlow RPC" + ex.getMessage());
153 UpdateFlowOutput updateFlowOutput = rpcResultFromOFLib.getResult() ;
155 AddFlowOutputBuilder addFlowOutput = new AddFlowOutputBuilder() ;
156 addFlowOutput.setTransactionId(updateFlowOutput.getTransactionId()) ;
157 AddFlowOutput result = addFlowOutput.build();
159 Collection<RpcError> errors = rpcResultFromOFLib.getErrors() ;
160 RpcResult<AddFlowOutput> rpcResult = Rpcs.getRpcResult(true, result, errors);
162 LOG.debug("Returning the Add Flow RPC result to MD-SAL");
163 return Futures.immediateFuture(rpcResult);
167 public Future<RpcResult<AddGroupOutput>> addGroup(AddGroupInput input) {
168 // Convert the AddGroupInput to GroupModInput
169 GroupModInput ofGroupModInput = GroupConvertor.toGroupModInput(input, version);
172 // For Flow provisioning, the SwitchConnectionDistinguisher is set to null so
173 // the request can be routed through any connection to the switch
175 SwitchConnectionDistinguisher cookie = null ;
177 LOG.debug("Calling the GroupMod RPC method on MessageDispatchService");
178 Future<RpcResult<UpdateGroupOutput>> resultFromOFLib = messageService.groupMod(ofGroupModInput, cookie) ;
180 RpcResult<UpdateGroupOutput> rpcResultFromOFLib = null ;
183 rpcResultFromOFLib = resultFromOFLib.get();
184 } catch( Exception ex ) {
185 LOG.error( " Error while getting result for AddGroup RPC" + ex.getMessage());
188 UpdateGroupOutput updateGroupOutput = rpcResultFromOFLib.getResult() ;
190 AddGroupOutputBuilder addGroupOutput = new AddGroupOutputBuilder() ;
191 addGroupOutput.setTransactionId(updateGroupOutput.getTransactionId()) ;
192 AddGroupOutput result = addGroupOutput.build();
194 Collection<RpcError> errors = rpcResultFromOFLib.getErrors() ;
195 RpcResult<AddGroupOutput> rpcResult = Rpcs.getRpcResult(true, result, errors);
197 LOG.debug("Returning the Add Group RPC result to MD-SAL");
198 return Futures.immediateFuture(rpcResult);
202 public Future<RpcResult<AddMeterOutput>> addMeter(AddMeterInput input) {
203 // Convert the AddMeterInput to MeterModInput
204 MeterModInput ofMeterModInput = MeterConvertor.toMeterModInput(input, version);
207 // For Meter provisioning, the SwitchConnectionDistinguisher is set to null so
208 // the request can be routed through any connection to the switch
210 SwitchConnectionDistinguisher cookie = null ;
212 LOG.debug("Calling the MeterMod RPC method on MessageDispatchService");
213 Future<RpcResult<UpdateMeterOutput>> resultFromOFLib = messageService.meterMod(ofMeterModInput, cookie) ;
215 RpcResult<UpdateMeterOutput> rpcResultFromOFLib = null ;
218 rpcResultFromOFLib = resultFromOFLib.get();
219 } catch( Exception ex ) {
220 LOG.error( " Error while getting result for AddMeter RPC" + ex.getMessage());
223 UpdateMeterOutput updateMeterOutput = rpcResultFromOFLib.getResult() ;
225 AddMeterOutputBuilder addMeterOutput = new AddMeterOutputBuilder() ;
226 addMeterOutput.setTransactionId(updateMeterOutput.getTransactionId()) ;
227 AddMeterOutput result = addMeterOutput.build();
229 Collection<RpcError> errors = rpcResultFromOFLib.getErrors() ;
230 RpcResult<AddMeterOutput> rpcResult = Rpcs.getRpcResult(true, result, errors);
232 LOG.debug("Returning the Add Meter RPC result to MD-SAL");
233 return Futures.immediateFuture(rpcResult);
237 public Future<RpcResult<RemoveFlowOutput>> removeFlow(RemoveFlowInput input) {
238 // Convert the RemoveFlowInput to FlowModInput
239 FlowModInput ofFlowModInput = FlowConvertor.toFlowModInput(input, version);
242 // For Flow provisioning, the SwitchConnectionDistinguisher is set to null so
243 // the request can be routed through any connection to the switch
245 SwitchConnectionDistinguisher cookie = null ;
247 LOG.debug("Calling the FlowMod RPC method on MessageDispatchService");
248 Future<RpcResult<UpdateFlowOutput>> resultFromOFLib = messageService.flowMod(ofFlowModInput, cookie) ;
250 RpcResult<UpdateFlowOutput> rpcResultFromOFLib = null ;
253 rpcResultFromOFLib = resultFromOFLib.get();
254 } catch( Exception ex ) {
255 LOG.error( " Error while getting result for remove Flow RPC" + ex.getMessage());
258 UpdateFlowOutput updateFlowOutput = rpcResultFromOFLib.getResult() ;
260 RemoveFlowOutputBuilder removeFlowOutput = new RemoveFlowOutputBuilder() ;
261 removeFlowOutput.setTransactionId(updateFlowOutput.getTransactionId()) ;
262 RemoveFlowOutput result = removeFlowOutput.build();
264 Collection<RpcError> errors = rpcResultFromOFLib.getErrors() ;
265 RpcResult<RemoveFlowOutput> rpcResult = Rpcs.getRpcResult(true, result, errors);
267 LOG.debug("Returning the Remove Flow RPC result to MD-SAL");
268 return Futures.immediateFuture(rpcResult);
272 public Future<RpcResult<RemoveGroupOutput>> removeGroup(
273 RemoveGroupInput input) {
274 // Convert the RemoveGroupInput to GroupModInput
275 GroupModInput ofGroupModInput = GroupConvertor.toGroupModInput(input, version);
278 // For Flow provisioning, the SwitchConnectionDistinguisher is set to null so
279 // the request can be routed through any connection to the switch
281 SwitchConnectionDistinguisher cookie = null ;
283 LOG.debug("Calling the GroupMod RPC method on MessageDispatchService");
284 Future<RpcResult<UpdateGroupOutput>> resultFromOFLib = messageService.groupMod(ofGroupModInput, cookie) ;
286 RpcResult<UpdateGroupOutput> rpcResultFromOFLib = null ;
289 rpcResultFromOFLib = resultFromOFLib.get();
290 } catch( Exception ex ) {
291 LOG.error( " Error while getting result for RemoveGroup RPC" + ex.getMessage());
294 UpdateGroupOutput updateGroupOutput = rpcResultFromOFLib.getResult() ;
296 RemoveGroupOutputBuilder removeGroupOutput = new RemoveGroupOutputBuilder() ;
297 removeGroupOutput.setTransactionId(updateGroupOutput.getTransactionId()) ;
298 RemoveGroupOutput result = removeGroupOutput.build();
300 Collection<RpcError> errors = rpcResultFromOFLib.getErrors() ;
301 RpcResult<RemoveGroupOutput> rpcResult = Rpcs.getRpcResult(true, result, errors);
303 LOG.debug("Returning the Remove Group RPC result to MD-SAL");
304 return Futures.immediateFuture(rpcResult);
308 public Future<RpcResult<RemoveMeterOutput>> removeMeter(
309 RemoveMeterInput input) {
310 // Convert the RemoveMeterInput to MeterModInput
311 MeterModInput ofMeterModInput = MeterConvertor.toMeterModInput(input, version);
314 // For Meter provisioning, the SwitchConnectionDistinguisher is set to null so
315 // the request can be routed through any connection to the switch
317 SwitchConnectionDistinguisher cookie = null ;
319 LOG.debug("Calling the MeterMod RPC method on MessageDispatchService");
320 Future<RpcResult<UpdateMeterOutput>> resultFromOFLib = messageService.meterMod(ofMeterModInput, cookie) ;
322 RpcResult<UpdateMeterOutput> rpcResultFromOFLib = null ;
325 rpcResultFromOFLib = resultFromOFLib.get();
326 } catch( Exception ex ) {
327 LOG.error( " Error while getting result for RemoveMeter RPC" + ex.getMessage());
330 UpdateMeterOutput updatemeterOutput = rpcResultFromOFLib.getResult() ;
332 RemoveMeterOutputBuilder removeMeterOutput = new RemoveMeterOutputBuilder() ;
333 removeMeterOutput.setTransactionId(updatemeterOutput.getTransactionId()) ;
334 RemoveMeterOutput result = removeMeterOutput.build();
336 Collection<RpcError> errors = rpcResultFromOFLib.getErrors() ;
337 RpcResult<RemoveMeterOutput> rpcResult = Rpcs.getRpcResult(true, result, errors);
339 LOG.debug("Returning the Remove Meter RPC result to MD-SAL");
340 return Futures.immediateFuture(rpcResult);
344 public Future<RpcResult<Void>> transmitPacket(TransmitPacketInput input) {
345 // TODO Auto-generated method stub
349 private FlowModInputBuilder toFlowModInputBuilder(Flow source) {
350 FlowModInputBuilder target = new FlowModInputBuilder();
351 target.setCookie(source.getCookie());
352 target.setIdleTimeout(source.getIdleTimeout());
353 target.setHardTimeout(source.getHardTimeout());
354 target.setMatch(toMatch(source.getMatch()));
359 private Match toMatch(
360 org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.Match match) {
361 MatchBuilder target = new MatchBuilder();
363 target.setMatchEntries(toMatchEntries(match));
368 private List<MatchEntries> toMatchEntries(
369 org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.Match match) {
370 List<MatchEntries> entries = new ArrayList<>();
376 public Future<RpcResult<UpdateFlowOutput>> updateFlow(UpdateFlowInput input) {
377 // Convert the UpdateFlowInput to FlowModInput
378 FlowModInput ofFlowModInput = FlowConvertor.toFlowModInput(input.getUpdatedFlow(), version);
380 // Call the RPC method on MessageDispatchService
382 // For Flow provisioning, the SwitchConnectionDistinguisher is set to null so
383 // the request can be routed through any connection to the switch
385 SwitchConnectionDistinguisher cookie = null ;
387 LOG.debug("Calling the FlowMod RPC method on MessageDispatchService");
388 Future<RpcResult<UpdateFlowOutput>> resultFromOFLib = messageService.flowMod(ofFlowModInput, cookie) ;
390 RpcResult<UpdateFlowOutput> rpcResultFromOFLib = null ;
393 rpcResultFromOFLib = resultFromOFLib.get();
394 } catch( Exception ex ) {
395 LOG.error( " Error while getting result for UpdateFlow RPC" + ex.getMessage());
398 UpdateFlowOutput updateFlowOutputOFLib = rpcResultFromOFLib.getResult() ;
400 UpdateFlowOutputBuilder updateFlowOutput = new UpdateFlowOutputBuilder() ;
401 updateFlowOutput.setTransactionId(updateFlowOutputOFLib.getTransactionId()) ;
402 UpdateFlowOutput result = updateFlowOutput.build();
404 Collection<RpcError> errors = rpcResultFromOFLib.getErrors() ;
405 RpcResult<UpdateFlowOutput> rpcResult = Rpcs.getRpcResult(true, result, errors);
407 LOG.debug("Returning the Update Flow RPC result to MD-SAL");
408 return Futures.immediateFuture(rpcResult);
412 public Future<RpcResult<UpdateGroupOutput>> updateGroup(
413 UpdateGroupInput input) {
414 // Convert the UpdateGroupInput to GroupModInput
415 GroupModInput ofGroupModInput = GroupConvertor.toGroupModInput(input.getUpdatedGroup(), version);
418 // For Flow provisioning, the SwitchConnectionDistinguisher is set to null so
419 // the request can be routed through any connection to the switch
421 SwitchConnectionDistinguisher cookie = null ;
423 LOG.debug("Calling the GroupMod RPC method on MessageDispatchService");
424 Future<RpcResult<UpdateGroupOutput>> resultFromOFLib = messageService.groupMod(ofGroupModInput, cookie) ;
426 RpcResult<UpdateGroupOutput> rpcResultFromOFLib = null ;
429 rpcResultFromOFLib = resultFromOFLib.get();
430 } catch( Exception ex ) {
431 LOG.error( " Error while getting result for updateGroup RPC" + ex.getMessage());
434 UpdateGroupOutput updateGroupOutputOFLib = rpcResultFromOFLib.getResult() ;
436 UpdateGroupOutputBuilder updateGroupOutput = new UpdateGroupOutputBuilder() ;
437 updateGroupOutput.setTransactionId(updateGroupOutputOFLib.getTransactionId()) ;
438 UpdateGroupOutput result = updateGroupOutput.build();
440 Collection<RpcError> errors = rpcResultFromOFLib.getErrors() ;
441 RpcResult<UpdateGroupOutput> rpcResult = Rpcs.getRpcResult(true, result, errors);
443 LOG.debug("Returning the Update Group RPC result to MD-SAL");
444 return Futures.immediateFuture(rpcResult);
448 public Future<RpcResult<UpdateMeterOutput>> updateMeter(
449 UpdateMeterInput input) {
450 // Convert the UpdateMeterInput to MeterModInput
451 MeterModInput ofMeterModInput = MeterConvertor.toMeterModInput(input.getUpdatedMeter(), version);
454 // For Meter provisioning, the SwitchConnectionDistinguisher is set to null so
455 // the request can be routed through any connection to the switch
457 SwitchConnectionDistinguisher cookie = null ;
459 LOG.debug("Calling the MeterMod RPC method on MessageDispatchService");
460 Future<RpcResult<UpdateMeterOutput>> resultFromOFLib = messageService.meterMod(ofMeterModInput, cookie) ;
462 RpcResult<UpdateMeterOutput> rpcResultFromOFLib = null ;
465 rpcResultFromOFLib = resultFromOFLib.get();
466 } catch( Exception ex ) {
467 LOG.error( " Error while getting result for UpdateMeter RPC" + ex.getMessage());
470 UpdateMeterOutput updateMeterOutputFromOFLib = rpcResultFromOFLib.getResult() ;
472 UpdateMeterOutputBuilder updateMeterOutput = new UpdateMeterOutputBuilder() ;
473 updateMeterOutput.setTransactionId(updateMeterOutputFromOFLib.getTransactionId()) ;
474 UpdateMeterOutput result = updateMeterOutput.build();
476 Collection<RpcError> errors = rpcResultFromOFLib.getErrors() ;
477 RpcResult<UpdateMeterOutput> rpcResult = Rpcs.getRpcResult(true, result, errors);
479 LOG.debug("Returning the Update Meter RPC result to MD-SAL");
480 return Futures.immediateFuture(rpcResult);
484 public NodeId getNodeId() {
489 * Methods for requesting statistics from switch
492 public Future<RpcResult<GetAllGroupStatisticsOutput>> getAllGroupStatistics(GetAllGroupStatisticsInput input) {
494 //Generate xid to associate it with the request
495 Long xid = this.getSessionContext().getNextXid();
497 LOG.debug("Prepare statistics request for all the groups - Transaction id - {}",xid);
499 // Create multipart request header
500 MultipartRequestInputBuilder mprInput = new MultipartRequestInputBuilder();
501 mprInput.setType(MultipartType.OFPMPGROUP);
502 mprInput.setVersion((short)0x04);
503 mprInput.setXid(xid);
504 mprInput.setFlags(new MultipartRequestFlags(false));
506 // Create multipart request body for fetch all the group stats
507 MultipartRequestGroupBuilder mprGroupBuild = new MultipartRequestGroupBuilder();
508 mprGroupBuild.setGroupId((long) Group.OFPGALL.getIntValue());
510 //Set request body to main multipart request
511 mprInput.setMultipartRequestBody(mprGroupBuild.build());
513 //Send the request, no cookies associated, use any connection
514 LOG.debug("Send group statistics request to the switch :{}",mprGroupBuild);
515 this.messageService.multipartRequest(mprInput.build(), null);
517 // Prepare rpc return output. Set xid and send it back.
518 LOG.debug("Return results and transaction id back to caller");
519 GetAllGroupStatisticsOutputBuilder output = new GetAllGroupStatisticsOutputBuilder();
520 output.setTransactionId(generateTransactionId(xid));
521 output.setGroupStats(null);
523 Collection<RpcError> errors = Collections.emptyList();
524 RpcResult<GetAllGroupStatisticsOutput> rpcResult = Rpcs.getRpcResult(true, output.build(), errors);
525 return Futures.immediateFuture(rpcResult);
530 public Future<RpcResult<GetGroupDescriptionOutput>> getGroupDescription(GetGroupDescriptionInput input) {
532 //Generate xid to associate it with the request
533 Long xid = this.getSessionContext().getNextXid();
535 LOG.debug("Prepare group description statistics request - Transaction id - {}",xid);
537 // Create multipart request header
538 MultipartRequestInputBuilder mprInput = new MultipartRequestInputBuilder();
539 mprInput.setType(MultipartType.OFPMPGROUPDESC);
540 mprInput.setVersion((short)0x04);
541 mprInput.setXid(xid);
542 mprInput.setFlags(new MultipartRequestFlags(false));
544 // Create multipart request body for fetch all the group description stats
545 MultipartRequestGroupDescBuilder mprGroupDescBuild = new MultipartRequestGroupDescBuilder();
547 //Set request body to main multipart request
548 mprInput.setMultipartRequestBody(mprGroupDescBuild.build());
550 //Send the request, no cookies associated, use any connection
551 LOG.debug("Send group desciption statistics request to switch : {}",mprGroupDescBuild);
552 this.messageService.multipartRequest(mprInput.build(), null);
554 // Prepare rpc return output. Set xid and send it back.
555 LOG.debug("Return results and transaction id back to caller");
556 GetGroupDescriptionOutputBuilder output = new GetGroupDescriptionOutputBuilder();
557 output.setTransactionId(generateTransactionId(xid));
558 output.setGroupDescStats(null);
560 Collection<RpcError> errors = Collections.emptyList();
561 RpcResult<GetGroupDescriptionOutput> rpcResult = Rpcs.getRpcResult(true, output.build(), errors);
562 return Futures.immediateFuture(rpcResult);
567 public Future<RpcResult<GetGroupFeaturesOutput>> getGroupFeatures(GetGroupFeaturesInput input) {
569 //Generate xid to associate it with the request
570 Long xid = this.getSessionContext().getNextXid();
572 LOG.debug("Prepare group features statistics request - Transaction id - {}",xid);
574 // Create multipart request header
575 MultipartRequestInputBuilder mprInput = new MultipartRequestInputBuilder();
576 mprInput.setType(MultipartType.OFPMPGROUPFEATURES);
577 mprInput.setVersion((short)0x04);
578 mprInput.setXid(xid);
579 mprInput.setFlags(new MultipartRequestFlags(false));
581 // Create multipart request body for fetch all the group description stats
582 MultipartRequestGroupFeaturesBuilder mprGroupFeaturesBuild = new MultipartRequestGroupFeaturesBuilder();
584 //Set request body to main multipart request
585 mprInput.setMultipartRequestBody(mprGroupFeaturesBuild.build());
587 //Send the request, no cookies associated, use any connection
588 LOG.debug("Send group features statistics request :{}",mprGroupFeaturesBuild);
589 this.messageService.multipartRequest(mprInput.build(), null);
591 // Prepare rpc return output. Set xid and send it back.
592 LOG.debug("Return results and transaction id back to caller");
593 GetGroupFeaturesOutputBuilder output = new GetGroupFeaturesOutputBuilder();
594 output.setTransactionId(generateTransactionId(xid));
596 Collection<RpcError> errors = Collections.emptyList();
597 RpcResult<GetGroupFeaturesOutput> rpcResult = Rpcs.getRpcResult(true, output.build(), errors);
598 return Futures.immediateFuture(rpcResult);
602 public Future<RpcResult<GetGroupStatisticsOutput>> getGroupStatistics(GetGroupStatisticsInput input) {
604 //Generate xid to associate it with the request
605 Long xid = this.getSessionContext().getNextXid();
607 LOG.debug("Prepare statistics request for node {} group ({}) - Transaction id - {}",input.getNode(),input.getGroupId(),xid);
609 // Create multipart request header
610 MultipartRequestInputBuilder mprInput = new MultipartRequestInputBuilder();
611 mprInput.setType(MultipartType.OFPMPGROUP);
612 mprInput.setVersion((short)0x04);
613 mprInput.setXid(xid);
614 mprInput.setFlags(new MultipartRequestFlags(false));
616 // Create multipart request body for fetch all the group stats
617 MultipartRequestGroupBuilder mprGroupBuild = new MultipartRequestGroupBuilder();
618 mprGroupBuild.setGroupId(input.getGroupId().getValue());
620 //Set request body to main multipart request
621 mprInput.setMultipartRequestBody(mprGroupBuild.build());
623 //Send the request, no cookies associated, use any connection
624 LOG.debug("Send group statistics request :{}",mprGroupBuild);
625 this.messageService.multipartRequest(mprInput.build(), null);
627 // Prepare rpc return output. Set xid and send it back.
628 LOG.debug("Return results and transaction id back to caller");
629 GetGroupStatisticsOutputBuilder output = new GetGroupStatisticsOutputBuilder();
630 output.setTransactionId(generateTransactionId(xid));
631 output.setGroupStats(null);
633 Collection<RpcError> errors = Collections.emptyList();
634 RpcResult<GetGroupStatisticsOutput> rpcResult = Rpcs.getRpcResult(true, output.build(), errors);
635 return Futures.immediateFuture(rpcResult);
639 public Future<RpcResult<GetAllMeterConfigStatisticsOutput>> getAllMeterConfigStatistics(
640 GetAllMeterConfigStatisticsInput input) {
642 //Generate xid to associate it with the request
643 Long xid = this.getSessionContext().getNextXid();
645 LOG.debug("Prepare config request for all the meters - Transaction id - {}",xid);
647 // Create multipart request header
648 MultipartRequestInputBuilder mprInput = new MultipartRequestInputBuilder();
649 mprInput.setType(MultipartType.OFPMPMETERCONFIG);
650 mprInput.setVersion((short)0x04);
651 mprInput.setXid(xid);
652 mprInput.setFlags(new MultipartRequestFlags(false));
654 // Create multipart request body for fetch all the meter stats
655 MultipartRequestMeterConfigBuilder mprMeterConfigBuild = new MultipartRequestMeterConfigBuilder();
656 mprMeterConfigBuild.setMeterId((long) Meter.OFPMALL.getIntValue());
658 //Set request body to main multipart request
659 mprInput.setMultipartRequestBody(mprMeterConfigBuild.build());
661 //Send the request, no cookies associated, use any connection
662 LOG.debug("Send meter statistics request :{}",mprMeterConfigBuild);
663 this.messageService.multipartRequest(mprInput.build(), null);
665 // Prepare rpc return output. Set xid and send it back.
666 LOG.debug("Return results and transaction id back to caller");
667 GetAllMeterConfigStatisticsOutputBuilder output = new GetAllMeterConfigStatisticsOutputBuilder();
668 output.setTransactionId(generateTransactionId(xid));
669 output.setMeterConfigStats(null);
671 Collection<RpcError> errors = Collections.emptyList();
672 RpcResult<GetAllMeterConfigStatisticsOutput> rpcResult = Rpcs.getRpcResult(true, output.build(), errors);
673 return Futures.immediateFuture(rpcResult);
677 public Future<RpcResult<GetAllMeterStatisticsOutput>> getAllMeterStatistics(GetAllMeterStatisticsInput input) {
679 //Generate xid to associate it with the request
680 Long xid = this.getSessionContext().getNextXid();
682 LOG.debug("Prepare statistics request for all the meters - Transaction id - {}",xid);
684 // Create multipart request header
685 MultipartRequestInputBuilder mprInput = new MultipartRequestInputBuilder();
686 mprInput.setType(MultipartType.OFPMPMETER);
687 mprInput.setVersion((short)0x04);
688 mprInput.setXid(xid);
689 mprInput.setFlags(new MultipartRequestFlags(false));
691 // Create multipart request body for fetch all the meter stats
692 MultipartRequestMeterBuilder mprMeterBuild = new MultipartRequestMeterBuilder();
693 mprMeterBuild.setMeterId((long) Meter.OFPMALL.getIntValue());
695 //Set request body to main multipart request
696 mprInput.setMultipartRequestBody(mprMeterBuild.build());
698 //Send the request, no cookies associated, use any connection
699 LOG.debug("Send meter statistics request :{}",mprMeterBuild);
700 this.messageService.multipartRequest(mprInput.build(), null);
702 // Prepare rpc return output. Set xid and send it back.
703 LOG.debug("Return results and transaction id back to caller");
704 GetAllMeterStatisticsOutputBuilder output = new GetAllMeterStatisticsOutputBuilder();
705 output.setTransactionId(generateTransactionId(xid));
706 output.setMeterStats(null);
708 Collection<RpcError> errors = Collections.emptyList();
709 RpcResult<GetAllMeterStatisticsOutput> rpcResult = Rpcs.getRpcResult(true, output.build(), errors);
710 return Futures.immediateFuture(rpcResult);
714 public Future<RpcResult<GetMeterFeaturesOutput>> getMeterFeatures(GetMeterFeaturesInput input) {
716 //Generate xid to associate it with the request
717 Long xid = this.getSessionContext().getNextXid();
719 LOG.debug("Prepare features statistics request for all the meters - Transaction id - {}",xid);
721 // Create multipart request header
722 MultipartRequestInputBuilder mprInput = new MultipartRequestInputBuilder();
723 mprInput.setType(MultipartType.OFPMPMETERFEATURES);
724 mprInput.setVersion((short)0x04);
725 mprInput.setXid(xid);
726 mprInput.setFlags(new MultipartRequestFlags(false));
728 // Create multipart request body for fetch all the group description stats
729 MultipartRequestMeterFeaturesBuilder mprMeterFeaturesBuild = new MultipartRequestMeterFeaturesBuilder();
731 //Set request body to main multipart request
732 mprInput.setMultipartRequestBody(mprMeterFeaturesBuild.build());
734 //Send the request, no cookies associated, use any connection
735 LOG.debug("Send meter features statistics request :{}",mprMeterFeaturesBuild);
736 this.messageService.multipartRequest(mprInput.build(), null);
738 // Prepare rpc return output. Set xid and send it back.
739 LOG.debug("Return results and transaction id back to caller");
740 GetMeterFeaturesOutputBuilder output = new GetMeterFeaturesOutputBuilder();
741 output.setTransactionId(generateTransactionId(xid));
743 Collection<RpcError> errors = Collections.emptyList();
744 RpcResult<GetMeterFeaturesOutput> rpcResult = Rpcs.getRpcResult(true, output.build(), errors);
745 return Futures.immediateFuture(rpcResult);
749 public Future<RpcResult<GetMeterStatisticsOutput>> getMeterStatistics(GetMeterStatisticsInput input) {
750 //Generate xid to associate it with the request
751 Long xid = this.getSessionContext().getNextXid();
753 LOG.debug("Preprae statistics request for Meter ({}) - Transaction id - {}",input.getMeterId().getValue(),xid);
755 // Create multipart request header
756 MultipartRequestInputBuilder mprInput = new MultipartRequestInputBuilder();
757 mprInput.setType(MultipartType.OFPMPMETER);
758 mprInput.setVersion((short)0x04);
759 mprInput.setXid(xid);
760 mprInput.setFlags(new MultipartRequestFlags(false));
762 // Create multipart request body for fetch all the meter stats
763 MultipartRequestMeterBuilder mprMeterBuild = new MultipartRequestMeterBuilder();
764 //Select specific meter
765 mprMeterBuild.setMeterId(input.getMeterId().getValue());
767 //Set request body to main multipart request
768 mprInput.setMultipartRequestBody(mprMeterBuild.build());
770 //Send the request, no cookies associated, use any connection
771 LOG.debug("Send meter statistics request :{}",mprMeterBuild);
772 this.messageService.multipartRequest(mprInput.build(), null);
774 // Prepare rpc return output. Set xid and send it back.
775 LOG.debug("Return results and transaction id back to caller");
776 GetMeterStatisticsOutputBuilder output = new GetMeterStatisticsOutputBuilder();
777 output.setTransactionId(generateTransactionId(xid));
778 output.setMeterStats(null);
780 Collection<RpcError> errors = Collections.emptyList();
781 RpcResult<GetMeterStatisticsOutput> rpcResult = Rpcs.getRpcResult(true, output.build(), errors);
782 return Futures.immediateFuture(rpcResult);
785 private TransactionId generateTransactionId(Long xid){
786 String stringXid =xid.toString();
787 BigInteger bigIntXid = new BigInteger( stringXid );
788 return new TransactionId(bigIntXid);
793 public Future<RpcResult<GetPortOutput>> getPort() {
794 // TODO Auto-generated method stub
799 public Future<RpcResult<UpdatePortOutput>> updatePort(UpdatePortInput input) {
800 PortModInput ofPortModInput = null ;
801 RpcResult<UpdatePortOutput> rpcResultFromOFLib = null ;
804 // For Flow provisioning, the SwitchConnectionDistinguisher is set to null so
805 // the request can be routed through any connection to the switch
807 SwitchConnectionDistinguisher cookie = null ;
809 // NSF sends a list of port and the ModelDrivenSwitch will
810 // send one port at a time towards the switch ( mutiple RPCs calls)
811 List<Port> inputPorts = input.getUpdatedPort().getPort().getPort() ;
813 // Get the Xid. The same Xid has to be sent in all the RPCs
814 Long Xid = sessionContext.getNextXid();
816 for( Port inputPort : inputPorts) {
818 // Convert the UpdateGroupInput to GroupModInput
819 ofPortModInput = PortConvertor.toPortModInput(inputPort, version) ;
821 // Insert the Xid ( transaction Id) before calling the RPC on the OFLibrary
823 PortModInputBuilder mdInput = new PortModInputBuilder();
825 mdInput.setVersion(ofPortModInput.getVersion()) ;
826 mdInput.setPortNo(ofPortModInput.getPortNo()) ;
827 mdInput.setMaskV10(ofPortModInput.getMaskV10()) ;
828 mdInput.setMask(ofPortModInput.getMask()) ;
829 mdInput.setHwAddress(ofPortModInput.getHwAddress());
830 mdInput.setConfigV10(ofPortModInput.getConfigV10()) ;
831 mdInput.setConfig(ofPortModInput.getConfig()) ;
832 mdInput.setAdvertiseV10(ofPortModInput.getAdvertiseV10()) ;
833 mdInput.setAdvertise(ofPortModInput.getAdvertise()) ;
835 LOG.debug("Calling the PortMod RPC method on MessageDispatchService");
836 Future<RpcResult<UpdatePortOutput>> resultFromOFLib = messageService.portMod(ofPortModInput, cookie) ;
839 rpcResultFromOFLib = resultFromOFLib.get();
840 } catch( Exception ex ) {
841 LOG.error( " Error while getting result for updatePort RPC" + ex.getMessage());
844 // The Future response value for all the RPCs except the last one is ignored
848 //Extract the Xid only from the Future for the last RPC and
849 // send it back to the NSF
850 UpdatePortOutput updatePortOutputOFLib = rpcResultFromOFLib.getResult() ;
852 UpdatePortOutputBuilder updatePortOutput = new UpdatePortOutputBuilder() ;
853 updatePortOutput.setTransactionId(updatePortOutputOFLib.getTransactionId()) ;
854 UpdatePortOutput result = updatePortOutput.build();
856 Collection<RpcError> errors = rpcResultFromOFLib.getErrors() ;
857 RpcResult<UpdatePortOutput> rpcResult = Rpcs.getRpcResult(true, result, errors);
859 LOG.debug("Returning the Update Group RPC result to MD-SAL");
860 return Futures.immediateFuture(rpcResult);