2 * ============LICENSE_START=======================================================
3 * feature-session-persistence
4 * ================================================================================
5 * Copyright (C) 2017 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.persistence;
23 import static org.junit.Assert.assertEquals;
24 import static org.junit.Assert.assertFalse;
25 import static org.junit.Assert.assertNotNull;
26 import static org.junit.Assert.assertNull;
27 import static org.mockito.Matchers.any;
28 import static org.mockito.Matchers.anyInt;
29 import static org.mockito.Matchers.anyLong;
30 import static org.mockito.Matchers.anyString;
31 import static org.mockito.Mockito.mock;
32 import static org.mockito.Mockito.never;
33 import static org.mockito.Mockito.times;
34 import static org.mockito.Mockito.verify;
35 import static org.mockito.Mockito.when;
37 import java.io.FileNotFoundException;
38 import java.io.FileReader;
39 import java.io.IOException;
40 import java.net.UnknownHostException;
41 import java.sql.Connection;
42 import java.sql.DriverManager;
43 import java.sql.PreparedStatement;
44 import java.sql.ResultSet;
45 import java.sql.SQLException;
46 import java.sql.Timestamp;
47 import java.util.ArrayList;
48 import java.util.List;
49 import java.util.Properties;
51 import javax.persistence.EntityManagerFactory;
53 import org.junit.After;
54 import org.junit.AfterClass;
55 import org.junit.Before;
56 import org.junit.BeforeClass;
57 import org.junit.Test;
58 import org.kie.api.KieBase;
59 import org.kie.api.KieServices;
60 import org.kie.api.persistence.jpa.KieStoreServices;
61 import org.kie.api.runtime.Environment;
62 import org.kie.api.runtime.EnvironmentName;
63 import org.kie.api.runtime.KieContainer;
64 import org.kie.api.runtime.KieSession;
65 import org.kie.api.runtime.KieSessionConfiguration;
66 import org.mockito.ArgumentCaptor;
67 import org.onap.policy.drools.persistence.DroolsPersistenceProperties;
68 import org.onap.policy.drools.persistence.DroolsSession;
69 import org.onap.policy.drools.persistence.DroolsSessionConnector;
70 import org.onap.policy.drools.persistence.PersistenceFeature;
71 import org.onap.policy.drools.core.PolicyContainer;
72 import org.onap.policy.drools.core.PolicySession;
73 import org.onap.policy.drools.system.PolicyController;
75 import bitronix.tm.BitronixTransactionManager;
76 import bitronix.tm.Configuration;
77 import bitronix.tm.resource.jdbc.PoolingDataSource;
79 public class PersistenceFeatureTest {
81 private static final String JDBC_DATASRC = "fake.datasource";
82 private static final String JDBC_DRIVER = "fake.driver";
83 private static final String JDBC_URL = "fake.url";
84 private static final String JDBC_USER = "fake.user";
85 private static final String JDBC_PASSWD = "fake.password";
86 private static final String SRC_TEST_RESOURCES = "src/test/resources";
88 private static Properties stdprops;
90 private DroolsSessionConnector jpa;
91 private DroolsSession sess;
92 private PoolingDataSource pds;
93 private KieSession kiesess;
94 private Properties dsprops;
95 private EntityManagerFactory emf;
96 private Connection conn;
97 private Properties props;
98 private KieServices kiesvc;
99 private Environment kieenv;
100 private KieSessionConfiguration kiecfg;
101 private KieBase kiebase;
102 private KieStoreServices kiestore;
103 private KieContainer kiecont;
104 private Configuration bitcfg;
105 private BitronixTransactionManager bittrans;
106 private PolicyController polctlr;
107 private PolicyContainer polcont;
108 private PolicySession polsess;
109 private PersistenceFeature.Factory fact;
111 private PersistenceFeature feat;
115 public static void setUpBeforeClass() throws Exception {
116 stdprops = new Properties();
118 stdprops.put(DroolsPersistenceProperties.DB_DATA_SOURCE, JDBC_DATASRC);
119 stdprops.put(DroolsPersistenceProperties.DB_DRIVER, JDBC_DRIVER);
120 stdprops.put(DroolsPersistenceProperties.DB_URL, JDBC_URL);
121 stdprops.put(DroolsPersistenceProperties.DB_USER, JDBC_USER);
122 stdprops.put(DroolsPersistenceProperties.DB_PWD, JDBC_PASSWD);
123 stdprops.put(DroolsPersistenceProperties.DB_SESSIONINFO_TIMEOUT, "50");
127 public static void tearDownAfterClass() throws Exception {
131 public void setUp() throws Exception {
132 jpa = mock(DroolsSessionConnector.class);
133 sess = mock(DroolsSession.class);
134 pds = mock(PoolingDataSource.class);
135 kiesess = mock(KieSession.class);
136 dsprops = new Properties();
139 props = new Properties();
140 kiesvc = mock(KieServices.class);
141 kieenv = mock(Environment.class);
142 kiecfg = mock(KieSessionConfiguration.class);
143 kiebase = mock(KieBase.class);
144 kiestore = mock(KieStoreServices.class);
145 kiecont = mock(KieContainer.class);
146 bitcfg = mock(Configuration.class);
147 bittrans = mock(BitronixTransactionManager.class);
148 polcont = mock(PolicyContainer.class);
149 polctlr = mock(PolicyController.class);
150 polsess = mock(PolicySession.class);
151 fact = mock(PersistenceFeature.Factory.class);
153 feat = new PersistenceFeature();
154 feat.setFactory(fact);
156 props.putAll(stdprops);
158 when(pds.getUniqueName()).thenReturn("myds");
160 when(fact.getKieServices()).thenReturn(kiesvc);
161 when(fact.getTransMgrConfig()).thenReturn(bitcfg);
162 when(fact.getTransMgr()).thenReturn(bittrans);
163 when(fact.loadProperties(anyString())).thenReturn(props);
165 when(kiesvc.newEnvironment()).thenReturn(kieenv);
166 when(kiesvc.getStoreServices()).thenReturn(kiestore);
167 when(kiesvc.newKieSessionConfiguration()).thenReturn(kiecfg);
169 when(polcont.getKieContainer()).thenReturn(kiecont);
171 when(polsess.getPolicyContainer()).thenReturn(polcont);
173 when(kiecont.getKieBase(anyString())).thenReturn(kiebase);
177 public void tearDown() {
178 // this will cause the in-memory test DB to be dropped
180 try { conn.close(); } catch (SQLException e) { }
184 try { emf.close(); } catch (Exception e) { }
189 public void testGetContainerAdjunct_New() throws Exception {
191 feat.globalInit(null, SRC_TEST_RESOURCES);
194 setUpKie("myname", 999L, true);
196 // force getContainerAdjunct() to be invoked
197 feat.activatePolicySession(polcont, "myname", "mybase");
199 ArgumentCaptor<PersistenceFeature.ContainerAdjunct> adjcap =
200 ArgumentCaptor.forClass(PersistenceFeature.ContainerAdjunct.class);
202 verify(polcont, times(1)).setAdjunct(any(), adjcap.capture());
204 assertNotNull( adjcap.getValue());
208 public void testGetContainerAdjunct_Existing() throws Exception {
210 feat.globalInit(null, SRC_TEST_RESOURCES);
213 setUpKie("myname", 999L, true);
215 // force getContainerAdjunct() to be invoked
216 feat.activatePolicySession(polcont, "myname", "mybase");
218 ArgumentCaptor<PersistenceFeature.ContainerAdjunct> adjcap =
219 ArgumentCaptor.forClass(PersistenceFeature.ContainerAdjunct.class);
221 verify(polcont, times(1)).setAdjunct(any(), adjcap.capture());
223 // return adjunct on next call
224 when(polcont.getAdjunct(any())).thenReturn( adjcap.getValue());
226 // force getContainerAdjunct() to be invoked again
227 setUpKie("myname2", 999L, true);
228 feat.activatePolicySession(polcont, "myname2", "mybase");
230 // ensure it isn't invoked again
231 verify(polcont, times(1)).setAdjunct(any(), any());
235 public void testGetSequenceNumber() {
236 assertEquals(1, feat.getSequenceNumber());
240 public void testGlobalInit() throws Exception {
241 when(fact.getHostName()).thenReturn("myhost");
243 feat.globalInit(null, SRC_TEST_RESOURCES);
245 // verify that various factory methods were invoked
246 verify(fact).getHostName();
247 verify(fact).getKieServices();
248 verify(fact).getTransMgrConfig();
249 verify(fact).loadProperties("src/test/resources/feature-session-persistence.properties");
251 verify(bitcfg).setJournal(null);
252 verify(bitcfg).setServerId("myhost");
256 public void testActivatePolicySession() throws Exception {
257 PreparedStatement ps = mockDbConn(5);
258 setUpKie("myname", 999L, true);
260 feat.globalInit(null, SRC_TEST_RESOURCES);
261 feat.beforeActivate(null);
264 feat.activatePolicySession(polcont, "myname", "mybase");
266 verify(kiestore).loadKieSession(anyLong(), any(), any(), any());
267 verify(kiestore, never()).newKieSession(any(), any(), any());
269 assertEquals(s, kiesess);
271 verify(ps).executeUpdate();
273 verify(kieenv, times(2)).set(anyString(), any());
275 assertFalse( dsprops.isEmpty());
277 verify(jpa).get("myname");
278 verify(jpa).replace(any());
282 public void testActivatePolicySession_NoPersistence() throws Exception {
283 feat.globalInit(null, SRC_TEST_RESOURCES);
285 PreparedStatement ps = mockDbConn(5);
286 setUpKie("myname", 999L, true);
288 props.remove("persistence.type");
290 feat.beforeStart(null);
292 assertNull( feat.activatePolicySession(polcont, "myname", "mybase"));
294 verify(ps, never()).executeUpdate();
295 verify(kiestore, never()).loadKieSession(anyLong(), any(), any(), any());
296 verify(kiestore, never()).newKieSession(any(), any(), any());
300 * Verifies that a new KIE session is created when there is no existing
304 public void testActivatePolicySession_New() throws Exception {
305 feat.globalInit(null, SRC_TEST_RESOURCES);
308 setUpKie("noName", 999L, true);
312 feat.activatePolicySession(polcont, "myname", "mybase");
314 verify(kiestore, never()).loadKieSession(anyLong(), any(), any(), any());
315 verify(kiestore).newKieSession(any(), any(), any());
317 assertEquals(s, kiesess);
319 verify(kieenv, times(2)).set(anyString(), any());
321 assertFalse( dsprops.isEmpty());
323 verify(jpa).get("myname");
324 verify(jpa).replace(any());
328 * Verifies that a new KIE session is created when there KIE fails
329 * to load an existing session.
332 public void testActivatePolicySession_LoadFailed() throws Exception {
333 feat.globalInit(null, SRC_TEST_RESOURCES);
336 setUpKie("myname", 999L, false);
340 feat.activatePolicySession(polcont, "myname", "mybase");
342 verify(kiestore).loadKieSession(anyLong(), any(), any(), any());
343 verify(kiestore).newKieSession(any(), any(), any());
345 assertEquals(s, kiesess);
347 verify(kieenv, times(2)).set(anyString(), any());
349 assertFalse( dsprops.isEmpty());
351 verify(jpa).get("myname");
353 ArgumentCaptor<DroolsSession> d =
354 ArgumentCaptor.forClass(DroolsSession.class);
355 verify(jpa).replace( d.capture());
357 assertEquals("myname", d.getValue().getSessionName());
358 assertEquals(100L, d.getValue().getSessionId());
362 public void testConfigureKieEnv() throws Exception {
363 feat.globalInit(null, SRC_TEST_RESOURCES);
366 setUpKie("myname", 999L, false);
368 feat.activatePolicySession(polcont, "myname", "mybase");
370 verify(kieenv, times(2)).set(any(), any());
372 verify(kieenv).set(EnvironmentName.ENTITY_MANAGER_FACTORY, emf);
373 verify(kieenv).set(EnvironmentName.TRANSACTION_MANAGER, bittrans);
377 public void testInitDataSource() throws Exception {
378 feat.globalInit(null, SRC_TEST_RESOURCES);
381 setUpKie("myname", 999L, false);
383 feat.activatePolicySession(polcont, "myname", "mybase");
385 assertEquals(JDBC_URL, dsprops.getProperty("URL"));
386 assertEquals(JDBC_USER, dsprops.getProperty("user"));
387 assertEquals(JDBC_PASSWD, dsprops.getProperty("password"));
389 verify(pds).setUniqueName("jdbc/BitronixJTADataSource/myname");
390 verify(pds).setClassName(JDBC_DATASRC);
391 verify(pds).setMaxPoolSize(anyInt());
392 verify(pds).setIsolationLevel("SERIALIZABLE");
393 verify(pds).setAllowLocalTransactions(true);
398 public void testLoadKieSession() throws Exception {
399 feat.globalInit(null, SRC_TEST_RESOURCES);
402 setUpKie("myname", 999L, true);
406 feat.activatePolicySession(polcont, "myname", "mybase");
408 verify(kiestore).loadKieSession(999L, kiebase, kiecfg, kieenv);
409 verify(kiestore, never()).newKieSession(any(), any(), any());
411 assertEquals(s, kiesess);
415 * Verifies that loadKieSession() returns null (thus causing newKieSession()
416 * to be called) when an Exception occurs.
419 public void testLoadKieSession_Ex() throws Exception {
420 feat.globalInit(null, SRC_TEST_RESOURCES);
423 setUpKie("myname", 999L, false);
425 when(kiestore.loadKieSession(anyLong(), any(), any(), any()))
426 .thenThrow( new RuntimeException("expected exception"));
430 feat.activatePolicySession(polcont, "myname", "mybase");
432 verify(kiestore).loadKieSession(anyLong(), any(), any(), any());
433 verify(kiestore).newKieSession(any(), any(), any());
435 assertEquals(s, kiesess);
439 public void testNewKieSession() throws Exception {
440 feat.globalInit(null, SRC_TEST_RESOURCES);
443 setUpKie("myname", 999L, false);
447 feat.activatePolicySession(polcont, "myname", "mybase");
449 verify(kiestore).newKieSession(kiebase, null, kieenv);
451 assertEquals(s, kiesess);
455 public void testLoadDataSource_RepeatSameSession() throws Exception {
456 feat.globalInit(null, SRC_TEST_RESOURCES);
459 setUpKie("myname", 999L, false);
461 feat.activatePolicySession(polcont, "myname", "mybase");
463 ArgumentCaptor<PersistenceFeature.ContainerAdjunct> adjcap =
464 ArgumentCaptor.forClass(PersistenceFeature.ContainerAdjunct.class);
466 verify(polcont).setAdjunct(any(), adjcap.capture());
468 when(polcont.getAdjunct(any())).thenReturn( adjcap.getValue());
471 feat.activatePolicySession(polcont, "myname", "mybase");
473 verify(fact, times(1)).makePoolingDataSource();
477 public void testLoadDataSource_DiffSession() throws Exception {
478 feat.globalInit(null, SRC_TEST_RESOURCES);
481 setUpKie("myname", 999L, false);
482 feat.activatePolicySession(polcont, "myname", "mybase");
484 ArgumentCaptor<PersistenceFeature.ContainerAdjunct> adjcap =
485 ArgumentCaptor.forClass(PersistenceFeature.ContainerAdjunct.class);
487 verify(polcont).setAdjunct(any(), adjcap.capture());
489 when(polcont.getAdjunct(any())).thenReturn( adjcap.getValue());
491 setUpKie("myname2", 999L, false);
494 feat.activatePolicySession(polcont, "myname2", "mybase");
496 verify(fact, times(2)).makePoolingDataSource();
500 public void testDisposeKieSession() throws Exception {
501 feat.globalInit(null, SRC_TEST_RESOURCES);
503 ArgumentCaptor<PersistenceFeature.ContainerAdjunct> adjcap =
504 ArgumentCaptor.forClass(PersistenceFeature.ContainerAdjunct.class);
507 setUpKie("myname", 999L, false);
509 feat.activatePolicySession(polcont, "myname", "mybase");
511 verify(pds, never()).close();
512 verify(polcont).setAdjunct(any(), adjcap.capture());
514 when(polcont.getAdjunct(any())).thenReturn( adjcap.getValue());
516 feat.disposeKieSession(polsess);
518 // call twice to ensure it isn't re-closed
519 feat.disposeKieSession(polsess);
521 verify(pds, times(1)).close();
525 public void testDisposeKieSession_NoAdjunct() throws Exception {
526 feat.globalInit(null, SRC_TEST_RESOURCES);
528 feat.disposeKieSession(polsess);
532 public void testDisposeKieSession_NoPersistence() throws Exception {
533 feat.globalInit(null, SRC_TEST_RESOURCES);
535 ArgumentCaptor<PersistenceFeature.ContainerAdjunct> adjcap =
536 ArgumentCaptor.forClass(PersistenceFeature.ContainerAdjunct.class);
539 setUpKie("myname", 999L, false);
541 feat.activatePolicySession(polcont, "myname", "mybase");
543 verify(pds, never()).close();
544 verify(polcont).setAdjunct(any(), adjcap.capture());
546 when(polcont.getAdjunct(any())).thenReturn( adjcap.getValue());
548 // specify a session that was never loaded
549 when(polsess.getName()).thenReturn("anotherName");
551 feat.disposeKieSession(polsess);
553 verify(pds, never()).close();
557 public void testDestroyKieSession() throws Exception {
558 feat.globalInit(null, SRC_TEST_RESOURCES);
560 ArgumentCaptor<PersistenceFeature.ContainerAdjunct> adjcap =
561 ArgumentCaptor.forClass(PersistenceFeature.ContainerAdjunct.class);
564 setUpKie("myname", 999L, false);
566 feat.activatePolicySession(polcont, "myname", "mybase");
568 verify(pds, never()).close();
569 verify(polcont).setAdjunct(any(), adjcap.capture());
571 when(polcont.getAdjunct(any())).thenReturn( adjcap.getValue());
573 feat.destroyKieSession(polsess);
575 // call twice to ensure it isn't re-closed
576 feat.destroyKieSession(polsess);
578 verify(pds, times(1)).close();
582 public void testDestroyKieSession_NoAdjunct() throws Exception {
583 feat.globalInit(null, SRC_TEST_RESOURCES);
585 feat.destroyKieSession(polsess);
589 public void testDestroyKieSession_NoPersistence() throws Exception {
590 feat.globalInit(null, SRC_TEST_RESOURCES);
592 ArgumentCaptor<PersistenceFeature.ContainerAdjunct> adjcap =
593 ArgumentCaptor.forClass(PersistenceFeature.ContainerAdjunct.class);
596 setUpKie("myname", 999L, false);
598 feat.activatePolicySession(polcont, "myname", "mybase");
600 verify(pds, never()).close();
601 verify(polcont).setAdjunct(any(), adjcap.capture());
603 when(polcont.getAdjunct(any())).thenReturn( adjcap.getValue());
605 // specify a session that was never loaded
606 when(polsess.getName()).thenReturn("anotherName");
608 feat.destroyKieSession(polsess);
610 verify(pds, never()).close();
614 public void testAfterStart() {
615 assertFalse( feat.afterStart(null));
619 public void testBeforeStart() {
620 assertFalse( feat.beforeStart(null));
624 public void testBeforeShutdown() {
625 assertFalse( feat.beforeShutdown(null));
629 public void testAfterShutdown() {
630 assertFalse( feat.afterShutdown(null));
634 public void testBeforeConfigure() {
635 assertFalse( feat.beforeConfigure(null, null));
639 public void testAfterConfigure() {
640 assertFalse( feat.afterConfigure(null));
644 public void testBeforeActivate() {
645 assertFalse( feat.beforeActivate(null));
649 public void testAfterActivate() {
650 assertFalse( feat.afterActivate(null));
654 public void testBeforeDeactivate() {
655 assertFalse( feat.beforeDeactivate(null));
659 public void testAfterDeactivate() {
660 assertFalse( feat.afterDeactivate(null));
664 public void testBeforeStop() {
665 assertFalse( feat.beforeStop(null));
669 public void testAfterStop() {
670 assertFalse( feat.afterStop(null));
674 public void testBeforeLock() {
675 assertFalse( feat.beforeLock(null));
679 public void testAfterLock() {
680 assertFalse( feat.afterLock(null));
684 public void testBeforeUnlock() {
685 assertFalse( feat.beforeUnlock(null));
689 public void testAfterUnlock() {
690 assertFalse( feat.afterUnlock(null));
694 public void testGetPersistenceTimeout_Valid() throws Exception {
695 PreparedStatement s = mockDbConn(5);
697 feat.globalInit(null, SRC_TEST_RESOURCES);
699 setUpKie("myname", 999L, true);
701 feat.activatePolicySession(polcont, "myname", "mybase");
703 verify(s).executeUpdate();
707 public void testGetPersistenceTimeout_Missing() throws Exception {
709 props.remove(DroolsPersistenceProperties.DB_SESSIONINFO_TIMEOUT);
711 PreparedStatement s = mockDbConn(0);
713 feat.globalInit(null, SRC_TEST_RESOURCES);
715 setUpKie("myname", 999L, true);
717 feat.activatePolicySession(polcont, "myname", "mybase");
719 verify(s, never()).executeUpdate();
723 public void testGetPersistenceTimeout_Invalid() throws Exception {
724 props.setProperty(DroolsPersistenceProperties.DB_SESSIONINFO_TIMEOUT, "abc");
725 PreparedStatement s = mockDbConn(0);
727 feat.globalInit(null, SRC_TEST_RESOURCES);
729 setUpKie("myname", 999L, true);
731 feat.activatePolicySession(polcont, "myname", "mybase");
733 verify(s, never()).executeUpdate();
737 public void testInitHostName() throws Exception {
738 when(fact.getHostName()).thenReturn("myhost");
740 feat.globalInit(null, SRC_TEST_RESOURCES);
742 verify(bitcfg).setServerId("myhost");
745 @Test(expected = RuntimeException.class)
746 public void testInitHostName_Ex() throws Exception {
747 when(fact.getHostName())
749 new UnknownHostException("expected exception"));
751 feat.globalInit(null, SRC_TEST_RESOURCES);
755 public void testCleanUpSessionInfo() throws Exception {
756 setUpKie("myname", 999L, true);
758 // use a real DB so we can verify that the "delete" works correctly
759 fact = new PartialFactory();
760 feat.setFactory(fact);
762 makeSessionInfoTbl(20000);
765 feat.globalInit(null, SRC_TEST_RESOURCES);
767 feat.beforeStart(null);
768 feat.activatePolicySession(polcont, "myname", "mybase");
770 assertEquals("[1, 4, 5]", getSessions().toString());
774 public void testCleanUpSessionInfo_WithBeforeStart() throws Exception {
775 PreparedStatement s = mockDbConn(0);
777 feat.globalInit(null, SRC_TEST_RESOURCES);
779 setUpKie("myname", 999L, true);
782 feat.beforeStart(null);
784 feat.activatePolicySession(polcont, "myname", "mybase");
785 verify(s, times(1)).executeUpdate();
787 // should not clean-up again
788 feat.activatePolicySession(polcont, "myname", "mybase");
789 feat.activatePolicySession(polcont, "myname", "mybase");
790 verify(s, times(1)).executeUpdate();
794 feat.beforeStart(null);
796 feat.activatePolicySession(polcont, "myname", "mybase");
797 verify(s, times(2)).executeUpdate();
799 // should not clean-up again
800 feat.activatePolicySession(polcont, "myname", "mybase");
801 feat.activatePolicySession(polcont, "myname", "mybase");
802 verify(s, times(2)).executeUpdate();
806 public void testCleanUpSessionInfo_WithBeforeActivate() throws Exception {
807 PreparedStatement s = mockDbConn(0);
809 feat.globalInit(null, SRC_TEST_RESOURCES);
811 setUpKie("myname", 999L, true);
814 feat.beforeActivate(null);
816 feat.activatePolicySession(polcont, "myname", "mybase");
817 verify(s, times(1)).executeUpdate();
819 // should not clean-up again
820 feat.activatePolicySession(polcont, "myname", "mybase");
821 feat.activatePolicySession(polcont, "myname", "mybase");
822 verify(s, times(1)).executeUpdate();
826 feat.beforeActivate(null);
828 feat.activatePolicySession(polcont, "myname", "mybase");
829 verify(s, times(2)).executeUpdate();
831 // should not clean-up again
832 feat.activatePolicySession(polcont, "myname", "mybase");
833 feat.activatePolicySession(polcont, "myname", "mybase");
834 verify(s, times(2)).executeUpdate();
838 public void testCleanUpSessionInfo_NoTimeout() throws Exception {
840 props.remove(DroolsPersistenceProperties.DB_SESSIONINFO_TIMEOUT);
842 PreparedStatement s = mockDbConn(0);
844 feat.globalInit(null, SRC_TEST_RESOURCES);
846 setUpKie("myname", 999L, true);
848 feat.activatePolicySession(polcont, "myname", "mybase");
850 verify(s, never()).executeUpdate();
854 public void testCleanUpSessionInfo_NoUrl() throws Exception {
855 PreparedStatement s = mockDbConn(0);
857 props.remove(DroolsPersistenceProperties.DB_URL);
859 feat.globalInit(null, SRC_TEST_RESOURCES);
861 setUpKie("myname", 999L, true);
863 feat.activatePolicySession(polcont, "myname", "mybase");
865 verify(s, never()).executeUpdate();
869 public void testCleanUpSessionInfo_NoUser() throws Exception {
870 PreparedStatement s = mockDbConn(0);
872 props.remove(DroolsPersistenceProperties.DB_USER);
874 feat.globalInit(null, SRC_TEST_RESOURCES);
876 setUpKie("myname", 999L, true);
878 feat.activatePolicySession(polcont, "myname", "mybase");
880 verify(s, never()).executeUpdate();
884 public void testCleanUpSessionInfo_NoPassword() throws Exception {
885 PreparedStatement s = mockDbConn(0);
887 props.remove(DroolsPersistenceProperties.DB_PWD);
889 feat.globalInit(null, SRC_TEST_RESOURCES);
891 setUpKie("myname", 999L, true);
893 feat.activatePolicySession(polcont, "myname", "mybase");
895 verify(s, never()).executeUpdate();
899 public void testCleanUpSessionInfo_SqlEx() throws Exception {
900 PreparedStatement s = mockDbConn(-1);
902 feat.globalInit(null, SRC_TEST_RESOURCES);
904 setUpKie("myname", 999L, true);
906 feat.activatePolicySession(polcont, "myname", "mybase");
908 verify(s).executeUpdate();
912 public void testGetDroolsSessionConnector() throws Exception {
913 feat.globalInit(null, SRC_TEST_RESOURCES);
916 setUpKie("myname", 999L, true);
919 feat.activatePolicySession(polcont, "myname", "mybase");
922 ArgumentCaptor<Properties> propcap =
923 ArgumentCaptor.forClass(Properties.class);
925 verify(fact).makeJpaConnector(anyString(), propcap.capture());
927 Properties p = propcap.getValue();
930 assertEquals(JDBC_DRIVER,
931 p.getProperty("javax.persistence.jdbc.driver"));
933 assertEquals(JDBC_URL,
934 p.getProperty("javax.persistence.jdbc.url"));
936 assertEquals(JDBC_USER,
937 p.getProperty("javax.persistence.jdbc.user"));
939 assertEquals(JDBC_PASSWD,
940 p.getProperty("javax.persistence.jdbc.password"));
944 public void testReplaceSession() throws Exception {
945 feat.globalInit(null, SRC_TEST_RESOURCES);
947 ArgumentCaptor<DroolsSession> sesscap =
948 ArgumentCaptor.forClass(DroolsSession.class);
951 setUpKie("myname", 999L, true);
954 feat.activatePolicySession(polcont, "myname", "mybase");
956 verify(jpa).replace( sesscap.capture());
958 assertEquals("myname", sesscap.getValue().getSessionName());
959 assertEquals(999L, sesscap.getValue().getSessionId());
963 public void testIsPersistenceEnabled_Auto() throws Exception {
964 feat.globalInit(null, SRC_TEST_RESOURCES);
967 setUpKie("myname", 999L, true);
969 props.setProperty("persistence.type", "auto");
971 assertNotNull( feat.activatePolicySession(polcont, "myname", "mybase"));
975 public void testIsPersistenceEnabled_Native() throws Exception {
976 feat.globalInit(null, SRC_TEST_RESOURCES);
979 setUpKie("myname", 999L, true);
981 props.setProperty("persistence.type", "native");
983 assertNotNull( feat.activatePolicySession(polcont, "myname", "mybase"));
987 public void testIsPersistenceEnabled_None() throws Exception {
988 feat.globalInit(null, SRC_TEST_RESOURCES);
991 setUpKie("myname", 999L, true);
993 props.remove("persistence.type");
995 assertNull( feat.activatePolicySession(polcont, "myname", "mybase"));
999 public void testGetProperties_Ex() throws Exception {
1000 feat.globalInit(null, SRC_TEST_RESOURCES);
1003 setUpKie("myname", 999L, true);
1005 when(fact.getPolicyContainer(polcont))
1006 .thenThrow( new IllegalArgumentException("expected exception"));
1008 assertNull( feat.activatePolicySession(polcont, "myname", "mybase"));
1012 public void testGetProperty_Specific() throws Exception {
1013 feat.globalInit(null, SRC_TEST_RESOURCES);
1016 setUpKie("myname", 999L, true);
1018 props.remove("persistence.type");
1019 props.setProperty("persistence.myname.type", "auto");
1021 assertNotNull( feat.activatePolicySession(polcont, "myname", "mybase"));
1025 public void testGetProperty_Specific_None() throws Exception {
1026 feat.globalInit(null, SRC_TEST_RESOURCES);
1029 setUpKie("myname", 999L, true);
1031 props.remove("persistence.type");
1032 props.setProperty("persistence.xxx.type", "auto");
1034 assertNull( feat.activatePolicySession(polcont, "myname", "mybase"));
1038 public void testGetProperty_Both_SpecificOn() throws Exception {
1039 feat.globalInit(null, SRC_TEST_RESOURCES);
1042 setUpKie("myname", 999L, true);
1044 props.setProperty("persistence.type", "other");
1045 props.setProperty("persistence.myname.type", "auto");
1047 assertNotNull( feat.activatePolicySession(polcont, "myname", "mybase"));
1051 public void testGetProperty_Both_SpecificDisabledOff() throws Exception {
1052 feat.globalInit(null, SRC_TEST_RESOURCES);
1055 setUpKie("myname", 999L, true);
1057 props.setProperty("persistence.type", "auto");
1058 props.setProperty("persistence.myname.type", "other");
1060 assertNull( feat.activatePolicySession(polcont, "myname", "mybase"));
1064 public void testGetProperty_None() throws Exception {
1065 feat.globalInit(null, SRC_TEST_RESOURCES);
1068 setUpKie("myname", 999L, true);
1070 props.remove("persistence.type");
1072 assertNull( feat.activatePolicySession(polcont, "myname", "mybase"));
1077 * Gets an ordered list of ids of the current SessionInfo records.
1078 * @return ordered list of SessInfo IDs
1079 * @throws SQLException
1080 * @throws IOException
1082 private List<Integer> getSessions() throws SQLException, IOException {
1085 ArrayList<Integer> lst = new ArrayList<>(5);
1088 PreparedStatement stmt = conn.prepareStatement("SELECT id from sessioninfo order by id");
1089 ResultSet rs = stmt.executeQuery()) {
1092 lst.add( rs.getInt(1));
1100 * Sets up for doing invoking the newKieSession() method.
1101 * @param sessnm name to which JPA should respond with a session
1102 * @param sessid session id to be returned by the session
1103 * @param loadOk {@code true} if loadKieSession() should return a
1104 * value, {@code false} to return null
1106 private void setUpKie(String sessnm, long sessid, boolean loadOk) {
1108 when(fact.makeJpaConnector(any(), any())).thenReturn(jpa);
1109 when(fact.makePoolingDataSource()).thenReturn(pds);
1110 when(fact.getPolicyContainer(polcont)).thenReturn(polctlr);
1112 props.setProperty("persistence.type", "auto");
1114 when(polctlr.getProperties()).thenReturn(props);
1116 when(jpa.get(sessnm)).thenReturn(sess);
1118 when(pds.getDriverProperties()).thenReturn(dsprops);
1120 when(sess.getSessionId()).thenReturn(sessid);
1122 when(polsess.getPolicyContainer()).thenReturn(polcont);
1123 when(polsess.getName()).thenReturn(sessnm);
1126 when(kiesess.getIdentifier()).thenReturn(sessid);
1127 when(kiestore.loadKieSession(anyLong(), any(), any(), any()))
1128 .thenReturn(kiesess);
1131 // use an alternate id for the new session
1132 when(kiesess.getIdentifier()).thenReturn(100L);
1133 when(kiestore.loadKieSession(anyLong(), any(), any(), any()))
1137 when(kiestore.newKieSession(any(), any(), any())).thenReturn(kiesess);
1141 * Creates the SessionInfo DB table and populates it with some data.
1142 * @param expMs number of milli-seconds for expired sessioninfo records
1143 * @throws SQLException
1144 * @throws IOException
1146 private void makeSessionInfoTbl(int expMs)
1147 throws SQLException, IOException {
1152 PreparedStatement stmt = conn.prepareStatement(
1153 "CREATE TABLE sessioninfo(id int, lastmodificationdate timestamp)")) {
1155 stmt.executeUpdate();
1159 PreparedStatement stmt = conn.prepareStatement(
1160 "INSERT into sessioninfo(id, lastmodificationdate) values(?, ?)")) {
1165 ts = new Timestamp( System.currentTimeMillis());
1166 stmt.setTimestamp(2, ts);
1169 stmt.executeUpdate();
1172 stmt.executeUpdate();
1175 stmt.executeUpdate();
1178 ts = new Timestamp( System.currentTimeMillis() - expMs);
1179 stmt.setTimestamp(2, ts);
1182 stmt.executeUpdate();
1185 stmt.executeUpdate();
1190 * Attaches {@link #conn} to the DB, if it isn't already attached.
1191 * @throws SQLException
1192 * @throws IOException if the property file cannot be read
1194 private void attachDb() throws SQLException, IOException {
1196 Properties p = loadDbProps();
1198 conn = DriverManager.getConnection(
1199 p.getProperty(DroolsPersistenceProperties.DB_URL),
1200 p.getProperty(DroolsPersistenceProperties.DB_USER),
1201 p.getProperty(DroolsPersistenceProperties.DB_PWD));
1202 conn.setAutoCommit(true);
1207 * Loads the DB properties from the file,
1208 * <i>feature-session-persistence.properties</i>.
1209 * @return the properties that were loaded
1210 * @throws IOException if the property file cannot be read
1211 * @throws FileNotFoundException if the property file does not exist
1213 private Properties loadDbProps()
1214 throws IOException, FileNotFoundException {
1216 Properties p = new Properties();
1218 try(FileReader rdr = new FileReader(
1219 "src/test/resources/feature-session-persistence.properties")) {
1227 * Create a mock DB connection and statement.
1228 * @param retval value to be returned when the statement is executed,
1229 * or negative to throw an exception
1230 * @return the statement that will be returned by the connection
1231 * @throws SQLException
1233 private PreparedStatement mockDbConn(int retval) throws SQLException {
1234 Connection c = mock(Connection.class);
1235 PreparedStatement s = mock(PreparedStatement.class);
1237 when(fact.makeDbConnection(anyString(), anyString(), anyString()))
1239 when(c.prepareStatement(anyString())).thenReturn(s);
1242 // should throw an exception
1243 when(s.executeUpdate())
1244 .thenThrow( new SQLException("expected exception"));
1247 // should return the value
1248 when(s.executeUpdate()).thenReturn(retval);
1255 * A partial factory, which exports a few of the real methods, but
1256 * overrides the rest.
1258 private class PartialFactory extends PersistenceFeature.Factory {
1261 public PoolingDataSource makePoolingDataSource() {
1266 public KieServices getKieServices() {
1271 public BitronixTransactionManager getTransMgr() {
1276 public EntityManagerFactory makeEntMgrFact(String pu,
1277 Properties propMap) {
1278 if(pu.equals("onapsessionsPU")) {
1282 return super.makeEntMgrFact("junitPersistenceFeaturePU", propMap);
1286 public PolicyController getPolicyContainer(PolicyContainer container) {