Update to pom files and package organization of bng-app
Also, update maven repo to HTTPS.
Change-Id: I664f819b2a671a5e85dcfd3e87e333f1163366d5
diff --git a/app/src/main/java/org/opencord/bng/impl/BngStatsManager.java b/app/src/main/java/org/opencord/bng/impl/BngStatsManager.java
new file mode 100644
index 0000000..6a2a716
--- /dev/null
+++ b/app/src/main/java/org/opencord/bng/impl/BngStatsManager.java
@@ -0,0 +1,207 @@
+/*
+ * Copyright 2019-present Open Networking Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.opencord.bng.impl;
+
+import com.google.common.collect.Maps;
+import org.onlab.util.SharedScheduledExecutors;
+import org.onlab.util.Tools;
+import org.onosproject.cfg.ComponentConfigService;
+import org.onosproject.core.ApplicationId;
+import org.onosproject.core.CoreService;
+import org.onosproject.event.AbstractListenerManager;
+import org.onosproject.net.DeviceId;
+import org.onosproject.net.behaviour.BngProgrammable;
+import org.onosproject.net.device.DeviceService;
+import org.onosproject.net.pi.runtime.PiCounterCellData;
+import org.opencord.bng.BngAttachment;
+import org.opencord.bng.BngService;
+import org.opencord.bng.BngStatsEvent;
+import org.opencord.bng.BngStatsEventListener;
+import org.opencord.bng.BngStatsEventSubject;
+import org.opencord.bng.BngStatsService;
+import org.osgi.service.component.ComponentContext;
+import org.osgi.service.component.annotations.Activate;
+import org.osgi.service.component.annotations.Component;
+import org.osgi.service.component.annotations.Deactivate;
+import org.osgi.service.component.annotations.Modified;
+import org.osgi.service.component.annotations.Reference;
+import org.osgi.service.component.annotations.ReferenceCardinality;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.Dictionary;
+import java.util.Map;
+import java.util.Properties;
+import java.util.concurrent.ScheduledFuture;
+import java.util.concurrent.TimeUnit;
+
+import static org.opencord.bng.impl.OsgiPropertyConstants.BNG_STATISTICS_PROBE_RATE;
+import static org.opencord.bng.impl.OsgiPropertyConstants.BNG_STATISTICS_PROBE_RATE_DEFAULT;
+
+@Component(immediate = true,
+ property = {
+ BNG_STATISTICS_PROBE_RATE + ":Long=" + BNG_STATISTICS_PROBE_RATE_DEFAULT,
+ }
+)
+public class BngStatsManager
+ extends AbstractListenerManager<BngStatsEvent, BngStatsEventListener> implements BngStatsService {
+
+ private final Logger log = LoggerFactory.getLogger(getClass());
+ private final BngStatisticsMonitor bngStatsMonitor = new BngStatisticsMonitor();
+
+ @Reference(cardinality = ReferenceCardinality.MANDATORY)
+ protected ComponentConfigService componentConfigService;
+
+ @Reference(cardinality = ReferenceCardinality.MANDATORY)
+ protected BngService bngService;
+
+ @Reference(cardinality = ReferenceCardinality.MANDATORY)
+ protected DeviceService deviceService;
+
+ @Reference(cardinality = ReferenceCardinality.MANDATORY)
+ protected CoreService coreService;
+
+ private ApplicationId appId;
+ /**
+ * The BNG statistics probe rate.
+ */
+ private long bngStatisticsProbeRate = BNG_STATISTICS_PROBE_RATE_DEFAULT;
+ private ScheduledFuture<?> timeout;
+
+ @Activate
+ protected void activate() {
+ eventDispatcher.addSink(BngStatsEvent.class, listenerRegistry);
+ componentConfigService.registerProperties(getClass());
+ appId = coreService.getAppId(BngManager.BNG_APP);
+ start();
+ log.info("BNG Statistics manager activated");
+ }
+
+ @Modified
+ protected void modified(ComponentContext context) {
+ Dictionary<?, ?> properties = context != null ? context.getProperties() : new Properties();
+ Long probeRate = Tools.getLongProperty(properties, BNG_STATISTICS_PROBE_RATE);
+ if (probeRate != null) {
+ bngStatisticsProbeRate = probeRate;
+ }
+ }
+
+ @Deactivate
+ protected void deactivate() {
+ shutdown();
+ componentConfigService.unregisterProperties(getClass(), false);
+ eventDispatcher.removeSink(BngStatsEvent.class);
+ log.info("BNG Statistics manager deactivated");
+
+ }
+
+ /**
+ * Starts the BNG statistics monitor. Does nothing if the monitor is already
+ * running.
+ */
+ private void start() {
+ synchronized (bngStatsMonitor) {
+ if (timeout == null) {
+ timeout = SharedScheduledExecutors.newTimeout(bngStatsMonitor, 0, TimeUnit.MILLISECONDS);
+ }
+ }
+ }
+
+ /**
+ * Stops the BNG statistics monitor.
+ */
+ private void shutdown() {
+ synchronized (bngStatsMonitor) {
+ if (timeout != null) {
+ timeout.cancel(true);
+ timeout = null;
+ }
+ }
+ }
+
+ private Map<String, Map<BngProgrammable.BngCounterType, PiCounterCellData>> getStats(
+ Map<String, BngAttachment> attachments) {
+ Map<String, Map<BngProgrammable.BngCounterType, PiCounterCellData>>
+ stats = Maps.newHashMap();
+ attachments.forEach((key, value) -> stats.put(key, getStats(key)));
+ return stats;
+ }
+
+ @Override
+ public Map<BngProgrammable.BngCounterType, PiCounterCellData> getStats(
+ String bngAttachmentKey) {
+ BngProgrammable bngProgrammable = getBngProgrammable(bngService.getBngDeviceId());
+ BngAttachment attachment = bngService.getAttachment(bngAttachmentKey);
+ if (bngProgrammable != null && attachment != null) {
+ try {
+ return bngProgrammable.readCounters(attachment);
+ } catch (BngProgrammable.BngProgrammableException e) {
+ log.error("Error getting statistics of {}", bngAttachmentKey);
+ }
+ }
+ return Maps.newHashMap();
+ }
+
+ @Override
+ public PiCounterCellData getControlStats() {
+ BngProgrammable bngProgrammable = getBngProgrammable(bngService.getBngDeviceId());
+ if (bngProgrammable != null) {
+ try {
+ return bngProgrammable.readControlTrafficCounter();
+ } catch (BngProgrammable.BngProgrammableException e) {
+ log.error("Error control plane packets statistics");
+ }
+ }
+ return null;
+ }
+
+ private BngProgrammable getBngProgrammable(DeviceId deviceId) {
+ if (deviceId != null && deviceService.isAvailable(deviceId)) {
+ return deviceService.getDevice(deviceId).as(BngProgrammable.class);
+ }
+ return null;
+ }
+
+ private class BngStatisticsMonitor implements Runnable {
+ @Override
+ public void run() {
+ BngProgrammable bngProgrammable = getBngProgrammable(bngService.getBngDeviceId());
+ if (bngProgrammable != null) {
+ var attachments = bngService.getAttachments();
+ Map<String, Map<BngProgrammable.BngCounterType, PiCounterCellData>>
+ attachmentsStats = getStats(attachments);
+ // Create an event for each attachment statistics
+ attachmentsStats.forEach((attachmentKey, stats) -> {
+ BngStatsEventSubject evInfo =
+ new BngStatsEventSubject(attachmentKey,
+ attachments.get(attachmentKey),
+ stats);
+ post(new BngStatsEvent(BngStatsEvent.EventType.STATS_UPDATED, evInfo));
+ });
+ } else {
+ log.debug("BngProgrammable not available");
+ }
+ synchronized (this) {
+ if (timeout != null) {
+ timeout = SharedScheduledExecutors.newTimeout(this, bngStatisticsProbeRate, TimeUnit.MILLISECONDS);
+ }
+ }
+ }
+ }
+}
+
+