1 package org.opendaylight.controller.sal.compatibility
3 import java.util.concurrent.ExecutionException
4 import org.opendaylight.controller.sal.core.Node
5 import org.opendaylight.controller.sal.flowprogrammer.Flow
6 import org.opendaylight.controller.sal.flowprogrammer.IPluginInFlowProgrammerService
7 import org.opendaylight.controller.sal.flowprogrammer.IPluginOutFlowProgrammerService
8 import org.opendaylight.controller.sal.utils.Status
9 import org.opendaylight.controller.sal.utils.StatusCode
10 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.FlowAdded
11 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.FlowRemoved
12 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.SwitchFlowRemoved
13 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.FlowUpdated
14 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.SalFlowListener
15 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.SalFlowService
16 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.NodeErrorNotification
17 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.NodeExperimenterErrorNotification
18 import org.opendaylight.yangtools.yang.common.RpcResult
19 import org.slf4j.LoggerFactory
21 import org.opendaylight.controller.sal.binding.api.data.DataBrokerService
22 import org.opendaylight.controller.md.sal.common.api.TransactionStatus
23 import org.opendaylight.controller.md.sal.common.api.data.DataModification
24 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNode
25 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.Table
26 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.TableKey
27 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.FlowKey
28 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.Nodes
29 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.NodeKey
30 import org.opendaylight.yangtools.yang.binding.DataObject
31 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier
32 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.AddFlowInput
33 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeId
34 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.FlowKey
35 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowId
38 import static extension org.opendaylight.controller.sal.compatibility.MDFlowMapping.*
40 import static extension org.opendaylight.controller.sal.compatibility.NodeMapping.*
41 import static extension org.opendaylight.controller.sal.compatibility.ToSalConversionsUtils.*
43 class FlowProgrammerAdapter implements IPluginInFlowProgrammerService, SalFlowListener {
45 private static val LOG = LoggerFactory.getLogger(FlowProgrammerAdapter);
48 private SalFlowService delegate;
51 private DataBrokerService dataBrokerService;
54 private IPluginOutFlowProgrammerService flowProgrammerPublisher;
56 override addFlow(Node node, Flow flow) {
57 return addFlowAsync(node,flow,0)
60 override modifyFlow(Node node, Flow oldFlow, Flow newFlow) {
61 return modifyFlowAsync(node, oldFlow,newFlow,0)
64 override removeFlow(Node node, Flow flow) {
65 return removeFlowAsync(node, flow,0);
68 override addFlowAsync(Node node, Flow flow, long rid) {
69 writeFlow(flow.toMDFlow, new NodeKey(new NodeId(node.getNodeIDString())));
70 return toStatus(true);
73 override modifyFlowAsync(Node node, Flow oldFlow, Flow newFlow, long rid) {
74 writeFlow(newFlow.toMDFlow, new NodeKey(new NodeId(node.getNodeIDString())));
75 return toStatus(true);
78 override removeFlowAsync(Node node, Flow adflow, long rid) {
79 val flow = adflow.toMDFlow;
80 val modification = this._dataBrokerService.beginTransaction();
81 val flowPath = InstanceIdentifier.builder(Nodes)
82 .child(org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node, new NodeKey(new NodeId(node.getNodeIDString())))
83 .augmentation(FlowCapableNode)
84 .child(Table, new TableKey(flow.getTableId()))
85 .child(org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.Flow, new FlowKey(flow.id))
87 modification.removeConfigurationData(flowPath);
88 val commitFuture = modification.commit();
89 return toStatus(true);
92 override removeAllFlows(Node node) {
93 // I know this looks like a copout... but its exactly what the legacy OFplugin did
94 return new Status(StatusCode.SUCCESS);
97 override syncSendBarrierMessage(Node node) {
99 // FIXME: Update YANG model
103 override asyncSendBarrierMessage(Node node) {
105 // FIXME: Update YANG model
109 private static def toStatus(boolean successful) {
111 return new Status(StatusCode.SUCCESS);
113 return new Status(StatusCode.INTERNALERROR);
118 private def writeFlow(org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.Flow flow, NodeKey nodeKey) {
119 val modification = this._dataBrokerService.beginTransaction();
120 val flowPath = InstanceIdentifier.builder(Nodes)
121 .child(org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node, nodeKey)
122 .augmentation(FlowCapableNode)
123 .child(Table, new TableKey(flow.getTableId()))
124 .child(org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.Flow, new FlowKey(flow.id))
126 modification.putConfigurationData(flowPath, flow);
127 val commitFuture = modification.commit();
129 val result = commitFuture.get();
130 val status = result.getResult();
131 } catch (InterruptedException e) {
132 LOG.error(e.getMessage(), e);
133 } catch (ExecutionException e) {
134 LOG.error(e.getMessage(), e);
138 public static def toStatus(RpcResult<?> result) {
139 return toStatus(result.isSuccessful());
142 private static dispatch def Status processException(InterruptedException e) {
143 LOG.error("Interruption occured during processing flow",e);
144 return new Status(StatusCode.INTERNALERROR);
147 private static dispatch def Status processException(ExecutionException e) {
148 LOG.error("Execution exception occured during processing flow",e.cause);
149 return new Status(StatusCode.INTERNALERROR);
152 private static dispatch def Status processException(Exception e) {
153 throw new RuntimeException(e);
156 override onFlowAdded(FlowAdded notification) {
157 // NOOP : Not supported by AD SAL
160 override onFlowRemoved(FlowRemoved notification) {
161 flowProgrammerPublisher.flowRemoved(notification.node.toADNode,notification.toFlow());
164 override onFlowUpdated(FlowUpdated notification) {
165 // NOOP : Not supported by AD SAL
168 override onSwitchFlowRemoved(SwitchFlowRemoved notification) {
169 // NOOP : Not supported by AD SAL
172 override onNodeErrorNotification(NodeErrorNotification notification) {
173 // NOOP : Not supported by AD SAL
176 override onNodeExperimenterErrorNotification(
177 NodeExperimenterErrorNotification notification) {
178 // NOOP : Not supported by AD SAL