blob: b336c2890b6dd2c4d55dbc3caba59efe009edbf4 [file] [log] [blame]
Matteo Scandoloaa2adde2021-09-13 12:45:32 -07001/*
2 * Copyright 2021-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 */
16
17package org.opencord.olt.impl;
18
19import org.onosproject.cluster.ClusterService;
20import org.onosproject.cluster.LeadershipService;
21import org.onosproject.cluster.NodeId;
22import org.onosproject.mastership.MastershipService;
23import org.onosproject.net.Device;
24import org.onosproject.net.DeviceId;
25import org.onosproject.net.Port;
26import org.onosproject.net.PortNumber;
27import org.onosproject.net.device.DeviceService;
28import org.opencord.sadis.BaseInformationService;
29import org.opencord.sadis.SadisService;
30import org.opencord.sadis.SubscriberAndDeviceInformation;
31import org.osgi.service.component.annotations.Activate;
32import org.osgi.service.component.annotations.Component;
33import org.osgi.service.component.annotations.Reference;
34import org.osgi.service.component.annotations.ReferenceCardinality;
35import org.osgi.service.component.annotations.ReferencePolicy;
36import org.slf4j.Logger;
37
38import java.util.List;
39import java.util.Optional;
40
41import static org.slf4j.LoggerFactory.getLogger;
42
43/**
44 * The implementation of the OltDeviceService.
45 */
46@Component(immediate = true)
47public class OltDeviceService implements OltDeviceServiceInterface {
48
49 protected BaseInformationService<SubscriberAndDeviceInformation> subsService;
50 private final Logger log = getLogger(getClass());
51
52 @Reference(cardinality = ReferenceCardinality.OPTIONAL,
53 bind = "bindSadisService",
54 unbind = "unbindSadisService",
55 policy = ReferencePolicy.DYNAMIC)
56 protected volatile SadisService sadisService;
57
58 @Reference(cardinality = ReferenceCardinality.MANDATORY)
59 protected DeviceService deviceService;
60
61 @Reference(cardinality = ReferenceCardinality.MANDATORY)
62 protected ClusterService clusterService;
63
64 @Reference(cardinality = ReferenceCardinality.MANDATORY)
65 protected MastershipService mastershipService;
66
67 @Reference(cardinality = ReferenceCardinality.MANDATORY)
68 protected LeadershipService leadershipService;
69
70 @Activate
71 public void activate() {
72 log.info("Activated");
73 }
74
75 /**
76 * Returns true if the device is an OLT.
77 *
78 * @param device the Device to be checked
79 * @return boolean
80 */
81 public boolean isOlt(Device device) {
82 return getOltInfo(device) != null;
83 }
84
85 private SubscriberAndDeviceInformation getOltInfo(Device dev) {
86 if (subsService == null) {
87 return null;
88 }
89 String devSerialNo = dev.serialNumber();
90 return subsService.get(devSerialNo);
91 }
92
93
94 /**
95 * Returns true if the port is an NNI Port on the OLT.
96 * NOTE: We can check if a port is a NNI based on the SADIS config, specifically the uplinkPort section
97 *
98 * @param dev the Device this port belongs to
99 * @param portNumber the PortNumber to be checked
100 * @return boolean
101 */
102 @Override
103 public boolean isNniPort(Device dev, PortNumber portNumber) {
104 SubscriberAndDeviceInformation deviceInfo = getOltInfo(dev);
105 return deviceInfo != null && portNumber.toLong() == deviceInfo.uplinkPort();
106 }
107
108 @Override
109 public Optional<Port> getNniPort(Device device) {
110 SubscriberAndDeviceInformation deviceInfo = getOltInfo(device);
111 if (deviceInfo == null) {
112 return Optional.empty();
113 }
114 List<Port> ports = deviceService.getPorts(device.id());
115 if (log.isTraceEnabled()) {
116 log.trace("Get NNI Port looks for NNI in: {}", ports);
117 }
118 return ports.stream()
119 .filter(p -> p.number().toLong() == deviceInfo.uplinkPort())
120 .findFirst();
121 }
122
123 protected void bindSadisService(SadisService service) {
124 this.subsService = service.getSubscriberInfoService();
125 log.info("Sadis service is loaded");
126 }
127
128 protected void unbindSadisService(SadisService service) {
129 this.subsService = null;
130 log.info("Sadis service is unloaded");
131 }
132
133 /**
134 * Checks for mastership or falls back to leadership on deviceId.
135 * If the device is available use mastership,
136 * otherwise fallback on leadership.
137 * Leadership on the device topic is needed because the master can be NONE
138 * in case the device went away, we still need to handle events
139 * consistently
140 *
141 * @param deviceId The device ID to check.
142 * @return boolean (true if the current instance is managing the device)
143 */
144 @Override
145 public boolean isLocalLeader(DeviceId deviceId) {
146 if (deviceService.isAvailable(deviceId)) {
147 return mastershipService.isLocalMaster(deviceId);
148 } else {
149 // Fallback with Leadership service - device id is used as topic
150 NodeId leader = leadershipService.runForLeadership(
151 deviceId.toString()).leaderNodeId();
152 // Verify if this node is the leader
153 return clusterService.getLocalNode().id().equals(leader);
154 }
155 }
156}