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);
+                }
+            }
+        }
+    }
+}
+
+