[SLICEANALYSIS] Bugfix for sliceanalysis startup Exception, break the circular dependency 38/131238/4 1.1.5-slice-analysis-ms
authordecheng zhang <decheng.zhang@huawei.com>
Tue, 27 Sep 2022 18:05:58 +0000 (14:05 -0400)
committerdecheng zhang <decheng.zhang@huawei.com>
Tue, 27 Sep 2022 19:04:41 +0000 (15:04 -0400)
Break the circular dependency by seperating networkpolicymonitor from bandwidthEvaluator

Issue-ID: DCAEGEN2-3270
Signed-off-by: decheng zhang <decheng.zhang@huawei.com>
Change-Id: I2632e5ea500121b8c223bdbcda16bdc24dc36895
Signed-off-by: decheng zhang <decheng.zhang@huawei.com>
components/slice-analysis-ms/ChangeLog.md
components/slice-analysis-ms/src/main/java/org/onap/slice/analysis/ms/service/ccvpn/BandwidthEvaluator.java
components/slice-analysis-ms/src/main/java/org/onap/slice/analysis/ms/service/ccvpn/FixedUpperBoundStrategy.java
components/slice-analysis-ms/src/main/java/org/onap/slice/analysis/ms/service/ccvpn/FlexibleThresholdStrategy.java
components/slice-analysis-ms/src/main/java/org/onap/slice/analysis/ms/service/ccvpn/NetworkPolicyMonitor.java [new file with mode: 0644]
components/slice-analysis-ms/src/main/java/org/onap/slice/analysis/ms/service/ccvpn/StrategyFactory.java
components/slice-analysis-ms/src/test/java/org/onap/slice/analysis/ms/service/ccvpn/NetworkPolicyMonitorTest.java [new file with mode: 0644]

