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.openflowjava.protocol.api.util.BinContent;
19 import org.opendaylight.openflowplugin.openflow.md.core.SwitchConnectionDistinguisher;
20 import org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.FlowConvertor;
21 import org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.GroupConvertor;
22 import org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.MeterConvertor;
23 import org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.PortConvertor;
24 import org.opendaylight.openflowplugin.openflow.md.core.session.IMessageDispatchService;
25 import org.opendaylight.openflowplugin.openflow.md.core.session.SessionContext;
26 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.AddFlowInput;
27 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.AddFlowOutput;
28 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.AddFlowOutputBuilder;
29 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.RemoveFlowInput;
30 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.RemoveFlowOutput;
31 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.RemoveFlowOutputBuilder;
32 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.UpdateFlowInput;
33 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.UpdateFlowOutput;
34 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.UpdateFlowOutputBuilder;
35 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.service.rev130918.AddGroupOutput;
36 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.transaction.rev131103.TransactionId;
37 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.port.rev130925.port.mod.port.Port;
38 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.Flow;
39 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.service.rev130918.AddGroupInput;
40 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.service.rev130918.AddGroupOutputBuilder;
41 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.service.rev130918.RemoveGroupInput;
42 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.service.rev130918.RemoveGroupOutput;
43 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.service.rev130918.RemoveGroupOutputBuilder;
44 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.service.rev130918.UpdateGroupInput;
45 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.service.rev130918.UpdateGroupOutput;
46 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.service.rev130918.UpdateGroupOutputBuilder;
47 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.statistics.rev131111.GetAllGroupStatisticsInput;
48 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.statistics.rev131111.GetAllGroupStatisticsOutput;
49 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.statistics.rev131111.GetAllGroupStatisticsOutputBuilder;
50 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.statistics.rev131111.GetGroupDescriptionInput;
51 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.statistics.rev131111.GetGroupDescriptionOutput;
52 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.statistics.rev131111.GetGroupDescriptionOutputBuilder;
53 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.statistics.rev131111.GetGroupFeaturesInput;
54 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.statistics.rev131111.GetGroupFeaturesOutput;
55 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.statistics.rev131111.GetGroupFeaturesOutputBuilder;
56 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.statistics.rev131111.GetGroupStatisticsInput;
57 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.statistics.rev131111.GetGroupStatisticsOutput;
58 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.statistics.rev131111.GetGroupStatisticsOutputBuilder;
59 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeId;
60 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node;
61 import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.service.rev130918.AddMeterInput;
62 import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.service.rev130918.AddMeterOutput;
63 import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.service.rev130918.AddMeterOutputBuilder;
64 import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.service.rev130918.RemoveMeterInput;
65 import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.service.rev130918.RemoveMeterOutput;
66 import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.service.rev130918.RemoveMeterOutputBuilder;
67 import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.service.rev130918.UpdateMeterInput;
68 import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.service.rev130918.UpdateMeterOutput;
69 import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.service.rev130918.UpdateMeterOutputBuilder;
70 import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.statistics.rev131111.GetAllMeterConfigStatisticsInput;
71 import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.statistics.rev131111.GetAllMeterConfigStatisticsOutput;
72 import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.statistics.rev131111.GetAllMeterConfigStatisticsOutputBuilder;
73 import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.statistics.rev131111.GetAllMeterStatisticsInput;
74 import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.statistics.rev131111.GetAllMeterStatisticsOutput;
75 import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.statistics.rev131111.GetAllMeterStatisticsOutputBuilder;
76 import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.statistics.rev131111.GetMeterFeaturesInput;
77 import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.statistics.rev131111.GetMeterFeaturesOutput;
78 import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.statistics.rev131111.GetMeterFeaturesOutputBuilder;
79 import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.statistics.rev131111.GetMeterStatisticsInput;
80 import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.statistics.rev131111.GetMeterStatisticsOutput;
81 import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.statistics.rev131111.GetMeterStatisticsOutputBuilder;
82 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.Group;
83 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.Meter;
84 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.MultipartRequestFlags;
85 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.MultipartType;
86 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev130731.oxm.fields.MatchEntries;
87 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.FlowModInput;
88 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.FlowModInputBuilder;
89 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.GroupModInput;
90 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.MeterModInput;
91 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.MultipartRequestInputBuilder;
92 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.PortModInput;
93 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.PortModInputBuilder;
94 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.match.grouping.Match;
95 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.match.grouping.MatchBuilder;
96 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.MultipartRequestGroupBuilder;
97 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.MultipartRequestGroupDescBuilder;
98 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.MultipartRequestGroupFeaturesBuilder;
99 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.MultipartRequestMeterBuilder;
100 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.MultipartRequestMeterConfigBuilder;
101 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.MultipartRequestMeterFeaturesBuilder;
102 import org.opendaylight.yang.gen.v1.urn.opendaylight.packet.service.rev130709.TransmitPacketInput;
103 import org.opendaylight.yang.gen.v1.urn.opendaylight.port.service.rev131107.GetPortOutput;
104 import org.opendaylight.yang.gen.v1.urn.opendaylight.port.service.rev131107.UpdatePortInput;
105 import org.opendaylight.yang.gen.v1.urn.opendaylight.port.service.rev131107.UpdatePortOutput;
106 import org.opendaylight.yang.gen.v1.urn.opendaylight.port.service.rev131107.UpdatePortOutputBuilder;
107 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
108 import org.opendaylight.yangtools.yang.common.RpcError;
109 import org.opendaylight.yangtools.yang.common.RpcResult;
110 import org.slf4j.Logger;
112 import com.google.common.util.concurrent.Futures;
115 * RPC implementation of MD-switch
117 public class ModelDrivenSwitchImpl extends AbstractModelDrivenSwitch {
119 private static final Logger LOG = org.slf4j.LoggerFactory
120 .getLogger(ModelDrivenSwitchImpl.class);
121 private final NodeId nodeId;
122 private final IMessageDispatchService messageService ;
123 private short version = 0;
125 protected ModelDrivenSwitchImpl(NodeId nodeId,
126 InstanceIdentifier<Node> identifier, SessionContext context) {
127 super(identifier, context);
128 this.nodeId = nodeId;
129 messageService = sessionContext.getMessageDispatchService() ;
130 version = context.getPrimaryConductor().getVersion();
134 public Future<RpcResult<AddFlowOutput>> addFlow(AddFlowInput input) {
135 // Convert the AddFlowInput to FlowModInput
136 FlowModInput ofFlowModInput = FlowConvertor.toFlowModInput(input, version);
138 // For Flow provisioning, the SwitchConnectionDistinguisher is set to null so
139 // the request can be routed through any connection to the switch
141 SwitchConnectionDistinguisher cookie = null ;
143 LOG.debug("Calling the FlowMod RPC method on MessageDispatchService");
144 Future<RpcResult<UpdateFlowOutput>> resultFromOFLib = messageService.flowMod(ofFlowModInput, cookie) ;
146 RpcResult<UpdateFlowOutput> rpcResultFromOFLib = null ;
149 rpcResultFromOFLib = resultFromOFLib.get();
150 } catch( Exception ex ) {
151 LOG.error( " Error while getting result for AddFlow RPC" + ex.getMessage());
154 UpdateFlowOutput updateFlowOutput = rpcResultFromOFLib.getResult() ;
156 AddFlowOutputBuilder addFlowOutput = new AddFlowOutputBuilder() ;
157 addFlowOutput.setTransactionId(updateFlowOutput.getTransactionId()) ;
158 AddFlowOutput result = addFlowOutput.build();
160 Collection<RpcError> errors = rpcResultFromOFLib.getErrors() ;
161 RpcResult<AddFlowOutput> rpcResult = Rpcs.getRpcResult(true, result, errors);
163 LOG.debug("Returning the Add Flow RPC result to MD-SAL");
164 return Futures.immediateFuture(rpcResult);
168 public Future<RpcResult<AddGroupOutput>> addGroup(AddGroupInput input) {
169 // Convert the AddGroupInput to GroupModInput
170 GroupModInput ofGroupModInput = GroupConvertor.toGroupModInput(input, version);
173 // For Flow provisioning, the SwitchConnectionDistinguisher is set to null so
174 // the request can be routed through any connection to the switch
176 SwitchConnectionDistinguisher cookie = null ;
178 LOG.debug("Calling the GroupMod RPC method on MessageDispatchService");
179 Future<RpcResult<UpdateGroupOutput>> resultFromOFLib = messageService.groupMod(ofGroupModInput, cookie) ;
181 RpcResult<UpdateGroupOutput> rpcResultFromOFLib = null ;
184 rpcResultFromOFLib = resultFromOFLib.get();
185 } catch( Exception ex ) {
186 LOG.error( " Error while getting result for AddGroup RPC" + ex.getMessage());
189 UpdateGroupOutput updateGroupOutput = rpcResultFromOFLib.getResult() ;
191 AddGroupOutputBuilder addGroupOutput = new AddGroupOutputBuilder() ;
192 addGroupOutput.setTransactionId(updateGroupOutput.getTransactionId()) ;
193 AddGroupOutput result = addGroupOutput.build();
195 Collection<RpcError> errors = rpcResultFromOFLib.getErrors() ;
196 RpcResult<AddGroupOutput> rpcResult = Rpcs.getRpcResult(true, result, errors);
198 LOG.debug("Returning the Add Group RPC result to MD-SAL");
199 return Futures.immediateFuture(rpcResult);
203 public Future<RpcResult<AddMeterOutput>> addMeter(AddMeterInput input) {
204 // Convert the AddMeterInput to MeterModInput
205 MeterModInput ofMeterModInput = MeterConvertor.toMeterModInput(input, version);
208 // For Meter provisioning, the SwitchConnectionDistinguisher is set to null so
209 // the request can be routed through any connection to the switch
211 SwitchConnectionDistinguisher cookie = null ;
213 LOG.debug("Calling the MeterMod RPC method on MessageDispatchService");
214 Future<RpcResult<UpdateMeterOutput>> resultFromOFLib = messageService.meterMod(ofMeterModInput, cookie) ;
216 RpcResult<UpdateMeterOutput> rpcResultFromOFLib = null ;
219 rpcResultFromOFLib = resultFromOFLib.get();
220 } catch( Exception ex ) {
221 LOG.error( " Error while getting result for AddMeter RPC" + ex.getMessage());
224 UpdateMeterOutput updateMeterOutput = rpcResultFromOFLib.getResult() ;
226 AddMeterOutputBuilder addMeterOutput = new AddMeterOutputBuilder() ;
227 addMeterOutput.setTransactionId(updateMeterOutput.getTransactionId()) ;
228 AddMeterOutput result = addMeterOutput.build();
230 Collection<RpcError> errors = rpcResultFromOFLib.getErrors() ;
231 RpcResult<AddMeterOutput> rpcResult = Rpcs.getRpcResult(true, result, errors);
233 LOG.debug("Returning the Add Meter RPC result to MD-SAL");
234 return Futures.immediateFuture(rpcResult);
238 public Future<RpcResult<RemoveFlowOutput>> removeFlow(RemoveFlowInput input) {
239 // Convert the RemoveFlowInput to FlowModInput
240 FlowModInput ofFlowModInput = FlowConvertor.toFlowModInput(input, version);
243 // For Flow provisioning, the SwitchConnectionDistinguisher is set to null so
244 // the request can be routed through any connection to the switch
246 SwitchConnectionDistinguisher cookie = null ;
248 LOG.debug("Calling the FlowMod RPC method on MessageDispatchService");
249 Future<RpcResult<UpdateFlowOutput>> resultFromOFLib = messageService.flowMod(ofFlowModInput, cookie) ;
251 RpcResult<UpdateFlowOutput> rpcResultFromOFLib = null ;
254 rpcResultFromOFLib = resultFromOFLib.get();
255 } catch( Exception ex ) {
256 LOG.error( " Error while getting result for remove Flow RPC" + ex.getMessage());
259 UpdateFlowOutput updateFlowOutput = rpcResultFromOFLib.getResult() ;
261 RemoveFlowOutputBuilder removeFlowOutput = new RemoveFlowOutputBuilder() ;
262 removeFlowOutput.setTransactionId(updateFlowOutput.getTransactionId()) ;
263 RemoveFlowOutput result = removeFlowOutput.build();
265 Collection<RpcError> errors = rpcResultFromOFLib.getErrors() ;
266 RpcResult<RemoveFlowOutput> rpcResult = Rpcs.getRpcResult(true, result, errors);
268 LOG.debug("Returning the Remove Flow RPC result to MD-SAL");
269 return Futures.immediateFuture(rpcResult);
273 public Future<RpcResult<RemoveGroupOutput>> removeGroup(
274 RemoveGroupInput input) {
275 // Convert the RemoveGroupInput to GroupModInput
276 GroupModInput ofGroupModInput = GroupConvertor.toGroupModInput(input, version);
279 // For Flow provisioning, the SwitchConnectionDistinguisher is set to null so
280 // the request can be routed through any connection to the switch
282 SwitchConnectionDistinguisher cookie = null ;
284 LOG.debug("Calling the GroupMod RPC method on MessageDispatchService");
285 Future<RpcResult<UpdateGroupOutput>> resultFromOFLib = messageService.groupMod(ofGroupModInput, cookie) ;
287 RpcResult<UpdateGroupOutput> rpcResultFromOFLib = null ;
290 rpcResultFromOFLib = resultFromOFLib.get();
291 } catch( Exception ex ) {
292 LOG.error( " Error while getting result for RemoveGroup RPC" + ex.getMessage());
295 UpdateGroupOutput updateGroupOutput = rpcResultFromOFLib.getResult() ;
297 RemoveGroupOutputBuilder removeGroupOutput = new RemoveGroupOutputBuilder() ;
298 removeGroupOutput.setTransactionId(updateGroupOutput.getTransactionId()) ;
299 RemoveGroupOutput result = removeGroupOutput.build();
301 Collection<RpcError> errors = rpcResultFromOFLib.getErrors() ;
302 RpcResult<RemoveGroupOutput> rpcResult = Rpcs.getRpcResult(true, result, errors);
304 LOG.debug("Returning the Remove Group RPC result to MD-SAL");
305 return Futures.immediateFuture(rpcResult);
309 public Future<RpcResult<RemoveMeterOutput>> removeMeter(
310 RemoveMeterInput input) {
311 // Convert the RemoveMeterInput to MeterModInput
312 MeterModInput ofMeterModInput = MeterConvertor.toMeterModInput(input, version);
315 // For Meter provisioning, the SwitchConnectionDistinguisher is set to null so
316 // the request can be routed through any connection to the switch
318 SwitchConnectionDistinguisher cookie = null ;
320 LOG.debug("Calling the MeterMod RPC method on MessageDispatchService");
321 Future<RpcResult<UpdateMeterOutput>> resultFromOFLib = messageService.meterMod(ofMeterModInput, cookie) ;
323 RpcResult<UpdateMeterOutput> rpcResultFromOFLib = null ;
326 rpcResultFromOFLib = resultFromOFLib.get();
327 } catch( Exception ex ) {
328 LOG.error( " Error while getting result for RemoveMeter RPC" + ex.getMessage());
331 UpdateMeterOutput updatemeterOutput = rpcResultFromOFLib.getResult() ;
333 RemoveMeterOutputBuilder removeMeterOutput = new RemoveMeterOutputBuilder() ;
334 removeMeterOutput.setTransactionId(updatemeterOutput.getTransactionId()) ;
335 RemoveMeterOutput result = removeMeterOutput.build();
337 Collection<RpcError> errors = rpcResultFromOFLib.getErrors() ;
338 RpcResult<RemoveMeterOutput> rpcResult = Rpcs.getRpcResult(true, result, errors);
340 LOG.debug("Returning the Remove Meter RPC result to MD-SAL");
341 return Futures.immediateFuture(rpcResult);
345 public Future<RpcResult<Void>> transmitPacket(TransmitPacketInput input) {
346 // TODO Auto-generated method stub
350 private FlowModInputBuilder toFlowModInputBuilder(Flow source) {
351 FlowModInputBuilder target = new FlowModInputBuilder();
352 target.setCookie(source.getCookie());
353 target.setIdleTimeout(source.getIdleTimeout());
354 target.setHardTimeout(source.getHardTimeout());
355 target.setMatch(toMatch(source.getMatch()));
360 private Match toMatch(
361 org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.Match match) {
362 MatchBuilder target = new MatchBuilder();
364 target.setMatchEntries(toMatchEntries(match));
369 private List<MatchEntries> toMatchEntries(
370 org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.Match match) {
371 List<MatchEntries> entries = new ArrayList<>();
377 public Future<RpcResult<UpdateFlowOutput>> updateFlow(UpdateFlowInput input) {
378 // Convert the UpdateFlowInput to FlowModInput
379 FlowModInput ofFlowModInput = FlowConvertor.toFlowModInput(input.getUpdatedFlow(), version);
381 // Call the RPC method on MessageDispatchService
383 // For Flow provisioning, the SwitchConnectionDistinguisher is set to null so
384 // the request can be routed through any connection to the switch
386 SwitchConnectionDistinguisher cookie = null ;
388 LOG.debug("Calling the FlowMod RPC method on MessageDispatchService");
389 Future<RpcResult<UpdateFlowOutput>> resultFromOFLib = messageService.flowMod(ofFlowModInput, cookie) ;
391 RpcResult<UpdateFlowOutput> rpcResultFromOFLib = null ;
394 rpcResultFromOFLib = resultFromOFLib.get();
395 } catch( Exception ex ) {
396 LOG.error( " Error while getting result for UpdateFlow RPC" + ex.getMessage());
399 UpdateFlowOutput updateFlowOutputOFLib = rpcResultFromOFLib.getResult() ;
401 UpdateFlowOutputBuilder updateFlowOutput = new UpdateFlowOutputBuilder() ;
402 updateFlowOutput.setTransactionId(updateFlowOutputOFLib.getTransactionId()) ;
403 UpdateFlowOutput result = updateFlowOutput.build();
405 Collection<RpcError> errors = rpcResultFromOFLib.getErrors() ;
406 RpcResult<UpdateFlowOutput> rpcResult = Rpcs.getRpcResult(true, result, errors);
408 LOG.debug("Returning the Update Flow RPC result to MD-SAL");
409 return Futures.immediateFuture(rpcResult);
413 public Future<RpcResult<UpdateGroupOutput>> updateGroup(
414 UpdateGroupInput input) {
415 // Convert the UpdateGroupInput to GroupModInput
416 GroupModInput ofGroupModInput = GroupConvertor.toGroupModInput(input.getUpdatedGroup(), version);
419 // For Flow provisioning, the SwitchConnectionDistinguisher is set to null so
420 // the request can be routed through any connection to the switch
422 SwitchConnectionDistinguisher cookie = null ;
424 LOG.debug("Calling the GroupMod RPC method on MessageDispatchService");
425 Future<RpcResult<UpdateGroupOutput>> resultFromOFLib = messageService.groupMod(ofGroupModInput, cookie) ;
427 RpcResult<UpdateGroupOutput> rpcResultFromOFLib = null ;
430 rpcResultFromOFLib = resultFromOFLib.get();
431 } catch( Exception ex ) {
432 LOG.error( " Error while getting result for updateGroup RPC" + ex.getMessage());
435 UpdateGroupOutput updateGroupOutputOFLib = rpcResultFromOFLib.getResult() ;
437 UpdateGroupOutputBuilder updateGroupOutput = new UpdateGroupOutputBuilder() ;
438 updateGroupOutput.setTransactionId(updateGroupOutputOFLib.getTransactionId()) ;
439 UpdateGroupOutput result = updateGroupOutput.build();
441 Collection<RpcError> errors = rpcResultFromOFLib.getErrors() ;
442 RpcResult<UpdateGroupOutput> rpcResult = Rpcs.getRpcResult(true, result, errors);
444 LOG.debug("Returning the Update Group RPC result to MD-SAL");
445 return Futures.immediateFuture(rpcResult);
449 public Future<RpcResult<UpdateMeterOutput>> updateMeter(
450 UpdateMeterInput input) {
451 // Convert the UpdateMeterInput to MeterModInput
452 MeterModInput ofMeterModInput = MeterConvertor.toMeterModInput(input.getUpdatedMeter(), version);
455 // For Meter provisioning, the SwitchConnectionDistinguisher is set to null so
456 // the request can be routed through any connection to the switch
458 SwitchConnectionDistinguisher cookie = null ;
460 LOG.debug("Calling the MeterMod RPC method on MessageDispatchService");
461 Future<RpcResult<UpdateMeterOutput>> resultFromOFLib = messageService.meterMod(ofMeterModInput, cookie) ;
463 RpcResult<UpdateMeterOutput> rpcResultFromOFLib = null ;
466 rpcResultFromOFLib = resultFromOFLib.get();
467 } catch( Exception ex ) {
468 LOG.error( " Error while getting result for UpdateMeter RPC" + ex.getMessage());
471 UpdateMeterOutput updateMeterOutputFromOFLib = rpcResultFromOFLib.getResult() ;
473 UpdateMeterOutputBuilder updateMeterOutput = new UpdateMeterOutputBuilder() ;
474 updateMeterOutput.setTransactionId(updateMeterOutputFromOFLib.getTransactionId()) ;
475 UpdateMeterOutput result = updateMeterOutput.build();
477 Collection<RpcError> errors = rpcResultFromOFLib.getErrors() ;
478 RpcResult<UpdateMeterOutput> rpcResult = Rpcs.getRpcResult(true, result, errors);
480 LOG.debug("Returning the Update Meter RPC result to MD-SAL");
481 return Futures.immediateFuture(rpcResult);
485 public NodeId getNodeId() {
490 * Methods for requesting statistics from switch
493 public Future<RpcResult<GetAllGroupStatisticsOutput>> getAllGroupStatistics(GetAllGroupStatisticsInput input) {
495 //Generate xid to associate it with the request
496 Long xid = this.getSessionContext().getNextXid();
498 LOG.debug("Prepare statistics request for all the groups - Transaction id - {}",xid);
500 // Create multipart request header
501 MultipartRequestInputBuilder mprInput = new MultipartRequestInputBuilder();
502 mprInput.setType(MultipartType.OFPMPGROUP);
503 mprInput.setVersion(version);
504 mprInput.setXid(xid);
505 mprInput.setFlags(new MultipartRequestFlags(false));
507 // Create multipart request body for fetch all the group stats
508 MultipartRequestGroupBuilder mprGroupBuild = new MultipartRequestGroupBuilder();
509 mprGroupBuild.setGroupId(BinContent.intToUnsignedLong(Group.OFPGALL.getIntValue()));
511 //Set request body to main multipart request
512 mprInput.setMultipartRequestBody(mprGroupBuild.build());
514 //Send the request, no cookies associated, use any connection
515 LOG.debug("Send group statistics request to the switch :{}",mprGroupBuild);
516 this.messageService.multipartRequest(mprInput.build(), null);
518 // Prepare rpc return output. Set xid and send it back.
519 LOG.debug("Return results and transaction id back to caller");
520 GetAllGroupStatisticsOutputBuilder output = new GetAllGroupStatisticsOutputBuilder();
521 output.setTransactionId(generateTransactionId(xid));
522 output.setGroupStats(null);
524 Collection<RpcError> errors = Collections.emptyList();
525 RpcResult<GetAllGroupStatisticsOutput> rpcResult = Rpcs.getRpcResult(true, output.build(), errors);
526 return Futures.immediateFuture(rpcResult);
531 public Future<RpcResult<GetGroupDescriptionOutput>> getGroupDescription(GetGroupDescriptionInput input) {
533 //Generate xid to associate it with the request
534 Long xid = this.getSessionContext().getNextXid();
536 LOG.debug("Prepare group description statistics request - Transaction id - {}",xid);
538 // Create multipart request header
539 MultipartRequestInputBuilder mprInput = new MultipartRequestInputBuilder();
540 mprInput.setType(MultipartType.OFPMPGROUPDESC);
541 mprInput.setVersion(version);
542 mprInput.setXid(xid);
543 mprInput.setFlags(new MultipartRequestFlags(false));
545 // Create multipart request body for fetch all the group description stats
546 MultipartRequestGroupDescBuilder mprGroupDescBuild = new MultipartRequestGroupDescBuilder();
548 //Set request body to main multipart request
549 mprInput.setMultipartRequestBody(mprGroupDescBuild.build());
551 //Send the request, no cookies associated, use any connection
552 LOG.debug("Send group desciption statistics request to switch : {}",mprGroupDescBuild);
553 this.messageService.multipartRequest(mprInput.build(), null);
555 // Prepare rpc return output. Set xid and send it back.
556 LOG.debug("Return results and transaction id back to caller");
557 GetGroupDescriptionOutputBuilder output = new GetGroupDescriptionOutputBuilder();
558 output.setTransactionId(generateTransactionId(xid));
559 output.setGroupDescStats(null);
561 Collection<RpcError> errors = Collections.emptyList();
562 RpcResult<GetGroupDescriptionOutput> rpcResult = Rpcs.getRpcResult(true, output.build(), errors);
563 return Futures.immediateFuture(rpcResult);
568 public Future<RpcResult<GetGroupFeaturesOutput>> getGroupFeatures(GetGroupFeaturesInput input) {
570 //Generate xid to associate it with the request
571 Long xid = this.getSessionContext().getNextXid();
573 LOG.debug("Prepare group features statistics request - Transaction id - {}",xid);
575 // Create multipart request header
576 MultipartRequestInputBuilder mprInput = new MultipartRequestInputBuilder();
577 mprInput.setType(MultipartType.OFPMPGROUPFEATURES);
578 mprInput.setVersion(version);
579 mprInput.setXid(xid);
580 mprInput.setFlags(new MultipartRequestFlags(false));
582 // Create multipart request body for fetch all the group description stats
583 MultipartRequestGroupFeaturesBuilder mprGroupFeaturesBuild = new MultipartRequestGroupFeaturesBuilder();
585 //Set request body to main multipart request
586 mprInput.setMultipartRequestBody(mprGroupFeaturesBuild.build());
588 //Send the request, no cookies associated, use any connection
589 LOG.debug("Send group features statistics request :{}",mprGroupFeaturesBuild);
590 this.messageService.multipartRequest(mprInput.build(), null);
592 // Prepare rpc return output. Set xid and send it back.
593 LOG.debug("Return results and transaction id back to caller");
594 GetGroupFeaturesOutputBuilder output = new GetGroupFeaturesOutputBuilder();
595 output.setTransactionId(generateTransactionId(xid));
597 Collection<RpcError> errors = Collections.emptyList();
598 RpcResult<GetGroupFeaturesOutput> rpcResult = Rpcs.getRpcResult(true, output.build(), errors);
599 return Futures.immediateFuture(rpcResult);
603 public Future<RpcResult<GetGroupStatisticsOutput>> getGroupStatistics(GetGroupStatisticsInput input) {
605 //Generate xid to associate it with the request
606 Long xid = this.getSessionContext().getNextXid();
608 LOG.debug("Prepare statistics request for node {} group ({}) - Transaction id - {}",input.getNode(),input.getGroupId(),xid);
610 // Create multipart request header
611 MultipartRequestInputBuilder mprInput = new MultipartRequestInputBuilder();
612 mprInput.setType(MultipartType.OFPMPGROUP);
613 mprInput.setVersion(version);
614 mprInput.setXid(xid);
615 mprInput.setFlags(new MultipartRequestFlags(false));
617 // Create multipart request body for fetch all the group stats
618 MultipartRequestGroupBuilder mprGroupBuild = new MultipartRequestGroupBuilder();
619 mprGroupBuild.setGroupId(input.getGroupId().getValue());
621 //Set request body to main multipart request
622 mprInput.setMultipartRequestBody(mprGroupBuild.build());
624 //Send the request, no cookies associated, use any connection
625 LOG.debug("Send group statistics request :{}",mprGroupBuild);
626 this.messageService.multipartRequest(mprInput.build(), null);
628 // Prepare rpc return output. Set xid and send it back.
629 LOG.debug("Return results and transaction id back to caller");
630 GetGroupStatisticsOutputBuilder output = new GetGroupStatisticsOutputBuilder();
631 output.setTransactionId(generateTransactionId(xid));
632 output.setGroupStats(null);
634 Collection<RpcError> errors = Collections.emptyList();
635 RpcResult<GetGroupStatisticsOutput> rpcResult = Rpcs.getRpcResult(true, output.build(), errors);
636 return Futures.immediateFuture(rpcResult);
640 public Future<RpcResult<GetAllMeterConfigStatisticsOutput>> getAllMeterConfigStatistics(
641 GetAllMeterConfigStatisticsInput input) {
643 //Generate xid to associate it with the request
644 Long xid = this.getSessionContext().getNextXid();
646 LOG.debug("Prepare config request for all the meters - Transaction id - {}",xid);
648 // Create multipart request header
649 MultipartRequestInputBuilder mprInput = new MultipartRequestInputBuilder();
650 mprInput.setType(MultipartType.OFPMPMETERCONFIG);
651 mprInput.setVersion(version);
652 mprInput.setXid(xid);
653 mprInput.setFlags(new MultipartRequestFlags(false));
655 // Create multipart request body for fetch all the meter stats
656 MultipartRequestMeterConfigBuilder mprMeterConfigBuild = new MultipartRequestMeterConfigBuilder();
657 mprMeterConfigBuild.setMeterId(BinContent.intToUnsignedLong(Meter.OFPMALL.getIntValue()));
659 //Set request body to main multipart request
660 mprInput.setMultipartRequestBody(mprMeterConfigBuild.build());
662 //Send the request, no cookies associated, use any connection
663 LOG.debug("Send meter statistics request :{}",mprMeterConfigBuild);
664 this.messageService.multipartRequest(mprInput.build(), null);
666 // Prepare rpc return output. Set xid and send it back.
667 LOG.debug("Return results and transaction id back to caller");
668 GetAllMeterConfigStatisticsOutputBuilder output = new GetAllMeterConfigStatisticsOutputBuilder();
669 output.setTransactionId(generateTransactionId(xid));
670 output.setMeterConfigStats(null);
672 Collection<RpcError> errors = Collections.emptyList();
673 RpcResult<GetAllMeterConfigStatisticsOutput> rpcResult = Rpcs.getRpcResult(true, output.build(), errors);
674 return Futures.immediateFuture(rpcResult);
678 public Future<RpcResult<GetAllMeterStatisticsOutput>> getAllMeterStatistics(GetAllMeterStatisticsInput input) {
680 //Generate xid to associate it with the request
681 Long xid = this.getSessionContext().getNextXid();
683 LOG.debug("Prepare statistics request for all the meters - Transaction id - {}",xid);
685 // Create multipart request header
686 MultipartRequestInputBuilder mprInput = new MultipartRequestInputBuilder();
687 mprInput.setType(MultipartType.OFPMPMETER);
688 mprInput.setVersion(version);
689 mprInput.setXid(xid);
690 mprInput.setFlags(new MultipartRequestFlags(false));
692 // Create multipart request body for fetch all the meter stats
693 MultipartRequestMeterBuilder mprMeterBuild = new MultipartRequestMeterBuilder();
694 mprMeterBuild.setMeterId(BinContent.intToUnsignedLong(Meter.OFPMALL.getIntValue()));
696 //Set request body to main multipart request
697 mprInput.setMultipartRequestBody(mprMeterBuild.build());
699 //Send the request, no cookies associated, use any connection
700 LOG.debug("Send meter statistics request :{}",mprMeterBuild);
701 this.messageService.multipartRequest(mprInput.build(), null);
703 // Prepare rpc return output. Set xid and send it back.
704 LOG.debug("Return results and transaction id back to caller");
705 GetAllMeterStatisticsOutputBuilder output = new GetAllMeterStatisticsOutputBuilder();
706 output.setTransactionId(generateTransactionId(xid));
707 output.setMeterStats(null);
709 Collection<RpcError> errors = Collections.emptyList();
710 RpcResult<GetAllMeterStatisticsOutput> rpcResult = Rpcs.getRpcResult(true, output.build(), errors);
711 return Futures.immediateFuture(rpcResult);
715 public Future<RpcResult<GetMeterFeaturesOutput>> getMeterFeatures(GetMeterFeaturesInput input) {
717 //Generate xid to associate it with the request
718 Long xid = this.getSessionContext().getNextXid();
720 LOG.debug("Prepare features statistics request for all the meters - Transaction id - {}",xid);
722 // Create multipart request header
723 MultipartRequestInputBuilder mprInput = new MultipartRequestInputBuilder();
724 mprInput.setType(MultipartType.OFPMPMETERFEATURES);
725 mprInput.setVersion(version);
726 mprInput.setXid(xid);
727 mprInput.setFlags(new MultipartRequestFlags(false));
729 // Create multipart request body for fetch all the group description stats
730 MultipartRequestMeterFeaturesBuilder mprMeterFeaturesBuild = new MultipartRequestMeterFeaturesBuilder();
732 //Set request body to main multipart request
733 mprInput.setMultipartRequestBody(mprMeterFeaturesBuild.build());
735 //Send the request, no cookies associated, use any connection
736 LOG.debug("Send meter features statistics request :{}",mprMeterFeaturesBuild);
737 this.messageService.multipartRequest(mprInput.build(), null);
739 // Prepare rpc return output. Set xid and send it back.
740 LOG.debug("Return results and transaction id back to caller");
741 GetMeterFeaturesOutputBuilder output = new GetMeterFeaturesOutputBuilder();
742 output.setTransactionId(generateTransactionId(xid));
744 Collection<RpcError> errors = Collections.emptyList();
745 RpcResult<GetMeterFeaturesOutput> rpcResult = Rpcs.getRpcResult(true, output.build(), errors);
746 return Futures.immediateFuture(rpcResult);
750 public Future<RpcResult<GetMeterStatisticsOutput>> getMeterStatistics(GetMeterStatisticsInput input) {
751 //Generate xid to associate it with the request
752 Long xid = this.getSessionContext().getNextXid();
754 LOG.debug("Preprae statistics request for Meter ({}) - Transaction id - {}",input.getMeterId().getValue(),xid);
756 // Create multipart request header
757 MultipartRequestInputBuilder mprInput = new MultipartRequestInputBuilder();
758 mprInput.setType(MultipartType.OFPMPMETER);
759 mprInput.setVersion(version);
760 mprInput.setXid(xid);
761 mprInput.setFlags(new MultipartRequestFlags(false));
763 // Create multipart request body for fetch all the meter stats
764 MultipartRequestMeterBuilder mprMeterBuild = new MultipartRequestMeterBuilder();
765 //Select specific meter
766 mprMeterBuild.setMeterId(input.getMeterId().getValue());
768 //Set request body to main multipart request
769 mprInput.setMultipartRequestBody(mprMeterBuild.build());
771 //Send the request, no cookies associated, use any connection
772 LOG.debug("Send meter statistics request :{}",mprMeterBuild);
773 this.messageService.multipartRequest(mprInput.build(), null);
775 // Prepare rpc return output. Set xid and send it back.
776 LOG.debug("Return results and transaction id back to caller");
777 GetMeterStatisticsOutputBuilder output = new GetMeterStatisticsOutputBuilder();
778 output.setTransactionId(generateTransactionId(xid));
779 output.setMeterStats(null);
781 Collection<RpcError> errors = Collections.emptyList();
782 RpcResult<GetMeterStatisticsOutput> rpcResult = Rpcs.getRpcResult(true, output.build(), errors);
783 return Futures.immediateFuture(rpcResult);
786 private TransactionId generateTransactionId(Long xid){
787 String stringXid =xid.toString();
788 BigInteger bigIntXid = new BigInteger( stringXid );
789 return new TransactionId(bigIntXid);
794 public Future<RpcResult<GetPortOutput>> getPort() {
795 // TODO Auto-generated method stub
800 public Future<RpcResult<UpdatePortOutput>> updatePort(UpdatePortInput input) {
801 PortModInput ofPortModInput = null ;
802 RpcResult<UpdatePortOutput> rpcResultFromOFLib = null ;
805 // For Flow provisioning, the SwitchConnectionDistinguisher is set to null so
806 // the request can be routed through any connection to the switch
808 SwitchConnectionDistinguisher cookie = null ;
810 // NSF sends a list of port and the ModelDrivenSwitch will
811 // send one port at a time towards the switch ( mutiple RPCs calls)
812 List<Port> inputPorts = input.getUpdatedPort().getPort().getPort() ;
814 // Get the Xid. The same Xid has to be sent in all the RPCs
815 Long Xid = sessionContext.getNextXid();
817 for( Port inputPort : inputPorts) {
819 // Convert the UpdateGroupInput to GroupModInput
820 ofPortModInput = PortConvertor.toPortModInput(inputPort, version) ;
822 // Insert the Xid ( transaction Id) before calling the RPC on the OFLibrary
824 PortModInputBuilder mdInput = new PortModInputBuilder();
826 mdInput.setVersion(ofPortModInput.getVersion()) ;
827 mdInput.setPortNo(ofPortModInput.getPortNo()) ;
828 mdInput.setMaskV10(ofPortModInput.getMaskV10()) ;
829 mdInput.setMask(ofPortModInput.getMask()) ;
830 mdInput.setHwAddress(ofPortModInput.getHwAddress());
831 mdInput.setConfigV10(ofPortModInput.getConfigV10()) ;
832 mdInput.setConfig(ofPortModInput.getConfig()) ;
833 mdInput.setAdvertiseV10(ofPortModInput.getAdvertiseV10()) ;
834 mdInput.setAdvertise(ofPortModInput.getAdvertise()) ;
836 LOG.debug("Calling the PortMod RPC method on MessageDispatchService");
837 Future<RpcResult<UpdatePortOutput>> resultFromOFLib = messageService.portMod(ofPortModInput, cookie) ;
840 rpcResultFromOFLib = resultFromOFLib.get();
841 } catch( Exception ex ) {
842 LOG.error( " Error while getting result for updatePort RPC" + ex.getMessage());
845 // The Future response value for all the RPCs except the last one is ignored
849 //Extract the Xid only from the Future for the last RPC and
850 // send it back to the NSF
851 UpdatePortOutput updatePortOutputOFLib = rpcResultFromOFLib.getResult() ;
853 UpdatePortOutputBuilder updatePortOutput = new UpdatePortOutputBuilder() ;
854 updatePortOutput.setTransactionId(updatePortOutputOFLib.getTransactionId()) ;
855 UpdatePortOutput result = updatePortOutput.build();
857 Collection<RpcError> errors = rpcResultFromOFLib.getErrors() ;
858 RpcResult<UpdatePortOutput> rpcResult = Rpcs.getRpcResult(true, result, errors);
860 LOG.debug("Returning the Update Group RPC result to MD-SAL");
861 return Futures.immediateFuture(rpcResult);