blob: 8b17246e212ad78a2daa0f902183952d75a7a441 [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 Leenheerb6f95e22017-03-15 12:18:59 -0700126 if (!isTransparent(link.src().deviceId())) {
127 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();
Sho SHIMIZUee2aa652015-02-25 18:56:43 -0800139
Marc De Leenheerb6f95e22017-03-15 12:18:59 -0700140 if (!isNoFlowRule(current.deviceId())) {
Yuta HIGUCHI09697d02017-03-03 16:53:39 -0800141 rules.add(rule);
142 }
Sho SHIMIZUee2aa652015-02-25 18:56:43 -0800143
Marc De Leenheer1afa2a02015-05-13 09:18:07 -0700144 current = link.dst();
Sho SHIMIZUee2aa652015-02-25 18:56:43 -0800145 selectorBuilder.matchInPort(link.dst().port());
Marc De Leenheerb6f95e22017-03-15 12:18:59 -0700146 if (!isTransparent(link.dst().deviceId())) {
147 selectorBuilder.add(Criteria.matchLambda(intent.lambda()));
148 selectorBuilder.add(Criteria.matchOchSignalType(intent.signalType()));
149 }
Sho SHIMIZUee2aa652015-02-25 18:56:43 -0800150 }
151
Marc De Leenheer1afa2a02015-05-13 09:18:07 -0700152 // Build the egress ROADM rule
153 TrafficTreatment.Builder treatmentLast = DefaultTrafficTreatment.builder();
Sho SHIMIZUee2aa652015-02-25 18:56:43 -0800154 treatmentLast.setOutput(intent.dst().port());
Marc De Leenheer1afa2a02015-05-13 09:18:07 -0700155
156 FlowRule rule = new DefaultFlowRule.Builder()
157 .forDevice(intent.dst().deviceId())
158 .withSelector(selectorBuilder.build())
159 .withTreatment(treatmentLast.build())
Brian O'Connor81134662015-06-25 17:23:33 -0400160 .withPriority(intent.priority())
Marc De Leenheer1afa2a02015-05-13 09:18:07 -0700161 .fromApp(appId)
162 .makePermanent()
163 .build();
Yuta HIGUCHI09697d02017-03-03 16:53:39 -0800164
Marc De Leenheerb6f95e22017-03-15 12:18:59 -0700165 if (!isNoFlowRule(intent.dst().deviceId())) {
Yuta HIGUCHI09697d02017-03-03 16:53:39 -0800166 rules.add(rule);
167 }
Sho SHIMIZUee2aa652015-02-25 18:56:43 -0800168
169 return rules;
170 }
Marc De Leenheer4a1c1fa2015-06-01 18:08:56 -0700171
172 /**
173 * Create rules for the reverse path of the intent.
174 *
175 * @param intent the intent
176 * @return list of flow rules
177 */
178 private List<FlowRule> createReverseRules(OpticalPathIntent intent) {
179 TrafficSelector.Builder selectorBuilder = DefaultTrafficSelector.builder();
180 selectorBuilder.matchInPort(intent.dst().port());
181
182 List<FlowRule> rules = new LinkedList<>();
183 ConnectPoint current = intent.dst();
184
185 for (Link link : Lists.reverse(intent.path().links())) {
186 TrafficTreatment.Builder treatmentBuilder = DefaultTrafficTreatment.builder();
Marc De Leenheerb6f95e22017-03-15 12:18:59 -0700187 if (isTransparent(link.dst().deviceId())) {
188 treatmentBuilder.add(Instructions.modL0Lambda(intent.lambda()));
189 }
Marc De Leenheer4a1c1fa2015-06-01 18:08:56 -0700190 treatmentBuilder.setOutput(link.dst().port());
191
192 FlowRule rule = DefaultFlowRule.builder()
193 .forDevice(current.deviceId())
194 .withSelector(selectorBuilder.build())
195 .withTreatment(treatmentBuilder.build())
Brian O'Connor81134662015-06-25 17:23:33 -0400196 .withPriority(intent.priority())
Marc De Leenheer4a1c1fa2015-06-01 18:08:56 -0700197 .fromApp(appId)
198 .makePermanent()
199 .build();
200
Marc De Leenheerb6f95e22017-03-15 12:18:59 -0700201 if (!isNoFlowRule(current.deviceId())) {
Yuta HIGUCHI09697d02017-03-03 16:53:39 -0800202 rules.add(rule);
203 }
Marc De Leenheer4a1c1fa2015-06-01 18:08:56 -0700204
205 current = link.src();
206 selectorBuilder.matchInPort(link.src().port());
Marc De Leenheerb6f95e22017-03-15 12:18:59 -0700207 if (isTransparent(link.src().deviceId())) {
208 selectorBuilder.add(Criteria.matchLambda(intent.lambda()));
209 selectorBuilder.add(Criteria.matchOchSignalType(intent.signalType()));
210 }
Marc De Leenheer4a1c1fa2015-06-01 18:08:56 -0700211 }
212
213 // Build the egress ROADM rule
214 TrafficTreatment.Builder treatmentLast = DefaultTrafficTreatment.builder();
215 treatmentLast.setOutput(intent.src().port());
216
217 FlowRule rule = new DefaultFlowRule.Builder()
218 .forDevice(intent.src().deviceId())
219 .withSelector(selectorBuilder.build())
220 .withTreatment(treatmentLast.build())
Brian O'Connor81134662015-06-25 17:23:33 -0400221 .withPriority(intent.priority())
Marc De Leenheer4a1c1fa2015-06-01 18:08:56 -0700222 .fromApp(appId)
223 .makePermanent()
224 .build();
Yuta HIGUCHI09697d02017-03-03 16:53:39 -0800225
Marc De Leenheerb6f95e22017-03-15 12:18:59 -0700226 if (!isNoFlowRule(intent.src().deviceId())) {
Yuta HIGUCHI09697d02017-03-03 16:53:39 -0800227 rules.add(rule);
228 }
Marc De Leenheer4a1c1fa2015-06-01 18:08:56 -0700229
230 return rules;
231 }
Marc De Leenheerb6f95e22017-03-15 12:18:59 -0700232
233 /**
234 * Returns true if device does not accept flow rules, false otherwise.
235 *
236 * @param deviceId the device
237 * @return true if device does not accept flow rule, false otherwise
238 */
239 private boolean isNoFlowRule(DeviceId deviceId) {
240 return NO_FLOWRULE_DEVICES.contains(
241 Optional.ofNullable(deviceService.getDevice(deviceId))
242 .map(Device::type)
243 .orElse(Type.OTHER));
244 }
245
246 /**
247 * Returns true if device is wavelength transparent, false otherwise.
248 *
249 * @param deviceId the device
250 * @return true if wavelength transparent, false otherwise
251 */
252 private boolean isTransparent(DeviceId deviceId) {
253 return TRANSPARENT_DEVICES.contains(
254 Optional.ofNullable(deviceService.getDevice(deviceId))
255 .map(Device::type)
256 .orElse(Type.OTHER));
257 }
Sho SHIMIZUee2aa652015-02-25 18:56:43 -0800258}