5ccf29b7acf8f24c56255c71c841e2cfbfab078d
[holmes/engine-management.git] / engine-d / src / main / java / org / onap / holmes / engine / manager / DroolsEngine.java
1 /**\r
2  * Copyright 2017 ZTE Corporation.\r
3  *\r
4  * Licensed under the Apache License, Version 2.0 (the "License");\r
5  * you may not use this file except in compliance with the License.\r
6  * You may obtain a copy of the License at\r
7  *\r
8  * http://www.apache.org/licenses/LICENSE-2.0\r
9  *\r
10  * Unless required by applicable law or agreed to in writing, software\r
11  * distributed under the License is distributed on an "AS IS" BASIS,\r
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
13  * See the License for the specific language governing permissions and\r
14  * limitations under the License.\r
15  */\r
16 package org.onap.holmes.engine.manager;\r
17 \r
18 \r
19 import java.io.StringReader;\r
20 import java.util.HashSet;\r
21 import java.util.List;\r
22 import java.util.Locale;\r
23 import java.util.Set;\r
24 import javax.annotation.PostConstruct;\r
25 import javax.inject.Inject;\r
26 import lombok.extern.slf4j.Slf4j;\r
27 import org.drools.KnowledgeBase;\r
28 import org.drools.KnowledgeBaseConfiguration;\r
29 import org.drools.KnowledgeBaseFactory;\r
30 import org.drools.builder.KnowledgeBuilder;\r
31 import org.drools.builder.KnowledgeBuilderFactory;\r
32 import org.drools.builder.ResourceType;\r
33 import org.drools.conf.EventProcessingOption;\r
34 import org.drools.definition.KnowledgePackage;\r
35 import org.drools.io.Resource;\r
36 import org.drools.io.ResourceFactory;\r
37 import org.drools.runtime.StatefulKnowledgeSession;\r
38 import org.drools.runtime.rule.FactHandle;\r
39 import org.jvnet.hk2.annotations.Service;\r
40 import org.onap.holmes.common.api.stat.VesAlarm;\r
41 import org.onap.holmes.engine.request.DeployRuleRequest;\r
42 import org.onap.holmes.common.api.entity.CorrelationRule;\r
43 import org.onap.holmes.common.exception.CorrelationException;\r
44 import org.onap.holmes.common.utils.ExceptionUtil;\r
45 import org.onap.holmes.engine.wrapper.RuleMgtWrapper;\r
46 \r
47 @Slf4j\r
48 @Service\r
49 public class DroolsEngine {\r
50 \r
51     private final static int ENABLE = 1;\r
52     private final Set<String> packageNames = new HashSet<String>();\r
53     @Inject\r
54     private RuleMgtWrapper ruleMgtWrapper;\r
55     private KnowledgeBase kbase;\r
56     private KnowledgeBaseConfiguration kconf;\r
57     private StatefulKnowledgeSession ksession;\r
58 \r
59     @PostConstruct\r
60     private void init() {\r
61         try {\r
62             // start engine\r
63             start();\r
64         } catch (Exception e) {\r
65             log.error("Failed to start the service: " + e.getMessage(), e);\r
66             throw ExceptionUtil.buildExceptionResponse("Failed to start the drools engine!");\r
67         }\r
68     }\r
69 \r
70     private void start() throws CorrelationException {\r
71         log.info("Drools Engine Initialize Beginning...");\r
72 \r
73         initEngineParameter();\r
74         initDeployRule();\r
75 \r
76         log.info("Business Rule Engine Initialize Successfully.");\r
77     }\r
78 \r
79     public void stop() {\r
80         this.ksession.dispose();\r
81     }\r
82 \r
83     private void initEngineParameter() {\r
84         this.kconf = KnowledgeBaseFactory.newKnowledgeBaseConfiguration();\r
85 \r
86         this.kconf.setOption(EventProcessingOption.STREAM);\r
87 \r
88         this.kconf.setProperty("drools.assertBehaviour", "equality");\r
89 \r
90         this.kbase = KnowledgeBaseFactory.newKnowledgeBase("D-ENGINE", this.kconf);\r
91 \r
92         this.ksession = kbase.newStatefulKnowledgeSession();\r
93     }\r
94 \r
95     private void initDeployRule() throws CorrelationException {\r
96         List<CorrelationRule> rules = ruleMgtWrapper.queryRuleByEnable(ENABLE);\r
97 \r
98         if (rules.isEmpty()) {\r
99             return;\r
100         }\r
101         for (CorrelationRule rule : rules) {\r
102             if (rule.getContent() != null) {\r
103                 deployRuleFromDB(rule.getContent());\r
104             }\r
105         }\r
106     }\r
107 \r
108     private void deployRuleFromDB(String ruleContent) throws CorrelationException {\r
109         StringReader reader = new StringReader(ruleContent);\r
110         Resource res = ResourceFactory.newReaderResource(reader);\r
111 \r
112         KnowledgeBuilder kbuilder = KnowledgeBuilderFactory.newKnowledgeBuilder();\r
113 \r
114         kbuilder.add(res, ResourceType.DRL);\r
115 \r
116         try {\r
117 \r
118             kbase.addKnowledgePackages(kbuilder.getKnowledgePackages());\r
119         } catch (Exception e) {\r
120             throw new CorrelationException(e.getMessage(), e);\r
121         }\r
122         ksession.fireAllRules();\r
123     }\r
124 \r
125     public synchronized String deployRule(DeployRuleRequest rule, Locale locale)\r
126         throws CorrelationException {\r
127         StringReader reader = new StringReader(rule.getContent());\r
128         Resource res = ResourceFactory.newReaderResource(reader);\r
129 \r
130         KnowledgeBuilder kbuilder = KnowledgeBuilderFactory.newKnowledgeBuilder();\r
131 \r
132         kbuilder.add(res, ResourceType.DRL);\r
133 \r
134         judgeRuleContent(locale, kbuilder, true);\r
135 \r
136         String packageName = kbuilder.getKnowledgePackages().iterator().next().getName();\r
137         try {\r
138             packageNames.add(packageName);\r
139             kbase.addKnowledgePackages(kbuilder.getKnowledgePackages());\r
140         } catch (Exception e) {\r
141             throw new CorrelationException("Failed to deploy the rule.", e);\r
142         }\r
143 \r
144         ksession.fireAllRules();\r
145         return packageName;\r
146     }\r
147 \r
148     public synchronized void undeployRule(String packageName, Locale locale)\r
149         throws CorrelationException {\r
150 \r
151         KnowledgePackage pkg = kbase.getKnowledgePackage(packageName);\r
152 \r
153         if (null == pkg) {\r
154             throw new CorrelationException("The rule " + packageName + " does not exist!");\r
155         }\r
156 \r
157         try {\r
158             kbase.removeKnowledgePackage(pkg.getName());\r
159         } catch (Exception e) {\r
160             throw new CorrelationException("Failed to delete the rule: " + packageName, e);\r
161         }\r
162         packageNames.remove(pkg.getName());\r
163     }\r
164 \r
165     public void compileRule(String content, Locale locale)\r
166         throws CorrelationException {\r
167         StringReader reader = new StringReader(content);\r
168         Resource res = ResourceFactory.newReaderResource(reader);\r
169 \r
170         KnowledgeBuilder kbuilder = KnowledgeBuilderFactory.newKnowledgeBuilder();\r
171 \r
172         kbuilder.add(res, ResourceType.DRL);\r
173 \r
174         judgeRuleContent(locale, kbuilder, false);\r
175     }\r
176 \r
177     private void judgeRuleContent(Locale locale, KnowledgeBuilder kbuilder, boolean judgePackageName)\r
178         throws CorrelationException {\r
179         if (kbuilder.hasErrors()) {\r
180             String errorMsg = "There are errors in the rule: " + kbuilder.getErrors().toString();\r
181             log.error(errorMsg);\r
182             throw new CorrelationException(errorMsg);\r
183         }\r
184 \r
185         String packageName = kbuilder.getKnowledgePackages().iterator().next().getName();\r
186 \r
187         if (packageNames.contains(packageName) && judgePackageName) {\r
188             throw new CorrelationException("The rule " + packageName + " already exists in the drools engine.");\r
189         }\r
190     }\r
191 \r
192     public void putRaisedIntoStream(VesAlarm raiseAlarm) {\r
193         FactHandle factHandle = this.ksession.getFactHandle(raiseAlarm);\r
194         if (factHandle != null) {\r
195             Object obj = this.ksession.getObject(factHandle);\r
196             if (obj != null && obj instanceof VesAlarm) {\r
197                 raiseAlarm.setRootFlag(((VesAlarm) obj).getRootFlag());\r
198             }\r
199             this.ksession.retract(factHandle);\r
200         }\r
201         this.ksession.insert(raiseAlarm);\r
202         this.ksession.fireAllRules();\r
203     }\r
204 \r
205 }\r