f3c6e058d4710d7b004830283a5097e6eb4fa1f6
[policy/drools-applications.git] /
1 /*-
2  * ============LICENSE_START=======================================================
3  * demo
4  * ================================================================================
5  * Copyright (C) 2018 AT&T Intellectual Property. All rights reserved.
6  * ================================================================================
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  *
11  *      http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  * ============LICENSE_END=========================================================
19  */
20
21 package org.onap.policy.template.demo;
22
23 import static org.junit.Assert.assertEquals;
24 import static org.junit.Assert.assertNotNull;
25 import static org.junit.Assert.assertTrue;
26 import static org.junit.Assert.fail;
27
28 import java.io.IOException;
29 import java.io.UnsupportedEncodingException;
30 import java.net.URLEncoder;
31 import java.util.Iterator;
32 import java.util.LinkedList;
33 import java.util.List;
34 import org.junit.AfterClass;
35 import org.junit.BeforeClass;
36 import org.junit.Test;
37 import org.kie.api.runtime.KieSession;
38 import org.onap.policy.controlloop.policy.ControlLoopPolicy;
39 import org.onap.policy.drools.utils.logging.LoggerUtil;
40 import org.onap.policy.template.demo.Util.Pair;
41 import org.slf4j.Logger;
42 import org.slf4j.LoggerFactory;
43
44 /**
45  * Verifies that Params objects are cleaned up when rules are updated. This loads
46  * <b>two</b> copies of the rule set into a single policy to ensure that the two copies
47  * interact appropriately with each other's Params objects.
48  */
49 public class ControlLoopParamsCleanupTest {
50     private static final Logger logger = LoggerFactory.getLogger(ControlLoopParamsCleanupTest.class);
51
52     private static final String YAML = "src/test/resources/yaml/policy_ControlLoop_ParamsCleanup-test.yaml";
53
54     /**
55      * YAML to be used when the first rule set is updated.
56      */
57     private static final String YAML2 = "src/test/resources/yaml/policy_ControlLoop_ParamsCleanup-test2.yaml";
58
59     private static final String POLICY_VERSION = "v2.0";
60
61     private static final String POLICY_NAME = "CL_CleanupTest";
62
63     private static final String POLICY_SCOPE = "type=operational";
64
65     private static final String CONTROL_LOOP_NAME = "ControlLoop-Params-Cleanup-Test";
66
67     private static final String DROOLS_TEMPLATE = "../archetype-cl-amsterdam/src/main/resources/archetype-resources/"
68                     + "src/main/resources/__closedLoopControlName__.drl";
69
70     // values specific to the second copy of the rules
71
72     private static final String YAML_B = "src/test/resources/yaml/policy_ControlLoop_ParamsCleanup-test-B.yaml";
73     private static final String POLICY_NAME_B = "CL_CleanupTest_B";
74     private static final String CONTROL_LOOP_NAME_B = "ControlLoop-Params-Cleanup-Test-B";
75
76     private static KieSession kieSession;
77     private static Util.RuleSpec[] specifications;
78
79     /**
80      * Setup the simulator.
81      */
82     @BeforeClass
83     public static void setUpSimulator() {
84         LoggerUtil.setLevel(LoggerUtil.ROOT_LOGGER, "INFO");
85
86         try {
87             specifications = new Util.RuleSpec[2];
88
89             specifications[0] = new Util.RuleSpec(DROOLS_TEMPLATE, CONTROL_LOOP_NAME, POLICY_SCOPE, POLICY_NAME,
90                             POLICY_VERSION, loadYaml(YAML));
91
92             specifications[1] = new Util.RuleSpec(DROOLS_TEMPLATE, CONTROL_LOOP_NAME_B, POLICY_SCOPE, POLICY_NAME_B,
93                             POLICY_VERSION, loadYaml(YAML_B));
94
95             kieSession = Util.buildContainer(POLICY_VERSION, specifications);
96
97         } catch (IOException e) {
98             logger.error("Could not create kieSession", e);
99             fail("Could not create kieSession");
100         }
101     }
102
103     /**
104      * Tear down.
105      */
106     @AfterClass
107     public static void tearDown() {
108         kieSession.dispose();
109     }
110
111     @Test
112     public void test() throws IOException {
113
114         /*
115          * Let rules create Params objects. There should be one object for each set of
116          * rules.
117          */
118         kieSession.fireAllRules();
119         List<Object> facts = getSessionObjects();
120         assertEquals(specifications.length, facts.size());
121         Iterator<Object> iter = facts.iterator();
122
123         final Object fact1 = iter.next();
124         assertTrue(fact1.toString().contains(loadYaml(YAML)));
125
126         final Object fact1b = iter.next();
127         assertTrue(fact1b.toString().contains(loadYaml(YAML_B)));
128
129         logger.info("UPDATING VERSION TO v3.0");
130         updatePolicy(YAML2, "v3.0");
131
132         /*
133          * Let rules update Params objects. The Params for the first set of rules should
134          * now be deleted and replaced with a new one, while the Params for the second set
135          * should be unchanged.
136          */
137         kieSession.fireAllRules();
138         facts = getSessionObjects();
139         assertEquals(specifications.length, facts.size());
140         iter = facts.iterator();
141
142         final Object fact2 = iter.next();
143         assertTrue(fact2 != fact1);
144         assertTrue(fact2 != fact1b);
145         assertTrue(fact2.toString().contains(loadYaml(YAML2)));
146
147         assertTrue(iter.next() == fact1b);
148
149         logger.info("UPDATING VERSION TO v4.0");
150         updatePolicy(YAML, "v4.0");
151
152         /*
153          * Let rules update Params objects. The Params for the first set of rules should
154          * now be deleted and replaced with a new one, while the Params for the second set
155          * should be unchanged.
156          */
157         kieSession.fireAllRules();
158         facts = getSessionObjects();
159         assertEquals(specifications.length, facts.size());
160         iter = facts.iterator();
161
162         final Object fact3 = iter.next();
163         assertTrue(fact3.toString().contains(loadYaml(YAML)));
164         assertTrue(fact3 != fact2);
165         assertTrue(fact3 != fact1b);
166
167         assertTrue(iter.next() == fact1b);
168
169         logger.info("UPDATING VERSION TO v4.0 (i.e., unchanged)");
170         updatePolicy(YAML, "v4.0");
171
172         /*
173          * Let rules update Params objects. As the version (and YAML) are unchanged for
174          * either rule set, both Params objects should be unchanged.
175          */
176         kieSession.fireAllRules();
177         facts = getSessionObjects();
178         assertEquals(specifications.length, facts.size());
179         iter = facts.iterator();
180         assertTrue(iter.next() == fact3);
181         assertTrue(iter.next() == fact1b);
182         
183         /*
184          * Now we'll delete the first rule set.  That won't actually have any immediate
185          * effect, so then we'll update the second rule set, which should trigger a
186          * clean-up of both.
187          */
188         Util.RuleSpec[] specs = new Util.RuleSpec[1];
189         specs[0] = specifications[1];
190
191         logger.info("UPDATING VERSION TO v5.0 - DELETED RULE SET");
192         Util.updateContainer("v5.0", specs);
193
194         specs[0] = new Util.RuleSpec(DROOLS_TEMPLATE, CONTROL_LOOP_NAME_B, POLICY_SCOPE, POLICY_NAME_B,
195                         POLICY_VERSION, loadYaml(YAML));
196         
197         logger.info("UPDATING VERSION TO v6.0 - UPDATED SECOND RULE SET");
198         Util.updateContainer("v6.0", specs);
199         
200         kieSession.fireAllRules();
201         facts = getSessionObjects();
202         assertEquals(specs.length, facts.size());
203         iter = facts.iterator();
204         assertTrue(iter.next().toString().contains(CONTROL_LOOP_NAME_B));
205     }
206
207     /**
208      * Updates the policy, changing the YAML associated with the first rule set.
209      *
210      * @param yamlFile name of the YAML file
211      * @param policyVersion policy version
212      * @throws IOException if an error occurs
213      */
214     private static void updatePolicy(String yamlFile, String policyVersion) throws IOException {
215
216         specifications[0] = new Util.RuleSpec(DROOLS_TEMPLATE, CONTROL_LOOP_NAME, POLICY_SCOPE, POLICY_NAME,
217                         policyVersion, loadYaml(yamlFile));
218
219         /*
220          * Update the policy within the container.
221          */
222         Util.updateContainer(policyVersion, specifications);
223     }
224
225     /**
226      * Loads a YAML file and URL-encodes it.
227      *
228      * @param yamlFile name of the YAML file
229      * @return the contents of the specified file, URL-encoded
230      * @throws UnsupportedEncodingException if an error occurs
231      */
232     private static String loadYaml(String yamlFile) throws UnsupportedEncodingException {
233         Pair<ControlLoopPolicy, String> pair = Util.loadYaml(yamlFile);
234         assertNotNull(pair);
235         assertNotNull(pair.first);
236         assertNotNull(pair.first.getControlLoop());
237         assertNotNull(pair.first.getControlLoop().getControlLoopName());
238         assertTrue(pair.first.getControlLoop().getControlLoopName().length() > 0);
239
240         return URLEncoder.encode(pair.second, "UTF-8");
241     }
242
243     /**
244      * Gets the session objects.
245      *
246      * @return the session objects
247      */
248     private static List<Object> getSessionObjects() {
249         // sort the objects so we know the order
250         LinkedList<Object> lst = new LinkedList<>(kieSession.getObjects());
251         lst.sort((left, right) -> left.toString().compareTo(right.toString()));
252
253         return lst;
254     }
255 }