summaryrefslogtreecommitdiffstats
path: root/rulemgt/src/main
diff options
context:
space:
mode:
authorGuangrong Fu <fu.guangrong@zte.com.cn>2021-12-01 14:22:37 +0800
committerGuangrong Fu <fu.guangrong@zte.com.cn>2021-12-01 15:25:34 +0800
commit5cc6fc1a762c547f420ce281deac69f02f6c2b83 (patch)
treef59492080a97a46699cffa634a19423e0050f06d /rulemgt/src/main
parent2eedf476653c9054d946332a15b62d465619abd4 (diff)
Change rule retrieval from CBS to ConfigMap
Issue-ID: HOLMES-488 Signed-off-by: Guangrong Fu <fu.guangrong@zte.com.cn> Change-Id: I89f4d47b9b2e0f1c9c9d32083a146d54d0000c5d
Diffstat (limited to 'rulemgt/src/main')
-rw-r--r--rulemgt/src/main/java/org/onap/holmes/rulemgt/RuleActiveApp.java17
-rw-r--r--rulemgt/src/main/java/org/onap/holmes/rulemgt/dcae/ConfigFileScanningTask.java190
-rw-r--r--rulemgt/src/main/java/org/onap/holmes/rulemgt/dcae/DcaeConfigurationPolling.java1
3 files changed, 197 insertions, 11 deletions
diff --git a/rulemgt/src/main/java/org/onap/holmes/rulemgt/RuleActiveApp.java b/rulemgt/src/main/java/org/onap/holmes/rulemgt/RuleActiveApp.java
index f77b909..a9a78c8 100644
--- a/rulemgt/src/main/java/org/onap/holmes/rulemgt/RuleActiveApp.java
+++ b/rulemgt/src/main/java/org/onap/holmes/rulemgt/RuleActiveApp.java
@@ -17,13 +17,10 @@
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
index 0000000..9f7b89f
--- /dev/null
+++ b/rulemgt/src/main/java/org/onap/holmes/rulemgt/dcae/ConfigFileScanningTask.java
@@ -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;
+ }
+}
diff --git a/rulemgt/src/main/java/org/onap/holmes/rulemgt/dcae/DcaeConfigurationPolling.java b/rulemgt/src/main/java/org/onap/holmes/rulemgt/dcae/DcaeConfigurationPolling.java
index f07d8ac..8049e8f 100644
--- a/rulemgt/src/main/java/org/onap/holmes/rulemgt/dcae/DcaeConfigurationPolling.java
+++ b/rulemgt/src/main/java/org/onap/holmes/rulemgt/dcae/DcaeConfigurationPolling.java
@@ -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;