blob: a0cace966b2285991f120a79c4c83b4a20cb8d2d [file] [log] [blame]
Jimmy Yanda878fc2016-09-02 16:32:01 -07001/*
2 * Copyright 2016-present Open Networking Laboratory
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.roadm;
17
18import com.google.common.collect.Range;
19import org.apache.felix.scr.annotations.Activate;
20import org.apache.felix.scr.annotations.Component;
21import org.apache.felix.scr.annotations.Deactivate;
22import org.apache.felix.scr.annotations.Reference;
23import org.apache.felix.scr.annotations.ReferenceCardinality;
24import org.apache.felix.scr.annotations.Service;
25import org.onosproject.core.ApplicationId;
26import org.onosproject.core.CoreService;
27import org.onosproject.net.ChannelSpacing;
MaoLu937cf422017-03-03 23:31:46 -080028import org.onosproject.net.ConnectPoint;
Jimmy Yanda878fc2016-09-02 16:32:01 -070029import org.onosproject.net.Device;
30import org.onosproject.net.DeviceId;
31import org.onosproject.net.Direction;
32import org.onosproject.net.OchSignal;
33import org.onosproject.net.OchSignalType;
34import org.onosproject.net.Port;
35import org.onosproject.net.PortNumber;
36import org.onosproject.net.behaviour.LambdaQuery;
37import org.onosproject.net.behaviour.PowerConfig;
MaoLu937cf422017-03-03 23:31:46 -080038import org.onosproject.net.behaviour.protection.ProtectionConfigBehaviour;
39import org.onosproject.net.behaviour.protection.ProtectedTransportEndpointState;
40import org.onosproject.net.behaviour.protection.TransportEndpointState;
Jimmy Yanda878fc2016-09-02 16:32:01 -070041import org.onosproject.net.device.DeviceEvent;
42import org.onosproject.net.device.DeviceListener;
43import org.onosproject.net.device.DeviceService;
44import org.onosproject.net.flow.DefaultFlowRule;
45import org.onosproject.net.flow.DefaultTrafficSelector;
46import org.onosproject.net.flow.DefaultTrafficTreatment;
47import org.onosproject.net.flow.FlowEntry;
48import org.onosproject.net.flow.FlowId;
49import org.onosproject.net.flow.FlowRule;
50import org.onosproject.net.flow.FlowRuleService;
51import org.onosproject.net.flow.TrafficSelector;
52import org.onosproject.net.flow.TrafficTreatment;
53import org.onosproject.net.flow.criteria.Criteria;
54import org.onosproject.net.flow.instructions.Instructions;
MaoLu937cf422017-03-03 23:31:46 -080055import org.onosproject.net.optical.OpticalAnnotations;
56
Jimmy Yanda878fc2016-09-02 16:32:01 -070057import org.slf4j.Logger;
58import org.slf4j.LoggerFactory;
59
60import java.util.Collections;
61import java.util.List;
MaoLu937cf422017-03-03 23:31:46 -080062import java.util.Map;
Jimmy Yanda878fc2016-09-02 16:32:01 -070063import java.util.Optional;
64import java.util.Set;
MaoLu937cf422017-03-03 23:31:46 -080065import java.util.concurrent.CompletableFuture;
66import java.util.concurrent.ExecutionException;
Jimmy Yanda878fc2016-09-02 16:32:01 -070067import java.util.concurrent.TimeUnit;
68
MaoLu937cf422017-03-03 23:31:46 -080069
Jimmy Yanda878fc2016-09-02 16:32:01 -070070import static com.google.common.base.Preconditions.checkNotNull;
71
72/**
73 * Application for monitoring and configuring ROADM devices.
74 */
75@Component(immediate = true)
76@Service
77public class RoadmManager implements RoadmService {
78
79 private static final String APP_NAME = "org.onosproject.roadm";
80 private ApplicationId appId;
81
82 private final Logger log = LoggerFactory.getLogger(getClass());
83
84 private DeviceListener deviceListener = new InternalDeviceListener();
85
86 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
87 protected RoadmStore roadmStore;
88
89 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
90 protected CoreService coreService;
91
92 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
93 protected DeviceService deviceService;
94
95 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
96 protected FlowRuleService flowRuleService;
97
98 @Activate
99 protected void activate() {
100 appId = coreService.registerApplication(APP_NAME);
101 deviceService.addListener(deviceListener);
102 initDevices();
103
104 log.info("Started");
105 }
106
107 @Deactivate
108 protected void deactivate() {
109 deviceService.removeListener(deviceListener);
110
111 log.info("Stopped");
112 }
113
MaoLu937cf422017-03-03 23:31:46 -0800114 @Override
115 public void setProtectionSwitchWorkingPath(DeviceId deviceId, int index) {
116 checkNotNull(deviceId);
117 ProtectionConfigBehaviour behaviour = getProtectionConfig(deviceId);
118 if (behaviour == null) {
Jimmy Yanda878fc2016-09-02 16:32:01 -0700119 return;
120 }
MaoLu937cf422017-03-03 23:31:46 -0800121 Map<ConnectPoint, ProtectedTransportEndpointState> map = getProtectionSwitchStates(behaviour);
122 if (map == null) {
123 log.warn("Failed to get protected transport endpoint state in device {}", deviceId);
Jimmy Yanda878fc2016-09-02 16:32:01 -0700124 return;
125 }
MaoLu937cf422017-03-03 23:31:46 -0800126 if (map.isEmpty()) {
127 log.warn("No protected transport endpoint state found in device {}", deviceId);
128 return;
Jimmy Yanda878fc2016-09-02 16:32:01 -0700129 }
MaoLu937cf422017-03-03 23:31:46 -0800130 behaviour.switchWorkingPath(map.keySet().toArray(new ConnectPoint[0])[0], index);
Jimmy Yanda878fc2016-09-02 16:32:01 -0700131 }
132
MaoLu937cf422017-03-03 23:31:46 -0800133 @Override
134 public String getProtectionSwitchPortState(DeviceId deviceId, PortNumber portNumber) {
135 checkNotNull(deviceId);
136 ProtectionConfigBehaviour behaviour = getProtectionConfig(deviceId);
137 if (behaviour == null) {
138 return null;
Jimmy Yanda878fc2016-09-02 16:32:01 -0700139 }
MaoLu937cf422017-03-03 23:31:46 -0800140 Map<ConnectPoint, ProtectedTransportEndpointState> map = getProtectionSwitchStates(behaviour);
141 if (map == null) {
142 log.warn("Failed to get protected transport endpoint state in device {}", deviceId);
143 return null;
144 }
145 for (ProtectedTransportEndpointState state : map.values()) {
146 for (TransportEndpointState element : state.pathStates()) {
147 if (element.description().output().connectPoint().port().equals(portNumber)) {
148 return element.attributes().get(OpticalAnnotations.INPUT_PORT_STATUS);
Jimmy Yanda878fc2016-09-02 16:32:01 -0700149 }
Jimmy Yanda878fc2016-09-02 16:32:01 -0700150 }
151 }
MaoLu937cf422017-03-03 23:31:46 -0800152 log.warn("Unable to get port status, device: {}, port: {}", deviceId, portNumber);
153 return null;
Jimmy Yanda878fc2016-09-02 16:32:01 -0700154 }
155
156 @Override
157 public void setTargetPortPower(DeviceId deviceId, PortNumber portNumber, long power) {
158 checkNotNull(deviceId);
159 checkNotNull(portNumber);
160 PowerConfig<Object> powerConfig = getPowerConfig(deviceId);
161 if (powerConfig != null) {
162 roadmStore.setTargetPower(deviceId, portNumber, power);
163 powerConfig.setTargetPower(portNumber, Direction.ALL, power);
164 } else {
165 log.warn("Unable to set target port power for device {}", deviceId);
166 }
167 }
168
169 @Override
170 public Long getTargetPortPower(DeviceId deviceId, PortNumber portNumber) {
171 checkNotNull(deviceId);
172 checkNotNull(portNumber);
MaoLu937cf422017-03-03 23:31:46 -0800173 // getTargetPortPower is not yet implemented in PowerConfig so we access store instead
Jimmy Yanda878fc2016-09-02 16:32:01 -0700174 return roadmStore.getTargetPower(deviceId, portNumber);
175 }
176
177 @Override
178 public void setAttenuation(DeviceId deviceId, PortNumber portNumber,
179 OchSignal ochSignal, long attenuation) {
180 checkNotNull(deviceId);
181 checkNotNull(portNumber);
182 checkNotNull(ochSignal);
183 PowerConfig<Object> powerConfig = getPowerConfig(deviceId);
184 if (powerConfig != null) {
185 powerConfig.setTargetPower(portNumber, ochSignal, attenuation);
186 } else {
187 log.warn("Cannot set attenuation for channel index {} on device {}",
188 ochSignal.spacingMultiplier(), deviceId);
189 }
190 }
191
192 @Override
MaoLu937cf422017-03-03 23:31:46 -0800193 public Long getAttenuation(DeviceId deviceId, PortNumber portNumber, OchSignal ochSignal) {
Jimmy Yanda878fc2016-09-02 16:32:01 -0700194 checkNotNull(deviceId);
195 checkNotNull(portNumber);
196 checkNotNull(ochSignal);
197 PowerConfig<Object> powerConfig = getPowerConfig(deviceId);
198 if (powerConfig != null) {
MaoLu937cf422017-03-03 23:31:46 -0800199 Optional<Long> attenuation = powerConfig.getTargetPower(portNumber, ochSignal);
Jimmy Yanda878fc2016-09-02 16:32:01 -0700200 if (attenuation.isPresent()) {
201 return attenuation.get();
202 }
203 }
204 return null;
205 }
206
207 @Override
208 public Long getCurrentPortPower(DeviceId deviceId, PortNumber portNumber) {
209 checkNotNull(deviceId);
210 checkNotNull(portNumber);
211 PowerConfig<Object> powerConfig = getPowerConfig(deviceId);
212 if (powerConfig != null) {
MaoLu937cf422017-03-03 23:31:46 -0800213 Optional<Long> currentPower = powerConfig.currentPower(portNumber, Direction.ALL);
Jimmy Yanda878fc2016-09-02 16:32:01 -0700214 if (currentPower.isPresent()) {
215 return currentPower.get();
216 }
217 }
218 return null;
219 }
220
221 @Override
MaoLu937cf422017-03-03 23:31:46 -0800222 public Long getCurrentChannelPower(DeviceId deviceId, PortNumber portNumber, OchSignal ochSignal) {
Jimmy Yanda878fc2016-09-02 16:32:01 -0700223 checkNotNull(deviceId);
224 checkNotNull(portNumber);
225 checkNotNull(ochSignal);
226 PowerConfig<Object> powerConfig = getPowerConfig(deviceId);
227 if (powerConfig != null) {
MaoLu937cf422017-03-03 23:31:46 -0800228 Optional<Long> currentPower = powerConfig.currentPower(portNumber, ochSignal);
Jimmy Yanda878fc2016-09-02 16:32:01 -0700229 if (currentPower.isPresent()) {
230 return currentPower.get();
231 }
232 }
233 return null;
234 }
235
236 @Override
237 public Set<OchSignal> queryLambdas(DeviceId deviceId, PortNumber portNumber) {
238 checkNotNull(deviceId);
239 checkNotNull(portNumber);
240 LambdaQuery lambdaQuery = getLambdaQuery(deviceId);
241 if (lambdaQuery != null) {
242 return lambdaQuery.queryLambdas(portNumber);
243 }
244 return Collections.emptySet();
245 }
246
247 @Override
248 public FlowId createConnection(DeviceId deviceId, int priority, boolean isPermanent,
MaoLu937cf422017-03-03 23:31:46 -0800249 int timeout, PortNumber inPort, PortNumber outPort, OchSignal ochSignal) {
Jimmy Yanda878fc2016-09-02 16:32:01 -0700250 checkNotNull(deviceId);
251 checkNotNull(inPort);
252 checkNotNull(outPort);
253
MaoLu937cf422017-03-03 23:31:46 -0800254 TrafficSelector selector = DefaultTrafficSelector.builder()
255 .add(Criteria.matchInPort(inPort))
256 .add(Criteria.matchOchSignalType(OchSignalType.FIXED_GRID))
257 .add(Criteria.matchLambda(ochSignal))
258 .build();
259 TrafficTreatment treatment = DefaultTrafficTreatment.builder()
260 .add(Instructions.createOutput(outPort))
261 .build();
262
263 FlowRule.Builder flowBuilder = DefaultFlowRule.builder()
264 .forDevice(deviceId)
265 .fromApp(appId)
266 .withPriority(priority)
267 .withSelector(selector)
268 .withTreatment(treatment);
Jimmy Yanda878fc2016-09-02 16:32:01 -0700269 if (isPermanent) {
270 flowBuilder.makePermanent();
271 } else {
272 flowBuilder.makeTemporary(timeout);
273 }
Jimmy Yanda878fc2016-09-02 16:32:01 -0700274
275 FlowRule flowRule = flowBuilder.build();
276 flowRuleService.applyFlowRules(flowRule);
277
278 log.info("Created connection from input port {} to output port {}",
279 inPort.toLong(), outPort.toLong());
280
281 return flowRule.id();
282 }
283
284 @Override
285 public FlowId createConnection(DeviceId deviceId, int priority, boolean isPermanent,
286 int timeout, PortNumber inPort, PortNumber outPort,
287 OchSignal ochSignal, long attenuation) {
288 checkNotNull(deviceId);
289 checkNotNull(inPort);
290 checkNotNull(outPort);
MaoLu937cf422017-03-03 23:31:46 -0800291 FlowId flowId = createConnection(deviceId, priority, isPermanent, timeout, inPort, outPort, ochSignal);
Jimmy Yanda878fc2016-09-02 16:32:01 -0700292 delayedSetAttenuation(deviceId, outPort, ochSignal, attenuation);
293 return flowId;
294 }
295
Jimmy Yanda878fc2016-09-02 16:32:01 -0700296 @Override
297 public void removeConnection(DeviceId deviceId, FlowId flowId) {
298 checkNotNull(deviceId);
299 checkNotNull(flowId);
300 for (FlowEntry entry : flowRuleService.getFlowEntries(deviceId)) {
301 if (entry.id().equals(flowId)) {
302 flowRuleService.removeFlowRules(entry);
303 log.info("Deleted connection {}", entry.id());
304 break;
305 }
306 }
307 }
308
309 @Override
310 public boolean hasPortTargetPower(DeviceId deviceId, PortNumber portNumber) {
311 checkNotNull(deviceId);
312 checkNotNull(portNumber);
313 PowerConfig<Object> powerConfig = getPowerConfig(deviceId);
314 if (powerConfig != null) {
MaoLu937cf422017-03-03 23:31:46 -0800315 Optional<Range<Long>> range = powerConfig.getTargetPowerRange(portNumber, Direction.ALL);
Jimmy Yanda878fc2016-09-02 16:32:01 -0700316 return range.isPresent();
317 }
318 return false;
319 }
320
321 @Override
MaoLu937cf422017-03-03 23:31:46 -0800322 public boolean portTargetPowerInRange(DeviceId deviceId, PortNumber portNumber, long power) {
Jimmy Yanda878fc2016-09-02 16:32:01 -0700323 checkNotNull(deviceId);
324 checkNotNull(portNumber);
325 PowerConfig<Object> powerConfig = getPowerConfig(deviceId);
326 if (powerConfig != null) {
MaoLu937cf422017-03-03 23:31:46 -0800327 Optional<Range<Long>> range = powerConfig.getTargetPowerRange(portNumber, Direction.ALL);
Jimmy Yanda878fc2016-09-02 16:32:01 -0700328 return range.isPresent() && range.get().contains(power);
329 }
330 return false;
331 }
332
333 @Override
MaoLu937cf422017-03-03 23:31:46 -0800334 public boolean attenuationInRange(DeviceId deviceId, PortNumber outPort, long att) {
Jimmy Yanda878fc2016-09-02 16:32:01 -0700335 checkNotNull(deviceId);
336 checkNotNull(outPort);
337 PowerConfig<Object> powerConfig = getPowerConfig(deviceId);
338 if (powerConfig != null) {
339 OchSignal stubOch = OchSignal.newDwdmSlot(ChannelSpacing.CHL_50GHZ, 0);
MaoLu937cf422017-03-03 23:31:46 -0800340 Optional<Range<Long>> range = powerConfig.getTargetPowerRange(outPort, stubOch);
Jimmy Yanda878fc2016-09-02 16:32:01 -0700341 return range.isPresent() && range.get().contains(att);
342 }
343 return false;
344 }
345
346 @Override
347 public boolean validInputPort(DeviceId deviceId, PortNumber portNumber) {
348 checkNotNull(deviceId);
349 checkNotNull(portNumber);
350 PowerConfig<Object> powerConfig = getPowerConfig(deviceId);
351 if (powerConfig != null) {
MaoLu937cf422017-03-03 23:31:46 -0800352 Optional<Range<Long>> range = powerConfig.getInputPowerRange(portNumber, Direction.ALL);
Jimmy Yanda878fc2016-09-02 16:32:01 -0700353 return range.isPresent();
354 }
355 return false;
356 }
357
358 @Override
359 public boolean validOutputPort(DeviceId deviceId, PortNumber portNumber) {
360 return hasPortTargetPower(deviceId, portNumber);
361 }
362
363 @Override
MaoLu937cf422017-03-03 23:31:46 -0800364 public boolean validChannel(DeviceId deviceId, PortNumber portNumber, OchSignal ochSignal) {
Jimmy Yanda878fc2016-09-02 16:32:01 -0700365 checkNotNull(deviceId);
366 checkNotNull(portNumber);
MaoLu937cf422017-03-03 23:31:46 -0800367 checkNotNull(ochSignal);
Jimmy Yanda878fc2016-09-02 16:32:01 -0700368 LambdaQuery lambdaQuery = getLambdaQuery(deviceId);
369 if (lambdaQuery != null) {
370 Set<OchSignal> channels = lambdaQuery.queryLambdas(portNumber);
371 return channels.contains(ochSignal);
372 }
373 return false;
374 }
375
376 @Override
377 public boolean channelAvailable(DeviceId deviceId, OchSignal ochSignal) {
378 checkNotNull(deviceId);
379 checkNotNull(ochSignal);
380 for (FlowEntry entry : flowRuleService.getFlowEntries(deviceId)) {
381 if (ChannelData.fromFlow(entry).ochSignal().equals(ochSignal)) {
382 return false;
383 }
384 }
385 return true;
386 }
387
388 @Override
MaoLu937cf422017-03-03 23:31:46 -0800389 public boolean validConnection(DeviceId deviceId, PortNumber inPort, PortNumber outPort) {
Jimmy Yanda878fc2016-09-02 16:32:01 -0700390 checkNotNull(deviceId);
391 checkNotNull(inPort);
392 checkNotNull(outPort);
393 return validInputPort(deviceId, inPort) && validOutputPort(deviceId, outPort);
394 }
395
396 @Override
397 public Range<Long> targetPortPowerRange(DeviceId deviceId, PortNumber portNumber) {
398 checkNotNull(deviceId);
399 checkNotNull(portNumber);
400 PowerConfig<Object> powerConfig = getPowerConfig(deviceId);
401 if (powerConfig != null) {
MaoLu937cf422017-03-03 23:31:46 -0800402 Optional<Range<Long>> range = powerConfig.getTargetPowerRange(portNumber, Direction.ALL);
Jimmy Yanda878fc2016-09-02 16:32:01 -0700403 if (range.isPresent()) {
404 return range.get();
405 }
406 }
407 return null;
408 }
409
410 @Override
MaoLu937cf422017-03-03 23:31:46 -0800411 public Range<Long> attenuationRange(DeviceId deviceId, PortNumber portNumber, OchSignal ochSignal) {
Jimmy Yanda878fc2016-09-02 16:32:01 -0700412 checkNotNull(deviceId);
413 checkNotNull(portNumber);
414 checkNotNull(ochSignal);
415 PowerConfig<Object> powerConfig = getPowerConfig(deviceId);
416 if (powerConfig != null) {
MaoLu937cf422017-03-03 23:31:46 -0800417 Optional<Range<Long>> range = powerConfig.getTargetPowerRange(portNumber, ochSignal);
Jimmy Yanda878fc2016-09-02 16:32:01 -0700418 if (range.isPresent()) {
419 return range.get();
420 }
421 }
422 return null;
423 }
424
425 @Override
426 public Range<Long> inputPortPowerRange(DeviceId deviceId, PortNumber portNumber) {
427 checkNotNull(deviceId);
428 checkNotNull(portNumber);
429 PowerConfig<Object> powerConfig = getPowerConfig(deviceId);
430 if (powerConfig != null) {
MaoLu937cf422017-03-03 23:31:46 -0800431 Optional<Range<Long>> range = powerConfig.getInputPowerRange(portNumber, Direction.ALL);
Jimmy Yanda878fc2016-09-02 16:32:01 -0700432 if (range.isPresent()) {
433 return range.get();
434 }
435 }
436 return null;
437 }
438
MaoLu937cf422017-03-03 23:31:46 -0800439 private PowerConfig<Object> getPowerConfig(DeviceId deviceId) {
440 Device device = deviceService.getDevice(deviceId);
441 if (device != null && device.is(PowerConfig.class)) {
442 return device.as(PowerConfig.class);
443 }
444 log.warn("Unable to load PowerConfig for {}", deviceId);
445 return null;
446 }
447
448 private LambdaQuery getLambdaQuery(DeviceId deviceId) {
449 Device device = deviceService.getDevice(deviceId);
450 if (device != null && device.is(LambdaQuery.class)) {
451 return device.as(LambdaQuery.class);
452 }
453 log.warn("Unable to load LambdaQuery for {}", deviceId);
454 return null;
455 }
456
457 private ProtectionConfigBehaviour getProtectionConfig(DeviceId deviceId) {
458 Device device = deviceService.getDevice(deviceId);
459 if (device != null && device.is(ProtectionConfigBehaviour.class)) {
460 return device.as(ProtectionConfigBehaviour.class);
461 }
462 log.warn("Unable to load ProtectionConfigBehaviour for {}", deviceId);
463 return null;
464 }
465
466 // Initialize all devices
467 private void initDevices() {
468 for (Device device : deviceService.getDevices(Device.Type.ROADM)) {
469 initDevice(device.id());
470 //FIXME
471 // As roadm application is a optional tool for now.
472 // The target power initialization will be enhanced later,
473 // hopefully using an formal optical subsystem.
474 // setAllInitialTargetPortPowers(device.id());
475 }
476 }
477
478 // Initialize RoadmStore for a device to support target power
479 private void initDevice(DeviceId deviceId) {
480 if (!roadmStore.deviceAvailable(deviceId)) {
481 roadmStore.addDevice(deviceId);
482 }
483 log.info("Initialized device {}", deviceId);
484 }
485
486 // Sets the target port powers for a port on a device
487 // Attempts to read target powers from store. If no value is found then
488 // default value is used instead.
489 private void setInitialTargetPortPower(DeviceId deviceId, PortNumber portNumber) {
490 PowerConfig<Object> powerConfig = getPowerConfig(deviceId);
491 if (powerConfig == null) {
492 log.warn("Unable to set default initial powers for port {} on device {}", portNumber, deviceId);
493 return;
494 }
495
496 Optional<Range<Long>> range = powerConfig.getTargetPowerRange(portNumber, Direction.ALL);
497 if (!range.isPresent()) {
498 log.warn("No target power range found for port {} on device {}", portNumber, deviceId);
499 return;
500 }
501
502 Long power = roadmStore.getTargetPower(deviceId, portNumber);
503 if (power == null) {
504 // Set default to middle of the range
505 power = (range.get().lowerEndpoint() + range.get().upperEndpoint()) / 2;
506 roadmStore.setTargetPower(deviceId, portNumber, power);
507 }
508 powerConfig.setTargetPower(portNumber, Direction.ALL, power);
509 }
510
511 // Sets the target port powers for each each port on a device
512 // Attempts to read target powers from store. If no value is found then
513 // default value is used instead
514 private void setAllInitialTargetPortPowers(DeviceId deviceId) {
515 PowerConfig<Object> powerConfig = getPowerConfig(deviceId);
516 if (powerConfig == null) {
517 log.warn("Unable to set default initial powers for device {}", deviceId);
518 return;
519 }
520
521 List<Port> ports = deviceService.getPorts(deviceId);
522 for (Port port : ports) {
523 Optional<Range<Long>> range = powerConfig.getTargetPowerRange(port.number(), Direction.ALL);
524 if (range.isPresent()) {
525 Long power = roadmStore.getTargetPower(deviceId, port.number());
526 if (power == null) {
527 // Set default to middle of the range
528 power = (range.get().lowerEndpoint() + range.get().upperEndpoint()) / 2;
529 roadmStore.setTargetPower(deviceId, port.number(), power);
530 }
531 powerConfig.setTargetPower(port.number(), Direction.ALL, power);
532 } else {
533 log.warn("No target power range found for port {} on device {}", port.number(), deviceId);
534 }
535 }
536 }
537
538 // Delay the call to setTargetPower because the flow may not be in the store yet
539 private void delayedSetAttenuation(DeviceId deviceId, PortNumber outPort,
540 OchSignal ochSignal, long attenuation) {
541 Runnable setAtt = () -> {
542 try {
543 TimeUnit.SECONDS.sleep(1);
544 } catch (InterruptedException e) {
545 log.warn("Thread interrupted. Setting attenuation early.");
546 }
547 setAttenuation(deviceId, outPort, ochSignal, attenuation);
548 };
549 new Thread(setAtt).start();
550 }
551
552 // get protection endpoint states
553 private Map<ConnectPoint, ProtectedTransportEndpointState> getProtectionSwitchStates(
554 ProtectionConfigBehaviour behaviour) {
555 CompletableFuture<Map<ConnectPoint, ProtectedTransportEndpointState>>
556 states = behaviour.getProtectionEndpointStates();
557 Map<ConnectPoint, ProtectedTransportEndpointState> map;
558 try {
559 map = states.get();
560 } catch (InterruptedException e1) {
561 log.error("Interrupted.", e1);
562 return null;
563 } catch (ExecutionException e1) {
564 log.error("Exception caught.", e1);
565 return null;
566 }
567 return map;
568 }
569
Jimmy Yanda878fc2016-09-02 16:32:01 -0700570 // Listens to device events.
571 private class InternalDeviceListener implements DeviceListener {
572 @Override
573 public void event(DeviceEvent deviceEvent) {
574 Device device = deviceEvent.subject();
575
576 switch (deviceEvent.type()) {
577 case DEVICE_ADDED:
578 case DEVICE_UPDATED:
579 initDevice(device.id());
580 break;
581 case PORT_ADDED:
582 case PORT_UPDATED:
MaoLu937cf422017-03-03 23:31:46 -0800583 //FIXME
584 // As roadm application is a optional tool for now.
585 // The target power initialization will be enhanced later,
586 // hopefully using an formal optical subsystem.
587 // setInitialTargetPortPower(device.id(), deviceEvent.port().number());
Jimmy Yanda878fc2016-09-02 16:32:01 -0700588 break;
589 default:
590 break;
591
592 }
593 }
594 }
595}