Change rule retrieval from CBS to ConfigMap 93/125993/2
authorGuangrong Fu <fu.guangrong@zte.com.cn>
Wed, 1 Dec 2021 06:22:37 +0000 (14:22 +0800)
committerGuangrong Fu <fu.guangrong@zte.com.cn>
Wed, 1 Dec 2021 07:25:34 +0000 (15:25 +0800)
Issue-ID: HOLMES-488
Signed-off-by: Guangrong Fu <fu.guangrong@zte.com.cn>
Change-Id: I89f4d47b9b2e0f1c9c9d32083a146d54d0000c5d

15 files changed:
pom.xml
rulemgt-frontend/pom.xml
rulemgt-standalone/pom.xml
rulemgt/pom.xml
rulemgt/src/main/java/org/onap/holmes/rulemgt/RuleActiveApp.java
rulemgt/src/main/java/org/onap/holmes/rulemgt/dcae/ConfigFileScanningTask.java [new file with mode: 0644]
rulemgt/src/main/java/org/onap/holmes/rulemgt/dcae/DcaeConfigurationPolling.java
rulemgt/src/test/java/org/onap/holmes/rulemgt/dcae/ConfigFileScanningTaskTest.java [new file with mode: 0644]
rulemgt/src/test/resources/ControlLoop-VOLTE-2179b738-fd36-4843-a71a-a8c24c70c55b-changed.drl [new file with mode: 0644]
rulemgt/src/test/resources/ControlLoop-VOLTE-2179b738-fd36-4843-a71a-a8c24c70c55b-spaces.drl [new file with mode: 0644]
rulemgt/src/test/resources/ControlLoop-VOLTE-2179b738-fd36-4843-a71a-a8c24c70c55b.drl [new file with mode: 0644]
rulemgt/src/test/resources/index-add.json [new file with mode: 0644]
rulemgt/src/test/resources/index-empty.json [new file with mode: 0644]
rulemgt/src/test/resources/index-rule-changed.json [new file with mode: 0644]
rulemgt/src/test/resources/index-rule-spaces-test.json [new file with mode: 0644]

diff --git a/pom.xml b/pom.xml
index ec1c6d6..b3d917c 100644 (file)
--- a/pom.xml
+++ b/pom.xml
@@ -25,7 +25,7 @@
 
     <groupId>org.onap.holmes.rule-management</groupId>
     <artifactId>holmes-rulemgt-parent</artifactId>
-    <version>1.3.4-SNAPSHOT</version>
+    <version>1.3.5-SNAPSHOT</version>
     <packaging>pom</packaging>
     <name>holmes-rule-management</name>
     <modules>
         <dependency>
             <groupId>org.onap.holmes.common</groupId>
             <artifactId>holmes-actions</artifactId>
-            <version>1.3.5</version>
+            <version>1.3.7</version>
             <exclusions>
                 <exclusion>
                     <groupId>org.glassfish.jersey.containers</groupId>
index 9609647..fbcb136 100644 (file)
@@ -24,7 +24,7 @@
   <parent>
     <groupId>org.onap.holmes.rule-management</groupId>
     <artifactId>holmes-rulemgt-parent</artifactId>
-    <version>1.3.4-SNAPSHOT</version>
+    <version>1.3.5-SNAPSHOT</version>
   </parent>
 
   <artifactId>holmes-rulemgt-frontend</artifactId>
index db98945..be9e5ca 100644 (file)
@@ -23,7 +23,7 @@
     <parent>
         <groupId>org.onap.holmes.rule-management</groupId>
         <artifactId>holmes-rulemgt-parent</artifactId>
-        <version>1.3.4-SNAPSHOT</version>
+        <version>1.3.5-SNAPSHOT</version>
     </parent>
 
     <artifactId>holmes-rulemgt-standalone</artifactId>
index 13c568a..7fbb227 100644 (file)
@@ -20,7 +20,7 @@
     <parent>
         <groupId>org.onap.holmes.rule-management</groupId>
         <artifactId>holmes-rulemgt-parent</artifactId>
-        <version>1.3.4-SNAPSHOT</version>
+        <version>1.3.5-SNAPSHOT</version>
     </parent>
 
     <artifactId>holmes-rulemgt</artifactId>
index f77b909..a9a78c8 100644 (file)
 package org.onap.holmes.rulemgt;
 
 import io.dropwizard.setup.Environment;
-import org.onap.holmes.common.config.MicroServiceConfig;
+import org.onap.holmes.common.ConfigFileScanner;
 import org.onap.holmes.common.dropwizard.ioc.bundle.IOCApplication;
-import org.onap.holmes.common.utils.CommonUtils;
 import org.onap.holmes.common.utils.transactionid.TransactionIdFilter;
-import org.onap.holmes.rulemgt.dcae.DcaeConfigurationPolling;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
+import org.onap.holmes.rulemgt.dcae.ConfigFileScanningTask;
 
 import javax.servlet.DispatcherType;
 import java.util.EnumSet;
