blob: d0e78fc98128e4a23602a10b120ea448ff900ebd [file] [log] [blame]
fahadnaeemkhan71827242017-09-21 15:10:07 -07001/*
2 * Copyright 2016-present Open Networking Foundation
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16package org.onosproject.drivers.ciena;
17
18import org.onosproject.net.DeviceId;
19import org.onosproject.net.OchSignal;
20import org.onosproject.net.PortNumber;
21import org.onosproject.driver.optical.flowrule.CrossConnectFlowRule;
22import org.onosproject.net.driver.AbstractHandlerBehaviour;
23import org.onosproject.net.flow.FlowEntry;
24import org.onosproject.net.flow.FlowRule;
25import org.onosproject.net.flow.FlowRuleProgrammable;
26
27import org.slf4j.Logger;
28
29
30import java.util.List;
31import java.util.Collection;
32import java.util.Collections;
33import java.util.stream.Collectors;
34
35import static org.slf4j.LoggerFactory.getLogger;
36
37public class CienaFlowRuleProgrammable extends AbstractHandlerBehaviour implements FlowRuleProgrammable {
38 private CienaRestDevice restCiena;
39 private final Logger log = getLogger(getClass());
40
41 @Override
42 public Collection<FlowEntry> getFlowEntries() {
43 DeviceId deviceId = handler().data().deviceId();
44 log.debug("getting flow entries for device {}", deviceId);
fahadnaeemkhana62bd2f2017-10-11 12:39:55 -070045 try {
46 restCiena = new CienaRestDevice(handler());
47 } catch (NullPointerException e) {
48 log.error("unable to create CienaRestDevice:\n{}", e);
49 return Collections.emptyList();
50 }
51 return restCiena.getFlowEntries();
fahadnaeemkhan71827242017-09-21 15:10:07 -070052 }
53
54 @Override
55 public Collection<FlowRule> applyFlowRules(Collection<FlowRule> rules) {
56 log.debug("installing flow rules: {}", rules);
fahadnaeemkhana62bd2f2017-10-11 12:39:55 -070057 try {
58 restCiena = new CienaRestDevice(handler());
59 } catch (NullPointerException e) {
60 log.error("unable to create CienaRestDevice:\n{}", e);
61 return Collections.emptyList();
62 }
fahadnaeemkhan71827242017-09-21 15:10:07 -070063 // Apply the valid rules on the device
64 Collection<FlowRule> added = rules.stream()
65 .map(r -> createCrossConnectFlowRule(r))
66 .filter(xc -> installCrossConnect(xc))
67 .collect(Collectors.toList());
fahadnaeemkhana62bd2f2017-10-11 12:39:55 -070068 restCiena.setCrossConnectCache(added);
fahadnaeemkhan71827242017-09-21 15:10:07 -070069 return added;
70 }
71
72 @Override
73 public Collection<FlowRule> removeFlowRules(Collection<FlowRule> rules) {
74 log.debug("removing flow rules: {}", rules);
fahadnaeemkhana62bd2f2017-10-11 12:39:55 -070075 try {
76 restCiena = new CienaRestDevice(handler());
77 } catch (NullPointerException e) {
78 log.error("unable to create CienaRestDevice:\n{}", e);
79 return Collections.emptyList();
80 }
81 Collection<FlowRule> removed = rules.stream()
82 .map(r -> createCrossConnectFlowRule(r))
83 .filter(xc -> xc != null)
84 .collect(Collectors.toList());
85 restCiena.removeCrossConnectCache(removed);
86 return removed;
fahadnaeemkhan71827242017-09-21 15:10:07 -070087 }
88
89 private CrossConnectFlowRule createCrossConnectFlowRule(FlowRule r) {
fahadnaeemkhana62bd2f2017-10-11 12:39:55 -070090 List<PortNumber> linePorts = CienaRestDevice.getLinesidePortId().stream()
fahadnaeemkhan71827242017-09-21 15:10:07 -070091 .map(p -> PortNumber.portNumber(p))
92 .collect(Collectors.toList());
93 try {
94 return new CrossConnectFlowRule(r, linePorts);
95 } catch (IllegalArgumentException e) {
96 log.debug("unable to create cross connect for rule:\n{}", r);
97 }
98 return null;
99 }
100
101 private boolean installCrossConnect(CrossConnectFlowRule xc) {
102 if (xc == null) {
103 return false;
104 }
105 // only handling lineside rule
106 if (xc.isAddRule()) {
107 PortNumber outPort = xc.addDrop();
108 OchSignal signal = xc.ochSignal();
109 return install(outPort, signal);
110 }
111 return false;
112 }
113
114 private boolean removeCrossConnect(CrossConnectFlowRule xc) {
115 //for now setting channel to 0 for remove rule
116 if (xc == null) {
117 return false;
118 }
119 // only handling lineside rule
120 if (xc.isAddRule()) {
121 PortNumber outPort = xc.addDrop();
fahadnaeemkhanffc917f2017-10-03 14:04:46 -0700122 OchSignal signal = OchSignal.newDwdmSlot(xc.ochSignal().channelSpacing(), 0);
fahadnaeemkhan71827242017-09-21 15:10:07 -0700123 return install(outPort, signal);
124 }
125 return false;
126 }
127
128 private boolean install(PortNumber outPort, OchSignal signal) {
129 /*
130 * rule is installed in three steps
131 * 1- disable port
132 * 2- change channel
133 * 3- enable port
134 */
135 try {
136 restCiena = new CienaRestDevice(handler());
137 } catch (NullPointerException e) {
138 log.error("unable to create CienaRestDevice, {}", e);
139 return false;
140 }
141 //1- disable port
142 //blindly disabling port
143 if (!restCiena.disablePort(outPort)) {
fahadnaeemkhan71827242017-09-21 15:10:07 -0700144 return false;
145 }
146 //2- change channel
147 if (!restCiena.changeChannel(signal, outPort)) {
fahadnaeemkhan71827242017-09-21 15:10:07 -0700148 return false;
149 }
150 //3- enable port
151 if (!restCiena.enablePort(outPort)) {
fahadnaeemkhan71827242017-09-21 15:10:07 -0700152 return false;
153 }
154 return true;
155 }
fahadnaeemkhana62bd2f2017-10-11 12:39:55 -0700156
fahadnaeemkhan71827242017-09-21 15:10:07 -0700157}