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.util.ArrayList;
11 import java.util.Collection;
12 import java.util.List;
13 import java.util.concurrent.Future;
15 import org.opendaylight.controller.sal.common.util.Rpcs;
16 import org.opendaylight.openflowplugin.openflow.md.core.SwitchConnectionDistinguisher;
17 import org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.FlowConvertor;
18 import org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.GroupConvertor;
19 import org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.MeterConverter;
20 import org.opendaylight.openflowplugin.openflow.md.core.session.IMessageDispatchService;
21 import org.opendaylight.openflowplugin.openflow.md.core.session.SessionContext;
22 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.AddFlowInput;
23 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.AddFlowOutput;
24 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.AddFlowOutputBuilder;
25 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.NodeFlow;
26 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.RemoveFlowInput;
27 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.RemoveFlowOutput;
28 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.RemoveFlowOutputBuilder;
29 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.UpdateFlowInput;
30 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.UpdateFlowOutput;
31 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.UpdateFlowOutputBuilder;
32 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.service.rev130918.AddGroupOutput;
33 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.Flow;
34 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.service.rev130918.AddGroupInput;
35 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.service.rev130918.AddGroupOutput;
36 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.service.rev130918.AddGroupOutputBuilder;
37 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.service.rev130918.RemoveGroupInput;
38 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.service.rev130918.RemoveGroupOutput;
39 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.service.rev130918.RemoveGroupOutputBuilder;
40 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.service.rev130918.UpdateGroupInput;
41 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.service.rev130918.UpdateGroupOutput;
42 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.service.rev130918.UpdateGroupOutputBuilder;
43 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeId;
44 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node;
45 import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.service.rev130918.AddMeterInput;
46 import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.service.rev130918.AddMeterOutput;
47 import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.service.rev130918.AddMeterOutputBuilder;
48 import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.service.rev130918.RemoveMeterInput;
49 import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.service.rev130918.RemoveMeterOutput;
50 import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.service.rev130918.RemoveMeterOutputBuilder;
51 import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.service.rev130918.UpdateMeterInput;
52 import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.service.rev130918.UpdateMeterOutput;
53 import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.service.rev130918.UpdateMeterOutputBuilder;
54 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev130731.oxm.fields.MatchEntries;
55 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.FlowModInput;
56 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.FlowModInputBuilder;
57 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.GroupModInput;
58 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.MeterModInput;
59 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.match.grouping.Match;
60 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.match.grouping.MatchBuilder;
61 import org.opendaylight.yang.gen.v1.urn.opendaylight.packet.service.rev130709.TransmitPacketInput;
62 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
63 import org.opendaylight.yangtools.yang.common.RpcError;
64 import org.opendaylight.yangtools.yang.common.RpcResult;
65 import org.slf4j.Logger;
67 import com.google.common.util.concurrent.Futures;
70 * RPC implementation of MD-switch
72 public class ModelDrivenSwitchImpl extends AbstractModelDrivenSwitch {
74 private static final Logger LOG = org.slf4j.LoggerFactory
75 .getLogger(ModelDrivenSwitchImpl.class);
76 private final NodeId nodeId;
77 private IMessageDispatchService messageService ;
79 protected ModelDrivenSwitchImpl(NodeId nodeId,
80 InstanceIdentifier<Node> identifier, SessionContext context) {
81 super(identifier, context);
83 messageService = sessionContext.getMessageDispatchService() ;
87 public Future<RpcResult<AddFlowOutput>> addFlow(AddFlowInput input) {
88 // Convert the AddFlowInput to FlowModInput
89 FlowModInput ofFlowModInput = FlowConvertor.toFlowModInput(input) ;
91 // For Flow provisioning, the SwitchConnectionDistinguisher is set to null so
92 // the request can be routed through any connection to the switch
94 SwitchConnectionDistinguisher cookie = null ;
96 LOG.debug("Calling the FlowMod RPC method on MessageDispatchService");
97 Future<RpcResult<UpdateFlowOutput>> resultFromOFLib = messageService.flowMod(ofFlowModInput, cookie) ;
99 RpcResult<UpdateFlowOutput> rpcResultFromOFLib = null ;
102 rpcResultFromOFLib = resultFromOFLib.get();
103 } catch( Exception ex ) {
104 LOG.error( " Error while getting result for AddFlow RPC" + ex.getMessage());
107 UpdateFlowOutput updateFlowOutput = rpcResultFromOFLib.getResult() ;
109 AddFlowOutputBuilder addFlowOutput = new AddFlowOutputBuilder() ;
110 addFlowOutput.setTransactionId(updateFlowOutput.getTransactionId()) ;
111 AddFlowOutput result = addFlowOutput.build();
113 Collection<RpcError> errors = rpcResultFromOFLib.getErrors() ;
114 RpcResult<AddFlowOutput> rpcResult = Rpcs.getRpcResult(true, result, errors);
116 LOG.debug("Returning the Add Flow RPC result to MD-SAL");
117 return Futures.immediateFuture(rpcResult);
121 public Future<RpcResult<AddGroupOutput>> addGroup(AddGroupInput input) {
122 // Convert the AddGroupInput to GroupModInput
123 GroupModInput ofGroupModInput = GroupConvertor.toGroupModInput(input) ;
126 // For Flow provisioning, the SwitchConnectionDistinguisher is set to null so
127 // the request can be routed through any connection to the switch
129 SwitchConnectionDistinguisher cookie = null ;
131 LOG.debug("Calling the GroupMod RPC method on MessageDispatchService");
132 Future<RpcResult<UpdateGroupOutput>> resultFromOFLib = messageService.groupMod(ofGroupModInput, cookie) ;
134 RpcResult<UpdateGroupOutput> rpcResultFromOFLib = null ;
137 rpcResultFromOFLib = resultFromOFLib.get();
138 } catch( Exception ex ) {
139 LOG.error( " Error while getting result for AddGroup RPC" + ex.getMessage());
142 UpdateGroupOutput updateGroupOutput = rpcResultFromOFLib.getResult() ;
144 AddGroupOutputBuilder addGroupOutput = new AddGroupOutputBuilder() ;
145 addGroupOutput.setTransactionId(updateGroupOutput.getTransactionId()) ;
146 AddGroupOutput result = addGroupOutput.build();
148 Collection<RpcError> errors = rpcResultFromOFLib.getErrors() ;
149 RpcResult<AddGroupOutput> rpcResult = Rpcs.getRpcResult(true, result, errors);
151 LOG.debug("Returning the Add Group RPC result to MD-SAL");
152 return Futures.immediateFuture(rpcResult);
156 public Future<RpcResult<AddMeterOutput>> addMeter(AddMeterInput input) {
157 // Convert the AddMeterInput to MeterModInput
158 MeterModInput ofMeterModInput = MeterConverter.toMeterModInput(input) ;
161 // For Meter provisioning, the SwitchConnectionDistinguisher is set to null so
162 // the request can be routed through any connection to the switch
164 SwitchConnectionDistinguisher cookie = null ;
166 LOG.debug("Calling the MeterMod RPC method on MessageDispatchService");
167 Future<RpcResult<UpdateMeterOutput>> resultFromOFLib = messageService.meterMod(ofMeterModInput, cookie) ;
169 RpcResult<UpdateMeterOutput> rpcResultFromOFLib = null ;
172 rpcResultFromOFLib = resultFromOFLib.get();
173 } catch( Exception ex ) {
174 LOG.error( " Error while getting result for AddMeter RPC" + ex.getMessage());
177 UpdateMeterOutput updateMeterOutput = rpcResultFromOFLib.getResult() ;
179 AddMeterOutputBuilder addMeterOutput = new AddMeterOutputBuilder() ;
180 addMeterOutput.setTransactionId(updateMeterOutput.getTransactionId()) ;
181 AddMeterOutput result = addMeterOutput.build();
183 Collection<RpcError> errors = rpcResultFromOFLib.getErrors() ;
184 RpcResult<AddMeterOutput> rpcResult = Rpcs.getRpcResult(true, result, errors);
186 LOG.debug("Returning the Add Meter RPC result to MD-SAL");
187 return Futures.immediateFuture(rpcResult);
191 public Future<RpcResult<RemoveFlowOutput>> removeFlow(RemoveFlowInput input) {
192 // Convert the RemoveFlowInput to FlowModInput
193 FlowModInput ofFlowModInput = FlowConvertor.toFlowModInput(input) ;
196 // For Flow provisioning, the SwitchConnectionDistinguisher is set to null so
197 // the request can be routed through any connection to the switch
199 SwitchConnectionDistinguisher cookie = null ;
201 LOG.debug("Calling the FlowMod RPC method on MessageDispatchService");
202 Future<RpcResult<UpdateFlowOutput>> resultFromOFLib = messageService.flowMod(ofFlowModInput, cookie) ;
204 RpcResult<UpdateFlowOutput> rpcResultFromOFLib = null ;
207 rpcResultFromOFLib = resultFromOFLib.get();
208 } catch( Exception ex ) {
209 LOG.error( " Error while getting result for remove Flow RPC" + ex.getMessage());
212 UpdateFlowOutput updateFlowOutput = rpcResultFromOFLib.getResult() ;
214 RemoveFlowOutputBuilder removeFlowOutput = new RemoveFlowOutputBuilder() ;
215 removeFlowOutput.setTransactionId(updateFlowOutput.getTransactionId()) ;
216 RemoveFlowOutput result = removeFlowOutput.build();
218 Collection<RpcError> errors = rpcResultFromOFLib.getErrors() ;
219 RpcResult<RemoveFlowOutput> rpcResult = Rpcs.getRpcResult(true, result, errors);
221 LOG.debug("Returning the Remove Flow RPC result to MD-SAL");
222 return Futures.immediateFuture(rpcResult);
226 public Future<RpcResult<RemoveGroupOutput>> removeGroup(
227 RemoveGroupInput input) {
228 // Convert the RemoveGroupInput to GroupModInput
229 GroupModInput ofGroupModInput = GroupConvertor.toGroupModInput(input.getUpdatedGroup()) ;
232 // For Flow provisioning, the SwitchConnectionDistinguisher is set to null so
233 // the request can be routed through any connection to the switch
235 SwitchConnectionDistinguisher cookie = null ;
237 LOG.debug("Calling the GroupMod RPC method on MessageDispatchService");
238 Future<RpcResult<UpdateGroupOutput>> resultFromOFLib = messageService.groupMod(ofGroupModInput, cookie) ;
240 RpcResult<UpdateGroupOutput> rpcResultFromOFLib = null ;
243 rpcResultFromOFLib = resultFromOFLib.get();
244 } catch( Exception ex ) {
245 LOG.error( " Error while getting result for RemoveGroup RPC" + ex.getMessage());
248 UpdateGroupOutput updateGroupOutput = rpcResultFromOFLib.getResult() ;
250 RemoveGroupOutputBuilder removeGroupOutput = new RemoveGroupOutputBuilder() ;
251 removeGroupOutput.setTransactionId(updateGroupOutput.getTransactionId()) ;
252 RemoveGroupOutput result = removeGroupOutput.build();
254 Collection<RpcError> errors = rpcResultFromOFLib.getErrors() ;
255 RpcResult<RemoveGroupOutput> rpcResult = Rpcs.getRpcResult(true, result, errors);
257 LOG.debug("Returning the Remove Group RPC result to MD-SAL");
258 return Futures.immediateFuture(rpcResult);
262 public Future<RpcResult<RemoveMeterOutput>> removeMeter(
263 RemoveMeterInput input) {
264 // Convert the RemoveMeterInput to MeterModInput
265 MeterModInput ofMeterModInput = MeterConverter.toMeterModInput(input) ;
268 // For Meter provisioning, the SwitchConnectionDistinguisher is set to null so
269 // the request can be routed through any connection to the switch
271 SwitchConnectionDistinguisher cookie = null ;
273 LOG.debug("Calling the MeterMod RPC method on MessageDispatchService");
274 Future<RpcResult<UpdateMeterOutput>> resultFromOFLib = messageService.meterMod(ofMeterModInput, cookie) ;
276 RpcResult<UpdateMeterOutput> rpcResultFromOFLib = null ;
279 rpcResultFromOFLib = resultFromOFLib.get();
280 } catch( Exception ex ) {
281 LOG.error( " Error while getting result for RemoveMeter RPC" + ex.getMessage());
284 UpdateMeterOutput updatemeterOutput = rpcResultFromOFLib.getResult() ;
286 RemoveMeterOutputBuilder removeMeterOutput = new RemoveMeterOutputBuilder() ;
287 removeMeterOutput.setTransactionId(updatemeterOutput.getTransactionId()) ;
288 RemoveMeterOutput result = removeMeterOutput.build();
290 Collection<RpcError> errors = rpcResultFromOFLib.getErrors() ;
291 RpcResult<RemoveMeterOutput> rpcResult = Rpcs.getRpcResult(true, result, errors);
293 LOG.debug("Returning the Remove Meter RPC result to MD-SAL");
294 return Futures.immediateFuture(rpcResult);
298 public Future<RpcResult<Void>> transmitPacket(TransmitPacketInput input) {
299 // TODO Auto-generated method stub
303 private FlowModInputBuilder toFlowModInputBuilder(Flow source) {
304 FlowModInputBuilder target = new FlowModInputBuilder();
305 target.setCookie(source.getCookie());
306 target.setIdleTimeout(source.getIdleTimeout());
307 target.setHardTimeout(source.getHardTimeout());
308 target.setMatch(toMatch(source.getMatch()));
313 private Match toMatch(
314 org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.Match match) {
315 MatchBuilder target = new MatchBuilder();
317 target.setMatchEntries(toMatchEntries(match));
322 private List<MatchEntries> toMatchEntries(
323 org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.Match match) {
324 List<MatchEntries> entries = new ArrayList<>();
330 public Future<RpcResult<UpdateFlowOutput>> updateFlow(UpdateFlowInput input) {
331 // Convert the UpdateFlowInput to FlowModInput
332 FlowModInput ofFlowModInput = FlowConvertor.toFlowModInput(input.getUpdatedFlow()) ;
334 // Call the RPC method on MessageDispatchService
336 // For Flow provisioning, the SwitchConnectionDistinguisher is set to null so
337 // the request can be routed through any connection to the switch
339 SwitchConnectionDistinguisher cookie = null ;
341 LOG.debug("Calling the FlowMod RPC method on MessageDispatchService");
342 Future<RpcResult<UpdateFlowOutput>> resultFromOFLib = messageService.flowMod(ofFlowModInput, cookie) ;
344 RpcResult<UpdateFlowOutput> rpcResultFromOFLib = null ;
347 rpcResultFromOFLib = resultFromOFLib.get();
348 } catch( Exception ex ) {
349 LOG.error( " Error while getting result for UpdateFlow RPC" + ex.getMessage());
352 UpdateFlowOutput updateFlowOutputOFLib = rpcResultFromOFLib.getResult() ;
354 UpdateFlowOutputBuilder updateFlowOutput = new UpdateFlowOutputBuilder() ;
355 updateFlowOutput.setTransactionId(updateFlowOutputOFLib.getTransactionId()) ;
356 UpdateFlowOutput result = updateFlowOutput.build();
358 Collection<RpcError> errors = rpcResultFromOFLib.getErrors() ;
359 RpcResult<UpdateFlowOutput> rpcResult = Rpcs.getRpcResult(true, result, errors);
361 LOG.debug("Returning the Update Flow RPC result to MD-SAL");
362 return Futures.immediateFuture(rpcResult);
366 public Future<RpcResult<UpdateGroupOutput>> updateGroup(
367 UpdateGroupInput input) {
368 // Convert the UpdateGroupInput to GroupModInput
369 GroupModInput ofGroupModInput = GroupConvertor.toGroupModInput(input.getUpdatedGroup()) ;
372 // For Flow provisioning, the SwitchConnectionDistinguisher is set to null so
373 // the request can be routed through any connection to the switch
375 SwitchConnectionDistinguisher cookie = null ;
377 LOG.debug("Calling the GroupMod RPC method on MessageDispatchService");
378 Future<RpcResult<UpdateGroupOutput>> resultFromOFLib = messageService.groupMod(ofGroupModInput, cookie) ;
380 RpcResult<UpdateGroupOutput> rpcResultFromOFLib = null ;
383 rpcResultFromOFLib = resultFromOFLib.get();
384 } catch( Exception ex ) {
385 LOG.error( " Error while getting result for updateGroup RPC" + ex.getMessage());
388 UpdateGroupOutput updateGroupOutputOFLib = rpcResultFromOFLib.getResult() ;
390 UpdateGroupOutputBuilder updateGroupOutput = new UpdateGroupOutputBuilder() ;
391 updateGroupOutput.setTransactionId(updateGroupOutputOFLib.getTransactionId()) ;
392 UpdateGroupOutput result = updateGroupOutput.build();
394 Collection<RpcError> errors = rpcResultFromOFLib.getErrors() ;
395 RpcResult<UpdateGroupOutput> rpcResult = Rpcs.getRpcResult(true, result, errors);
397 LOG.debug("Returning the Update Group RPC result to MD-SAL");
398 return Futures.immediateFuture(rpcResult);
402 public Future<RpcResult<UpdateMeterOutput>> updateMeter(
403 UpdateMeterInput input) {
404 // Convert the UpdateMeterInput to MeterModInput
405 MeterModInput ofMeterModInput = MeterConverter.toMeterModInput(input.getUpdatedMeter()) ;
408 // For Meter provisioning, the SwitchConnectionDistinguisher is set to null so
409 // the request can be routed through any connection to the switch
411 SwitchConnectionDistinguisher cookie = null ;
413 LOG.debug("Calling the MeterMod RPC method on MessageDispatchService");
414 Future<RpcResult<UpdateMeterOutput>> resultFromOFLib = messageService.meterMod(ofMeterModInput, cookie) ;
416 RpcResult<UpdateMeterOutput> rpcResultFromOFLib = null ;
419 rpcResultFromOFLib = resultFromOFLib.get();
420 } catch( Exception ex ) {
421 LOG.error( " Error while getting result for UpdateMeter RPC" + ex.getMessage());
424 UpdateMeterOutput updateMeterOutputFromOFLib = rpcResultFromOFLib.getResult() ;
426 UpdateMeterOutputBuilder updateMeterOutput = new UpdateMeterOutputBuilder() ;
427 updateMeterOutput.setTransactionId(updateMeterOutputFromOFLib.getTransactionId()) ;
428 UpdateMeterOutput result = updateMeterOutput.build();
430 Collection<RpcError> errors = rpcResultFromOFLib.getErrors() ;
431 RpcResult<UpdateMeterOutput> rpcResult = Rpcs.getRpcResult(true, result, errors);
433 LOG.debug("Returning the Update Meter RPC result to MD-SAL");
434 return Futures.immediateFuture(rpcResult);
438 public NodeId getNodeId() {