@@ -41,12 +38,10 @@ public class RuleActiveApp extends IOCApplication<RuleAppConfig> {
     public void run(RuleAppConfig configuration, Environment environment) throws Exception {
         super.run(configuration, environment);
 
-        if (!"1".equals(System.getenv("TESTING"))) {
-            ScheduledExecutorService service = Executors.newSingleThreadScheduledExecutor();
-            service.scheduleAtFixedRate(
-                    new DcaeConfigurationPolling(CommonUtils.getEnv(MicroServiceConfig.HOSTNAME)), 0,
-                    DcaeConfigurationPolling.POLLING_PERIOD, TimeUnit.MILLISECONDS);
-        }
+        ScheduledExecutorService service = Executors.newSingleThreadScheduledExecutor();
+        service.scheduleAtFixedRate(
+                new ConfigFileScanningTask(new ConfigFileScanner()), 60L,
+                ConfigFileScanningTask.POLLING_PERIOD, TimeUnit.SECONDS);
 
         environment.servlets().addFilter("customFilter", new TransactionIdFilter()).addMappingForUrlPatterns(EnumSet
                 .allOf(DispatcherType.class), true, "/*");
diff --git a/rulemgt/src/main/java/org/onap/holmes/rulemgt/dcae/ConfigFileScanningTask.java b/rulemgt/src/main/java/org/onap/holmes/rulemgt/dcae/ConfigFileScanningTask.java
new file mode 100644 (file)
index 0000000..9f7b89f
--- /dev/null
@@ -0,0 +1,190 @@
+/**
+ * Copyright 2021 ZTE Corporation.
+ * <p>
+ * 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
+ * <p>
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * <p>
+ * 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.onap.holmes.rulemgt.dcae;
+
+import com.google.gson.JsonArray;
+import com.google.gson.JsonElement;
+import com.google.gson.JsonObject;
+import com.google.gson.JsonParser;
+import org.apache.commons.lang.StringUtils;
+import org.onap.holmes.common.ConfigFileScanner;
+import org.onap.holmes.common.utils.FileUtils;
+import org.onap.holmes.common.utils.JerseyClient;
+import org.onap.holmes.rulemgt.bean.request.RuleCreateRequest;
+import org.onap.holmes.rulemgt.bean.response.RuleQueryListResponse;
+import org.onap.holmes.rulemgt.bean.response.RuleResult4API;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import javax.ws.rs.client.Entity;
+import javax.ws.rs.core.MediaType;
+import java.io.File;
+import java.nio.file.Paths;
+import java.util.*;
+
+public class ConfigFileScanningTask implements Runnable {
+    final public static long POLLING_PERIOD = 30L;
+    final private static Logger LOGGER = LoggerFactory.getLogger(ConfigFileScanningTask.class);
+    final private static long FILE_SIZE_LMT = 1024 * 1024 * 10; // 10MB
+    final private Map<String, String> configInEffect = new HashMap(); // Contents for configInEffect are <closedControlLoop>:<ruleContents> pairs.
+    private String configFile = "/opt/hrmrules/index.json";
+    private ConfigFileScanner configFileScanner;
+    private String url = "https://127.0.0.1:9101/api/holmes-rule-mgmt/v1/rule";
+
+    public ConfigFileScanningTask(ConfigFileScanner configFileScanner) {
+        this.configFileScanner = configFileScanner;
+    }
+
+    @Override
+    public void run() {
+        if (null == configFileScanner) {
+            configFileScanner = new ConfigFileScanner();
+        }
+        Map<String, String> newConfig = extractConfigItems(configFileScanner.scan(configFile));
+
+        List<RuleResult4API> deployedRules = getExistingRules();
+
+        // deal with newly added rules
+        final Set<String> existingKeys = new HashSet(configInEffect.keySet());
+        final Set<String> newKeys = new HashSet(newConfig.keySet());
+        newKeys.stream()
+                .filter(key -> !existingKeys.contains(key))
+                .forEach(key -> {
+                    if (deployRule(key, newConfig.get(key))) {
+                        configInEffect.put(key, newConfig.get(key));
+                        LOGGER.info("Rule '{}' has been deployed.", key);
+                    }
+                });
+
+        // deal with removed rules
+        existingKeys.stream().filter(key -> !newKeys.contains(key)).forEach(key -> {
+            if (deleteRule(find(deployedRules, key))) {
+                configInEffect.remove(key);
+                LOGGER.info("Rule '{}' has been removed.", key);
+            }
+        });
+
+        // deal with changed rules
+        existingKeys.stream().filter(key -> newKeys.contains(key)).forEach(key -> {
+            if (changed(configInEffect.get(key), newConfig.get(key))) {
+                if (deleteRule(find(deployedRules, key))) {
+                    configInEffect.remove(key);
+                    deployRule(key, newConfig.get(key));
+                    configInEffect.put(key, newConfig.get(key));
+                    LOGGER.info("Rule '{}' has been updated.", key);
+                }
+            }
+        });
+    }
+
+    private Map<String, String> extractConfigItems(Map<String, String> configFiles) {
+        Map<String, String> ret = new HashMap();
+        for (Map.Entry entry : configFiles.entrySet()) {
+            JsonArray ja = JsonParser.parseString(entry.getValue().toString()).getAsJsonArray();
+            Iterator<JsonElement> iterator = ja.iterator();
+            while (iterator.hasNext()) {
+                JsonObject jo = iterator.next().getAsJsonObject();
+                String contents = readFile(jo.get("file").getAsString());
+                if (StringUtils.isNotBlank(contents)) {
+                    ret.put(jo.get("closedControlLoopName").getAsString(), contents);
+                }
+            }
+        }
+        return ret;
+    }
+
+    private String normalizePath(String path) {
+        if (!path.startsWith("/")) {
+            return Paths.get(new File(configFile).getParent(), path).toString();
+        }
+        return path;
+    }
+    private String readFile(String path) {
+        String finalPath = normalizePath(path);
+        File file = new File(finalPath);
+        if (file.exists() && !file.isDirectory() && file.length() <= FILE_SIZE_LMT) {
+            return FileUtils.readTextFile(finalPath);
+        } else {
+            LOGGER.warn("The file {} does not exist or it is a directory or it is too large to load.", finalPath);
+        }
+        return null;
+    }
+
+    private RuleResult4API find(final List<RuleResult4API> rules, String clName) {
+        for (RuleResult4API rule : rules) {
+            if (rule.getLoopControlName().equals(clName)) {
+                return rule;
+            }
+        }
+        return null;
+    }
+
+    private boolean changed(String con1, String con2) {
+        // if either of the arguments is null, consider it as invalid and unchanged
+        if (con1 == null || con2 == null) {
+            return false;
+        }
+
+        if (!con1.replaceAll("\\s", StringUtils.EMPTY)
+                .equals(con2.replaceAll("\\s", StringUtils.EMPTY))) {
+            return true;
+        }
+
+        return false;
+    }
+
+    private List<RuleResult4API> getExistingRules() {
+        RuleQueryListResponse ruleQueryListResponse = JerseyClient.newInstance().get(url, RuleQueryListResponse.class);
+        List<RuleResult4API> deployedRules = Collections.EMPTY_LIST;
+        if (null != ruleQueryListResponse) {
+            deployedRules = ruleQueryListResponse.getCorrelationRules();
+        }
+        return deployedRules;
+    }
+
+    private boolean deployRule(String clName, String contents) {
+        RuleCreateRequest ruleCreateRequest = getRuleCreateRequest(clName, contents);
+        if (JerseyClient.newInstance().header("Accept", MediaType.APPLICATION_JSON)
+                .put(url, Entity.json(ruleCreateRequest)) == null) {
+            LOGGER.error("Failed to deploy rule: {}.", clName);
+            return false;
+        }
+        return true;
+    }
+
+    private RuleCreateRequest getRuleCreateRequest(String clName, String contents) {
+        RuleCreateRequest ruleCreateRequest = new RuleCreateRequest();
+        ruleCreateRequest.setLoopControlName(clName);
+        ruleCreateRequest.setRuleName(clName);
+        ruleCreateRequest.setContent(contents);
+        ruleCreateRequest.setDescription("");
+        ruleCreateRequest.setEnabled(1);
+        return ruleCreateRequest;
+    }
+
+    private boolean deleteRule(RuleResult4API rule) {
+        if (rule == null) {
+            LOGGER.info("No rule found, nothing to delete.");
+            return false;
+        }
+        if (null == JerseyClient.newInstance().delete(url + "/" + rule.getRuleId())) {
+            LOGGER.warn("Failed to delete rule, the rule id is: {}", rule.getRuleId());
+            return false;
+        }
+        return true;
+    }
+}
index f07d8ac..8049e8f 100644 (file)
@@ -30,6 +30,7 @@ import javax.ws.rs.core.MediaType;
 import java.util.List;
 
 @Slf4j
+@Deprecated
 public class DcaeConfigurationPolling implements Runnable {
 
     public static final long POLLING_PERIOD = 30 * 1000L;
diff --git a/rulemgt/src/test/java/org/onap/holmes/rulemgt/dcae/ConfigFileScanningTaskTest.java b/rulemgt/src/test/java/org/onap/holmes/rulemgt/dcae/ConfigFileScanningTaskTest.java
new file mode 100644 (file)
index 0000000..053612b
--- /dev/null
@@ -0,0 +1,241 @@
+/**
+ * Copyright 2021 ZTE Corporation.
+ * <p>
+ * 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
+ * <p>
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * <p>
+ * 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.onap.holmes.rulemgt.dcae;
+
+import org.easymock.EasyMock;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.onap.holmes.common.ConfigFileScanner;
+import org.onap.holmes.common.utils.FileUtils;
+import org.onap.holmes.common.utils.JerseyClient;
+import org.onap.holmes.rulemgt.bean.response.RuleQueryListResponse;
+import org.onap.holmes.rulemgt.bean.response.RuleResult4API;
+import org.powermock.api.easymock.PowerMock;
+import org.powermock.core.classloader.annotations.PrepareForTest;
+import org.powermock.core.classloader.annotations.SuppressStaticInitializationFor;
+import org.powermock.modules.junit4.PowerMockRunner;
+import org.powermock.reflect.Whitebox;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import static org.hamcrest.core.Is.is;
+import static org.hamcrest.core.IsEqual.equalTo;
+import static org.junit.Assert.assertThat;
+
+@RunWith(PowerMockRunner.class)
+@PrepareForTest({JerseyClient.class})
+@SuppressStaticInitializationFor({"org.onap.holmes.common.utils.JerseyClient"})
+public class ConfigFileScanningTaskTest {
+
+    @Test
+    public void run_add_rules() throws Exception {
+        String clName = "ControlLoop-VOLTE-2179b738-fd36-4843-a71a-a8c24c70c55b";
+        String indexPath = getFilePath("index-add.json");
+        String contents = FileUtils.readTextFile(indexPath);
+
+        ConfigFileScanningTask cfst = new ConfigFileScanningTask(null);
+        Whitebox.setInternalState(cfst, "configFile", indexPath);
+
+        // mock for getExistingRules
+        JerseyClient jcMock = PowerMock.createMock(JerseyClient.class);
+        PowerMock.expectNew(JerseyClient.class).andReturn(jcMock).anyTimes();
+        RuleQueryListResponse rqlr = new RuleQueryListResponse();
+        rqlr.getCorrelationRules().add(getRuleResult4API(clName, contents));
+        EasyMock.expect(jcMock.get(EasyMock.anyString(), EasyMock.anyObject())).andReturn(rqlr);
+
+        // mock for deployRule
+        EasyMock.expect(jcMock.header(EasyMock.anyString(), EasyMock.anyObject())).andReturn(jcMock);
+        EasyMock.expect(jcMock.put(EasyMock.anyString(), EasyMock.anyObject())).andReturn("");
+
+        PowerMock.replayAll();
+        cfst.run();
+        PowerMock.verifyAll();
+
+        Map<String, String> config = Whitebox.getInternalState(cfst, "configInEffect");
+        assertThat(config.size(), is(1));
+    }
+
+    @Test
+    public void run_remove_rules_normal() throws Exception {
+        String clName = "ControlLoop-VOLTE-2179b738-fd36-4843-a71a-a8c24c70c55b";
+        String indexPath = getFilePath("index-add.json");
+        String contents = FileUtils.readTextFile(indexPath);
+        Map<String, String> configInEffect = new HashMap<>();
+        configInEffect.put(clName, contents);
+
+        ConfigFileScanningTask cfst = new ConfigFileScanningTask(new ConfigFileScanner());
+        Whitebox.setInternalState(cfst, "configFile", getFilePath("index-empty.json"));
+        Whitebox.setInternalState(cfst, "configInEffect", configInEffect);
+
+        // mock for getExistingRules
+        JerseyClient jcMock = PowerMock.createMock(JerseyClient.class);
+        PowerMock.expectNew(JerseyClient.class).andReturn(jcMock).anyTimes();
+        RuleQueryListResponse rqlr = new RuleQueryListResponse();
+        rqlr.getCorrelationRules().add(getRuleResult4API(clName, contents));
+        EasyMock.expect(jcMock.get(EasyMock.anyString(), EasyMock.anyObject())).andReturn(rqlr);
+
+        // mock for deleteRule
+        EasyMock.expect(jcMock.delete(EasyMock.anyString())).andReturn("");
+
+        PowerMock.replayAll();
+        cfst.run();
+        PowerMock.verifyAll();
+
+        Map<String, String> config = Whitebox.getInternalState(cfst, "configInEffect");
+        assertThat(config.size(), is(0));
+    }
+
+    @Test
+    public void run_remove_rules_delete_null_pointer() throws Exception {
+        String clName = "ControlLoop-VOLTE-2179b738-fd36-4843-a71a-a8c24c70c55b";
+        String indexPath = getFilePath("index-add.json");
+        String contents = FileUtils.readTextFile(indexPath);
+        Map<String, String> configInEffect = new HashMap<>();
+        configInEffect.put(clName, contents);
+
+        ConfigFileScanningTask cfst = new ConfigFileScanningTask(new ConfigFileScanner());
+        Whitebox.setInternalState(cfst, "configFile", indexPath);
+        Whitebox.setInternalState(cfst, "configInEffect", configInEffect);
+
+        // mock for getExistingRules
+        JerseyClient jcMock = PowerMock.createMock(JerseyClient.class);
+        PowerMock.expectNew(JerseyClient.class).andReturn(jcMock).anyTimes();
+        RuleQueryListResponse rqlr = new RuleQueryListResponse();
+        rqlr.getCorrelationRules().add(getRuleResult4API("a-non-existing-rule", contents));
+        EasyMock.expect(jcMock.get(EasyMock.anyString(), EasyMock.anyObject())).andReturn(rqlr);
+
+        PowerMock.replayAll();
+        cfst.run();
+        PowerMock.verifyAll();
+
+        Map<String, String> config = Whitebox.getInternalState(cfst, "configInEffect");
+        assertThat(config.size(), is(1));
+    }
+
+    @Test
+    public void run_remove_rules_api_calling_returning_null() throws Exception {
+        String clName = "ControlLoop-VOLTE-2179b738-fd36-4843-a71a-a8c24c70c55b";
+        String indexPath = getFilePath("index-add.json");
+        String contents = FileUtils.readTextFile(indexPath);
+        Map<String, String> configInEffect = new HashMap<>();
+        configInEffect.put(clName, contents);
+
+        ConfigFileScanningTask cfst = new ConfigFileScanningTask(new ConfigFileScanner());
+        Whitebox.setInternalState(cfst, "configFile", indexPath);
+        Whitebox.setInternalState(cfst, "configInEffect", configInEffect);
+
+        // mock for getExistingRules
+        JerseyClient jcMock = PowerMock.createMock(JerseyClient.class);
+        PowerMock.expectNew(JerseyClient.class).andReturn(jcMock).anyTimes();
+        RuleQueryListResponse rqlr = new RuleQueryListResponse();
+        rqlr.getCorrelationRules().add(getRuleResult4API(clName, contents));
+        EasyMock.expect(jcMock.get(EasyMock.anyString(), EasyMock.anyObject())).andReturn(rqlr);
+
+        // mock for deleteRule
+        EasyMock.expect(jcMock.delete(EasyMock.anyString())).andReturn(null);
+
+        PowerMock.replayAll();
+        cfst.run();
+        PowerMock.verifyAll();
+
+        Map<String, String> config = Whitebox.getInternalState(cfst, "configInEffect");
+        assertThat(config.size(), is(1));
+    }
+
+    @Test
+    public void run_change_rules_normal() throws Exception {
+        String clName = "ControlLoop-VOLTE-2179b738-fd36-4843-a71a-a8c24c70c55b";
+        String oldDrlPath = getFilePath("ControlLoop-VOLTE-2179b738-fd36-4843-a71a-a8c24c70c55b.drl");
+        String oldDrlContents = FileUtils.readTextFile(oldDrlPath);
+        Map<String, String> configInEffect = new HashMap<>();
+        configInEffect.put(clName, oldDrlContents);
+
+        ConfigFileScanningTask cfst = new ConfigFileScanningTask(new ConfigFileScanner());
+        Whitebox.setInternalState(cfst, "configFile", getFilePath("index-rule-changed.json"));
+        Whitebox.setInternalState(cfst, "configInEffect", configInEffect);
+
+        // mock for getExistingRules
+        JerseyClient jcMock = PowerMock.createMock(JerseyClient.class);
+        PowerMock.expectNew(JerseyClient.class).andReturn(jcMock).anyTimes();
+        RuleQueryListResponse rqlr = new RuleQueryListResponse();
+        rqlr.getCorrelationRules().add(getRuleResult4API(clName, oldDrlContents));
+        EasyMock.expect(jcMock.get(EasyMock.anyString(), EasyMock.anyObject())).andReturn(rqlr);
+
+        // mock for deleteRule
+        EasyMock.expect(jcMock.delete(EasyMock.anyString())).andReturn("");
+
+        // mock for deployRule
+        EasyMock.expect(jcMock.header(EasyMock.anyString(), EasyMock.anyObject())).andReturn(jcMock);
+        EasyMock.expect(jcMock.put(EasyMock.anyString(), EasyMock.anyObject())).andReturn("");
+
+        PowerMock.replayAll();
+        cfst.run();
+        PowerMock.verifyAll();
+
+        Map<String, String> config = Whitebox.getInternalState(cfst, "configInEffect");
+        assertThat(config.size(), is(1));
+        assertThat(config.get(clName),
+                equalTo(FileUtils.readTextFile(
+                        getFilePath("ControlLoop-VOLTE-2179b738-fd36-4843-a71a-a8c24c70c55b-changed.drl"))));
+    }
+
+    @Test
+    public void run_change_rules_no_change_except_for_spaces() throws Exception {
+        String clName = "ControlLoop-VOLTE-2179b738-fd36-4843-a71a-a8c24c70c55b";
+        String oldDrlPath = getFilePath("ControlLoop-VOLTE-2179b738-fd36-4843-a71a-a8c24c70c55b.drl");
+        String oldDrlContents = FileUtils.readTextFile(oldDrlPath);
+        Map<String, String> configInEffect = new HashMap<>();
+        configInEffect.put(clName, oldDrlContents);
+
+        ConfigFileScanningTask cfst = new ConfigFileScanningTask(new ConfigFileScanner());
+        Whitebox.setInternalState(cfst, "configFile", getFilePath("index-rule-spaces-test.json"));
+        Whitebox.setInternalState(cfst, "configInEffect", configInEffect);
+
+        // mock for getExistingRules
+        JerseyClient jcMock = PowerMock.createMock(JerseyClient.class);
+        PowerMock.expectNew(JerseyClient.class).andReturn(jcMock).anyTimes();
+        RuleQueryListResponse rqlr = new RuleQueryListResponse();
+        rqlr.getCorrelationRules().add(getRuleResult4API(clName, oldDrlContents));
+        EasyMock.expect(jcMock.get(EasyMock.anyString(), EasyMock.anyObject())).andReturn(rqlr);
+
+        PowerMock.replayAll();
+        cfst.run();
+        PowerMock.verifyAll();
+
+        Map<String, String> config = Whitebox.getInternalState(cfst, "configInEffect");
+        assertThat(config.size(), is(1));
+        assertThat(config.get(clName),
+                equalTo(FileUtils.readTextFile(
+                        getFilePath("ControlLoop-VOLTE-2179b738-fd36-4843-a71a-a8c24c70c55b.drl"))));
+    }
+
+    private String getFilePath(String fileName) {
+        return ConfigFileScanningTaskTest.class.getResource("/" + fileName).getFile();
+    }
+
+    private RuleResult4API getRuleResult4API(String clName, String contents) {
+        RuleResult4API ruleResult4API = new RuleResult4API();
+        ruleResult4API.setRuleId(clName);
+        ruleResult4API.setRuleName(clName);
+        ruleResult4API.setLoopControlName(clName);
+        ruleResult4API.setContent(contents);
+        ruleResult4API.setDescription("");
+        ruleResult4API.setEnabled(1);
+        return ruleResult4API;
+    }
+}
\ No newline at end of file
diff --git a/rulemgt/src/test/resources/ControlLoop-VOLTE-2179b738-fd36-4843-a71a-a8c24c70c55b-changed.drl b/rulemgt/src/test/resources/ControlLoop-VOLTE-2179b738-fd36-4843-a71a-a8c24c70c55b-changed.drl
new file mode 100644 (file)
index 0000000..039bf68
--- /dev/null
@@ -0,0 +1,91 @@
+package org.onap.holmes.droolsRule;
+
+import org.onap.holmes.common.dmaap.DmaapService;
+import org.onap.holmes.common.api.stat.VesAlarm;
+import org.onap.holmes.common.aai.CorrelationUtil;
+import org.onap.holmes.common.dmaap.entity.PolicyMsg;
+import org.onap.holmes.common.dropwizard.ioc.utils.ServiceLocatorHolder;
+import org.onap.holmes.common.utils.DroolsLog;
+
+rule "Relation_analysis_Rule"
+salience 200
+no-loop true
+    when
+        $root : VesAlarm(alarmIsCleared == 0,
+            $sourceId: sourceId, sourceId != null && !sourceId.equals(""),
+                       $sourceName: sourceName, sourceName != null && !sourceName.equals(""),
+                       $startEpochMicrosec: startEpochMicrosec,
+            eventName in ("Fault_MultiCloud_VMFailure"),
+            $eventId: eventId)
+        $child : VesAlarm( eventId != $eventId, parentId == null,
+            CorrelationUtil.getInstance().isTopologicallyRelated(sourceId, $sourceId, $sourceName),
+            eventName in ("Fault_MME_eNodeB out of service alarm"),
+            startEpochMicrosec < $startEpochMicrosec + 60000 && startEpochMicrosec > $startEpochMicrosec - 60000 )
+    then
+               DroolsLog.printInfo("===========================================================");
+               DroolsLog.printInfo("Relation_analysis_Rule: rootId=" + $root.getEventId() + ", childId=" + $child.getEventId());
+               $child.setParentId($root.getEventId());
+               update($child);
+               
+end
+
+rule "root_has_child_handle_Rule"
+salience 150
+no-loop true
+       when
+               $root : VesAlarm(alarmIsCleared == 0, rootFlag == 0, $eventId: eventId)
+               $child : VesAlarm(eventId != $eventId, parentId == $eventId)
+       then
+               DroolsLog.printInfo("===========================================================");
+               DroolsLog.printInfo("root_has_child_handle_Rule: rootId=" + $root.getEventId() + ", childId=" + $child.getEventId());
+               DmaapService dmaapService = ServiceLocatorHolder.getLocator().getService(DmaapService.class);
+               PolicyMsg policyMsg = dmaapService.getPolicyMsg($root, $child, "org.onap.holmes.droolsRule");
+        dmaapService.publishPolicyMsg(policyMsg, "dcae_cl_out");
+               $root.setRootFlag(1);
+               update($root);
+end
+
+rule "root_no_child_handle_Rule"
+salience 100
+no-loop true
+    when
+        $root : VesAlarm(alarmIsCleared == 0, rootFlag == 0,
+            sourceId != null && !sourceId.equals(""),
+                       sourceName != null && !sourceName.equals(""),
+            eventName in ("Fault_MultiCloud_VMFailure"))
+    then
+               DroolsLog.printInfo("===========================================================");
+               DroolsLog.printInfo("root_no_child_handle_Rule: rootId=" + $root.getEventId());
+               DmaapService dmaapService = ServiceLocatorHolder.getLocator().getService(DmaapService.class);
+               PolicyMsg policyMsg = dmaapService.getPolicyMsg($root, null, "org.onap.holmes.droolsRule");
+        dmaapService.publishPolicyMsg(policyMsg, "dcae_cl_out");
+               $root.setRootFlag(1);
+               update($root);
+end
+
+rule "root_cleared_handle_Rule"
+salience 100
+no-loop true
+    when
+        $root : VesAlarm(alarmIsCleared == 1, rootFlag == 1)
+    then
+               DroolsLog.printInfo("===========================================================");
+               DroolsLog.printInfo("root_cleared_handle_Rule: rootId=" + $root.getEventId());
+               DmaapService dmaapService = ServiceLocatorHolder.getLocator().getService(DmaapService.class);
+               PolicyMsg policyMsg = dmaapService.getPolicyMsg($root, null, "org.onap.holmes.droolsRule");
+        dmaapService.publishPolicyMsg(policyMsg, "dcae_cl_out");
+               retract($root);
+end
+
+rule "child_handle_Rule"
+salience 100
+no-loop true
+    when
+        $child : VesAlarm(alarmIsCleared == 1, rootFlag == 0)
+    then
+               DroolsLog.printInfo("===========================================================");
+               DroolsLog.printInfo("child_handle_Rule: childId=" + $child.getEventId());
+               retract($child);
+               DroolsLog.printInfo("done");
+end
diff --git a/rulemgt/src/test/resources/ControlLoop-VOLTE-2179b738-fd36-4843-a71a-a8c24c70c55b-spaces.drl b/rulemgt/src/test/resources/ControlLoop-VOLTE-2179b738-fd36-4843-a71a-a8c24c70c55b-spaces.drl
new file mode 100644 (file)
index 0000000..a75f202
--- /dev/null
@@ -0,0 +1,88 @@
+package org.onap.holmes.droolsRule;
+
+import org.onap.holmes.common.dmaap.DmaapService;
+import org.onap.holmes.common.api.stat.VesAlarm;
+import org.onap.holmes.common.aai.CorrelationUtil;
+import org.onap.holmes.common.dmaap.entity.PolicyMsg;
+import org.onap.holmes.common.dropwizard.ioc.utils.ServiceLocatorHolder;
+import org.onap.holmes.common.utils.DroolsLog;
+
+rule "Relation_analysis_Rule"
+salience 200
+no-loop true
+    when
+        $root : VesAlarm(alarmIsCleared == 0,
+            $sourceId: sourceId, sourceId != null && !sourceId.equals(""),
+                       $sourceName: sourceName, sourceName != null && !sourceName.equals(""),
+                       $startEpochMicrosec: startEpochMicrosec,
+            eventName in ("Fault_MultiCloud_VMFailure"),
+            $eventId: eventId)
+        $child : VesAlarm( eventId != $eventId, parentId == null,
+            CorrelationUtil.getInstance().isTopologicallyRelated(sourceId, $sourceId, $sourceName),
+            eventName in ("Fault_MME_eNodeB out of service alarm"),
+            startEpochMicrosec < $startEpochMicrosec + 60000 && startEpochMicrosec > $startEpochMicrosec - 60000 )
+    then
+               DroolsLog.printInfo( "===========================================================" );
+               DroolsLog.printInfo("Relation_analysis_Rule: rootId=" + $root.getEventId() + ", childId=" + $child.getEventId());
+               $child.setParentId($root.getEventId());
+               update($child);
+end
+
+rule "root_has_child_handle_Rule"
+salience 150
+no-loop true
+       when
+               $root : VesAlarm(alarmIsCleared == 0, rootFlag == 0, $eventId: eventId)
+               $child : VesAlarm(eventId != $eventId, parentId == $eventId)
+       then
+               DroolsLog.printInfo("===========================================================");
+               DroolsLog.printInfo("root_has_child_handle_Rule: rootId=" + $root.getEventId() + ", childId=" + $child.getEventId());
+               DmaapService dmaapService = ServiceLocatorHolder.getLocator().getService(DmaapService.class);
+               PolicyMsg policyMsg = dmaapService.getPolicyMsg($root, $child, "org.onap.holmes.droolsRule");
+        dmaapService.publishPolicyMsg(policyMsg, "dcae_cl_out");
+               $root.setRootFlag(1);
+               update($root);
+end
+
+rule "root_no_child_handle_Rule"
+salience 100
+no-loop true
+    when
+        $root : VesAlarm(alarmIsCleared == 0, rootFlag == 0,
+            sourceId != null && !sourceId.equals(""),
+                       sourceName != null && !sourceName.equals(""),
+            eventName in ("Fault_MultiCloud_VMFailure"))
+    then
+               DroolsLog.printInfo("===========================================================");
+               DroolsLog.printInfo("root_no_child_handle_Rule: rootId=" + $root.getEventId());
+               DmaapService dmaapService = ServiceLocatorHolder.getLocator().getService(DmaapService.class);
+               PolicyMsg policyMsg = dmaapService.getPolicyMsg($root, null, "org.onap.holmes.droolsRule");
+        dmaapService.publishPolicyMsg(policyMsg, "dcae_cl_out");
+               $root.setRootFlag(1);
+               update($root);
+end
+
+rule "root_cleared_handle_Rule"
+salience 100
+no-loop true
+    when
+        $root : VesAlarm(alarmIsCleared == 1, rootFlag == 1)
+    then
+               DroolsLog.printInfo("===========================================================");
+               DroolsLog.printInfo("root_cleared_handle_Rule: rootId=" + $root.getEventId());
+               DmaapService dmaapService = ServiceLocatorHolder.getLocator().getService(DmaapService.class);
+               PolicyMsg policyMsg = dmaapService.getPolicyMsg($root, null, "org.onap.holmes.droolsRule");
+        dmaapService.publishPolicyMsg(policyMsg, "dcae_cl_out");
+               retract($root);
+end
+
+rule "child_handle_Rule"
+salience 100
+no-loop true
+    when
+        $child : VesAlarm(alarmIsCleared == 1, rootFlag == 0)
+    then
+               DroolsLog.printInfo("===========================================================");
+               DroolsLog.printInfo("child_handle_Rule: childId=" + $child.getEventId());
+               retract($child);
+end
diff --git a/rulemgt/src/test/resources/ControlLoop-VOLTE-2179b738-fd36-4843-a71a-a8c24c70c55b.drl b/rulemgt/src/test/resources/ControlLoop-VOLTE-2179b738-fd36-4843-a71a-a8c24c70c55b.drl
new file mode 100644 (file)
index 0000000..5fbaaa5
--- /dev/null
@@ -0,0 +1,90 @@
+package org.onap.holmes.droolsRule;
+
+import org.onap.holmes.common.dmaap.DmaapService;
+import org.onap.holmes.common.api.stat.VesAlarm;
+import org.onap.holmes.common.aai.CorrelationUtil;
+import org.onap.holmes.common.dmaap.entity.PolicyMsg;
+import org.onap.holmes.common.dropwizard.ioc.utils.ServiceLocatorHolder;
+import org.onap.holmes.common.utils.DroolsLog;
+
+rule "Relation_analysis_Rule"
+salience 200
+no-loop true
+    when
+        $root : VesAlarm(alarmIsCleared == 0,
+            $sourceId: sourceId, sourceId != null && !sourceId.equals(""),
+                       $sourceName: sourceName, sourceName != null && !sourceName.equals(""),
+                       $startEpochMicrosec: startEpochMicrosec,
+            eventName in ("Fault_MultiCloud_VMFailure"),
+            $eventId: eventId)
+        $child : VesAlarm( eventId != $eventId, parentId == null,
+            CorrelationUtil.getInstance().isTopologicallyRelated(sourceId, $sourceId, $sourceName),
+            eventName in ("Fault_MME_eNodeB out of service alarm"),
+            startEpochMicrosec < $startEpochMicrosec + 60000 && startEpochMicrosec > $startEpochMicrosec - 60000 )
+    then
+               DroolsLog.printInfo("===========================================================");
+               DroolsLog.printInfo("Relation_analysis_Rule: rootId=" + $root.getEventId() + ", childId=" + $child.getEventId());
+               $child.setParentId($root.getEventId());
+               update($child);
+               
+end
+
+rule "root_has_child_handle_Rule"
+salience 150
+no-loop true
+       when
+               $root : VesAlarm(alarmIsCleared == 0, rootFlag == 0, $eventId: eventId)
+               $child : VesAlarm(eventId != $eventId, parentId == $eventId)
+       then
+               DroolsLog.printInfo("===========================================================");
+               DroolsLog.printInfo("root_has_child_handle_Rule: rootId=" + $root.getEventId() + ", childId=" + $child.getEventId());
+               DmaapService dmaapService = ServiceLocatorHolder.getLocator().getService(DmaapService.class);
+               PolicyMsg policyMsg = dmaapService.getPolicyMsg($root, $child, "org.onap.holmes.droolsRule");
+        dmaapService.publishPolicyMsg(policyMsg, "dcae_cl_out");
+               $root.setRootFlag(1);
+               update($root);
+end
+
+rule "root_no_child_handle_Rule"
+salience 100
+no-loop true
+    when
+        $root : VesAlarm(alarmIsCleared == 0, rootFlag == 0,
+            sourceId != null && !sourceId.equals(""),
+                       sourceName != null && !sourceName.equals(""),
+            eventName in ("Fault_MultiCloud_VMFailure"))
+    then
+               DroolsLog.printInfo("===========================================================");
+               DroolsLog.printInfo("root_no_child_handle_Rule: rootId=" + $root.getEventId());
+               DmaapService dmaapService = ServiceLocatorHolder.getLocator().getService(DmaapService.class);
+               PolicyMsg policyMsg = dmaapService.getPolicyMsg($root, null, "org.onap.holmes.droolsRule");
+        dmaapService.publishPolicyMsg(policyMsg, "dcae_cl_out");
+               $root.setRootFlag(1);
+               update($root);
+end
+
+rule "root_cleared_handle_Rule"
+salience 100
+no-loop true
+    when
+        $root : VesAlarm(alarmIsCleared == 1, rootFlag == 1)
+    then
+               DroolsLog.printInfo("===========================================================");
+               DroolsLog.printInfo("root_cleared_handle_Rule: rootId=" + $root.getEventId());
+               DmaapService dmaapService = ServiceLocatorHolder.getLocator().getService(DmaapService.class);
+               PolicyMsg policyMsg = dmaapService.getPolicyMsg($root, null, "org.onap.holmes.droolsRule");
+        dmaapService.publishPolicyMsg(policyMsg, "dcae_cl_out");
+               retract($root);
+end
+
+rule "child_handle_Rule"
+salience 100
+no-loop true
+    when
+        $child : VesAlarm(alarmIsCleared == 1, rootFlag == 0)
+    then
+               DroolsLog.printInfo("===========================================================");
+               DroolsLog.printInfo("child_handle_Rule: childId=" + $child.getEventId());
+               retract($child);
+end
diff --git a/rulemgt/src/test/resources/index-add.json b/rulemgt/src/test/resources/index-add.json
new file mode 100644 (file)
index 0000000..f0ee695
--- /dev/null
@@ -0,0 +1,6 @@
+[
+  {
+    "closedControlLoopName": "ControlLoop-VOLTE-2179b738-fd36-4843-a71a-a8c24c70c55b",
+    "file": "ControlLoop-VOLTE-2179b738-fd36-4843-a71a-a8c24c70c55b.drl"
+  }
+]
\ No newline at end of file
diff --git a/rulemgt/src/test/resources/index-empty.json b/rulemgt/src/test/resources/index-empty.json
new file mode 100644 (file)
index 0000000..0637a08
--- /dev/null
@@ -0,0 +1 @@
+[]
\ No newline at end of file
diff --git a/rulemgt/src/test/resources/index-rule-changed.json b/rulemgt/src/test/resources/index-rule-changed.json
new file mode 100644 (file)
index 0000000..1c7b237
--- /dev/null
@@ -0,0 +1,6 @@
+[
+  {
+    "closedControlLoopName": "ControlLoop-VOLTE-2179b738-fd36-4843-a71a-a8c24c70c55b",
+    "file": "ControlLoop-VOLTE-2179b738-fd36-4843-a71a-a8c24c70c55b-changed.drl"
+  }
+]
\ No newline at end of file
diff --git a/rulemgt/src/test/resources/index-rule-spaces-test.json b/rulemgt/src/test/resources/index-rule-spaces-test.json
new file mode 100644 (file)
index 0000000..f1d82db
--- /dev/null
@@ -0,0 +1,6 @@
+[
+  {
+    "closedControlLoopName": "ControlLoop-VOLTE-2179b738-fd36-4843-a71a-a8c24c70c55b",
+    "file": "ControlLoop-VOLTE-2179b738-fd36-4843-a71a-a8c24c70c55b-spaces.drl"
+  }
+]
\ No newline at end of file