summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGuangrongFu <fu.guangrong@zte.com.cn>2018-08-14 17:52:44 +0800
committerGuangrongFu <fu.guangrong@zte.com.cn>2018-08-14 18:08:54 +0800
commit163dd74935802f562ef7272cadf0f88b6a63960a (patch)
treed11148f48d7020129d98a4a464100339aa9b3a5a
parent43ea5d47cc50cfc3200d4f7a1b9748fab3426bf2 (diff)
Optimized Rule Deployment Logic
Change-Id: Iff47a4d028aaad96ac8d7517d721ae43b50a9b89 Issue-ID: HOLMES-156 Signed-off-by: GuangrongFu <fu.guangrong@zte.com.cn>
-rw-r--r--engine-d/src/main/java/org/onap/holmes/engine/manager/DroolsEngine.java629
-rw-r--r--engine-d/src/main/java/org/onap/holmes/engine/resources/EngineResources.java7
-rw-r--r--engine-d/src/test/java/org/onap/holmes/engine/manager/DroolsEngineTest.java272
-rw-r--r--engine-d/src/test/java/org/onap/holmes/engine/resources/EngineResourcesTest.java15
4 files changed, 492 insertions, 431 deletions
diff --git a/engine-d/src/main/java/org/onap/holmes/engine/manager/DroolsEngine.java b/engine-d/src/main/java/org/onap/holmes/engine/manager/DroolsEngine.java
index bb3795d..7472457 100644
--- a/engine-d/src/main/java/org/onap/holmes/engine/manager/DroolsEngine.java
+++ b/engine-d/src/main/java/org/onap/holmes/engine/manager/DroolsEngine.java
@@ -1,321 +1,308 @@
-/**
- * Copyright 2017 ZTE Corporation.
- *
- * 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.onap.holmes.engine.manager;
-import java.io.StringReader;
-import java.util.ArrayList;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Locale;
-import java.util.Set;
-import javax.annotation.PostConstruct;
-import javax.inject.Inject;
-import lombok.extern.slf4j.Slf4j;
-import org.drools.compiler.kie.builder.impl.InternalKieModule;
-import org.jvnet.hk2.annotations.Service;
-
-import org.kie.api.KieBase;
-import org.kie.api.KieServices;
-import org.kie.api.builder.KieBuilder;
-import org.kie.api.builder.KieFileSystem;
-import org.kie.api.builder.KieRepository;
-import org.kie.api.builder.Message;
-import org.kie.api.builder.Message.Level;
-import org.kie.api.builder.model.KieBaseModel;
-import org.kie.api.builder.model.KieModuleModel;
-import org.kie.api.builder.model.KieSessionModel;
-import org.kie.api.conf.EqualityBehaviorOption;
-import org.kie.api.conf.EventProcessingOption;
-import org.kie.api.definition.KiePackage;
-import org.kie.api.io.KieResources;
-import org.kie.api.io.ResourceType;
-import org.kie.api.runtime.KieContainer;
-import org.kie.api.runtime.KieSession;
-import org.kie.api.runtime.conf.ClockTypeOption;
-import org.kie.api.runtime.rule.FactHandle;
-
-import org.onap.holmes.common.api.entity.AlarmInfo;
-
-import org.onap.holmes.common.api.stat.VesAlarm;
-import org.onap.holmes.common.dmaap.DmaapService;
-import org.onap.holmes.common.exception.AlarmInfoException;
-import org.onap.holmes.common.utils.DbDaoUtil;
-import org.onap.holmes.engine.db.AlarmInfoDao;
-import org.onap.holmes.engine.request.DeployRuleRequest;
-import org.onap.holmes.common.api.entity.CorrelationRule;
-import org.onap.holmes.common.exception.CorrelationException;
-import org.onap.holmes.common.utils.ExceptionUtil;
-import org.onap.holmes.engine.wrapper.RuleMgtWrapper;
-
-@Slf4j
-@Service
-public class DroolsEngine {
-
- private static final int ENABLE = 1;
- public static final String UTF_8 = "UTF-8";
- public static final String K_BASE = "KBase";
- private static final String RULES_FILE_NAME = "src/main/resources/rules/rule.drl";
- private final Set<String> packageNames = new HashSet<String>();
-
- @Inject
- private RuleMgtWrapper ruleMgtWrapper;
-
-
- private KieBase kieBase;
- private KieSession kieSession;
- private KieContainer kieContainer;
- private KieFileSystem kfs;
- private KieServices ks;
- private KieBuilder kieBuilder;
- private KieResources resources;
- private KieRepository kieRepository;
-
- private AlarmInfoDao alarmInfoDao;
- @Inject
- private DbDaoUtil daoUtil;
-
-
- @PostConstruct
- private void init() {
- alarmInfoDao = daoUtil.getJdbiDaoByOnDemand(AlarmInfoDao.class);
- try {
- // start engine
- start();
- } catch (Exception e) {
- log.error("Failed to start the service: " + e.getMessage(), e);
- throw ExceptionUtil.buildExceptionResponse("Failed to start the drools engine!");
- }
- }
-
- private void start() throws AlarmInfoException {
- log.info("Drools Engine Initialize Beginning...");
-
- initEngineParameter();
- alarmSynchronization();
-// initDeployRule();
-
- log.info("Alarm synchronization Successfully.");
- }
-
- public void stop() {
- this.kieSession.dispose();
- }
-
- public void initEngineParameter() {
- this.ks = KieServices.Factory.get();
- this.resources = ks.getResources();
- this.kieRepository = ks.getRepository();
- this.kfs = createKieFileSystemWithKProject(ks);
-
- this.kieBuilder = ks.newKieBuilder(kfs).buildAll();
- this.kieContainer = ks.newKieContainer(kieRepository.getDefaultReleaseId());
-
- this.kieBase = kieContainer.getKieBase();
- this.kieSession = kieContainer.newKieSession();
- }
-
- private void initDeployRule() throws CorrelationException {
- List<CorrelationRule> rules = ruleMgtWrapper.queryRuleByEnable(ENABLE);
-
- if (rules.isEmpty()) {
- return;
- }
- for (CorrelationRule rule : rules) {
- if (rule.getContent() != null) {
- deployRuleFromDB(rule.getContent());
- DmaapService.loopControlNames.put(rule.getPackageName(), rule.getClosedControlLoopName());
- }
- }
- }
-
- private void deployRuleFromDB(String ruleContent) throws CorrelationException {
- avoidDeployBug();
- StringReader reader = new StringReader(ruleContent);
- kfs.write(RULES_FILE_NAME,
- this.resources.newReaderResource(reader, UTF_8).setResourceType(ResourceType.DRL));
- kieBuilder = ks.newKieBuilder(kfs).buildAll();
- try {
- InternalKieModule internalKieModule = (InternalKieModule)kieBuilder.getKieModule();
- kieContainer.updateToVersion(internalKieModule.getReleaseId());
- } catch (Exception e) {
- throw new CorrelationException(e.getMessage(), e);
- }
- kieSession.fireAllRules();
- }
-
- public synchronized String deployRule(DeployRuleRequest rule, Locale locale)
- throws CorrelationException {
- avoidDeployBug();
- StringReader reader = new StringReader(rule.getContent());
- kfs.write(RULES_FILE_NAME,
- this.resources.newReaderResource(reader, UTF_8).setResourceType(ResourceType.DRL));
- kieBuilder = ks.newKieBuilder(kfs).buildAll();
-
- judgeRuleContent(locale, kieBuilder, true);
-
- InternalKieModule internalKieModule = (InternalKieModule)kieBuilder.getKieModule();;
- String packageName = internalKieModule.getKnowledgePackagesForKieBase(K_BASE).iterator().next().getName();
- try {
- kieContainer.updateToVersion(internalKieModule.getReleaseId());
- } catch (Exception e) {
- throw new CorrelationException("Failed to deploy the rule.", e);
- }
- packageNames.add(packageName);
- kieSession.fireAllRules();
- return packageName;
- }
-
- public synchronized void undeployRule(String packageName, Locale locale)
- throws CorrelationException {
- KiePackage kiePackage = kieBase.getKiePackage(packageName);
- if (null == kiePackage) {
- throw new CorrelationException("The rule " + packageName + " does not exist!");
- }
- try {
- kieBase.removeKiePackage(kiePackage.getName());
- } catch (Exception e) {
- throw new CorrelationException("Failed to delete the rule: " + packageName, e);
- }
- packageNames.remove(kiePackage.getName());
- }
-
- public void compileRule(String content, Locale locale)
- throws CorrelationException {
- StringReader reader = new StringReader(content);
-
- kfs.write(RULES_FILE_NAME,
- this.resources.newReaderResource(reader, UTF_8).setResourceType(ResourceType.DRL));
-
- kieBuilder = ks.newKieBuilder(kfs).buildAll();
-
- judgeRuleContent(locale, kieBuilder, false);
- }
-
- private void judgeRuleContent(Locale locale, KieBuilder kbuilder, boolean judgePackageName)
- throws CorrelationException {
- if (kbuilder.getResults().hasMessages(Message.Level.ERROR)) {
- String errorMsg = "There are errors in the rule: " + kbuilder.getResults()
- .getMessages(Level.ERROR).toString();
- log.error(errorMsg);
- throw new CorrelationException(errorMsg);
- }
- InternalKieModule internalKieModule = null;
- try {
- internalKieModule = (InternalKieModule) kbuilder.getKieModule();
- } catch (Exception e) {
- throw new CorrelationException("There are errors in the rule!" + e.getMessage(), e);
- }
- if (internalKieModule == null) {
- throw new CorrelationException("There are errors in the rule!");
- }
- String packageName = internalKieModule.getKnowledgePackagesForKieBase(K_BASE).iterator().next().getName();
-
- if (queryAllPackage().contains(packageName) && judgePackageName) {
- throw new CorrelationException("The rule " + packageName + " already exists in the drools engine.");
- }
- }
-
- public void putRaisedIntoStream(VesAlarm alarm) {
- FactHandle factHandle = this.kieSession.getFactHandle(alarm);
- if (factHandle != null) {
- Object obj = this.kieSession.getObject(factHandle);
- if (obj != null && obj instanceof VesAlarm) {
- alarm.setRootFlag(((VesAlarm) obj).getRootFlag());
- }
- this.kieSession.delete(factHandle);
-
- if (alarm.getAlarmIsCleared() == 1) {
- alarmInfoDao.deleteClearedAlarm(convertVesAlarm2AlarmInfo(alarm));
- }
- } else {
- this.kieSession.insert(alarm);
- }
-
- this.kieSession.fireAllRules();
-
- }
-
- public List<String> queryAllPackage() {
- List<KiePackage> kiePackages = (List<KiePackage>)kieBase.getKiePackages();
- List<String> list = new ArrayList<>();
- for(KiePackage kiePackage : kiePackages) {
- list.add(kiePackage.getName());
- }
- return list;
- }
-
- private KieFileSystem createKieFileSystemWithKProject(KieServices ks) {
- KieModuleModel kieModuleModel = ks.newKieModuleModel();
- KieBaseModel kieBaseModel = kieModuleModel.newKieBaseModel(K_BASE)
- .addPackage("rules")
- .setDefault(true)
- .setEqualsBehavior(EqualityBehaviorOption.EQUALITY)
- .setEventProcessingMode(EventProcessingOption.STREAM);
- KieSessionModel kieSessionModel = kieBaseModel.newKieSessionModel("KSession")
- .setDefault( true )
- .setType( KieSessionModel.KieSessionType.STATEFUL )
- .setClockType( ClockTypeOption.get("realtime") );
- KieFileSystem kfs = ks.newKieFileSystem();
- kfs.writeKModuleXML(kieModuleModel.toXML());
- return kfs;
- }
-
- private void avoidDeployBug() {
- String tmp = Math.random() + "";
- String rule = "package justInOrderToAvoidDeployBug" + tmp.substring(2);
- kfs.write(RULES_FILE_NAME, rule);
- kieBuilder = ks.newKieBuilder(kfs).buildAll();
- InternalKieModule internalKieModule = (InternalKieModule)kieBuilder.getKieModule();
- String packageName = internalKieModule.getKnowledgePackagesForKieBase(K_BASE).iterator().next().getName();
- kieRepository.addKieModule(internalKieModule);
- kieContainer.updateToVersion(internalKieModule.getReleaseId());
-
- KiePackage kiePackage = kieBase.getKiePackage(packageName);
- kieBase.removeKiePackage(kiePackage.getName());
- }
-
- public void alarmSynchronization() throws AlarmInfoException {
- alarmInfoDao.queryAllAlarm().forEach(alarmInfo -> alarmInfoDao.deleteClearedAlarm(alarmInfo));
- alarmInfoDao.queryAllAlarm().forEach(alarmInfo -> putRaisedIntoStream(convertAlarmInfo2VesAlarm(alarmInfo)));
- }
-
- private VesAlarm convertAlarmInfo2VesAlarm(AlarmInfo alarmInfo) {
- VesAlarm vesAlarm = new VesAlarm();
- vesAlarm.setEventId(alarmInfo.getEventId());
- vesAlarm.setEventName(alarmInfo.getEventName());
- vesAlarm.setStartEpochMicrosec(alarmInfo.getStartEpochMicroSec());
- vesAlarm.setSourceId(alarmInfo.getSourceId());
- vesAlarm.setSourceName(alarmInfo.getSourceName());
- vesAlarm.setRootFlag(alarmInfo.getRootFlag());
- vesAlarm.setAlarmIsCleared(alarmInfo.getAlarmIsCleared());
- vesAlarm.setLastEpochMicrosec(alarmInfo.getLastEpochMicroSec());
- return vesAlarm;
- }
-
- private AlarmInfo convertVesAlarm2AlarmInfo(VesAlarm vesAlarm){
- AlarmInfo alarmInfo = new AlarmInfo();
- alarmInfo.setEventId(vesAlarm.getEventId());
- alarmInfo.setEventName(vesAlarm.getEventName());
- alarmInfo.setStartEpochMicroSec(vesAlarm.getStartEpochMicrosec());
- alarmInfo.setLastEpochMicroSec(vesAlarm.getLastEpochMicrosec());
- alarmInfo.setSourceId(vesAlarm.getSourceId());
- alarmInfo.setSourceName(vesAlarm.getSourceName());
- alarmInfo.setAlarmIsCleared(vesAlarm.getAlarmIsCleared());
- alarmInfo.setRootFlag(vesAlarm.getRootFlag());
-
- return alarmInfo;
- }
-
-}
+/**
+ * Copyright 2017 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.engine.manager;
+
+import java.util.*;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.stream.Collectors;
+import javax.annotation.PostConstruct;
+import javax.inject.Inject;
+
+import lombok.extern.slf4j.Slf4j;
+import org.drools.compiler.kie.builder.impl.InternalKieModule;
+import org.drools.core.util.StringUtils;
+import org.jvnet.hk2.annotations.Service;
+
+import org.kie.api.KieServices;
+import org.kie.api.builder.*;
+import org.kie.api.builder.Message.Level;
+import org.kie.api.io.Resource;
+import org.kie.api.runtime.KieContainer;
+import org.kie.api.runtime.KieSession;
+import org.kie.api.runtime.rule.FactHandle;
+
+import org.onap.holmes.common.api.entity.AlarmInfo;
+
+import org.onap.holmes.common.api.stat.VesAlarm;
+import org.onap.holmes.common.dmaap.DmaapService;
+import org.onap.holmes.common.exception.AlarmInfoException;
+import org.onap.holmes.common.utils.DbDaoUtil;
+import org.onap.holmes.engine.db.AlarmInfoDao;
+import org.onap.holmes.engine.request.DeployRuleRequest;
+import org.onap.holmes.common.api.entity.CorrelationRule;
+import org.onap.holmes.common.exception.CorrelationException;
+import org.onap.holmes.common.utils.ExceptionUtil;
+import org.onap.holmes.engine.wrapper.RuleMgtWrapper;
+
+@Slf4j
+@Service
+public class DroolsEngine {
+
+ @Inject
+ private RuleMgtWrapper ruleMgtWrapper;
+ @Inject
+ private DbDaoUtil daoUtil;
+
+ private final static int ENABLE = 1;
+ private AlarmInfoDao alarmInfoDao;
+ private final Map<String, String> deployed = new ConcurrentHashMap<>();
+ private KieServices ks = KieServices.Factory.get();
+ private ReleaseId releaseId = ks.newReleaseId("org.onap.holmes", "rules", "1.0.0-SNAPSHOT");
+ private ReleaseId compilationRelease = ks.newReleaseId("org.onap.holmes", "compilation", "1.0.0-SNAPSHOT");
+ private KieContainer container;
+ private KieSession session;
+
+ @PostConstruct
+ private void init() {
+ alarmInfoDao = daoUtil.getJdbiDaoByOnDemand(AlarmInfoDao.class);
+ try {
+ log.info("Drools engine initializing...");
+ initEngine();
+ log.info("Drools engine initialized.");
+
+ log.info("Start deploy existing rules...");
+ initRules();
+ log.info("All rules were deployed.");
+
+ log.info("Synchronizing alarms...");
+ syncAlarms();
+ log.info("Alarm synchronization succeeded.");
+ } catch (Exception e) {
+ log.error("Failed to startup the engine of Holmes: " + e.getMessage(), e);
+ throw ExceptionUtil.buildExceptionResponse("Failed to startup Drools!");
+ }
+ }
+
+ public void stop() {
+ session.dispose();
+ }
+
+ public void initEngine() {
+ KieModule km = null;
+ try {
+ String drl = "package holmes;";
+ deployed.put(getPackageName(drl), drl);
+ km = createAndDeployJar(ks, releaseId, new ArrayList<>(deployed.values()));
+ } catch (Exception e) {
+ log.error("Failed to initialize the engine service module.", e);
+ }
+ container = ks.newKieContainer(km.getReleaseId());
+ session = container.newKieSession();
+ deployed.clear();
+ }
+
+ private void initRules() throws CorrelationException {
+ List<CorrelationRule> rules = ruleMgtWrapper.queryRuleByEnable(ENABLE);
+ if (rules.isEmpty()) {
+ return;
+ }
+
+ for (CorrelationRule rule : rules) {
+ if (!StringUtils.isEmpty(rule.getContent())) {
+ deployRule(rule.getContent());
+ DmaapService.loopControlNames.put(rule.getPackageName(), rule.getClosedControlLoopName());
+ }
+ }
+
+ session.fireAllRules();
+ }
+
+ public void syncAlarms() throws AlarmInfoException {
+ alarmInfoDao.queryAllAlarm().forEach(alarmInfo -> alarmInfoDao.deleteClearedAlarm(alarmInfo));
+ alarmInfoDao.queryAllAlarm().forEach(alarmInfo -> putRaisedIntoStream(convertAlarmInfo2VesAlarm(alarmInfo)));
+ }
+
+ public String deployRule(DeployRuleRequest rule) throws CorrelationException {
+ return deployRule(rule.getContent());
+ }
+
+ private synchronized String deployRule(String rule) throws CorrelationException {
+ final String packageName = getPackageName(rule);
+
+ if (StringUtils.isEmpty(packageName)) {
+ throw new CorrelationException("The package name can not be empty.");
+ }
+
+ if (deployed.containsKey(packageName)) {
+ throw new CorrelationException("A rule with the same package name already exists in the system.");
+ }
+
+ if (!StringUtils.isEmpty(rule)) {
+ deployed.put(packageName, rule);
+ try {
+ refreshInMemRules();
+ } catch (CorrelationException e) {
+ deployed.remove(packageName);
+ throw e;
+ }
+ session.fireAllRules();
+ }
+
+ return packageName;
+ }
+
+ public synchronized void undeployRule(String packageName) throws CorrelationException {
+
+ if (StringUtils.isEmpty(packageName)) {
+ throw new CorrelationException("The package name should not be null.");
+ }
+
+ if (!deployed.containsKey(packageName)) {
+ throw new CorrelationException("The rule " + packageName + " does not exist!");
+ }
+
+ String removed = deployed.remove(packageName);
+ try {
+ refreshInMemRules();
+ } catch (Exception e) {
+ deployed.put(packageName, removed);
+ throw new CorrelationException("Failed to delete the rule: " + packageName, e);
+ }
+ }
+
+ private void refreshInMemRules() throws CorrelationException {
+ KieModule km = createAndDeployJar(ks, releaseId, new ArrayList<>(deployed.values()));
+ container.updateToVersion(km.getReleaseId());
+ }
+
+ public void compileRule(String content)
+ throws CorrelationException {
+
+ KieFileSystem kfs = ks.newKieFileSystem().generateAndWritePomXML(compilationRelease);
+ kfs.write("src/main/resources/rules/rule.drl", content);
+ KieBuilder builder = ks.newKieBuilder(kfs).buildAll();
+ if (builder.getResults().hasMessages(Message.Level.ERROR)) {
+ String errorMsg = "There are errors in the rule: " + builder.getResults()
+ .getMessages(Level.ERROR).toString();
+ log.info("Compilation failure: " + errorMsg);
+ throw new CorrelationException(errorMsg);
+ }
+
+ if (deployed.containsKey(getPackageName(content))) {
+ throw new CorrelationException("There's no compilation error. But a rule with the same package name already " +
+ "exists in the engine, which may cause a deployment failure.");
+ }
+
+ ks.getRepository().removeKieModule(compilationRelease);
+ }
+
+ public void putRaisedIntoStream(VesAlarm alarm) {
+ FactHandle factHandle = this.session.getFactHandle(alarm);
+ if (factHandle != null) {
+ Object obj = this.session.getObject(factHandle);
+ if (obj != null && obj instanceof VesAlarm) {
+ alarm.setRootFlag(((VesAlarm) obj).getRootFlag());
+ }
+ this.session.delete(factHandle);
+
+ if (alarm.getAlarmIsCleared() == 1) {
+ alarmInfoDao.deleteClearedAlarm(convertVesAlarm2AlarmInfo(alarm));
+ }
+ } else {
+ this.session.insert(alarm);
+ }
+
+ this.session.fireAllRules();
+ }
+
+ public List<String> queryPackagesFromEngine() {
+ return container.getKieBase().getKiePackages().stream()
+ .filter(pkg -> pkg.getRules().size() != 0)
+ .map(pkg -> pkg.getName())
+ .collect(Collectors.toList());
+ }
+
+
+
+ private VesAlarm convertAlarmInfo2VesAlarm(AlarmInfo alarmInfo) {
+ VesAlarm vesAlarm = new VesAlarm();
+ vesAlarm.setEventId(alarmInfo.getEventId());
+ vesAlarm.setEventName(alarmInfo.getEventName());
+ vesAlarm.setStartEpochMicrosec(alarmInfo.getStartEpochMicroSec());
+ vesAlarm.setSourceId(alarmInfo.getSourceId());
+ vesAlarm.setSourceName(alarmInfo.getSourceName());
+ vesAlarm.setRootFlag(alarmInfo.getRootFlag());
+ vesAlarm.setAlarmIsCleared(alarmInfo.getAlarmIsCleared());
+ vesAlarm.setLastEpochMicrosec(alarmInfo.getLastEpochMicroSec());
+ return vesAlarm;
+ }
+
+ private AlarmInfo convertVesAlarm2AlarmInfo(VesAlarm vesAlarm) {
+ AlarmInfo alarmInfo = new AlarmInfo();
+ alarmInfo.setEventId(vesAlarm.getEventId());
+ alarmInfo.setEventName(vesAlarm.getEventName());
+ alarmInfo.setStartEpochMicroSec(vesAlarm.getStartEpochMicrosec());
+ alarmInfo.setLastEpochMicroSec(vesAlarm.getLastEpochMicrosec());
+ alarmInfo.setSourceId(vesAlarm.getSourceId());
+ alarmInfo.setSourceName(vesAlarm.getSourceName());
+ alarmInfo.setAlarmIsCleared(vesAlarm.getAlarmIsCleared());
+ alarmInfo.setRootFlag(vesAlarm.getRootFlag());
+
+ return alarmInfo;
+ }
+
+ private String getPackageName(String contents) {
+ String ret = contents.trim();
+ StringBuilder stringBuilder = new StringBuilder();
+ if (ret.startsWith("package")) {
+ ret = ret.substring(7).trim();
+ for (int i = 0; i < ret.length(); i++) {
+ char tmp = ret.charAt(i);
+ if (tmp == ';' || tmp == ' ' || tmp == '\n') {
+ break;
+ }
+ stringBuilder.append(tmp);
+ }
+ }
+ return stringBuilder.toString();
+ }
+
+ private KieModule createAndDeployJar(KieServices ks, ReleaseId releaseId, List<String> drls) throws CorrelationException {
+ byte[] jar = createJar(ks, releaseId, drls);
+ KieModule km = deployJarIntoRepository(ks, jar);
+ return km;
+ }
+
+ private byte[] createJar(KieServices ks, ReleaseId releaseId, List<String> drls) throws CorrelationException {
+ KieFileSystem kfs = ks.newKieFileSystem().generateAndWritePomXML(releaseId);
+ int i = 0;
+ for (String drl : drls) {
+ if (!StringUtils.isEmpty(drl)) {
+ kfs.write("src/main/resources/" + getPackageName(drl) + ".drl", drl);
+ }
+ }
+ KieBuilder kb = ks.newKieBuilder(kfs).buildAll();
+ if (kb.getResults().hasMessages(Message.Level.ERROR)) {
+ StringBuilder sb = new StringBuilder();
+ for (Message msg : kb.getResults().getMessages()) {
+ sb.append(String.format("[%s]Line: %d, Col: %d\t%s\n", msg.getLevel().toString(), msg.getLine(),
+ msg.getColumn(), msg.getText()));
+ }
+ throw new CorrelationException("Failed to compile JAR. Details: \n" + sb.toString());
+ }
+
+ InternalKieModule kieModule = (InternalKieModule) ks.getRepository()
+ .getKieModule(releaseId);
+
+ return kieModule.getBytes();
+ }
+
+ private KieModule deployJarIntoRepository(KieServices ks, byte[] jar) {
+ Resource jarRes = ks.getResources().newByteArrayResource(jar);
+ return ks.getRepository().addKieModule(jarRes);
+ }
+
+}
diff --git a/engine-d/src/main/java/org/onap/holmes/engine/resources/EngineResources.java b/engine-d/src/main/java/org/onap/holmes/engine/resources/EngineResources.java
index 4088d72..0d26b6e 100644
--- a/engine-d/src/main/java/org/onap/holmes/engine/resources/EngineResources.java
+++ b/engine-d/src/main/java/org/onap/holmes/engine/resources/EngineResources.java
@@ -77,7 +77,7 @@ public class EngineResources {
DmaapService.loopControlNames
.put(packageName, deployRuleRequest.getLoopControlName());
- String packageNameRet = droolsEngine.deployRule(deployRuleRequest, locale);
+ String packageNameRet = droolsEngine.deployRule(deployRuleRequest);
if (!packageName.equals(packageNameRet)) {
log.info("The parsed package name is different from that returned by the engine.");
DmaapService.loopControlNames.remove(packageName);
@@ -109,12 +109,13 @@ public class EngineResources {
Locale locale = LanguageUtil.getLocale(httpRequest);
try {
- droolsEngine.undeployRule(packageName, locale);
+ droolsEngine.undeployRule(packageName);
DmaapService.loopControlNames.remove(packageName);
} catch (CorrelationException correlationException) {
log.error(correlationException.getMessage(), correlationException);
throw ExceptionUtil.buildExceptionResponse(correlationException.getMessage());
}
+
return true;
}
@@ -129,7 +130,7 @@ public class EngineResources {
Locale locale = LanguageUtil.getLocale(httpRequest);
try {
- droolsEngine.compileRule(compileRuleRequest.getContent(), locale);
+ droolsEngine.compileRule(compileRuleRequest.getContent());
} catch (CorrelationException correlationException) {
log.error(correlationException.getMessage(), correlationException);
throw ExceptionUtil.buildExceptionResponse(correlationException.getMessage());
diff --git a/engine-d/src/test/java/org/onap/holmes/engine/manager/DroolsEngineTest.java b/engine-d/src/test/java/org/onap/holmes/engine/manager/DroolsEngineTest.java
index 71ef172..4ad9107 100644
--- a/engine-d/src/test/java/org/onap/holmes/engine/manager/DroolsEngineTest.java
+++ b/engine-d/src/test/java/org/onap/holmes/engine/manager/DroolsEngineTest.java
@@ -1,12 +1,12 @@
/**
* Copyright 2017 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.
@@ -16,23 +16,14 @@
package org.onap.holmes.engine.manager;
-import org.easymock.EasyMock;
import org.junit.Before;
+import org.junit.BeforeClass;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;
-import org.kie.api.KieBase;
-import org.kie.api.KieServices;
-import org.kie.api.builder.KieBuilder;
-import org.kie.api.builder.KieFileSystem;
-import org.kie.api.builder.KieRepository;
-import org.kie.api.io.KieResources;
-import org.kie.api.runtime.KieContainer;
-import org.kie.api.runtime.KieSession;
import org.onap.holmes.common.api.entity.AlarmInfo;
import org.onap.holmes.common.api.entity.CorrelationRule;
import org.onap.holmes.common.api.stat.VesAlarm;
-import org.onap.holmes.common.constant.AlarmConst;
import org.onap.holmes.common.exception.CorrelationException;
import org.onap.holmes.common.utils.DbDaoUtil;
import org.onap.holmes.engine.db.AlarmInfoDao;
@@ -41,10 +32,12 @@ import org.onap.holmes.engine.wrapper.RuleMgtWrapper;
import org.powermock.api.easymock.PowerMock;
import org.powermock.reflect.Whitebox;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Locale;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.util.*;
+import java.util.stream.Collectors;
+import static org.easymock.EasyMock.anyObject;
import static org.hamcrest.CoreMatchers.is;
import static org.hamcrest.core.IsEqual.equalTo;
import static org.junit.Assert.assertThat;
@@ -56,135 +49,108 @@ public class DroolsEngineTest {
private RuleMgtWrapper ruleMgtWrapper;
- private KieBase kieBase;
- private KieSession kieSession;
- private KieContainer kieContainer;
- private KieFileSystem kfs;
- private KieServices ks;
- private KieBuilder kieBuilder;
- private KieResources resources;
- private KieRepository kieRepository;
-
private AlarmInfoDao alarmInfoDaoMock;
private DroolsEngine droolsEngine;
- private DbDaoUtil dbDaoUtilMock;
+ private DbDaoUtil dbDaoUtilStub;
- @Before
- public void setUp() throws Exception {
+ public DroolsEngineTest() throws Exception {
droolsEngine = new DroolsEngine();
+ ruleMgtWrapper = new RuleMgtWrapperStub();
+ dbDaoUtilStub = new DbDaoUtilStub();
+ Whitebox.setInternalState(droolsEngine, "daoUtil", dbDaoUtilStub);
+ Whitebox.setInternalState(droolsEngine, "ruleMgtWrapper", ruleMgtWrapper);
+ Whitebox.invokeMethod(droolsEngine, "init");
+ }
- ks = KieServices.Factory.get();
- resources = ks.getResources();
- kieRepository = ks.getRepository();
- kfs = Whitebox.invokeMethod(droolsEngine, "createKieFileSystemWithKProject", ks);
- kieBuilder = ks.newKieBuilder(kfs).buildAll();
- kieContainer = ks.newKieContainer(kieRepository.getDefaultReleaseId());
- kieBase = kieContainer.getKieBase();
- kieSession = kieContainer.newKieSession();
-
- alarmInfoDaoMock = PowerMock.createMock(AlarmInfoDao.class);
- dbDaoUtilMock = PowerMock.createMock(DbDaoUtil.class);
-
-
- Whitebox.setInternalState(droolsEngine, "kieBase", kieBase);
- Whitebox.setInternalState(droolsEngine, "kieSession", kieSession);
- Whitebox.setInternalState(droolsEngine, "kieContainer", kieContainer);
- Whitebox.setInternalState(droolsEngine, "kfs", kfs);
- Whitebox.setInternalState(droolsEngine, "ks", ks);
- Whitebox.setInternalState(droolsEngine, "kieBuilder", kieBuilder);
- Whitebox.setInternalState(droolsEngine, "resources", resources);
- Whitebox.setInternalState(droolsEngine, "kieRepository", kieRepository);
-
- Whitebox.setInternalState(droolsEngine, "daoUtil", dbDaoUtilMock);
- Whitebox.setInternalState(droolsEngine, "alarmInfoDao", alarmInfoDaoMock);
-
+ @Before
+ public void setUp() throws Exception {
PowerMock.resetAll();
}
@Test
- public void init() throws Exception {
-
- List<CorrelationRule> rules = new ArrayList<CorrelationRule>();
- CorrelationRule rule = new CorrelationRule();
- rule.setContent("package content");
- rule.setClosedControlLoopName("test");
- rule.setPackageName("org.onap.holmes");
- rules.add(rule);
-
-// expect(ruleMgtWrapper.queryRuleByEnable(anyInt())).andReturn(rules);
- List<AlarmInfo> alarmInfoList = new ArrayList<AlarmInfo>();
- EasyMock.expect(dbDaoUtilMock.getJdbiDaoByOnDemand(AlarmInfoDao.class)).andReturn(alarmInfoDaoMock).anyTimes();
- EasyMock.expect(alarmInfoDaoMock.queryAllAlarm()).andReturn(alarmInfoList).anyTimes();
- PowerMock.replayAll();
-
- PowerMock.verifyAll();
+ public void deployRule_rule_is_null() throws CorrelationException {
+ thrown.expect(NullPointerException.class);
+ droolsEngine.deployRule(null);
}
@Test
- public void deployRule_rule_is_null() throws CorrelationException {
- Locale locale = PowerMock.createMock(Locale.class);
-
- thrown.expect(NullPointerException.class);
+ public void deployRule_invalid_rule_no_pkg_name() throws CorrelationException {
+ DeployRuleRequest rule = new DeployRuleRequest();
+ rule.setContent("rule123;");
+ thrown.expect(CorrelationException.class);
+ thrown.expectMessage("The package name can not be empty.");
- droolsEngine.deployRule(null, locale);
+ droolsEngine.deployRule(rule);
}
@Test
- public void deployRule_kbuilder_has_errors() throws CorrelationException {
+ public void deployRule_invalid_rule_illegal_contents() throws CorrelationException {
DeployRuleRequest rule = new DeployRuleRequest();
- rule.setContent("rule123");
- Locale locale = new Locale(AlarmConst.I18N_EN);
-
+ rule.setContent("package rule123; a random string");
thrown.expect(CorrelationException.class);
- droolsEngine.deployRule(rule, locale);
+ droolsEngine.deployRule(rule);
}
@Test
public void deployRule_package_name_repeat() throws CorrelationException {
DeployRuleRequest rule = new DeployRuleRequest();
rule.setContent("package rule123");
- Locale locale = new Locale(AlarmConst.I18N_EN);
thrown.expect(CorrelationException.class);
-
- droolsEngine.deployRule(rule, locale);
- droolsEngine.deployRule(rule, locale);
+ thrown.expectMessage("A rule with the same package name already exists in the system.");
+ droolsEngine.deployRule(rule);
+ droolsEngine.deployRule(rule);
}
@Test
public void undeployRule_package_name_is_null() throws CorrelationException {
String packageName = null;
- Locale locale = new Locale(AlarmConst.I18N_EN);
-
thrown.expect(CorrelationException.class);
+ thrown.expectMessage("The package name should not be null.");
- droolsEngine.undeployRule(packageName, locale);
+ droolsEngine.undeployRule(packageName);
}
@Test
public void undeployRule_normal() throws CorrelationException {
- Locale locale = new Locale(AlarmConst.I18N_EN);
-
DeployRuleRequest rule = new DeployRuleRequest();
rule.setContent("package rule123");
- droolsEngine.deployRule(rule, locale);
+ droolsEngine.deployRule(rule);
+ droolsEngine.undeployRule("rule123");
+ }
- String packageName = "rule123";
+ @Test
+ public void compileRule_compilation_failure() throws CorrelationException {
+ String content = "invalid contents";
- droolsEngine.undeployRule(packageName, locale);
+ thrown.expect(CorrelationException.class);
+
+ droolsEngine.compileRule(content);
}
@Test
- public void compileRule_kbuilder_has_errors() throws CorrelationException {
- String content = "have error content";
- Locale locale = new Locale(AlarmConst.I18N_EN);
-
+ public void compileRule_compilation_deployed_rule() throws CorrelationException {
+ String content = "package deployed;";
+ DeployRuleRequest rule = new DeployRuleRequest();
+ rule.setContent(content);
+ rule.setLoopControlName(UUID.randomUUID().toString());
thrown.expect(CorrelationException.class);
- droolsEngine.compileRule(content, locale);
+ droolsEngine.deployRule(rule);
+ droolsEngine.compileRule(content);
+ }
+
+ @Test
+ public void compileRule_compilation_normal() throws CorrelationException {
+ String content = "package deployed;";
+ DeployRuleRequest rule = new DeployRuleRequest();
+ rule.setContent(content);
+ rule.setLoopControlName(UUID.randomUUID().toString());
+
+ droolsEngine.compileRule(content);
}
@Test
@@ -221,9 +187,7 @@ public class DroolsEngineTest {
alarmInfo.setRootFlag(0);
alarmInfo.setAlarmIsCleared(1);
- PowerMock.replayAll();
- VesAlarm vesAlarm = Whitebox.invokeMethod(droolsEngine,"convertAlarmInfo2VesAlarm",alarmInfo);
- PowerMock.verifyAll();
+ VesAlarm vesAlarm = Whitebox.invokeMethod(droolsEngine, "convertAlarmInfo2VesAlarm", alarmInfo);
assertThat(vesAlarm.getAlarmIsCleared(), is(1));
assertThat(vesAlarm.getSourceName(), equalTo("sourceName"));
@@ -234,4 +198,114 @@ public class DroolsEngineTest {
assertThat(vesAlarm.getEventId(), equalTo("eventId"));
assertThat(vesAlarm.getRootFlag(), is(0));
}
+
+ @Test
+ public void testConvertVesAlarm2AlarmInfo() throws Exception {
+ VesAlarm vesAlarm = new VesAlarm();
+ vesAlarm.setEventId("eventId");
+ vesAlarm.setEventName("eventName");
+ vesAlarm.setStartEpochMicrosec(1L);
+ vesAlarm.setLastEpochMicrosec(1L);
+ vesAlarm.setSourceId("sourceId");
+ vesAlarm.setSourceName("sourceName");
+ vesAlarm.setRootFlag(0);
+ vesAlarm.setAlarmIsCleared(1);
+
+ AlarmInfo alarmInfo = Whitebox.invokeMethod(droolsEngine, "convertVesAlarm2AlarmInfo", vesAlarm);
+
+ assertThat(alarmInfo.getAlarmIsCleared(), is(1));
+ assertThat(alarmInfo.getSourceName(), equalTo("sourceName"));
+ assertThat(alarmInfo.getSourceId(), equalTo("sourceId"));
+ assertThat(alarmInfo.getStartEpochMicroSec(), is(1L));
+ assertThat(alarmInfo.getLastEpochMicroSec(), is(1L));
+ assertThat(alarmInfo.getEventName(), equalTo("eventName"));
+ assertThat(alarmInfo.getEventId(), equalTo("eventId"));
+ assertThat(alarmInfo.getRootFlag(), is(0));
+ }
+
+ @Test
+ public void testQueryPackagesFromEngine() throws CorrelationException {
+
+ DeployRuleRequest rule = new DeployRuleRequest();
+ rule.setContent("package packageCheck; rule \"test\" when eval(1==1) then System.out.println(1); end");
+ rule.setLoopControlName(UUID.randomUUID().toString());
+
+ droolsEngine.deployRule(rule);
+
+ List<String> packages = droolsEngine.queryPackagesFromEngine();
+
+ assertThat(packages.contains("packageCheck"), is(true));
+ }
+}
+
+class RuleMgtWrapperStub extends RuleMgtWrapper {
+ private List<CorrelationRule> rules;
+
+ public RuleMgtWrapperStub() {
+ rules = new ArrayList<>();
+ CorrelationRule rule = new CorrelationRule();
+ rule.setEnabled(1);
+ rule.setContent("package org.onap.holmes;");
+ rule.setPackageName("UT");
+ rule.setClosedControlLoopName(UUID.randomUUID().toString());
+ rules.add(rule);
+ }
+
+ public List<CorrelationRule> getRules() {
+ return rules;
+ }
+
+ public void setRules(List<CorrelationRule> rules) {
+ this.rules = rules;
+ }
+
+ @Override
+ public List<CorrelationRule> queryRuleByEnable(int enabled) throws CorrelationException {
+ return rules.stream().filter(rule -> rule.getEnabled() == enabled).collect(Collectors.toList());
+ }
+}
+
+class AlarmInfoDaoStub extends AlarmInfoDao {
+
+ private List<AlarmInfo> alarms;
+
+ public AlarmInfoDaoStub() {
+ alarms = new ArrayList<>();
+ AlarmInfo info = new AlarmInfo();
+ info.setEventId("eventId");
+ info.setEventName("eventName");
+ info.setStartEpochMicroSec(1L);
+ info.setLastEpochMicroSec(1L);
+ info.setSourceId("sourceId");
+ info.setSourceName("sourceName");
+ info.setRootFlag(0);
+ info.setAlarmIsCleared(1);
+ alarms.add(info);
+ }
+
+ @Override
+ protected String addAlarm(AlarmInfo alarmInfo) {
+ alarms.add(alarmInfo);
+ return null;
+ }
+
+ @Override
+ protected List<AlarmInfo> queryAlarm() {
+ return alarms;
+ }
+
+ @Override
+ protected int deleteAlarmByAlarmIsCleared(int alarmIsCleared) {
+ return 1;
+ }
+}
+
+class DbDaoUtilStub extends DbDaoUtil {
+ private AlarmInfoDao dao = new AlarmInfoDaoStub();
+ @Override
+ public <T> T getJdbiDaoByOnDemand(Class<T> daoClazz) {
+
+ return (T)dao;
+
+ }
}
diff --git a/engine-d/src/test/java/org/onap/holmes/engine/resources/EngineResourcesTest.java b/engine-d/src/test/java/org/onap/holmes/engine/resources/EngineResourcesTest.java
index 6be232f..a09eb3a 100644
--- a/engine-d/src/test/java/org/onap/holmes/engine/resources/EngineResourcesTest.java
+++ b/engine-d/src/test/java/org/onap/holmes/engine/resources/EngineResourcesTest.java
@@ -44,7 +44,7 @@ public class EngineResourcesTest {
droolsEngine = PowerMock.createMock(DroolsEngine.class);
engineResources = new EngineResources();
- Whitebox.setInternalState(engineResources,"droolsEngine",droolsEngine);
+ Whitebox.setInternalState(engineResources,"droolsEngine", droolsEngine);
PowerMock.resetAll();
}
@@ -56,7 +56,7 @@ public class EngineResourcesTest {
thrown.expect(WebApplicationException.class);
expect(httpRequest.getHeader("language-option")).andReturn("en_US");
- expect(droolsEngine.deployRule(anyObject(DeployRuleRequest.class), anyObject(Locale.class))).
+ expect(droolsEngine.deployRule(anyObject(DeployRuleRequest.class))).
andThrow(new CorrelationException(""));
PowerMock.replayAll();
engineResources.deployRule(deployRuleRequest, httpRequest);
@@ -71,8 +71,7 @@ public class EngineResourcesTest {
HttpServletRequest httpRequest = PowerMock.createMock(HttpServletRequest.class);
expect(httpRequest.getHeader("language-option")).andReturn("en_US");
- expect(droolsEngine.deployRule(anyObject(DeployRuleRequest.class),
- anyObject(Locale.class))).andReturn("packageName");
+ expect(droolsEngine.deployRule(anyObject(DeployRuleRequest.class))).andReturn("packageName");
PowerMock.replayAll();
engineResources.deployRule(deployRuleRequest, httpRequest);
PowerMock.verifyAll();
@@ -86,7 +85,7 @@ public class EngineResourcesTest {
thrown.expect(WebApplicationException.class);
expect(httpRequest.getHeader("language-option")).andReturn("en_US");
- droolsEngine.undeployRule(anyObject(String.class), anyObject(Locale.class));
+ droolsEngine.undeployRule(anyObject(String.class));
expectLastCall().andThrow(new CorrelationException(""));
PowerMock.replayAll();
engineResources.undeployRule(packageName, httpRequest);
@@ -99,7 +98,7 @@ public class EngineResourcesTest {
HttpServletRequest httpRequest = PowerMock.createMock(HttpServletRequest.class);
expect(httpRequest.getHeader("language-option")).andReturn("en_US");
- droolsEngine.undeployRule(anyObject(String.class), anyObject(Locale.class));
+ droolsEngine.undeployRule(anyObject(String.class));
PowerMock.replayAll();
engineResources.undeployRule(packageName, httpRequest);
PowerMock.verifyAll();
@@ -113,7 +112,7 @@ public class EngineResourcesTest {
thrown.expect(WebApplicationException.class);
expect(httpRequest.getHeader("language-option")).andReturn("en_US");
- droolsEngine.compileRule(anyObject(String.class),anyObject(Locale.class));
+ droolsEngine.compileRule(anyObject(String.class));
expectLastCall().andThrow(new CorrelationException(""));
PowerMock.replayAll();
engineResources.compileRule(compileRuleRequest, httpRequest);
@@ -126,7 +125,7 @@ public class EngineResourcesTest {
HttpServletRequest httpRequest = PowerMock.createMock(HttpServletRequest.class);
expect(httpRequest.getHeader("language-option")).andReturn("en_US");
- droolsEngine.compileRule(anyObject(String.class),anyObject(Locale.class));
+ droolsEngine.compileRule(anyObject(String.class));
PowerMock.replayAll();
engineResources.compileRule(compileRuleRequest, httpRequest);
PowerMock.verifyAll();