blob: 614ab904946a91da7865dd57952c2f23e6520077 [file] [log] [blame]
Sho SHIMIZUee2aa652015-02-25 18:56:43 -08001/*
Brian O'Connor0a4e6742016-09-15 23:03:10 -07002 * Copyright 2016-present Open Networking Laboratory
Sho SHIMIZUee2aa652015-02-25 18:56:43 -08003 *
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 */
Yuta HIGUCHId95d5902016-06-27 00:18:45 -070016package org.onosproject.net.optical.intent.impl.compiler;
Sho SHIMIZUee2aa652015-02-25 18:56:43 -080017
Marc De Leenheerb6f95e22017-03-15 12:18:59 -070018import com.google.common.collect.ImmutableSet;
Marc De Leenheer4a1c1fa2015-06-01 18:08:56 -070019import com.google.common.collect.Lists;
Sho SHIMIZUee2aa652015-02-25 18:56:43 -080020import org.apache.felix.scr.annotations.Activate;
21import org.apache.felix.scr.annotations.Component;
22import org.apache.felix.scr.annotations.Deactivate;
23import org.apache.felix.scr.annotations.Reference;
24import org.apache.felix.scr.annotations.ReferenceCardinality;
25import org.onosproject.core.ApplicationId;
26import org.onosproject.core.CoreService;
27import org.onosproject.net.ConnectPoint;
Yuta HIGUCHI09697d02017-03-03 16:53:39 -080028import org.onosproject.net.Device;
29import org.onosproject.net.Device.Type;
30import org.onosproject.net.DeviceId;
Sho SHIMIZUee2aa652015-02-25 18:56:43 -080031import org.onosproject.net.Link;
Yuta HIGUCHI09697d02017-03-03 16:53:39 -080032import org.onosproject.net.device.DeviceService;
33import org.onosproject.net.device.DeviceServiceAdapter;
Sho SHIMIZUee2aa652015-02-25 18:56:43 -080034import org.onosproject.net.flow.DefaultFlowRule;
35import org.onosproject.net.flow.DefaultTrafficSelector;
36import org.onosproject.net.flow.DefaultTrafficTreatment;
37import org.onosproject.net.flow.FlowRule;
38import org.onosproject.net.flow.TrafficSelector;
39import org.onosproject.net.flow.TrafficTreatment;
Marc De Leenheer1afa2a02015-05-13 09:18:07 -070040import org.onosproject.net.flow.criteria.Criteria;
41import org.onosproject.net.flow.instructions.Instructions;
Sho SHIMIZUee2aa652015-02-25 18:56:43 -080042import org.onosproject.net.intent.FlowRuleIntent;
43import org.onosproject.net.intent.Intent;
44import org.onosproject.net.intent.IntentCompiler;
45import org.onosproject.net.intent.IntentExtensionService;
46import org.onosproject.net.intent.OpticalPathIntent;
Luca Prete670ac5d2017-02-03 15:55:43 -080047import org.onosproject.net.intent.PathIntent;
Marc De Leenheer8c2caac2015-05-28 16:37:33 -070048import org.slf4j.Logger;
49import org.slf4j.LoggerFactory;
Sho SHIMIZUee2aa652015-02-25 18:56:43 -080050
Sho SHIMIZU98ffca82015-05-11 08:39:24 -070051import java.util.Collections;
Sho SHIMIZUee2aa652015-02-25 18:56:43 -080052import java.util.LinkedList;
53import java.util.List;
Yuta HIGUCHI09697d02017-03-03 16:53:39 -080054import java.util.Optional;
Marc De Leenheerb6f95e22017-03-15 12:18:59 -070055import java.util.Set;
Sho SHIMIZUee2aa652015-02-25 18:56:43 -080056
Sho SHIMIZUee2aa652015-02-25 18:56:43 -080057@Component(immediate = true)
58public class OpticalPathIntentCompiler implements IntentCompiler<OpticalPathIntent> {
59
Marc De Leenheer8c2caac2015-05-28 16:37:33 -070060 private static final Logger log = LoggerFactory.getLogger(OpticalPathIntentCompiler.class);
61
Sho SHIMIZUee2aa652015-02-25 18:56:43 -080062 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
63 protected IntentExtensionService intentManager;
64
65 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
66 protected CoreService coreService;
67
Yuta HIGUCHI09697d02017-03-03 16:53:39 -080068 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
69 protected DeviceService deviceService = new DeviceServiceAdapter();
70
Sho SHIMIZUee2aa652015-02-25 18:56:43 -080071 private ApplicationId appId;
Marc De Leenheerb6f95e22017-03-15 12:18:59 -070072 // Devices which are wavelength transparent and thus do not require wavelength-based match/actions
73 private static final Set<Type> TRANSPARENT_DEVICES =
74 ImmutableSet.of(Type.OPTICAL_AMPLIFIER, Type.FIBER_SWITCH);
75 // Devices which don't accept flow rules
76 private static final Set<Type> NO_FLOWRULE_DEVICES =
77 ImmutableSet.of(Type.OPTICAL_AMPLIFIER);
Sho SHIMIZUee2aa652015-02-25 18:56:43 -080078
Sho SHIMIZUee2aa652015-02-25 18:56:43 -080079 @Activate
80 public void activate() {
81 appId = coreService.registerApplication("org.onosproject.net.intent");
82 intentManager.registerCompiler(OpticalPathIntent.class, this);
83 }
84
85 @Deactivate
86 public void deactivate() {
87 intentManager.unregisterCompiler(OpticalPathIntent.class);
88 }
89
90 @Override
Sho SHIMIZUec07ffd2016-02-22 20:45:21 -080091 public List<Intent> compile(OpticalPathIntent intent, List<Intent> installable) {
Marc De Leenheer8c2caac2015-05-28 16:37:33 -070092 log.debug("Compiling optical path intent between {} and {}", intent.src(), intent.dst());
93
Marc De Leenheer4a1c1fa2015-06-01 18:08:56 -070094 // Create rules for forward and reverse path
95 List<FlowRule> rules = createRules(intent);
96 if (intent.isBidirectional()) {
97 rules.addAll(createReverseRules(intent));
98 }
99
Luca Prete670ac5d2017-02-03 15:55:43 -0800100 return Collections.singletonList(
101 new FlowRuleIntent(appId,
102 intent.key(),
103 rules,
104 intent.resources(),
105 PathIntent.ProtectionType.PRIMARY,
106 intent.resourceGroup()
107 )
108 );
Sho SHIMIZUee2aa652015-02-25 18:56:43 -0800109 }
110
Marc De Leenheer4a1c1fa2015-06-01 18:08:56 -0700111 /**
112 * Create rules for the forward path of the intent.
113 *
114 * @param intent the intent
115 * @return list of flow rules
116 */
Marc De Leenheer1afa2a02015-05-13 09:18:07 -0700117 private List<FlowRule> createRules(OpticalPathIntent intent) {
Sho SHIMIZUee2aa652015-02-25 18:56:43 -0800118 TrafficSelector.Builder selectorBuilder = DefaultTrafficSelector.builder();
119 selectorBuilder.matchInPort(intent.src().port());
120
121 List<FlowRule> rules = new LinkedList<>();
Marc De Leenheer1afa2a02015-05-13 09:18:07 -0700122 ConnectPoint current = intent.src();
Sho SHIMIZUee2aa652015-02-25 18:56:43 -0800123
124 for (Link link : intent.path().links()) {
Sho SHIMIZUee2aa652015-02-25 18:56:43 -0800125 TrafficTreatment.Builder treatmentBuilder = DefaultTrafficTreatment.builder();
Marc De Leenheer43b91ad2017-03-17 14:45:28 -0700126 if (!isTransparent(current.deviceId())) {
Marc De Leenheerb6f95e22017-03-15 12:18:59 -0700127 treatmentBuilder.add(Instructions.modL0Lambda(intent.lambda()));
128 }
Sho SHIMIZUee2aa652015-02-25 18:56:43 -0800129 treatmentBuilder.setOutput(link.src().port());
130
Marc De Leenheer1afa2a02015-05-13 09:18:07 -0700131 FlowRule rule = DefaultFlowRule.builder()
132 .forDevice(current.deviceId())
133 .withSelector(selectorBuilder.build())
134 .withTreatment(treatmentBuilder.build())
Brian O'Connor81134662015-06-25 17:23:33 -0400135 .withPriority(intent.priority())
Marc De Leenheer1afa2a02015-05-13 09:18:07 -0700136 .fromApp(appId)
137 .makePermanent()
138 .build();
Marc De Leenheer43b91ad2017-03-17 14:45:28 -0700139 selectorBuilder = DefaultTrafficSelector.builder();
Sho SHIMIZUee2aa652015-02-25 18:56:43 -0800140
Marc De Leenheerb6f95e22017-03-15 12:18:59 -0700141 if (!isNoFlowRule(current.deviceId())) {
Yuta HIGUCHI09697d02017-03-03 16:53:39 -0800142 rules.add(rule);
143 }
Sho SHIMIZUee2aa652015-02-25 18:56:43 -0800144
Marc De Leenheer1afa2a02015-05-13 09:18:07 -0700145 current = link.dst();
Sho SHIMIZUee2aa652015-02-25 18:56:43 -0800146 selectorBuilder.matchInPort(link.dst().port());
Marc De Leenheer43b91ad2017-03-17 14:45:28 -0700147 if (!isTransparent(current.deviceId())) {
Marc De Leenheerb6f95e22017-03-15 12:18:59 -0700148 selectorBuilder.add(Criteria.matchLambda(intent.lambda()));
149 selectorBuilder.add(Criteria.matchOchSignalType(intent.signalType()));
150 }
Sho SHIMIZUee2aa652015-02-25 18:56:43 -0800151 }
152
Marc De Leenheer1afa2a02015-05-13 09:18:07 -0700153 // Build the egress ROADM rule
154 TrafficTreatment.Builder treatmentLast = DefaultTrafficTreatment.builder();
Sho SHIMIZUee2aa652015-02-25 18:56:43 -0800155 treatmentLast.setOutput(intent.dst().port());
Marc De Leenheer1afa2a02015-05-13 09:18:07 -0700156
157 FlowRule rule = new DefaultFlowRule.Builder()
158 .forDevice(intent.dst().deviceId())
159 .withSelector(selectorBuilder.build())
160 .withTreatment(treatmentLast.build())
Brian O'Connor81134662015-06-25 17:23:33 -0400161 .withPriority(intent.priority())
Marc De Leenheer1afa2a02015-05-13 09:18:07 -0700162 .fromApp(appId)
163 .makePermanent()
164 .build();
Yuta HIGUCHI09697d02017-03-03 16:53:39 -0800165
Marc De Leenheerb6f95e22017-03-15 12:18:59 -0700166 if (!isNoFlowRule(intent.dst().deviceId())) {
Yuta HIGUCHI09697d02017-03-03 16:53:39 -0800167 rules.add(rule);
168 }
Sho SHIMIZUee2aa652015-02-25 18:56:43 -0800169
170 return rules;
171 }
Marc De Leenheer4a1c1fa2015-06-01 18:08:56 -0700172
173 /**
174 * Create rules for the reverse path of the intent.
175 *
176 * @param intent the intent
177 * @return list of flow rules
178 */
179 private List<FlowRule> createReverseRules(OpticalPathIntent intent) {
180 TrafficSelector.Builder selectorBuilder = DefaultTrafficSelector.builder();
181 selectorBuilder.matchInPort(intent.dst().port());
182
183 List<FlowRule> rules = new LinkedList<>();
184 ConnectPoint current = intent.dst();
185
186 for (Link link : Lists.reverse(intent.path().links())) {
187 TrafficTreatment.Builder treatmentBuilder = DefaultTrafficTreatment.builder();
Marc De Leenheer43b91ad2017-03-17 14:45:28 -0700188 if (!isTransparent(current.deviceId())) {
Marc De Leenheerb6f95e22017-03-15 12:18:59 -0700189 treatmentBuilder.add(Instructions.modL0Lambda(intent.lambda()));
190 }
Marc De Leenheer4a1c1fa2015-06-01 18:08:56 -0700191 treatmentBuilder.setOutput(link.dst().port());
192
193 FlowRule rule = DefaultFlowRule.builder()
194 .forDevice(current.deviceId())
195 .withSelector(selectorBuilder.build())
196 .withTreatment(treatmentBuilder.build())
Brian O'Connor81134662015-06-25 17:23:33 -0400197 .withPriority(intent.priority())
Marc De Leenheer4a1c1fa2015-06-01 18:08:56 -0700198 .fromApp(appId)
199 .makePermanent()
200 .build();
Marc De Leenheer43b91ad2017-03-17 14:45:28 -0700201 selectorBuilder = DefaultTrafficSelector.builder();
Marc De Leenheer4a1c1fa2015-06-01 18:08:56 -0700202
Marc De Leenheerb6f95e22017-03-15 12:18:59 -0700203 if (!isNoFlowRule(current.deviceId())) {
Yuta HIGUCHI09697d02017-03-03 16:53:39 -0800204 rules.add(rule);
205 }
Marc De Leenheer4a1c1fa2015-06-01 18:08:56 -0700206
207 current = link.src();
208 selectorBuilder.matchInPort(link.src().port());
Marc De Leenheer43b91ad2017-03-17 14:45:28 -0700209 if (!isTransparent(current.deviceId())) {
Marc De Leenheerb6f95e22017-03-15 12:18:59 -0700210 selectorBuilder.add(Criteria.matchLambda(intent.lambda()));
211 selectorBuilder.add(Criteria.matchOchSignalType(intent.signalType()));
212 }
Marc De Leenheer4a1c1fa2015-06-01 18:08:56 -0700213 }
214
215 // Build the egress ROADM rule
216 TrafficTreatment.Builder treatmentLast = DefaultTrafficTreatment.builder();
217 treatmentLast.setOutput(intent.src().port());
218
219 FlowRule rule = new DefaultFlowRule.Builder()
220 .forDevice(intent.src().deviceId())
221 .withSelector(selectorBuilder.build())
222 .withTreatment(treatmentLast.build())
Brian O'Connor81134662015-06-25 17:23:33 -0400223 .withPriority(intent.priority())
Marc De Leenheer4a1c1fa2015-06-01 18:08:56 -0700224 .fromApp(appId)
225 .makePermanent()
226 .build();
Yuta HIGUCHI09697d02017-03-03 16:53:39 -0800227
Marc De Leenheerb6f95e22017-03-15 12:18:59 -0700228 if (!isNoFlowRule(intent.src().deviceId())) {
Yuta HIGUCHI09697d02017-03-03 16:53:39 -0800229 rules.add(rule);
230 }
Marc De Leenheer4a1c1fa2015-06-01 18:08:56 -0700231
232 return rules;
233 }
Marc De Leenheerb6f95e22017-03-15 12:18:59 -0700234
235 /**
236 * Returns true if device does not accept flow rules, false otherwise.
237 *
238 * @param deviceId the device
239 * @return true if device does not accept flow rule, false otherwise
240 */
241 private boolean isNoFlowRule(DeviceId deviceId) {
242 return NO_FLOWRULE_DEVICES.contains(
243 Optional.ofNullable(deviceService.getDevice(deviceId))
244 .map(Device::type)
245 .orElse(Type.OTHER));
246 }
247
248 /**
249 * Returns true if device is wavelength transparent, false otherwise.
250 *
251 * @param deviceId the device
252 * @return true if wavelength transparent, false otherwise
253 */
254 private boolean isTransparent(DeviceId deviceId) {
255 return TRANSPARENT_DEVICES.contains(
256 Optional.ofNullable(deviceService.getDevice(deviceId))
257 .map(Device::type)
258 .orElse(Type.OTHER));
259 }
Sho SHIMIZUee2aa652015-02-25 18:56:43 -0800260}