blob: 5e05232dc2534f9b10b702101c85800c44ee8e1a [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;
fahadnaeemkhana37be5c2018-02-15 18:39:55 -080033import java.util.Objects;
fahadnaeemkhan71827242017-09-21 15:10:07 -070034import java.util.stream.Collectors;
35
36import static org.slf4j.LoggerFactory.getLogger;
37
38public class CienaFlowRuleProgrammable extends AbstractHandlerBehaviour implements FlowRuleProgrammable {
39 private CienaRestDevice restCiena;
40 private final Logger log = getLogger(getClass());
41
42 @Override
43 public Collection<FlowEntry> getFlowEntries() {
44 DeviceId deviceId = handler().data().deviceId();
45 log.debug("getting flow entries for device {}", deviceId);
fahadnaeemkhana62bd2f2017-10-11 12:39:55 -070046 try {
47 restCiena = new CienaRestDevice(handler());
48 } catch (NullPointerException e) {
49 log.error("unable to create CienaRestDevice:\n{}", e);
50 return Collections.emptyList();
51 }
52 return restCiena.getFlowEntries();
fahadnaeemkhan71827242017-09-21 15:10:07 -070053 }
54
55 @Override
56 public Collection<FlowRule> applyFlowRules(Collection<FlowRule> rules) {
57 log.debug("installing flow rules: {}", rules);
fahadnaeemkhana62bd2f2017-10-11 12:39:55 -070058 try {
59 restCiena = new CienaRestDevice(handler());
60 } catch (NullPointerException e) {
61 log.error("unable to create CienaRestDevice:\n{}", e);
62 return Collections.emptyList();
63 }
fahadnaeemkhan71827242017-09-21 15:10:07 -070064 // Apply the valid rules on the device
65 Collection<FlowRule> added = rules.stream()
fahadnaeemkhana37be5c2018-02-15 18:39:55 -080066 .map(this::createCrossConnectFlowRule)
67 .filter(this::installCrossConnect)
fahadnaeemkhan71827242017-09-21 15:10:07 -070068 .collect(Collectors.toList());
fahadnaeemkhana62bd2f2017-10-11 12:39:55 -070069 restCiena.setCrossConnectCache(added);
fahadnaeemkhan71827242017-09-21 15:10:07 -070070 return added;
71 }
72
73 @Override
74 public Collection<FlowRule> removeFlowRules(Collection<FlowRule> rules) {
75 log.debug("removing flow rules: {}", rules);
fahadnaeemkhana62bd2f2017-10-11 12:39:55 -070076 try {
77 restCiena = new CienaRestDevice(handler());
78 } catch (NullPointerException e) {
79 log.error("unable to create CienaRestDevice:\n{}", e);
80 return Collections.emptyList();
81 }
82 Collection<FlowRule> removed = rules.stream()
fahadnaeemkhana37be5c2018-02-15 18:39:55 -080083 .map(this::createCrossConnectFlowRule)
84 .filter(Objects::nonNull)
fahadnaeemkhana62bd2f2017-10-11 12:39:55 -070085 .collect(Collectors.toList());
86 restCiena.removeCrossConnectCache(removed);
87 return removed;
fahadnaeemkhan71827242017-09-21 15:10:07 -070088 }
89
90 private CrossConnectFlowRule createCrossConnectFlowRule(FlowRule r) {
fahadnaeemkhana62bd2f2017-10-11 12:39:55 -070091 List<PortNumber> linePorts = CienaRestDevice.getLinesidePortId().stream()
fahadnaeemkhana37be5c2018-02-15 18:39:55 -080092 .map(PortNumber::portNumber)
fahadnaeemkhan71827242017-09-21 15:10:07 -070093 .collect(Collectors.toList());
94 try {
95 return new CrossConnectFlowRule(r, linePorts);
96 } catch (IllegalArgumentException e) {
97 log.debug("unable to create cross connect for rule:\n{}", r);
98 }
99 return null;
100 }
101
102 private boolean installCrossConnect(CrossConnectFlowRule xc) {
103 if (xc == null) {
104 return false;
105 }
106 // only handling lineside rule
107 if (xc.isAddRule()) {
108 PortNumber outPort = xc.addDrop();
109 OchSignal signal = xc.ochSignal();
110 return install(outPort, signal);
111 }
112 return false;
113 }
114
115 private boolean removeCrossConnect(CrossConnectFlowRule xc) {
116 //for now setting channel to 0 for remove rule
117 if (xc == null) {
118 return false;
119 }
120 // only handling lineside rule
121 if (xc.isAddRule()) {
122 PortNumber outPort = xc.addDrop();
fahadnaeemkhanffc917f2017-10-03 14:04:46 -0700123 OchSignal signal = OchSignal.newDwdmSlot(xc.ochSignal().channelSpacing(), 0);
fahadnaeemkhan71827242017-09-21 15:10:07 -0700124 return install(outPort, signal);
125 }
126 return false;
127 }
128
129 private boolean install(PortNumber outPort, OchSignal signal) {
130 /*
131 * rule is installed in three steps
132 * 1- disable port
fahadnaeemkhana37be5c2018-02-15 18:39:55 -0800133 * 2- change frequency
fahadnaeemkhan71827242017-09-21 15:10:07 -0700134 * 3- enable port
135 */
136 try {
137 restCiena = new CienaRestDevice(handler());
138 } catch (NullPointerException e) {
139 log.error("unable to create CienaRestDevice, {}", e);
140 return false;
141 }
142 //1- disable port
143 //blindly disabling port
144 if (!restCiena.disablePort(outPort)) {
fahadnaeemkhan71827242017-09-21 15:10:07 -0700145 return false;
146 }
fahadnaeemkhana37be5c2018-02-15 18:39:55 -0800147 //2- change frequency
148 if (!restCiena.changeFrequency(signal, outPort)) {
fahadnaeemkhan71827242017-09-21 15:10:07 -0700149 return false;
150 }
151 //3- enable port
152 if (!restCiena.enablePort(outPort)) {
fahadnaeemkhan71827242017-09-21 15:10:07 -0700153 return false;
154 }
155 return true;
156 }
fahadnaeemkhana62bd2f2017-10-11 12:39:55 -0700157
fahadnaeemkhan71827242017-09-21 15:10:07 -0700158}