index aadb09b..aa92c9c 100644 (file)
@@ -21,7 +21,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
 
          - [DCAEGEN2-3273](https://jira.onap.org/browse/DCAEGEN2-3273) - Fix bug that config thread hang up when cbs policy is empty
 
-         - [DCAEGEN2-3270](https://jira.onap.org/browse/DCAEGEN2-3270) - Dcae slicems startup error
+         - [DCAEGEN2-3270](https://jira.onap.org/browse/DCAEGEN2-3270) - Dcae slicems startup error, breaking the circular dependency.
 
 ## [1.1.4] - 2022/07/28
          - [DCAEGEN2-3120](https://jira.onap.org/browse/DCAEGEN2-3120) - Enhance sliceanalysis MS to use DCAE SDK dmaap-client lib
index 67cda89..c5e3151 100644 (file)
@@ -50,17 +50,10 @@ public class BandwidthEvaluator {
     private static Logger log = LoggerFactory.getLogger(BandwidthEvaluator.class);
     private Configuration configuration;
 
-    @Autowired
-    AaiService aaiService;
-
-    @Autowired
-    CCVPNPmDatastore ccvpnPmDatastore;
-
     @Autowired
     StrategyFactory strategyFactory;
 
     private Loop evaluationEventLoop;
-    private Loop aaiEventLoop;
 
     private static final Event KILL_PILL = new SimpleEvent(null, 0);
     private static final int DEFAULT_EVAL_INTERVAL = 5;
@@ -98,34 +91,6 @@ public class BandwidthEvaluator {
             }
         };
 
-        /**
-         * AAI data consumer loop
-         */
-        aaiEventLoop = new Loop("AAIEventLoop"){
-            @Override
-            public void process(Event event) {
-                if (event.type() == SimpleEvent.Type.AAI_BW_REQ){
-                    log.debug("=== Processing new AAI network policy query at: {} ===", event.time());
-                    String serviceId = (String) event.subject();
-                    Map<String, Integer> maxBandwidthData = aaiService.fetchMaxBandwidthOfService(serviceId);
-                    if (maxBandwidthData.get("maxBandwidth") != null){
-                        log.debug("Successfully retrieved bandwidth info from AAI; service: {}, bandwidth: {}",
-                                serviceId, maxBandwidthData.get("maxBandwidth"));
-                        int bwValue = maxBandwidthData.get("maxBandwidth").intValue();
-                        if (ccvpnPmDatastore.getProvBwOfSvc(serviceId) == 0){
-                            ccvpnPmDatastore.updateProvBw(serviceId, bwValue, true);
-                            log.debug("Provision bw of cll {} updated from 0 to {}, max bw is {}", serviceId, ccvpnPmDatastore.getProvBwOfSvc(serviceId), bwValue);
-                        } else if (ccvpnPmDatastore.getProvBwOfSvc(serviceId) != bwValue) {
-                            log.debug("Service modification complete; serviceId: {} update prov bw from {} to {}", serviceId, ccvpnPmDatastore.getProvBwOfSvc(serviceId), bwValue);
-                            ccvpnPmDatastore.updateProvBw(serviceId, bwValue, true);
-                            ccvpnPmDatastore.updateSvcState(serviceId, ServiceState.RUNNING);
-                            log.debug("Service state of {} is changed to running, {}", serviceId, ccvpnPmDatastore.getStatusOfSvc(serviceId));
-                        }
-                    }
-                    log.debug("=== Processing AAI network policy query complete ===");
-                }
-            }
-        };
         scheduleEvaluation();
     }
 
@@ -135,7 +100,6 @@ public class BandwidthEvaluator {
     @PreDestroy
     public void stop(){
         stopScheduleEvaluation();
-        aaiEventLoop.stop();
         evaluationEventLoop.stop();
     }
 
@@ -165,9 +129,7 @@ public class BandwidthEvaluator {
     public void post(@NonNull Event event){
         log.info("A new event triggered, type: {}, subject: {}, at time: {}",
                 event.type(), event.subject(), event.time());
-        if (event.type() == SimpleEvent.Type.AAI_BW_REQ) {
-            aaiEventLoop.add(event);
-        } else if (event.type() == SimpleEvent.Type.PERIODIC_CHECK) {
+        if (event.type() == SimpleEvent.Type.PERIODIC_CHECK) {
             evaluationEventLoop.add(event);
         } else if (event.type() == SimpleEvent.Type.ONDEMAND_CHECK) {
             evaluationEventLoop.add(event);
index ec864aa..66dc6dc 100644 (file)
@@ -59,7 +59,7 @@ public class FixedUpperBoundStrategy implements EvaluationStrategy{
     private static double precision; // in Mbps;
 
     @Autowired
-    BandwidthEvaluator bandwidthEvaluator;
+    NetworkPolicyMonitor networkPolicyMonitor;
 
     @Autowired
     CCVPNPmDatastore ccvpnPmDatastore;
@@ -166,11 +166,11 @@ public class FixedUpperBoundStrategy implements EvaluationStrategy{
     }
 
     /**
-     * Post/broadcast event to the BandwidthEvaluator
+     * Post/broadcast event to the networkPolicyMonitor
      * @param event event object
      */
     private void post(Event event){
-        bandwidthEvaluator.post(event);
+        networkPolicyMonitor.post(event);
     }
 
     private void loadConfig() {
index 261794c..6b55216 100644 (file)
@@ -41,7 +41,7 @@ import java.util.stream.Collectors;
  */
 @Component
 public class FlexibleThresholdStrategy implements EvaluationStrategy{
-    private static Logger log = LoggerFactory.getLogger(FixedUpperBoundStrategy.class);
+    private static Logger log = LoggerFactory.getLogger(FlexibleThresholdStrategy.class);
     private Configuration configuration;
     private static final String TYPE_NAME = "FlexibleThresholdStrategy";
     private static final String SERVICE_INSTANCE_LOCATION_ID = "service-instance-location-id";
@@ -63,7 +63,7 @@ public class FlexibleThresholdStrategy implements EvaluationStrategy{
     private static double precision; // in Mbps;
 
     @Autowired
-    BandwidthEvaluator bandwidthEvaluator;
+    NetworkPolicyMonitor networkPolicyMonitor;
 
     @Autowired
     CCVPNPmDatastore ccvpnPmDatastore;
@@ -174,11 +174,11 @@ public class FlexibleThresholdStrategy implements EvaluationStrategy{
     }
 
     /**
-     * Post/broadcast event to the BandwidthEvaluator
+     * Post/broadcast event to the networkPolicyMonitor
      * @param event event object
      */
     private void post(Event event){
-        bandwidthEvaluator.post(event);
+        networkPolicyMonitor.post(event);
     }
 
     private void loadConfig() {
diff --git a/components/slice-analysis-ms/src/main/java/org/onap/slice/analysis/ms/service/ccvpn/NetworkPolicyMonitor.java b/components/slice-analysis-ms/src/main/java/org/onap/slice/analysis/ms/service/ccvpn/NetworkPolicyMonitor.java
new file mode 100644 (file)
index 0000000..9948804
--- /dev/null
@@ -0,0 +1,164 @@
+/*******************************************************************************
+ *  ============LICENSE_START=======================================================
+ *  slice-analysis-ms
+ *  ================================================================================
+ *   Copyright (C) 2022 Huawei Canada Limited.
+ *  ==============================================================================
+ *     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.
+ *     ============LICENSE_END=========================================================
+ *
+ *******************************************************************************/
+
+package org.onap.slice.analysis.ms.service.ccvpn;
+
+import lombok.NonNull;
+import org.onap.slice.analysis.ms.aai.AaiService;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+
+import javax.annotation.PostConstruct;
+import java.util.Map;
+import java.util.concurrent.BlockingQueue;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.Future;
+import java.util.concurrent.LinkedBlockingQueue;
+
+/**
+ * Actor that processes aai network-policy query request
+ */
+@Component
+public class NetworkPolicyMonitor {
+    private static Logger log = LoggerFactory.getLogger(NetworkPolicyMonitor.class);
+    private Loop aaiEventLoop;
+    private static final Event KILL_PILL = new SimpleEvent(null, 0);
+
+    @Autowired
+    AaiService aaiService;
+
+    @Autowired
+    CCVPNPmDatastore ccvpnPmDatastore;
+
+    /**
+     * Initialize and start the NetworkPolicyMonitor.
+     */
+    @PostConstruct
+    public void init() {
+        /**
+         * AAI data consumer loop
+         */
+        aaiEventLoop = new Loop("AAIEventLoop"){
+            @Override
+            public void process(Event event) {
+                if (event.type() == SimpleEvent.Type.AAI_BW_REQ){
+                    log.debug("=== Processing new AAI network policy query at: {} ===", event.time());
+                    String serviceId = (String) event.subject();
+                    Map<String, Integer> maxBandwidthData = aaiService.fetchMaxBandwidthOfService(serviceId);
+                    if (maxBandwidthData.get("maxBandwidth") != null){
+                        log.debug("Successfully retrieved bandwidth info from AAI; service: {}, bandwidth: {}",
+                                serviceId, maxBandwidthData.get("maxBandwidth"));
+                        int bwValue = maxBandwidthData.get("maxBandwidth").intValue();
+                        if (ccvpnPmDatastore.getProvBwOfSvc(serviceId) == 0){
+                            ccvpnPmDatastore.updateProvBw(serviceId, bwValue, true);
+                            log.debug("Provision bw of cll {} updated from 0 to {}, max bw is {}", serviceId, ccvpnPmDatastore.getProvBwOfSvc(serviceId), bwValue);
+                        } else if (ccvpnPmDatastore.getProvBwOfSvc(serviceId) != bwValue) {
+                            log.debug("Service modification complete; serviceId: {} update prov bw from {} to {}", serviceId, ccvpnPmDatastore.getProvBwOfSvc(serviceId), bwValue);
+                            ccvpnPmDatastore.updateProvBw(serviceId, bwValue, true);
+                            ccvpnPmDatastore.updateSvcState(serviceId, ServiceState.RUNNING);
+                            log.debug("Service state of {} is changed to running, {}", serviceId, ccvpnPmDatastore.getStatusOfSvc(serviceId));
+                        }
+                    }
+                    log.debug("=== Processing AAI network policy query complete ===");
+                }
+            }
+        };
+    }
+
+    /**
+     * Post/broadcast event between Loops
+     * @param event event object
+     */
+    public void post(@NonNull Event event) {
+        if (event.type() == SimpleEvent.Type.AAI_BW_REQ) {
+            aaiEventLoop.add(event);
+        }
+    }
+    /**
+     * Inner loop implementation. Each loop acts like an actor.
+     */
+    private abstract class Loop implements Runnable {
+        private final String name;
+        private volatile boolean running;
+        private final BlockingQueue<Event> eventsQueue;
+        private final ExecutorService executor;
+        private volatile Future<?> dispatchFuture;
+
+        /**
+         * Constructor that accepts a loop name
+         * @param name name of this loop
+         */
+        Loop(String name){
+            this.name = name;
+            executor = Executors.newSingleThreadExecutor();
+            eventsQueue = new LinkedBlockingQueue<>();
+            dispatchFuture = executor.submit(this);
+        }
+
+        /**
+         * Add new event to this loop
+         * @param evt Event
+         * @return true
+         */
+        public boolean add(Event evt) {
+            return eventsQueue.add(evt);
+        }
+
+        /**
+         * Running loop that process event accordingly
+         */
+        @Override
+        public void run(){
+            running = true;
+            log.info("NetworkPolicyMonitor -- {} initiated", this.name);
+            while (running){
+                try{
+                    Event event = eventsQueue.take();
+                    if (event == KILL_PILL){
+                        break;
+                    }
+                    process(event);
+                } catch (InterruptedException e){
+                    log.warn("Process loop interrupted");
+                } catch (Exception | Error e){
+                    log.warn("Process loop hit an error {}", e.getMessage());
+                }
+            }
+        }
+
+        /**
+         * Operation defined by subclass for different event processing
+         * @param event incoming event
+         */
+        abstract public void process(Event event);
+
+        /**
+         * Stop this loop
+         */
+        public void stop(){
+            running = false;
+            add(KILL_PILL);
+        }
+    }
+}
index 824731f..2feba83 100644 (file)
@@ -35,7 +35,7 @@ public class StrategyFactory {
     private static Logger log = LoggerFactory.getLogger(StrategyFactory.class);
 
     @Autowired
-    List<EvaluationStrategy> strategies;
+    public List<EvaluationStrategy> strategies;
 
     private StrategyFactory() {}
 
diff --git a/components/slice-analysis-ms/src/test/java/org/onap/slice/analysis/ms/service/ccvpn/NetworkPolicyMonitorTest.java b/components/slice-analysis-ms/src/test/java/org/onap/slice/analysis/ms/service/ccvpn/NetworkPolicyMonitorTest.java
new file mode 100644 (file)
index 0000000..23366ab
--- /dev/null
@@ -0,0 +1,51 @@
+/*******************************************************************************
+ *  ============LICENSE_START=======================================================
+ *  slice-analysis-ms
+ *  ================================================================================
+ *   Copyright (C) 2022 Huawei Canada Limited.
+ *   ==============================================================================
+ *     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.
+ *     ============LICENSE_END=========================================================
+ *
+ *******************************************************************************/
+
+package org.onap.slice.analysis.ms.service.ccvpn;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.InjectMocks;
+import org.mockito.Mockito;
+import org.mockito.Spy;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.test.context.junit4.SpringRunner;
+
+@RunWith(SpringRunner.class)
+@SpringBootTest(classes = BandwidthEvaluatorTest.class)
+public class NetworkPolicyMonitorTest {
+
+    @Spy
+    @InjectMocks
+    NetworkPolicyMonitor NetworkPolicyMonitor;
+    @Test
+    public void initTest() {
+        NetworkPolicyMonitor.init();
+        Mockito.verify(NetworkPolicyMonitor, Mockito.atLeastOnce()).init();
+    }
+
+    @Test
+    public void postTest() {
+        Event evt = new SimpleEvent(null, "{}");
+        NetworkPolicyMonitor.post(evt);
+        Mockito.verify(NetworkPolicyMonitor, Mockito.atLeastOnce()).post(Mockito.any(Event.class));
+    }
+}