blob: 7f44e23d56546ad39bf88e2784f8df00b8b48eec [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 }
MaoLudd5a00b2017-03-14 11:19:48 -0700152 // Do not need warning here for port polling.
153 log.debug("Unable to get port status, device: {}, port: {}", deviceId, portNumber);
MaoLu937cf422017-03-03 23:31:46 -0800154 return null;
Jimmy Yanda878fc2016-09-02 16:32:01 -0700155 }
156
157 @Override
158 public void setTargetPortPower(DeviceId deviceId, PortNumber portNumber, long power) {
159 checkNotNull(deviceId);
160 checkNotNull(portNumber);
161 PowerConfig<Object> powerConfig = getPowerConfig(deviceId);
162 if (powerConfig != null) {
163 roadmStore.setTargetPower(deviceId, portNumber, power);
164 powerConfig.setTargetPower(portNumber, Direction.ALL, power);
165 } else {
166 log.warn("Unable to set target port power for device {}", deviceId);
167 }
168 }
169
170 @Override
171 public Long getTargetPortPower(DeviceId deviceId, PortNumber portNumber) {
172 checkNotNull(deviceId);
173 checkNotNull(portNumber);
MaoLu937cf422017-03-03 23:31:46 -0800174 // getTargetPortPower is not yet implemented in PowerConfig so we access store instead
Jimmy Yanda878fc2016-09-02 16:32:01 -0700175 return roadmStore.getTargetPower(deviceId, portNumber);
176 }
177
178 @Override
179 public void setAttenuation(DeviceId deviceId, PortNumber portNumber,
180 OchSignal ochSignal, long attenuation) {
181 checkNotNull(deviceId);
182 checkNotNull(portNumber);
183 checkNotNull(ochSignal);
184 PowerConfig<Object> powerConfig = getPowerConfig(deviceId);
185 if (powerConfig != null) {
186 powerConfig.setTargetPower(portNumber, ochSignal, attenuation);
187 } else {
188 log.warn("Cannot set attenuation for channel index {} on device {}",
189 ochSignal.spacingMultiplier(), deviceId);
190 }
191 }
192
193 @Override
MaoLu937cf422017-03-03 23:31:46 -0800194 public Long getAttenuation(DeviceId deviceId, PortNumber portNumber, OchSignal ochSignal) {
Jimmy Yanda878fc2016-09-02 16:32:01 -0700195 checkNotNull(deviceId);
196 checkNotNull(portNumber);
197 checkNotNull(ochSignal);
198 PowerConfig<Object> powerConfig = getPowerConfig(deviceId);
199 if (powerConfig != null) {
MaoLu937cf422017-03-03 23:31:46 -0800200 Optional<Long> attenuation = powerConfig.getTargetPower(portNumber, ochSignal);
Jimmy Yanda878fc2016-09-02 16:32:01 -0700201 if (attenuation.isPresent()) {
202 return attenuation.get();
203 }
204 }
205 return null;
206 }
207
208 @Override
209 public Long getCurrentPortPower(DeviceId deviceId, PortNumber portNumber) {
210 checkNotNull(deviceId);
211 checkNotNull(portNumber);
212 PowerConfig<Object> powerConfig = getPowerConfig(deviceId);
213 if (powerConfig != null) {
MaoLu937cf422017-03-03 23:31:46 -0800214 Optional<Long> currentPower = powerConfig.currentPower(portNumber, Direction.ALL);
Jimmy Yanda878fc2016-09-02 16:32:01 -0700215 if (currentPower.isPresent()) {
216 return currentPower.get();
217 }
218 }
219 return null;
220 }
221
222 @Override
MaoLu937cf422017-03-03 23:31:46 -0800223 public Long getCurrentChannelPower(DeviceId deviceId, PortNumber portNumber, OchSignal ochSignal) {
Jimmy Yanda878fc2016-09-02 16:32:01 -0700224 checkNotNull(deviceId);
225 checkNotNull(portNumber);
226 checkNotNull(ochSignal);
227 PowerConfig<Object> powerConfig = getPowerConfig(deviceId);
228 if (powerConfig != null) {
MaoLu937cf422017-03-03 23:31:46 -0800229 Optional<Long> currentPower = powerConfig.currentPower(portNumber, ochSignal);
Jimmy Yanda878fc2016-09-02 16:32:01 -0700230 if (currentPower.isPresent()) {
231 return currentPower.get();
232 }
233 }
234 return null;
235 }
236
237 @Override
238 public Set<OchSignal> queryLambdas(DeviceId deviceId, PortNumber portNumber) {
239 checkNotNull(deviceId);
240 checkNotNull(portNumber);
241 LambdaQuery lambdaQuery = getLambdaQuery(deviceId);
242 if (lambdaQuery != null) {
243 return lambdaQuery.queryLambdas(portNumber);
244 }
245 return Collections.emptySet();
246 }
247
248 @Override
249 public FlowId createConnection(DeviceId deviceId, int priority, boolean isPermanent,
MaoLu937cf422017-03-03 23:31:46 -0800250 int timeout, PortNumber inPort, PortNumber outPort, OchSignal ochSignal) {
Jimmy Yanda878fc2016-09-02 16:32:01 -0700251 checkNotNull(deviceId);
252 checkNotNull(inPort);
253 checkNotNull(outPort);
254
MaoLu937cf422017-03-03 23:31:46 -0800255 TrafficSelector selector = DefaultTrafficSelector.builder()
256 .add(Criteria.matchInPort(inPort))
257 .add(Criteria.matchOchSignalType(OchSignalType.FIXED_GRID))
258 .add(Criteria.matchLambda(ochSignal))
259 .build();
260 TrafficTreatment treatment = DefaultTrafficTreatment.builder()
261 .add(Instructions.createOutput(outPort))
262 .build();
263
264 FlowRule.Builder flowBuilder = DefaultFlowRule.builder()
265 .forDevice(deviceId)
266 .fromApp(appId)
267 .withPriority(priority)
268 .withSelector(selector)
269 .withTreatment(treatment);
Jimmy Yanda878fc2016-09-02 16:32:01 -0700270 if (isPermanent) {
271 flowBuilder.makePermanent();
272 } else {
273 flowBuilder.makeTemporary(timeout);
274 }
Jimmy Yanda878fc2016-09-02 16:32:01 -0700275
276 FlowRule flowRule = flowBuilder.build();
277 flowRuleService.applyFlowRules(flowRule);
278
279 log.info("Created connection from input port {} to output port {}",
280 inPort.toLong(), outPort.toLong());
281
282 return flowRule.id();
283 }
284
285 @Override
286 public FlowId createConnection(DeviceId deviceId, int priority, boolean isPermanent,
287 int timeout, PortNumber inPort, PortNumber outPort,
288 OchSignal ochSignal, long attenuation) {
289 checkNotNull(deviceId);
290 checkNotNull(inPort);
291 checkNotNull(outPort);
MaoLu937cf422017-03-03 23:31:46 -0800292 FlowId flowId = createConnection(deviceId, priority, isPermanent, timeout, inPort, outPort, ochSignal);
Jimmy Yanda878fc2016-09-02 16:32:01 -0700293 delayedSetAttenuation(deviceId, outPort, ochSignal, attenuation);
294 return flowId;
295 }
296
Jimmy Yanda878fc2016-09-02 16:32:01 -0700297 @Override
298 public void removeConnection(DeviceId deviceId, FlowId flowId) {
299 checkNotNull(deviceId);
300 checkNotNull(flowId);
301 for (FlowEntry entry : flowRuleService.getFlowEntries(deviceId)) {
302 if (entry.id().equals(flowId)) {
303 flowRuleService.removeFlowRules(entry);
304 log.info("Deleted connection {}", entry.id());
305 break;
306 }
307 }
308 }
309
310 @Override
311 public boolean hasPortTargetPower(DeviceId deviceId, PortNumber portNumber) {
312 checkNotNull(deviceId);
313 checkNotNull(portNumber);
314 PowerConfig<Object> powerConfig = getPowerConfig(deviceId);
315 if (powerConfig != null) {
MaoLu937cf422017-03-03 23:31:46 -0800316 Optional<Range<Long>> range = powerConfig.getTargetPowerRange(portNumber, Direction.ALL);
Jimmy Yanda878fc2016-09-02 16:32:01 -0700317 return range.isPresent();
318 }
319 return false;
320 }
321
322 @Override
MaoLu937cf422017-03-03 23:31:46 -0800323 public boolean portTargetPowerInRange(DeviceId deviceId, PortNumber portNumber, long power) {
Jimmy Yanda878fc2016-09-02 16:32:01 -0700324 checkNotNull(deviceId);
325 checkNotNull(portNumber);
326 PowerConfig<Object> powerConfig = getPowerConfig(deviceId);
327 if (powerConfig != null) {
MaoLu937cf422017-03-03 23:31:46 -0800328 Optional<Range<Long>> range = powerConfig.getTargetPowerRange(portNumber, Direction.ALL);
Jimmy Yanda878fc2016-09-02 16:32:01 -0700329 return range.isPresent() && range.get().contains(power);
330 }
331 return false;
332 }
333
334 @Override
MaoLu937cf422017-03-03 23:31:46 -0800335 public boolean attenuationInRange(DeviceId deviceId, PortNumber outPort, long att) {
Jimmy Yanda878fc2016-09-02 16:32:01 -0700336 checkNotNull(deviceId);
337 checkNotNull(outPort);
338 PowerConfig<Object> powerConfig = getPowerConfig(deviceId);
339 if (powerConfig != null) {
340 OchSignal stubOch = OchSignal.newDwdmSlot(ChannelSpacing.CHL_50GHZ, 0);
MaoLu937cf422017-03-03 23:31:46 -0800341 Optional<Range<Long>> range = powerConfig.getTargetPowerRange(outPort, stubOch);
Jimmy Yanda878fc2016-09-02 16:32:01 -0700342 return range.isPresent() && range.get().contains(att);
343 }
344 return false;
345 }
346
347 @Override
348 public boolean validInputPort(DeviceId deviceId, PortNumber portNumber) {
349 checkNotNull(deviceId);
350 checkNotNull(portNumber);
351 PowerConfig<Object> powerConfig = getPowerConfig(deviceId);
352 if (powerConfig != null) {
MaoLu937cf422017-03-03 23:31:46 -0800353 Optional<Range<Long>> range = powerConfig.getInputPowerRange(portNumber, Direction.ALL);
Jimmy Yanda878fc2016-09-02 16:32:01 -0700354 return range.isPresent();
355 }
356 return false;
357 }
358
359 @Override
360 public boolean validOutputPort(DeviceId deviceId, PortNumber portNumber) {
361 return hasPortTargetPower(deviceId, portNumber);
362 }
363
364 @Override
MaoLu937cf422017-03-03 23:31:46 -0800365 public boolean validChannel(DeviceId deviceId, PortNumber portNumber, OchSignal ochSignal) {
Jimmy Yanda878fc2016-09-02 16:32:01 -0700366 checkNotNull(deviceId);
367 checkNotNull(portNumber);
MaoLu937cf422017-03-03 23:31:46 -0800368 checkNotNull(ochSignal);
Jimmy Yanda878fc2016-09-02 16:32:01 -0700369 LambdaQuery lambdaQuery = getLambdaQuery(deviceId);
370 if (lambdaQuery != null) {
371 Set<OchSignal> channels = lambdaQuery.queryLambdas(portNumber);
372 return channels.contains(ochSignal);
373 }
374 return false;
375 }
376
377 @Override
378 public boolean channelAvailable(DeviceId deviceId, OchSignal ochSignal) {
379 checkNotNull(deviceId);
380 checkNotNull(ochSignal);
381 for (FlowEntry entry : flowRuleService.getFlowEntries(deviceId)) {
382 if (ChannelData.fromFlow(entry).ochSignal().equals(ochSignal)) {
383 return false;
384 }
385 }
386 return true;
387 }
388
389 @Override
MaoLu937cf422017-03-03 23:31:46 -0800390 public boolean validConnection(DeviceId deviceId, PortNumber inPort, PortNumber outPort) {
Jimmy Yanda878fc2016-09-02 16:32:01 -0700391 checkNotNull(deviceId);
392 checkNotNull(inPort);
393 checkNotNull(outPort);
394 return validInputPort(deviceId, inPort) && validOutputPort(deviceId, outPort);
395 }
396
397 @Override
398 public Range<Long> targetPortPowerRange(DeviceId deviceId, PortNumber portNumber) {
399 checkNotNull(deviceId);
400 checkNotNull(portNumber);
401 PowerConfig<Object> powerConfig = getPowerConfig(deviceId);
402 if (powerConfig != null) {
MaoLu937cf422017-03-03 23:31:46 -0800403 Optional<Range<Long>> range = powerConfig.getTargetPowerRange(portNumber, Direction.ALL);
Jimmy Yanda878fc2016-09-02 16:32:01 -0700404 if (range.isPresent()) {
405 return range.get();
406 }
407 }
408 return null;
409 }
410
411 @Override
MaoLu937cf422017-03-03 23:31:46 -0800412 public Range<Long> attenuationRange(DeviceId deviceId, PortNumber portNumber, OchSignal ochSignal) {
Jimmy Yanda878fc2016-09-02 16:32:01 -0700413 checkNotNull(deviceId);
414 checkNotNull(portNumber);
415 checkNotNull(ochSignal);
416 PowerConfig<Object> powerConfig = getPowerConfig(deviceId);
417 if (powerConfig != null) {
MaoLu937cf422017-03-03 23:31:46 -0800418 Optional<Range<Long>> range = powerConfig.getTargetPowerRange(portNumber, ochSignal);
Jimmy Yanda878fc2016-09-02 16:32:01 -0700419 if (range.isPresent()) {
420 return range.get();
421 }
422 }
423 return null;
424 }
425
426 @Override
427 public Range<Long> inputPortPowerRange(DeviceId deviceId, PortNumber portNumber) {
428 checkNotNull(deviceId);
429 checkNotNull(portNumber);
430 PowerConfig<Object> powerConfig = getPowerConfig(deviceId);
431 if (powerConfig != null) {
MaoLu937cf422017-03-03 23:31:46 -0800432 Optional<Range<Long>> range = powerConfig.getInputPowerRange(portNumber, Direction.ALL);
Jimmy Yanda878fc2016-09-02 16:32:01 -0700433 if (range.isPresent()) {
434 return range.get();
435 }
436 }
437 return null;
438 }
439
MaoLu937cf422017-03-03 23:31:46 -0800440 private PowerConfig<Object> getPowerConfig(DeviceId deviceId) {
441 Device device = deviceService.getDevice(deviceId);
442 if (device != null && device.is(PowerConfig.class)) {
443 return device.as(PowerConfig.class);
444 }
MaoLudd5a00b2017-03-14 11:19:48 -0700445 // Do not need warning here for port polling.
446 log.debug("Unable to load PowerConfig for {}", deviceId);
MaoLu937cf422017-03-03 23:31:46 -0800447 return null;
448 }
449
450 private LambdaQuery getLambdaQuery(DeviceId deviceId) {
451 Device device = deviceService.getDevice(deviceId);
452 if (device != null && device.is(LambdaQuery.class)) {
453 return device.as(LambdaQuery.class);
454 }
MaoLudd5a00b2017-03-14 11:19:48 -0700455 // Do not need warning here for port polling.
456 log.debug("Unable to load LambdaQuery for {}", deviceId);
MaoLu937cf422017-03-03 23:31:46 -0800457 return null;
458 }
459
460 private ProtectionConfigBehaviour getProtectionConfig(DeviceId deviceId) {
461 Device device = deviceService.getDevice(deviceId);
462 if (device != null && device.is(ProtectionConfigBehaviour.class)) {
463 return device.as(ProtectionConfigBehaviour.class);
464 }
MaoLudd5a00b2017-03-14 11:19:48 -0700465 // Do not need warning here for port polling.
466 log.debug("Unable to load ProtectionConfigBehaviour for {}", deviceId);
MaoLu937cf422017-03-03 23:31:46 -0800467 return null;
468 }
469
470 // Initialize all devices
471 private void initDevices() {
472 for (Device device : deviceService.getDevices(Device.Type.ROADM)) {
473 initDevice(device.id());
474 //FIXME
475 // As roadm application is a optional tool for now.
476 // The target power initialization will be enhanced later,
477 // hopefully using an formal optical subsystem.
478 // setAllInitialTargetPortPowers(device.id());
479 }
480 }
481
482 // Initialize RoadmStore for a device to support target power
483 private void initDevice(DeviceId deviceId) {
484 if (!roadmStore.deviceAvailable(deviceId)) {
485 roadmStore.addDevice(deviceId);
486 }
487 log.info("Initialized device {}", deviceId);
488 }
489
490 // Sets the target port powers for a port on a device
491 // Attempts to read target powers from store. If no value is found then
492 // default value is used instead.
493 private void setInitialTargetPortPower(DeviceId deviceId, PortNumber portNumber) {
494 PowerConfig<Object> powerConfig = getPowerConfig(deviceId);
495 if (powerConfig == null) {
496 log.warn("Unable to set default initial powers for port {} on device {}", portNumber, deviceId);
497 return;
498 }
499
500 Optional<Range<Long>> range = powerConfig.getTargetPowerRange(portNumber, Direction.ALL);
501 if (!range.isPresent()) {
502 log.warn("No target power range found for port {} on device {}", portNumber, deviceId);
503 return;
504 }
505
506 Long power = roadmStore.getTargetPower(deviceId, portNumber);
507 if (power == null) {
508 // Set default to middle of the range
509 power = (range.get().lowerEndpoint() + range.get().upperEndpoint()) / 2;
510 roadmStore.setTargetPower(deviceId, portNumber, power);
511 }
512 powerConfig.setTargetPower(portNumber, Direction.ALL, power);
513 }
514
515 // Sets the target port powers for each each port on a device
516 // Attempts to read target powers from store. If no value is found then
517 // default value is used instead
518 private void setAllInitialTargetPortPowers(DeviceId deviceId) {
519 PowerConfig<Object> powerConfig = getPowerConfig(deviceId);
520 if (powerConfig == null) {
521 log.warn("Unable to set default initial powers for device {}", deviceId);
522 return;
523 }
524
525 List<Port> ports = deviceService.getPorts(deviceId);
526 for (Port port : ports) {
527 Optional<Range<Long>> range = powerConfig.getTargetPowerRange(port.number(), Direction.ALL);
528 if (range.isPresent()) {
529 Long power = roadmStore.getTargetPower(deviceId, port.number());
530 if (power == null) {
531 // Set default to middle of the range
532 power = (range.get().lowerEndpoint() + range.get().upperEndpoint()) / 2;
533 roadmStore.setTargetPower(deviceId, port.number(), power);
534 }
535 powerConfig.setTargetPower(port.number(), Direction.ALL, power);
536 } else {
537 log.warn("No target power range found for port {} on device {}", port.number(), deviceId);
538 }
539 }
540 }
541
542 // Delay the call to setTargetPower because the flow may not be in the store yet
543 private void delayedSetAttenuation(DeviceId deviceId, PortNumber outPort,
544 OchSignal ochSignal, long attenuation) {
545 Runnable setAtt = () -> {
546 try {
547 TimeUnit.SECONDS.sleep(1);
548 } catch (InterruptedException e) {
549 log.warn("Thread interrupted. Setting attenuation early.");
550 }
551 setAttenuation(deviceId, outPort, ochSignal, attenuation);
552 };
553 new Thread(setAtt).start();
554 }
555
556 // get protection endpoint states
557 private Map<ConnectPoint, ProtectedTransportEndpointState> getProtectionSwitchStates(
558 ProtectionConfigBehaviour behaviour) {
559 CompletableFuture<Map<ConnectPoint, ProtectedTransportEndpointState>>
560 states = behaviour.getProtectionEndpointStates();
561 Map<ConnectPoint, ProtectedTransportEndpointState> map;
562 try {
563 map = states.get();
564 } catch (InterruptedException e1) {
565 log.error("Interrupted.", e1);
566 return null;
567 } catch (ExecutionException e1) {
568 log.error("Exception caught.", e1);
569 return null;
570 }
571 return map;
572 }
573
Jimmy Yanda878fc2016-09-02 16:32:01 -0700574 // Listens to device events.
575 private class InternalDeviceListener implements DeviceListener {
576 @Override
577 public void event(DeviceEvent deviceEvent) {
578 Device device = deviceEvent.subject();
579
580 switch (deviceEvent.type()) {
581 case DEVICE_ADDED:
582 case DEVICE_UPDATED:
583 initDevice(device.id());
584 break;
585 case PORT_ADDED:
586 case PORT_UPDATED:
MaoLu937cf422017-03-03 23:31:46 -0800587 //FIXME
588 // As roadm application is a optional tool for now.
589 // The target power initialization will be enhanced later,
590 // hopefully using an formal optical subsystem.
591 // setInitialTargetPortPower(device.id(), deviceEvent.port().number());
Jimmy Yanda878fc2016-09-02 16:32:01 -0700592 break;
593 default:
594 break;
595
596 }
597 }
598 }
599}