2ecea5e1bd8fb6991bb694c50b41d1c3d47167ea
[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.common.dmaap.DmaapService;\r
42 import org.onap.holmes.engine.request.DeployRuleRequest;\r
43 import org.onap.holmes.common.api.entity.CorrelationRule;\r
44 import org.onap.holmes.common.exception.CorrelationException;\r
45 import org.onap.holmes.common.utils.ExceptionUtil;\r
46 import org.onap.holmes.engine.wrapper.RuleMgtWrapper;\r
47 \r
48 @Slf4j\r
49 @Service\r
50 public class DroolsEngine {\r
51 \r
52     private final static int ENABLE = 1;\r
53     private final Set<String> packageNames = new HashSet<String>();\r
54     @Inject\r
55     private RuleMgtWrapper ruleMgtWrapper;\r
56     private KnowledgeBase kbase;\r
57     private KnowledgeBaseConfiguration kconf;\r
58     private StatefulKnowledgeSession ksession;\r
59 \r
60     @PostConstruct\r
61     private void init() {\r
62         try {\r
63             // start engine\r
64             start();\r
65         } catch (Exception e) {\r
66             log.error("Failed to start the service: " + e.getMessage(), e);\r
67             throw ExceptionUtil.buildExceptionResponse("Failed to start the drools engine!");\r
68         }\r
69     }\r
70 \r
71     private void start() throws CorrelationException {\r
72         log.info("Drools Engine Initialize Beginning...");\r
73 \r
74         initEngineParameter();\r
75         initDeployRule();\r
76 \r
77         log.info("Business Rule Engine Initialize Successfully.");\r
78     }\r
79 \r
80     public void stop() {\r
81         this.ksession.dispose();\r
82     }\r
83 \r
84     private void initEngineParameter() {\r
85         this.kconf = KnowledgeBaseFactory.newKnowledgeBaseConfiguration();\r
86 \r
87         this.kconf.setOption(EventProcessingOption.STREAM);\r
88 \r
89         this.kconf.setProperty("drools.assertBehaviour", "equality");\r
90 \r
91         this.kbase = KnowledgeBaseFactory.newKnowledgeBase("D-ENGINE", this.kconf);\r
92 \r
93         this.ksession = kbase.newStatefulKnowledgeSession();\r
94     }\r
95 \r
96     private void initDeployRule() throws CorrelationException {\r
97         List<CorrelationRule> rules = ruleMgtWrapper.queryRuleByEnable(ENABLE);\r
98 \r
99         if (rules.isEmpty()) {\r
100             return;\r
101         }\r
102         for (CorrelationRule rule : rules) {\r
103             if (rule.getContent() != null) {\r
104                 deployRuleFromDB(rule.getContent());\r
105                 DmaapService.loopControlNames.put(rule.getPackageName(), rule.getClosedControlLoopName());\r
106             }\r
107         }\r
108     }\r
109 \r
110     private void deployRuleFromDB(String ruleContent) throws CorrelationException {\r
111         StringReader reader = new StringReader(ruleContent);\r
112         Resource res = ResourceFactory.newReaderResource(reader);\r
113 \r
114         KnowledgeBuilder kbuilder = KnowledgeBuilderFactory.newKnowledgeBuilder();\r
115 \r
116         kbuilder.add(res, ResourceType.DRL);\r
117 \r
118         try {\r
119 \r
120             kbase.addKnowledgePackages(kbuilder.getKnowledgePackages());\r
121         } catch (Exception e) {\r
122             throw new CorrelationException(e.getMessage(), e);\r
123         }\r
124         ksession.fireAllRules();\r
125     }\r
126 \r
127     public synchronized String deployRule(DeployRuleRequest rule, Locale locale)\r
128         throws CorrelationException {\r
129         StringReader reader = new StringReader(rule.getContent());\r
130         Resource res = ResourceFactory.newReaderResource(reader);\r
131 \r
132         KnowledgeBuilder kbuilder = KnowledgeBuilderFactory.newKnowledgeBuilder();\r
133 \r
134         kbuilder.add(res, ResourceType.DRL);\r
135 \r
136         judgeRuleContent(locale, kbuilder, true);\r
137 \r
138         String packageName = kbuilder.getKnowledgePackages().iterator().next().getName();\r
139         try {\r
140             packageNames.add(packageName);\r
141             kbase.addKnowledgePackages(kbuilder.getKnowledgePackages());\r
142         } catch (Exception e) {\r
143             throw new CorrelationException("Failed to deploy the rule.", e);\r
144         }\r
145 \r
146         ksession.fireAllRules();\r
147         return packageName;\r
148     }\r
149 \r
150     public synchronized void undeployRule(String packageName, Locale locale)\r
151         throws CorrelationException {\r
152 \r
153         KnowledgePackage pkg = kbase.getKnowledgePackage(packageName);\r
154 \r
155         if (null == pkg) {\r
156             throw new CorrelationException("The rule " + packageName + " does not exist!");\r
157         }\r
158 \r
159         try {\r
160             kbase.removeKnowledgePackage(pkg.getName());\r
161         } catch (Exception e) {\r
162             throw new CorrelationException("Failed to delete the rule: " + packageName, e);\r
163         }\r
164         packageNames.remove(pkg.getName());\r
165     }\r
166 \r
167     public void compileRule(String content, Locale locale)\r
168         throws CorrelationException {\r
169         StringReader reader = new StringReader(content);\r
170         Resource res = ResourceFactory.newReaderResource(reader);\r
171 \r
172         KnowledgeBuilder kbuilder = KnowledgeBuilderFactory.newKnowledgeBuilder();\r
173 \r
174         kbuilder.add(res, ResourceType.DRL);\r
175 \r
176         judgeRuleContent(locale, kbuilder, false);\r
177     }\r
178 \r
179     private void judgeRuleContent(Locale locale, KnowledgeBuilder kbuilder, boolean judgePackageName)\r
180         throws CorrelationException {\r
181         if (kbuilder.hasErrors()) {\r
182             String errorMsg = "There are errors in the rule: " + kbuilder.getErrors().toString();\r
183             log.error(errorMsg);\r
184             throw new CorrelationException(errorMsg);\r
185         }\r
186 \r
187         String packageName = kbuilder.getKnowledgePackages().iterator().next().getName();\r
188 \r
189         if (packageNames.contains(packageName) && judgePackageName) {\r
190             throw new CorrelationException("The rule " + packageName + " already exists in the drools engine.");\r
191         }\r
192     }\r
193 \r
194     public void putRaisedIntoStream(VesAlarm raiseAlarm) {\r
195         FactHandle factHandle = this.ksession.getFactHandle(raiseAlarm);\r
196         if (factHandle != null) {\r
197             Object obj = this.ksession.getObject(factHandle);\r
198             if (obj != null && obj instanceof VesAlarm) {\r
199                 raiseAlarm.setRootFlag(((VesAlarm) obj).getRootFlag());\r
200             }\r
201             this.ksession.retract(factHandle);\r
202         }\r
203         this.ksession.insert(raiseAlarm);\r
204         this.ksession.fireAllRules();\r
205     }\r
206 \r
207 }\r