2 * ============LICENSE_START=======================================================
3 * feature-active-standby-management
4 * ================================================================================
5 * Copyright (C) 2017-2019 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
11 * http://www.apache.org/licenses/LICENSE-2.0
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=========================================================
21 package org.onap.policy.drools.controller.test;
23 import static org.junit.Assert.assertTrue;
26 import java.io.FileInputStream;
27 import java.util.Date;
28 import java.util.Properties;
29 import java.util.function.Supplier;
30 import javax.persistence.EntityManager;
31 import javax.persistence.EntityManagerFactory;
32 import javax.persistence.EntityTransaction;
33 import javax.persistence.Persistence;
34 import org.apache.commons.lang3.time.DateUtils;
35 import org.junit.After;
36 import org.junit.AfterClass;
37 import org.junit.Before;
38 import org.junit.BeforeClass;
39 import org.junit.Test;
40 import org.onap.policy.common.im.StateManagement;
41 import org.onap.policy.drools.activestandby.ActiveStandbyFeatureApi;
42 import org.onap.policy.drools.activestandby.ActiveStandbyFeatureApiConstants;
43 import org.onap.policy.drools.activestandby.ActiveStandbyProperties;
44 import org.onap.policy.drools.activestandby.DroolsPdpEntity;
45 import org.onap.policy.drools.activestandby.DroolsPdpImpl;
46 import org.onap.policy.drools.activestandby.DroolsPdpsConnector;
47 import org.onap.policy.drools.activestandby.DroolsPdpsElectionHandler;
48 import org.onap.policy.drools.activestandby.JpaDroolsPdpsConnector;
49 import org.onap.policy.drools.core.PolicySessionFeatureApi;
50 import org.onap.policy.drools.statemanagement.StateManagementFeatureApi;
51 import org.onap.policy.drools.statemanagement.StateManagementFeatureApiConstants;
52 import org.slf4j.Logger;
53 import org.slf4j.LoggerFactory;
56 * Testing the allSeemsWell interface to verify that it correctly affects the
60 public class AllSeemsWellTest {
61 private static final Logger logger = LoggerFactory.getLogger(AllSeemsWellTest.class);
63 * Currently, the DroolsPdpsElectionHandler.DesignationWaiter is invoked every 1 seconds, starting
64 * at the start of the next multiple of pdpUpdateInterval, but with a minimum of 5 sec cushion
65 * to ensure that we wait for the DesignationWaiter to do its job, before
66 * checking the results. Add a few seconds for safety
69 private static int SLEEP_TIME_SEC = 10;
72 * DroolsPdpsElectionHandler runs every 1 seconds, so it takes 10 seconds for the
73 * checkWaitTimer() method to time out and call allSeemsWell which then requires
74 * the forward progress counter to go stale which should add an additional 5 sec.
77 private static int STALLED_ELECTION_HANDLER_SLEEP_TIME_SEC = 15;
80 * As soon as the election hander successfully runs, it will resume the forward progress.
81 * If the election handler runs ever 1 sec and test transaction is run every 1 sec and
82 * then fpc is written every 1 sec and then the fpc is checked every 2 sec, that could
83 * take a total of 5 sec to recognize the resumption of progress. So, add 1 for safety.
85 private static int RESUMED_ELECTION_HANDLER_SLEEP_TIME_SEC = 6;
87 private static EntityManagerFactory emfx;
88 private static EntityManagerFactory emfd;
89 private static EntityManager emx;
90 private static EntityManager emd;
91 private static EntityTransaction et;
93 private final String configDir = "src/test/resources/asw";
96 * See the IntegrityMonitor.getJmxUrl() method for the rationale behind this jmx related processing.
102 * @throws Exception exception
105 public static void setUpClass() throws Exception {
107 String userDir = System.getProperty("user.dir");
108 logger.debug("setUpClass: userDir={}", userDir);
109 System.setProperty("com.sun.management.jmxremote.port", "9980");
110 System.setProperty("com.sun.management.jmxremote.authenticate","false");
114 public static void tearDownClass() throws Exception {
120 * @throws Exception exception
123 public void setUp() throws Exception {
124 //Create teh data access for xaml db
125 Properties stateManagementProperties = new Properties();
126 stateManagementProperties.load(new FileInputStream(new File(
127 configDir + "/feature-state-management.properties")));
129 emfx = Persistence.createEntityManagerFactory("junitXacmlPU", stateManagementProperties);
131 // Create an entity manager to use the DB
132 emx = emfx.createEntityManager();
134 //Create the data access for drools db
135 Properties activeStandbyProperties = new Properties();
136 activeStandbyProperties.load(new FileInputStream(new File(
137 configDir + "/feature-active-standby-management.properties")));
139 emfd = Persistence.createEntityManagerFactory("junitDroolsPU", activeStandbyProperties);
141 // Create an entity manager to use the DB
142 emd = emfd.createEntityManager();
144 DroolsPdpsElectionHandler.setIsUnitTesting(true);
148 public void tearDown() throws Exception {
153 * Clean the xacml database.
155 public void cleanXacmlDb() {
156 et = emx.getTransaction();
159 // Make sure we leave the DB clean
160 emx.createQuery("DELETE FROM StateManagementEntity").executeUpdate();
161 emx.createQuery("DELETE FROM ResourceRegistrationEntity").executeUpdate();
162 emx.createQuery("DELETE FROM ForwardProgressEntity").executeUpdate();
168 * Clean the drools database.
170 public void cleanDroolsDb() {
171 et = emd.getTransaction();
174 // Make sure we leave the DB clean
175 emd.createQuery("DELETE FROM DroolsPdpEntity").executeUpdate();
181 // Tests hot standby when there is only one PDP.
185 public void testAllSeemsWell() throws Exception {
187 logger.debug("\n\ntestAllSeemsWell: Entering\n\n");
191 logger.debug("testAllSeemsWell: Reading stateManagementProperties");
192 Properties stateManagementProperties = new Properties();
193 stateManagementProperties.load(new FileInputStream(new File(
194 configDir + "/feature-state-management.properties")));
196 logger.debug("testAllSeemsWell: Creating emfXacml");
197 final EntityManagerFactory emfXacml = Persistence.createEntityManagerFactory(
198 "junitXacmlPU", stateManagementProperties);
200 logger.debug("testAllSeemsWell: Reading activeStandbyProperties");
201 Properties activeStandbyProperties = new Properties();
202 activeStandbyProperties.load(new FileInputStream(new File(
203 configDir + "/feature-active-standby-management.properties")));
204 final String thisPdpId = activeStandbyProperties
205 .getProperty(ActiveStandbyProperties.NODE_NAME);
207 logger.debug("testAllSeemsWell: Creating emfDrools");
208 EntityManagerFactory emfDrools = Persistence.createEntityManagerFactory(
209 "junitDroolsPU", activeStandbyProperties);
211 DroolsPdpsConnector conn = new JpaDroolsPdpsConnector(emfDrools);
213 logger.debug("testAllSeemsWell: Cleaning up tables");
214 conn.deleteAllPdps();
217 * Insert this PDP as not designated. Initial standby state will be
218 * either null or cold standby. Demoting should transit state to
222 logger.debug("testAllSeemsWell: Inserting PDP={} as not designated", thisPdpId);
223 Date yesterday = DateUtils.addDays(new Date(), -1);
224 DroolsPdpImpl pdp = new DroolsPdpImpl(thisPdpId, false, 4, yesterday);
226 DroolsPdpEntity droolsPdpEntity = conn.getPdp(thisPdpId);
227 logger.debug("testAllSeemsWell: After insertion, PDP={} has DESIGNATED={}",
228 thisPdpId, droolsPdpEntity.isDesignated());
229 assertTrue(droolsPdpEntity.isDesignated() == false);
231 logger.debug("testAllSeemsWell: Instantiating stateManagement object");
232 StateManagement sm = new StateManagement(emfXacml, "dummy");
233 sm.deleteAllStateManagementEntities();
236 // Now we want to create a StateManagementFeature and initialize it. It will be
237 // discovered by the ActiveStandbyFeature when the election handler initializes.
239 StateManagementFeatureApi stateManagementFeatureApi = null;
240 for (StateManagementFeatureApi feature : StateManagementFeatureApiConstants.getImpl().getList()) {
241 ((PolicySessionFeatureApi) feature).globalInit(null, configDir);
242 stateManagementFeatureApi = feature;
243 logger.debug("testAllSeemsWell stateManagementFeature.getResourceName(): {}",
244 stateManagementFeatureApi.getResourceName());
247 if (stateManagementFeatureApi == null) {
248 logger.error("testAllSeemsWell failed to initialize. "
249 + "Unable to get instance of StateManagementFeatureApi "
250 + "with resourceID: {}", thisPdpId);
251 logger.debug("testAllSeemsWell failed to initialize. "
252 + "Unable to get instance of StateManagementFeatureApi "
253 + "with resourceID: {}", thisPdpId);
255 final StateManagementFeatureApi smf = stateManagementFeatureApi;
257 // Create an ActiveStandbyFeature and initialize it. It will discover the StateManagementFeature
258 // that has been created.
259 ActiveStandbyFeatureApi activeStandbyFeature = null;
260 for (ActiveStandbyFeatureApi feature : ActiveStandbyFeatureApiConstants.getImpl().getList()) {
261 ((PolicySessionFeatureApi) feature).globalInit(null, configDir);
262 activeStandbyFeature = feature;
263 logger.debug("testAllSeemsWell activeStandbyFeature.getResourceName(): {}",
264 activeStandbyFeature.getResourceName());
267 if (activeStandbyFeature == null) {
268 logger.error("testAllSeemsWell failed to initialize. "
269 + "Unable to get instance of ActiveStandbyFeatureAPI "
270 + "with resourceID: {}", thisPdpId);
271 logger.debug("testAllSeemsWell failed to initialize. "
272 + "Unable to get instance of ActiveStandbyFeatureAPI "
273 + "with resourceID: {}", thisPdpId);
277 logger.debug("testAllSeemsWell: Demoting PDP={}", thisPdpId);
278 // demoting should cause state to transit to hotstandby
282 logger.debug("testAllSeemsWell: Sleeping {} s, to allow JpaDroolsPdpsConnector "
283 + "time to check droolspdpentity table", SLEEP_TIME_SEC);
284 waitForCondition(() -> conn.getPdp(thisPdpId).isDesignated(), SLEEP_TIME_SEC);
286 // Verify that this formerly un-designated PDP in HOT_STANDBY is now designated and providing service.
288 droolsPdpEntity = conn.getPdp(thisPdpId);
289 logger.debug("testAllSeemsWell: After sm.demote() invoked, DESIGNATED= {} "
290 + "for PDP= {}", droolsPdpEntity.isDesignated(), thisPdpId);
291 assertTrue(droolsPdpEntity.isDesignated() == true);
292 String standbyStatus = smf.getStandbyStatus(thisPdpId);
293 logger.debug("testAllSeemsWell: After demotion, PDP= {} "
294 + "has standbyStatus= {}", thisPdpId, standbyStatus);
295 assertTrue(standbyStatus != null && standbyStatus.equals(StateManagement.PROVIDING_SERVICE));
297 //Now we want to stall the election handler and see the if AllSeemsWell will make the
298 //standbystatus = coldstandby
300 DroolsPdpsElectionHandler.setIsStalled(true);
302 logger.debug("testAllSeemsWell: Sleeping {} s, to allow checkWaitTimer to recognize "
303 + "the election handler has stalled and for the testTransaction to fail to "
304 + "increment forward progress and for the lack of forward progress to be recognized.",
305 STALLED_ELECTION_HANDLER_SLEEP_TIME_SEC);
308 //It takes 10x the update interval (1 sec) before the watcher will declare the election handler dead
309 //and that just stops forward progress counter. So, the fp monitor must then run to determine
310 // if the fpc has stalled. That will take about another 5 sec.
311 waitForCondition(() -> smf.getStandbyStatus().equals(StateManagement.COLD_STANDBY),
312 STALLED_ELECTION_HANDLER_SLEEP_TIME_SEC);
314 logger.debug("testAllSeemsWell: After isStalled=true, PDP= {} "
315 + "has standbyStatus= {}", thisPdpId, smf.getStandbyStatus(thisPdpId));
317 assertTrue(smf.getStandbyStatus().equals(StateManagement.COLD_STANDBY));
319 //Now lets resume the election handler
320 DroolsPdpsElectionHandler.setIsStalled(false);
322 waitForCondition(() -> smf.getStandbyStatus().equals(StateManagement.PROVIDING_SERVICE),
323 RESUMED_ELECTION_HANDLER_SLEEP_TIME_SEC);
325 logger.debug("testAllSeemsWell: After isStalled=false, PDP= {} "
326 + "has standbyStatus= {}", thisPdpId, smf.getStandbyStatus(thisPdpId));
328 assertTrue(smf.getStandbyStatus().equals(StateManagement.PROVIDING_SERVICE));
330 //resumedElectionHandlerSleepTime = 5000;
331 logger.debug("\n\ntestAllSeemsWell: Exiting\n\n");
335 private void waitForCondition(Supplier<Boolean> testCondition, int timeoutInSeconds) throws InterruptedException {
336 int maxIterations = timeoutInSeconds * 10;
338 while (!testCondition.get() && iterations < maxIterations) {