From 8754c29599ef6e59be3de0536514367f2256142f Mon Sep 17 00:00:00 2001 From: Shiwei Tian Date: Thu, 15 Mar 2018 12:21:15 +0800 Subject: [PATCH] Update the Drools Engine to Version 6.5.0 Issue-ID: HOLMES-99 Change-Id: I69169d590055e1bce928de7b0ef998cbdcf46edb Signed-off-by: Shiwei Tian --- engine-d/pom.xml | 23 ++- .../org/onap/holmes/engine/EngineDAppConfig.java | 3 - .../onap/holmes/engine/manager/DroolsEngine.java | 193 +++++++++++++-------- .../holmes/engine/manager/DroolsEngineTest.java | 58 ++++--- pom.xml | 11 ++ 5 files changed, 191 insertions(+), 97 deletions(-) diff --git a/engine-d/pom.xml b/engine-d/pom.xml index c0cb28e..5a00357 100644 --- a/engine-d/pom.xml +++ b/engine-d/pom.xml @@ -30,7 +30,7 @@ jar - 5.4.0.Final + 6.5.0.Final @@ -45,8 +45,27 @@ json-lib 2.4 jdk15 + + + commons-collections + commons-collections + + + commons-beanutils + commons-beanutils + + + + + commons-collections + commons-collections + 3.2.2 + + + commons-beanutils + commons-beanutils + 1.9.3 - org.onap.msb.java-sdk msb-java-sdk diff --git a/engine-d/src/main/java/org/onap/holmes/engine/EngineDAppConfig.java b/engine-d/src/main/java/org/onap/holmes/engine/EngineDAppConfig.java index c42e9d9..c748f85 100644 --- a/engine-d/src/main/java/org/onap/holmes/engine/EngineDAppConfig.java +++ b/engine-d/src/main/java/org/onap/holmes/engine/EngineDAppConfig.java @@ -20,17 +20,14 @@ import io.dropwizard.Configuration; import io.dropwizard.db.DataSourceFactory; import javax.validation.Valid; import javax.validation.constraints.NotNull; -import org.hibernate.validator.constraints.NotEmpty; import org.jvnet.hk2.annotations.Service; import org.onap.holmes.common.config.MQConfig; @Service public class EngineDAppConfig extends Configuration { - @NotEmpty private String defaultName = "Correlation-Rule"; - @NotEmpty private String apidescription = "Holmes rule management rest API"; @JsonProperty 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 2ecea5e..d790ee7 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 @@ -14,29 +14,37 @@ * 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.annotation.PreDestroy; import javax.inject.Inject; import lombok.extern.slf4j.Slf4j; -import org.drools.KnowledgeBase; -import org.drools.KnowledgeBaseConfiguration; -import org.drools.KnowledgeBaseFactory; -import org.drools.builder.KnowledgeBuilder; -import org.drools.builder.KnowledgeBuilderFactory; -import org.drools.builder.ResourceType; -import org.drools.conf.EventProcessingOption; -import org.drools.definition.KnowledgePackage; -import org.drools.io.Resource; -import org.drools.io.ResourceFactory; -import org.drools.runtime.StatefulKnowledgeSession; -import org.drools.runtime.rule.FactHandle; +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.stat.VesAlarm; import org.onap.holmes.common.dmaap.DmaapService; import org.onap.holmes.engine.request.DeployRuleRequest; @@ -53,9 +61,15 @@ public class DroolsEngine { private final Set packageNames = new HashSet(); @Inject private RuleMgtWrapper ruleMgtWrapper; - private KnowledgeBase kbase; - private KnowledgeBaseConfiguration kconf; - private StatefulKnowledgeSession ksession; + + private KieBase kieBase; + private KieSession kieSession; + private KieContainer kieContainer; + private KieFileSystem kfs; + private KieServices ks; + private KieBuilder kieBuilder; + private KieResources resources; + private KieRepository kieRepository; @PostConstruct private void init() { @@ -78,19 +92,20 @@ public class DroolsEngine { } public void stop() { - this.ksession.dispose(); + this.kieSession.dispose(); } - private void initEngineParameter() { - this.kconf = KnowledgeBaseFactory.newKnowledgeBaseConfiguration(); - - this.kconf.setOption(EventProcessingOption.STREAM); + public void initEngineParameter() { + this.ks = KieServices.Factory.get(); + this.resources = ks.getResources(); + this.kieRepository = ks.getRepository(); + this.kfs = createKieFileSystemWithKProject(ks); - this.kconf.setProperty("drools.assertBehaviour", "equality"); + this.kieBuilder = ks.newKieBuilder(kfs).buildAll(); + this.kieContainer = ks.newKieContainer(kieRepository.getDefaultReleaseId()); - this.kbase = KnowledgeBaseFactory.newKnowledgeBase("D-ENGINE", this.kconf); - - this.ksession = kbase.newStatefulKnowledgeSession(); + this.kieBase = kieContainer.getKieBase(); + this.kieSession = kieContainer.newKieSession(); } private void initDeployRule() throws CorrelationException { @@ -108,100 +123,142 @@ public class DroolsEngine { } private void deployRuleFromDB(String ruleContent) throws CorrelationException { + avoidDeployBug(); StringReader reader = new StringReader(ruleContent); - Resource res = ResourceFactory.newReaderResource(reader); - - KnowledgeBuilder kbuilder = KnowledgeBuilderFactory.newKnowledgeBuilder(); - - kbuilder.add(res, ResourceType.DRL); - + kfs.write("src/main/resources/rules/rule.drl", + this.resources.newReaderResource(reader,"UTF-8").setResourceType(ResourceType.DRL)); + kieBuilder = ks.newKieBuilder(kfs).buildAll(); try { - - kbase.addKnowledgePackages(kbuilder.getKnowledgePackages()); + InternalKieModule internalKieModule = (InternalKieModule)kieBuilder.getKieModule(); + kieContainer.updateToVersion(internalKieModule.getReleaseId()); } catch (Exception e) { throw new CorrelationException(e.getMessage(), e); } - ksession.fireAllRules(); + kieSession.fireAllRules(); } public synchronized String deployRule(DeployRuleRequest rule, Locale locale) throws CorrelationException { + avoidDeployBug(); StringReader reader = new StringReader(rule.getContent()); - Resource res = ResourceFactory.newReaderResource(reader); - - KnowledgeBuilder kbuilder = KnowledgeBuilderFactory.newKnowledgeBuilder(); - - kbuilder.add(res, ResourceType.DRL); + kfs.write("src/main/resources/rules/rule.drl", + this.resources.newReaderResource(reader,"UTF-8").setResourceType(ResourceType.DRL)); + kieBuilder = ks.newKieBuilder(kfs).buildAll(); - judgeRuleContent(locale, kbuilder, true); + judgeRuleContent(locale, kieBuilder, true); - String packageName = kbuilder.getKnowledgePackages().iterator().next().getName(); + InternalKieModule internalKieModule = (InternalKieModule)kieBuilder.getKieModule();; + String packageName = internalKieModule.getKnowledgePackagesForKieBase("KBase").iterator().next().getName(); try { - packageNames.add(packageName); - kbase.addKnowledgePackages(kbuilder.getKnowledgePackages()); + kieContainer.updateToVersion(internalKieModule.getReleaseId()); } catch (Exception e) { throw new CorrelationException("Failed to deploy the rule.", e); } - - ksession.fireAllRules(); + packageNames.add(packageName); + kieSession.fireAllRules(); return packageName; } public synchronized void undeployRule(String packageName, Locale locale) throws CorrelationException { - - KnowledgePackage pkg = kbase.getKnowledgePackage(packageName); - - if (null == pkg) { + KiePackage kiePackage = kieBase.getKiePackage(packageName); + if (null == kiePackage) { throw new CorrelationException("The rule " + packageName + " does not exist!"); } - try { - kbase.removeKnowledgePackage(pkg.getName()); + kieBase.removeKiePackage(kiePackage.getName()); } catch (Exception e) { throw new CorrelationException("Failed to delete the rule: " + packageName, e); } - packageNames.remove(pkg.getName()); + packageNames.remove(kiePackage.getName()); } public void compileRule(String content, Locale locale) throws CorrelationException { StringReader reader = new StringReader(content); - Resource res = ResourceFactory.newReaderResource(reader); - KnowledgeBuilder kbuilder = KnowledgeBuilderFactory.newKnowledgeBuilder(); + kfs.write("src/main/resources/rules/rule.drl", + this.resources.newReaderResource(reader,"UTF-8").setResourceType(ResourceType.DRL)); - kbuilder.add(res, ResourceType.DRL); + kieBuilder = ks.newKieBuilder(kfs).buildAll(); - judgeRuleContent(locale, kbuilder, false); + judgeRuleContent(locale, kieBuilder, false); } - private void judgeRuleContent(Locale locale, KnowledgeBuilder kbuilder, boolean judgePackageName) + private void judgeRuleContent(Locale locale, KieBuilder kbuilder, boolean judgePackageName) throws CorrelationException { - if (kbuilder.hasErrors()) { - String errorMsg = "There are errors in the rule: " + kbuilder.getErrors().toString(); + 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("KBase").iterator().next().getName(); - String packageName = kbuilder.getKnowledgePackages().iterator().next().getName(); - - if (packageNames.contains(packageName) && judgePackageName) { + if (queryAllPackage().contains(packageName) && judgePackageName) { throw new CorrelationException("The rule " + packageName + " already exists in the drools engine."); } } public void putRaisedIntoStream(VesAlarm raiseAlarm) { - FactHandle factHandle = this.ksession.getFactHandle(raiseAlarm); + FactHandle factHandle = this.kieSession.getFactHandle(raiseAlarm); if (factHandle != null) { - Object obj = this.ksession.getObject(factHandle); + Object obj = this.kieSession.getObject(factHandle); if (obj != null && obj instanceof VesAlarm) { raiseAlarm.setRootFlag(((VesAlarm) obj).getRootFlag()); } - this.ksession.retract(factHandle); + this.kieSession.delete(factHandle); } - this.ksession.insert(raiseAlarm); - this.ksession.fireAllRules(); + this.kieSession.insert(raiseAlarm); + this.kieSession.fireAllRules(); + } + + public List queryAllPackage() { + List kiePackages = (List)kieBase.getKiePackages(); + List 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("KBase") + .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("src/main/resources/rules/rule.drl", rule); + kieBuilder = ks.newKieBuilder(kfs).buildAll(); + InternalKieModule internalKieModule = (InternalKieModule)kieBuilder.getKieModule(); + String packageName = internalKieModule.getKnowledgePackagesForKieBase("KBase").iterator().next().getName(); + kieRepository.addKieModule(internalKieModule); + kieContainer.updateToVersion(internalKieModule.getReleaseId()); + + KiePackage kiePackage = kieBase.getKiePackage(packageName); + kieBase.removeKiePackage(kiePackage.getName()); } } 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 dd0b55d..3325efa 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 @@ -23,15 +23,18 @@ import java.lang.reflect.Method; import java.util.ArrayList; import java.util.List; import java.util.Locale; -import org.drools.KnowledgeBase; -import org.drools.KnowledgeBaseConfiguration; -import org.drools.KnowledgeBaseFactory; -import org.drools.conf.EventProcessingOption; -import org.drools.runtime.StatefulKnowledgeSession; import org.junit.Before; 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.stat.VesAlarm; import org.onap.holmes.engine.request.DeployRuleRequest; import org.onap.holmes.common.api.entity.CorrelationRule; @@ -39,7 +42,6 @@ import org.onap.holmes.common.constant.AlarmConst; import org.onap.holmes.common.exception.CorrelationException; import org.onap.holmes.engine.wrapper.RuleMgtWrapper; import org.powermock.api.easymock.PowerMock; -import org.powermock.modules.junit4.rule.PowerMockRule; import org.powermock.reflect.Whitebox; public class DroolsEngineTest { @@ -47,37 +49,45 @@ public class DroolsEngineTest { @Rule public ExpectedException thrown = ExpectedException.none(); - @Rule - public PowerMockRule powerMockRule = new PowerMockRule(); - private RuleMgtWrapper ruleMgtWrapper; - private KnowledgeBase kbase; - - private KnowledgeBaseConfiguration kconf; - - private StatefulKnowledgeSession ksession; + 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 DroolsEngine droolsEngine; @Before - public void setUp() { + public void setUp() throws Exception { droolsEngine = new DroolsEngine(); - this.kconf = KnowledgeBaseFactory.newKnowledgeBaseConfiguration(); - this.kconf.setOption(EventProcessingOption.STREAM); - this.kconf.setProperty("drools.assertBehaviour", "equality"); - this.kbase = KnowledgeBaseFactory.newKnowledgeBase("D-ENGINE", this.kconf); - this.ksession = kbase.newStatefulKnowledgeSession(); + 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(); ruleMgtWrapper = PowerMock.createMock(RuleMgtWrapper.class); Whitebox.setInternalState(droolsEngine, "ruleMgtWrapper", ruleMgtWrapper); - Whitebox.setInternalState(droolsEngine, "kconf", kconf); - Whitebox.setInternalState(droolsEngine, "kbase", kbase); - Whitebox.setInternalState(droolsEngine, "ksession", ksession); + 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); PowerMock.resetAll(); } @@ -87,7 +97,7 @@ public class DroolsEngineTest { List rules = new ArrayList(); CorrelationRule rule = new CorrelationRule(); - rule.setContent("content"); + rule.setContent("package content"); rule.setClosedControlLoopName("test"); rule.setPackageName("org.onap.holmes"); rules.add(rule); diff --git a/pom.xml b/pom.xml index b01c61e..3d84112 100644 --- a/pom.xml +++ b/pom.xml @@ -76,6 +76,17 @@ org.onap.msb.java-sdk msb-java-sdk 1.1.0-SNAPSHOT + + + com.eclipsesource.jaxrs + jersey-all + + + + + com.eclipsesource.jaxrs + jersey-all + 2.8 org.reflections -- 2.16.6