blob: e2f4779301878f4b004ddc60f1bd2ef456ebf64f [file] [log] [blame]
Arjun E Kabf9e6e2020-03-02 10:15:21 +00001/*
2 * Copyright 2018-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 */
Daniele Moro8ea9e102020-03-24 18:56:52 +010016package org.opencord.cordmcast.impl;
Arjun E Kabf9e6e2020-03-02 10:15:21 +000017
18
19import org.onlab.packet.VlanId;
20import org.onlab.util.SafeRecurringTask;
21import org.onosproject.cfg.ComponentConfigService;
Ilayda Ozdemir0414dde2020-06-27 23:18:07 +000022import org.onosproject.cluster.ClusterService;
23import org.onosproject.cluster.LeadershipService;
Arjun E Kabf9e6e2020-03-02 10:15:21 +000024import org.onosproject.event.AbstractListenerManager;
25import org.onosproject.mcast.api.McastRoute;
26import org.onosproject.mcast.api.MulticastRouteService;
Daniele Moro8ea9e102020-03-24 18:56:52 +010027import org.opencord.cordmcast.CordMcastStatistics;
28import org.opencord.cordmcast.CordMcastStatisticsEvent;
29import org.opencord.cordmcast.CordMcastStatisticsEventListener;
30import org.opencord.cordmcast.CordMcastStatisticsService;
Arjun E Kabf9e6e2020-03-02 10:15:21 +000031import org.osgi.service.component.ComponentContext;
32import org.osgi.service.component.annotations.Modified;
33import org.osgi.service.component.annotations.Activate;
34import org.osgi.service.component.annotations.Deactivate;
35import org.osgi.service.component.annotations.Component;
36import org.osgi.service.component.annotations.Reference;
37import org.osgi.service.component.annotations.ReferenceCardinality;
38import org.slf4j.Logger;
39
40import java.util.Dictionary;
41import java.util.Set;
42import java.util.List;
43import java.util.ArrayList;
44import java.util.Properties;
Ilayda Ozdemir0414dde2020-06-27 23:18:07 +000045import java.util.Objects;
Arjun E Kabf9e6e2020-03-02 10:15:21 +000046
47import java.util.concurrent.Executors;
48import java.util.concurrent.ScheduledExecutorService;
49import java.util.concurrent.ScheduledFuture;
50import java.util.concurrent.TimeUnit;
51
52import static com.google.common.base.Strings.isNullOrEmpty;
53import static org.onlab.util.Tools.get;
Daniele Moro8ea9e102020-03-24 18:56:52 +010054import static org.opencord.cordmcast.impl.OsgiPropertyConstants.EVENT_GENERATION_PERIOD;
55import static org.opencord.cordmcast.impl.OsgiPropertyConstants.EVENT_GENERATION_PERIOD_DEFAULT;
Arjun E Kabf9e6e2020-03-02 10:15:21 +000056
57import static org.slf4j.LoggerFactory.getLogger;
58
59/**
60 * For managing CordMcastStatisticsEvent.
61 */
62@Component(immediate = true, property = { EVENT_GENERATION_PERIOD + ":Integer=" + EVENT_GENERATION_PERIOD_DEFAULT, })
63public class CordMcastStatisticsManager
64 extends AbstractListenerManager<CordMcastStatisticsEvent, CordMcastStatisticsEventListener>
65 implements CordMcastStatisticsService {
66
Ilayda Ozdemir0414dde2020-06-27 23:18:07 +000067 private static final String CORD_MCAST_STATISTICS_LEADERSHIP = "cord-mcast-statistics-leadership";
68
Arjun E Kabf9e6e2020-03-02 10:15:21 +000069 @Reference(cardinality = ReferenceCardinality.MANDATORY)
70 protected MulticastRouteService mcastService;
71
72 @Reference(cardinality = ReferenceCardinality.MANDATORY)
73 protected ComponentConfigService componentConfigService;
74
Ilayda Ozdemir0414dde2020-06-27 23:18:07 +000075 @Reference(cardinality = ReferenceCardinality.MANDATORY)
76 protected ClusterService clusterService;
77
78 @Reference(cardinality = ReferenceCardinality.MANDATORY)
79 protected LeadershipService leadershipService;
80
Arjun E Kabf9e6e2020-03-02 10:15:21 +000081
82 /**
83 * Multicast Statistics generation time interval.
84 **/
85 private int eventGenerationPeriodInSeconds = EVENT_GENERATION_PERIOD_DEFAULT;
86 private final Logger log = getLogger(getClass());
87 private ScheduledFuture<?> scheduledFuture = null;
88 private ScheduledExecutorService executor;
89
90 private VlanId vlanId;
Esin Karamane4890012020-04-19 11:58:54 +000091 private VlanId innerVlanId;
Arjun E Kabf9e6e2020-03-02 10:15:21 +000092
93 @Activate
94 public void activate(ComponentContext context) {
Ilayda Ozdemir0414dde2020-06-27 23:18:07 +000095 leadershipService.runForLeadership(CORD_MCAST_STATISTICS_LEADERSHIP);
Arjun E Kabf9e6e2020-03-02 10:15:21 +000096 eventDispatcher.addSink(CordMcastStatisticsEvent.class, listenerRegistry);
97 executor = Executors.newScheduledThreadPool(1);
98 componentConfigService.registerProperties(getClass());
99 modified(context);
100 log.info("CordMcastStatisticsManager activated.");
101 }
102
103 @Modified
104 public void modified(ComponentContext context) {
105 Dictionary<?, ?> properties = context != null ? context.getProperties() : new Properties();
106 try {
107 String s = get(properties, EVENT_GENERATION_PERIOD);
108 eventGenerationPeriodInSeconds =
109 isNullOrEmpty(s) ? EVENT_GENERATION_PERIOD_DEFAULT : Integer.parseInt(s.trim());
110 } catch (NumberFormatException ne) {
111 log.error("Unable to parse configuration parameter for eventGenerationPeriodInSeconds", ne);
112 eventGenerationPeriodInSeconds = EVENT_GENERATION_PERIOD_DEFAULT;
113 }
114 if (scheduledFuture != null) {
115 scheduledFuture.cancel(true);
116 }
117 scheduledFuture = executor.scheduleAtFixedRate(SafeRecurringTask.wrap(this::publishEvent),
118 0, eventGenerationPeriodInSeconds, TimeUnit.SECONDS);
119 }
120
121 @Deactivate
122 public void deactivate() {
123 eventDispatcher.removeSink(CordMcastStatisticsEvent.class);
124 scheduledFuture.cancel(true);
125 executor.shutdown();
Ilayda Ozdemir0414dde2020-06-27 23:18:07 +0000126 leadershipService.withdraw(CORD_MCAST_STATISTICS_LEADERSHIP);
127 log.info("CordMcastStatisticsManager deactivated.");
Arjun E Kabf9e6e2020-03-02 10:15:21 +0000128 }
129
130 public List<CordMcastStatistics> getMcastDetails() {
131 List<CordMcastStatistics> mcastData = new ArrayList<CordMcastStatistics>();
132 Set<McastRoute> routes = mcastService.getRoutes();
133 routes.forEach(route -> {
134 mcastData.add(new CordMcastStatistics(route.group(),
135 route.source().isEmpty() ? "*" : route.source().get().toString(),
Esin Karamane4890012020-04-19 11:58:54 +0000136 vlanId, innerVlanId));
Arjun E Kabf9e6e2020-03-02 10:15:21 +0000137 });
138 return mcastData;
139 }
140
141 @Override
142 public void setVlanValue(VlanId vlanValue) {
143 vlanId = vlanValue;
144 }
145
Esin Karamane4890012020-04-19 11:58:54 +0000146 @Override
147 public void setInnerVlanValue(VlanId innerVlanValue) {
148 innerVlanId = innerVlanValue;
149 }
150
Arjun E Kabf9e6e2020-03-02 10:15:21 +0000151 /**
152 * pushing mcast stat data as event.
153 */
154 protected void publishEvent() {
Ilayda Ozdemir0414dde2020-06-27 23:18:07 +0000155 // Only publish events if we are the cluster leader for Igmp-stats
156 if (!Objects.equals(leadershipService.getLeader(CORD_MCAST_STATISTICS_LEADERSHIP),
157 clusterService.getLocalNode().id())) {
158 log.debug("This is not leader of : {}", CORD_MCAST_STATISTICS_LEADERSHIP);
159 return;
160 }
Arjun E Kabf9e6e2020-03-02 10:15:21 +0000161 log.debug("pushing cord mcast event to kafka");
162 List<CordMcastStatistics> routeList = getMcastDetails();
163 routeList.forEach(mcastStats -> {
164 log.debug("Group: " +
165 (mcastStats.getGroupAddress() != null ? mcastStats.getGroupAddress().toString() : "null") +
166 " | Source: " +
167 (mcastStats.getSourceAddress() != null ? mcastStats.getSourceAddress().toString() : "null") +
168 " | Vlan: " +
Esin Karamane4890012020-04-19 11:58:54 +0000169 (mcastStats.getVlanId() != null ? mcastStats.getVlanId().toString() : "null") +
170 " | InnerVlan: " +
171 (mcastStats.getInnerVlanId() != null ? mcastStats.getInnerVlanId().toString() : "null"));
Arjun E Kabf9e6e2020-03-02 10:15:21 +0000172 });
173 post(new CordMcastStatisticsEvent(CordMcastStatisticsEvent.Type.STATUS_UPDATE, routeList));
174 }
175}