a7c33abaec4ab3be95d3dd3ea581c19477cbdaa5
[policy/drools-pdp.git] /
1 /*-
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
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.drools.persistence;
22
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.junit.Assert.assertTrue;
28 import static org.junit.Assert.fail;
29 import static org.mockito.Matchers.any;
30 import static org.mockito.Matchers.anyLong;
31 import static org.mockito.Matchers.anyString;
32 import static org.mockito.Mockito.mock;
33 import static org.mockito.Mockito.never;
34 import static org.mockito.Mockito.times;
35 import static org.mockito.Mockito.verify;
36 import static org.mockito.Mockito.when;
37 import static org.mockito.Mockito.doThrow;
38
39 import java.io.FileNotFoundException;
40 import java.io.FileReader;
41 import java.io.IOException;
42 import java.sql.Connection;
43 import java.sql.DriverManager;
44 import java.sql.PreparedStatement;
45 import java.sql.ResultSet;
46 import java.sql.SQLException;
47 import java.sql.Timestamp;
48 import java.util.ArrayList;
49 import java.util.List;
50 import java.util.Map;
51 import java.util.Properties;
52 import java.util.concurrent.CountDownLatch;
53 import java.util.concurrent.TimeUnit;
54
55 import javax.persistence.EntityManager;
56 import javax.persistence.EntityManagerFactory;
57 import javax.transaction.TransactionManager;
58 import javax.transaction.TransactionSynchronizationRegistry;
59 import javax.transaction.UserTransaction;
60
61 import org.apache.commons.dbcp2.BasicDataSource;
62 import org.junit.After;
63 import org.junit.Before;
64 import org.junit.BeforeClass;
65 import org.junit.Test;
66 import org.kie.api.KieBase;
67 import org.kie.api.KieServices;
68 import org.kie.api.persistence.jpa.KieStoreServices;
69 import org.kie.api.runtime.Environment;
70 import org.kie.api.runtime.EnvironmentName;
71 import org.kie.api.runtime.KieContainer;
72 import org.kie.api.runtime.KieSession;
73 import org.kie.api.runtime.KieSessionConfiguration;
74 import org.mockito.ArgumentCaptor;
75 import org.onap.policy.drools.core.PolicyContainer;
76 import org.onap.policy.drools.core.PolicySession;
77 import org.onap.policy.drools.core.PolicySession.ThreadModel;
78 import org.onap.policy.drools.persistence.PersistenceFeature.PersistenceFeatureException;
79 import org.onap.policy.drools.persistence.PersistenceFeature.PersistentThreadModel;
80 import org.onap.policy.drools.system.PolicyController;
81 import org.slf4j.Logger;
82 import org.slf4j.LoggerFactory;
83
84 public class PersistenceFeatureTest {
85
86         private static final Logger logger = LoggerFactory.getLogger(PersistenceFeatureTest.class);
87
88         private static final String JDBC_DRIVER = "fake.driver";
89         private static final String JDBC_URL = "fake.url";
90         private static final String JDBC_USER = "fake.user";
91         private static final String JDBC_PASSWD = "fake.password";
92         private static final String JTA_OSDIR = "target";
93         private static final String SRC_TEST_RESOURCES = "src/test/resources";
94
95         private static Properties stdprops;
96
97         private JpaDroolsSessionConnector jpa;
98         private DroolsSession sess;
99         private KieSession kiesess;
100         private BasicDataSource bds;
101         private EntityManagerFactory emf;
102         private Connection conn;
103         private Properties props;
104         private KieServices kiesvc;
105         private Environment kieenv;
106         private KieSessionConfiguration kiecfg;
107         private KieBase kiebase;
108         private KieStoreServices kiestore;
109         private KieContainer kiecont;
110         private TransactionManager transmgr;
111         private UserTransaction usertrans;
112         private TransactionSynchronizationRegistry transreg;
113         private PolicyController polctlr;
114         private PolicyContainer polcont;
115         private PolicySession polsess;
116         private PersistenceFeature.Factory fact;
117
118         private PersistenceFeature feat;
119
120         @BeforeClass
121         public static void setUpBeforeClass() throws Exception {
122                 stdprops = new Properties();
123
124                 stdprops.put(DroolsPersistenceProperties.DB_DRIVER, JDBC_DRIVER);
125                 stdprops.put(DroolsPersistenceProperties.DB_URL, JDBC_URL);
126                 stdprops.put(DroolsPersistenceProperties.DB_USER, JDBC_USER);
127                 stdprops.put(DroolsPersistenceProperties.DB_PWD, JDBC_PASSWD);
128                 stdprops.put(DroolsPersistenceProperties.JTA_OBJECTSTORE_DIR, JTA_OSDIR);
129                 stdprops.put(DroolsPersistenceProperties.DB_SESSIONINFO_TIMEOUT, "50");
130
131                 System.setProperty("com.arjuna.ats.arjuna.objectstore.objectStoreDir", "target/tm");
132                 System.setProperty("ObjectStoreEnvironmentBean.objectStoreDir", "target/tm");
133         }
134
135         @Before
136         public void setUp() throws Exception {
137                 jpa = mock(JpaDroolsSessionConnector.class);
138                 sess = mock(DroolsSession.class);
139                 bds = mock(BasicDataSource.class);
140                 emf = mock(EntityManagerFactory.class);
141                 kiesess = mock(KieSession.class);
142                 conn = null;
143                 props = new Properties();
144                 kiesvc = mock(KieServices.class);
145                 kieenv = mock(Environment.class);
146                 kiecfg = mock(KieSessionConfiguration.class);
147                 kiebase = mock(KieBase.class);
148                 kiestore = mock(KieStoreServices.class);
149                 kiecont = mock(KieContainer.class);
150                 transmgr = mock(TransactionManager.class);
151                 usertrans = mock(UserTransaction.class);
152                 transreg = mock(TransactionSynchronizationRegistry.class);
153                 polcont = mock(PolicyContainer.class);
154                 polctlr = mock(PolicyController.class);
155                 polsess = mock(PolicySession.class);
156                 fact = mock(PersistenceFeature.Factory.class);
157
158                 feat = new PersistenceFeature();
159                 feat.setFactory(fact);
160
161                 props.putAll(stdprops);
162
163                 System.setProperty("com.arjuna.ats.arjuna.objectstore.objectStoreDir", "target/tm");
164                 System.setProperty("ObjectStoreEnvironmentBean.objectStoreDir", "target/tm");
165
166                 when(fact.getKieServices()).thenReturn(kiesvc);
167                 when(fact.getTransMgr()).thenReturn(transmgr);
168                 when(fact.getUserTrans()).thenReturn(usertrans);
169                 when(fact.getTransSyncReg()).thenReturn(transreg);
170                 when(fact.loadProperties(anyString())).thenReturn(props);
171
172                 when(kiesvc.newEnvironment()).thenReturn(kieenv);
173                 when(kiesvc.getStoreServices()).thenReturn(kiestore);
174                 when(kiesvc.newKieSessionConfiguration()).thenReturn(kiecfg);
175
176                 when(polcont.getKieContainer()).thenReturn(kiecont);
177
178                 when(polsess.getPolicyContainer()).thenReturn(polcont);
179
180                 when(kiecont.getKieBase(anyString())).thenReturn(kiebase);
181         }
182
183         @After
184         public void tearDown() {
185                 // this will cause the in-memory test DB to be dropped
186                 if (conn != null) {
187                         try {
188                                 conn.close();
189                         } catch (SQLException e) {
190                                 logger.warn("failed to close connection", e);
191                         }
192                 }
193
194                 if (emf != null) {
195                         try {
196                                 emf.close();
197                         } catch (IllegalArgumentException e) {
198                                 logger.trace("ignored exception", e);
199                         }
200                 }
201         }
202
203         @Test
204         public void testGetContainerAdjunct_New() throws Exception {
205
206                 feat.globalInit(null, SRC_TEST_RESOURCES);
207
208                 mockDbConn(5);
209                 setUpKie("myname", 999L, true);
210
211                 // force getContainerAdjunct() to be invoked
212                 feat.activatePolicySession(polcont, "myname", "mybase");
213
214                 ArgumentCaptor<PersistenceFeature.ContainerAdjunct> adjcap = ArgumentCaptor
215                                 .forClass(PersistenceFeature.ContainerAdjunct.class);
216
217                 verify(polcont, times(1)).setAdjunct(any(), adjcap.capture());
218
219                 assertNotNull(adjcap.getValue());
220         }
221
222         @Test
223         public void testGetContainerAdjunct_Existing() throws Exception {
224
225                 feat.globalInit(null, SRC_TEST_RESOURCES);
226
227                 mockDbConn(5);
228                 setUpKie("myname", 999L, true);
229
230                 // force getContainerAdjunct() to be invoked
231                 feat.activatePolicySession(polcont, "myname", "mybase");
232
233                 ArgumentCaptor<PersistenceFeature.ContainerAdjunct> adjcap = ArgumentCaptor
234                                 .forClass(PersistenceFeature.ContainerAdjunct.class);
235
236                 verify(polcont, times(1)).setAdjunct(any(), adjcap.capture());
237
238                 // return adjunct on next call
239                 when(polcont.getAdjunct(any())).thenReturn(adjcap.getValue());
240
241                 // force getContainerAdjunct() to be invoked again
242                 setUpKie("myname2", 999L, true);
243                 feat.activatePolicySession(polcont, "myname2", "mybase");
244
245                 // ensure it isn't invoked again
246                 verify(polcont, times(1)).setAdjunct(any(), any());
247         }
248
249         @Test
250         public void testGetContainerAdjunct_WrongType() throws Exception {
251
252                 feat.globalInit(null, SRC_TEST_RESOURCES);
253
254                 mockDbConn(5);
255                 setUpKie("myname", 999L, true);
256
257                 // return false adjunct on next call
258                 when(polcont.getAdjunct(any())).thenReturn("not-a-real-adjunct");
259
260                 // force getContainerAdjunct() to be invoked
261                 setUpKie("myname2", 999L, true);
262                 feat.activatePolicySession(polcont, "myname2", "mybase");
263
264                 ArgumentCaptor<PersistenceFeature.ContainerAdjunct> adjcap = ArgumentCaptor
265                                 .forClass(PersistenceFeature.ContainerAdjunct.class);
266
267                 verify(polcont, times(1)).setAdjunct(any(), adjcap.capture());
268
269                 assertNotNull(adjcap.getValue());
270         }
271
272         @Test
273         public void testGetSequenceNumber() {
274                 assertEquals(1, feat.getSequenceNumber());
275         }
276
277         @Test
278         public void testGlobalInit() throws Exception {
279
280                 feat.globalInit(null, SRC_TEST_RESOURCES);
281
282                 // verify that various factory methods were invoked
283                 verify(fact).getKieServices();
284                 verify(fact).loadProperties("src/test/resources/feature-session-persistence.properties");
285         }
286
287         @Test(expected = NullPointerException.class)
288         public void testGlobalInit_IOEx() throws Exception {
289                 
290                 when(fact.loadProperties(anyString())).thenThrow(new IOException("expected exception"));
291
292                 feat.globalInit(null, SRC_TEST_RESOURCES);
293         }
294
295         @Test
296         public void testActivatePolicySession() throws Exception {
297                 PreparedStatement ps = mockDbConn(5);
298                 setUpKie("myname", 999L, true);
299
300                 feat.globalInit(null, SRC_TEST_RESOURCES);
301                 feat.beforeActivate(null);
302
303                 KieSession s = feat.activatePolicySession(polcont, "myname", "mybase");
304
305                 verify(kiestore).loadKieSession(anyLong(), any(), any(), any());
306                 verify(kiestore, never()).newKieSession(any(), any(), any());
307
308                 assertEquals(s, kiesess);
309
310                 verify(ps).executeUpdate();
311
312                 verify(kieenv, times(4)).set(anyString(), any());
313
314                 verify(jpa).get("myname");
315                 verify(jpa).replace(any());
316         }
317
318         @Test
319         public void testActivatePolicySession_NoPersistence() throws Exception {
320                 feat.globalInit(null, SRC_TEST_RESOURCES);
321
322                 PreparedStatement ps = mockDbConn(5);
323                 setUpKie("myname", 999L, true);
324
325                 props.remove("persistence.type");
326
327                 feat.beforeStart(null);
328
329                 assertNull(feat.activatePolicySession(polcont, "myname", "mybase"));
330
331                 verify(ps, never()).executeUpdate();
332                 verify(kiestore, never()).loadKieSession(anyLong(), any(), any(), any());
333                 verify(kiestore, never()).newKieSession(any(), any(), any());
334         }
335
336         /**
337          * Verifies that a new KIE session is created when there is no existing
338          * session entity.
339          */
340         @Test
341         public void testActivatePolicySession_New() throws Exception {
342                 feat.globalInit(null, SRC_TEST_RESOURCES);
343
344                 mockDbConn(5);
345                 setUpKie("noName", 999L, true);
346
347                 KieSession s = feat.activatePolicySession(polcont, "myname", "mybase");
348
349                 verify(kiestore, never()).loadKieSession(anyLong(), any(), any(), any());
350                 verify(kiestore).newKieSession(any(), any(), any());
351
352                 assertEquals(s, kiesess);
353
354                 verify(kieenv, times(4)).set(anyString(), any());
355
356                 verify(jpa).get("myname");
357                 verify(jpa).replace(any());
358         }
359
360         /**
361          * Verifies that a new KIE session is created when there KIE fails to load
362          * an existing session.
363          */
364         @Test
365         public void testActivatePolicySession_LoadFailed() throws Exception {
366                 feat.globalInit(null, SRC_TEST_RESOURCES);
367
368                 mockDbConn(5);
369                 setUpKie("myname", 999L, false);
370
371                 KieSession s = feat.activatePolicySession(polcont, "myname", "mybase");
372
373                 verify(kiestore).loadKieSession(anyLong(), any(), any(), any());
374                 verify(kiestore).newKieSession(any(), any(), any());
375
376                 assertEquals(s, kiesess);
377
378                 verify(kieenv, times(4)).set(anyString(), any());
379
380                 verify(jpa).get("myname");
381
382                 ArgumentCaptor<DroolsSession> d = ArgumentCaptor.forClass(DroolsSession.class);
383                 verify(jpa).replace(d.capture());
384
385                 assertEquals("myname", d.getValue().getSessionName());
386                 assertEquals(100L, d.getValue().getSessionId());
387         }
388
389         @Test
390         public void testLoadDataSource() throws Exception {
391                 feat.globalInit(null, SRC_TEST_RESOURCES);
392
393                 mockDbConn(5);
394                 setUpKie("myname", 999L, false);
395
396                 feat.activatePolicySession(polcont, "myname", "mybase");
397
398                 verify(fact).makeEntMgrFact(any());
399         }
400
401         @Test
402         public void testConfigureSysProps() throws Exception {
403                 feat.globalInit(null, SRC_TEST_RESOURCES);
404
405                 mockDbConn(5);
406                 setUpKie("myname", 999L, false);
407
408                 feat.activatePolicySession(polcont, "myname", "mybase");
409
410                 assertEquals("60", System.getProperty("com.arjuna.ats.arjuna.coordinator.defaultTimeout"));
411                 assertEquals(JTA_OSDIR, System.getProperty("com.arjuna.ats.arjuna.objectstore.objectStoreDir"));
412                 assertEquals(JTA_OSDIR, System.getProperty("ObjectStoreEnvironmentBean.objectStoreDir"));
413         }
414
415         @Test
416         public void testConfigureKieEnv() throws Exception {
417                 feat.globalInit(null, SRC_TEST_RESOURCES);
418
419                 mockDbConn(5);
420                 setUpKie("myname", 999L, false);
421
422                 feat.activatePolicySession(polcont, "myname", "mybase");
423
424                 verify(kieenv, times(4)).set(any(), any());
425
426                 verify(kieenv).set(EnvironmentName.ENTITY_MANAGER_FACTORY, emf);
427                 verify(kieenv).set(EnvironmentName.TRANSACTION, usertrans);
428                 verify(kieenv).set(EnvironmentName.TRANSACTION_MANAGER, transmgr);
429                 verify(kieenv).set(EnvironmentName.TRANSACTION_SYNCHRONIZATION_REGISTRY, transreg);
430                 
431                 verify(bds, times(1)).close();
432         }
433
434         @Test
435         public void testConfigureKieEnv_RtEx() throws Exception {
436                 feat.globalInit(null, SRC_TEST_RESOURCES);
437
438                 mockDbConn(5);
439                 setUpKie("myname", 999L, false);
440                 
441                 when(fact.getUserTrans()).thenThrow(new IllegalArgumentException("expected exception"));
442
443                 try {
444                         feat.activatePolicySession(polcont, "myname", "mybase");
445                         fail("missing exception");
446                         
447                 } catch(IllegalArgumentException ex) {
448                         logger.trace("expected exception", ex);
449                 }
450
451                 verify(bds, times(2)).close();
452         }
453
454         @Test
455         public void testLoadKieSession() throws Exception {
456                 feat.globalInit(null, SRC_TEST_RESOURCES);
457
458                 mockDbConn(5);
459                 setUpKie("myname", 999L, true);
460
461                 KieSession s = feat.activatePolicySession(polcont, "myname", "mybase");
462
463                 verify(kiestore).loadKieSession(999L, kiebase, kiecfg, kieenv);
464                 verify(kiestore, never()).newKieSession(any(), any(), any());
465
466                 assertEquals(s, kiesess);
467         }
468
469         /*
470          * Verifies that loadKieSession() returns null (thus causing newKieSession()
471          * to be called) when an Exception occurs.
472          */
473         @Test
474         public void testLoadKieSession_Ex() throws Exception {
475                 feat.globalInit(null, SRC_TEST_RESOURCES);
476
477                 mockDbConn(5);
478                 setUpKie("myname", 999L, false);
479
480                 when(kiestore.loadKieSession(anyLong(), any(), any(), any()))
481                                 .thenThrow(new IllegalArgumentException("expected exception"));
482
483                 KieSession s = feat.activatePolicySession(polcont, "myname", "mybase");
484
485                 verify(kiestore).loadKieSession(anyLong(), any(), any(), any());
486                 verify(kiestore).newKieSession(any(), any(), any());
487
488                 assertEquals(s, kiesess);
489         }
490
491         @Test
492         public void testNewKieSession() throws Exception {
493                 feat.globalInit(null, SRC_TEST_RESOURCES);
494
495                 mockDbConn(5);
496                 setUpKie("myname", 999L, false);
497
498                 KieSession s = feat.activatePolicySession(polcont, "myname", "mybase");
499
500                 verify(kiestore).newKieSession(kiebase, null, kieenv);
501
502                 assertEquals(s, kiesess);
503         }
504
505         @Test
506         public void testLoadDataSource_DiffSession() throws Exception {
507                 feat.globalInit(null, SRC_TEST_RESOURCES);
508
509                 mockDbConn(5);
510                 setUpKie("myname", 999L, false);
511                 feat.activatePolicySession(polcont, "myname", "mybase");
512
513                 ArgumentCaptor<PersistenceFeature.ContainerAdjunct> adjcap = ArgumentCaptor
514                                 .forClass(PersistenceFeature.ContainerAdjunct.class);
515
516                 verify(polcont).setAdjunct(any(), adjcap.capture());
517
518                 when(polcont.getAdjunct(any())).thenReturn(adjcap.getValue());
519
520                 setUpKie("myname2", 999L, false);
521
522                 // invoke it again
523                 feat.activatePolicySession(polcont, "myname2", "mybase");
524
525                 verify(fact, times(2)).makeEntMgrFact(any());
526         }
527         
528         @Test
529         public void testSelectThreadModel_Persistent() throws Exception {
530                 setUpKie("myname", 999L, true);
531                 
532                 ThreadModel m = feat.selectThreadModel(polsess);
533                 assertNotNull(m);
534                 assertTrue(m instanceof PersistentThreadModel);
535                 
536         }
537         
538         @Test
539         public void testSelectThreadModel_NotPersistent() throws Exception {
540                 when(fact.getPolicyController(any())).thenReturn(polctlr);
541                 assertNull(feat.selectThreadModel(polsess));
542                 
543         }
544         
545         @Test
546         public void testSelectThreadModel_Start__Run_Update_Stop() throws Exception {
547                 setUpKie("myname", 999L, true);
548                 
549                 ThreadModel m = feat.selectThreadModel(polsess);
550                 assertNotNull(m);
551                 assertTrue(m instanceof PersistentThreadModel);
552                 
553                 when(polsess.getKieSession()).thenReturn(kiesess);
554                 
555                 m.start();
556                 new CountDownLatch(1).await(10, TimeUnit.MILLISECONDS);
557                 m.updated();
558                 m.stop();
559         }
560
561         @Test
562         public void testDisposeKieSession() throws Exception {
563                 feat.globalInit(null, SRC_TEST_RESOURCES);
564
565                 ArgumentCaptor<PersistenceFeature.ContainerAdjunct> adjcap = ArgumentCaptor
566                                 .forClass(PersistenceFeature.ContainerAdjunct.class);
567
568                 mockDbConn(5);
569                 setUpKie("myname", 999L, false);
570
571                 feat.activatePolicySession(polcont, "myname", "mybase");
572
573                 verify(emf, never()).close();
574                 verify(polcont).setAdjunct(any(), adjcap.capture());
575
576                 when(polcont.getAdjunct(any())).thenReturn(adjcap.getValue());
577
578                 feat.disposeKieSession(polsess);
579
580                 // call twice to ensure it isn't re-closed
581                 feat.disposeKieSession(polsess);
582
583                 verify(emf, times(1)).close();
584         }
585
586         @Test
587         public void testDisposeKieSession_NoAdjunct() throws Exception {
588                 feat.globalInit(null, SRC_TEST_RESOURCES);
589
590                 feat.disposeKieSession(polsess);
591         }
592
593         @Test
594         public void testDisposeKieSession_NoPersistence() throws Exception {
595                 feat.globalInit(null, SRC_TEST_RESOURCES);
596
597                 ArgumentCaptor<PersistenceFeature.ContainerAdjunct> adjcap = ArgumentCaptor
598                                 .forClass(PersistenceFeature.ContainerAdjunct.class);
599
600                 mockDbConn(5);
601                 setUpKie("myname", 999L, false);
602
603                 feat.activatePolicySession(polcont, "myname", "mybase");
604
605                 verify(emf, never()).close();
606                 verify(polcont).setAdjunct(any(), adjcap.capture());
607
608                 when(polcont.getAdjunct(any())).thenReturn(adjcap.getValue());
609
610                 // specify a session that was never loaded
611                 when(polsess.getName()).thenReturn("anotherName");
612
613                 feat.disposeKieSession(polsess);
614
615                 verify(emf, never()).close();
616         }
617
618         @Test
619         public void testDestroyKieSession() throws Exception {
620                 feat.globalInit(null, SRC_TEST_RESOURCES);
621
622                 ArgumentCaptor<PersistenceFeature.ContainerAdjunct> adjcap = ArgumentCaptor
623                                 .forClass(PersistenceFeature.ContainerAdjunct.class);
624
625                 mockDbConn(5);
626                 setUpKie("myname", 999L, false);
627
628                 feat.activatePolicySession(polcont, "myname", "mybase");
629
630                 verify(emf, never()).close();
631                 verify(polcont).setAdjunct(any(), adjcap.capture());
632
633                 when(polcont.getAdjunct(any())).thenReturn(adjcap.getValue());
634
635                 feat.destroyKieSession(polsess);
636
637                 // call twice to ensure it isn't re-closed
638                 feat.destroyKieSession(polsess);
639
640                 verify(emf, times(1)).close();
641         }
642
643         @Test
644         public void testDestroyKieSession_NoAdjunct() throws Exception {
645                 feat.globalInit(null, SRC_TEST_RESOURCES);
646
647                 feat.destroyKieSession(polsess);
648         }
649
650         @Test
651         public void testDestroyKieSession_NoPersistence() throws Exception {
652                 feat.globalInit(null, SRC_TEST_RESOURCES);
653
654                 ArgumentCaptor<PersistenceFeature.ContainerAdjunct> adjcap = ArgumentCaptor
655                                 .forClass(PersistenceFeature.ContainerAdjunct.class);
656
657                 mockDbConn(5);
658                 setUpKie("myname", 999L, false);
659
660                 feat.activatePolicySession(polcont, "myname", "mybase");
661
662                 verify(emf, never()).close();
663                 verify(polcont).setAdjunct(any(), adjcap.capture());
664
665                 when(polcont.getAdjunct(any())).thenReturn(adjcap.getValue());
666
667                 // specify a session that was never loaded
668                 when(polsess.getName()).thenReturn("anotherName");
669
670                 feat.destroyKieSession(polsess);
671
672                 verify(emf, never()).close();
673         }
674
675         @Test
676         public void testAfterStart() {
677                 assertFalse(feat.afterStart(null));
678         }
679
680         @Test
681         public void testBeforeStart() {
682                 assertFalse(feat.beforeStart(null));
683         }
684
685         @Test
686         public void testBeforeShutdown() {
687                 assertFalse(feat.beforeShutdown(null));
688         }
689
690         @Test
691         public void testAfterShutdown() {
692                 assertFalse(feat.afterShutdown(null));
693         }
694
695         @Test
696         public void testBeforeConfigure() {
697                 assertFalse(feat.beforeConfigure(null, null));
698         }
699
700         @Test
701         public void testAfterConfigure() {
702                 assertFalse(feat.afterConfigure(null));
703         }
704
705         @Test
706         public void testBeforeActivate() {
707                 assertFalse(feat.beforeActivate(null));
708         }
709
710         @Test
711         public void testAfterActivate() {
712                 assertFalse(feat.afterActivate(null));
713         }
714
715         @Test
716         public void testBeforeDeactivate() {
717                 assertFalse(feat.beforeDeactivate(null));
718         }
719
720         @Test
721         public void testAfterDeactivate() {
722                 assertFalse(feat.afterDeactivate(null));
723         }
724
725         @Test
726         public void testBeforeStop() {
727                 assertFalse(feat.beforeStop(null));
728         }
729
730         @Test
731         public void testAfterStop() {
732                 assertFalse(feat.afterStop(null));
733         }
734
735         @Test
736         public void testBeforeLock() {
737                 assertFalse(feat.beforeLock(null));
738         }
739
740         @Test
741         public void testAfterLock() {
742                 assertFalse(feat.afterLock(null));
743         }
744
745         @Test
746         public void testBeforeUnlock() {
747                 assertFalse(feat.beforeUnlock(null));
748         }
749
750         @Test
751         public void testAfterUnlock() {
752                 assertFalse(feat.afterUnlock(null));
753         }
754
755         @Test
756         public void testGetPersistenceTimeout_Valid() throws Exception {
757                 PreparedStatement s = mockDbConn(5);
758
759                 feat.globalInit(null, SRC_TEST_RESOURCES);
760
761                 setUpKie("myname", 999L, true);
762
763                 feat.activatePolicySession(polcont, "myname", "mybase");
764
765                 verify(s).executeUpdate();
766         }
767
768         @Test
769         public void testGetPersistenceTimeout_Missing() throws Exception {
770
771                 props.remove(DroolsPersistenceProperties.DB_SESSIONINFO_TIMEOUT);
772
773                 PreparedStatement s = mockDbConn(0);
774
775                 feat.globalInit(null, SRC_TEST_RESOURCES);
776
777                 setUpKie("myname", 999L, true);
778
779                 feat.activatePolicySession(polcont, "myname", "mybase");
780
781                 verify(s, never()).executeUpdate();
782         }
783
784         @Test
785         public void testGetPersistenceTimeout_Invalid() throws Exception {
786                 props.setProperty(DroolsPersistenceProperties.DB_SESSIONINFO_TIMEOUT, "abc");
787                 PreparedStatement s = mockDbConn(0);
788
789                 feat.globalInit(null, SRC_TEST_RESOURCES);
790
791                 setUpKie("myname", 999L, true);
792
793                 feat.activatePolicySession(polcont, "myname", "mybase");
794
795                 verify(s, never()).executeUpdate();
796         }
797
798         @Test
799         public void testCleanUpSessionInfo() throws Exception {
800                 setUpKie("myname", 999L, true);
801
802                 // use a real DB so we can verify that the "delete" works correctly
803                 fact = new PartialFactory();
804                 feat.setFactory(fact);
805
806                 makeSessionInfoTbl(20000);
807
808                 // create mock entity manager for use by JPA connector
809                 EntityManager em = mock(EntityManager.class);
810                 when(emf.createEntityManager()).thenReturn(em);
811
812                 feat.globalInit(null, SRC_TEST_RESOURCES);
813
814                 feat.beforeStart(null);
815                 feat.activatePolicySession(polcont, "myname", "mybase");
816
817                 assertEquals("[1, 4, 5]", getSessions().toString());
818         }
819
820         @Test
821         public void testCleanUpSessionInfo_WithBeforeStart() throws Exception {
822                 PreparedStatement s = mockDbConn(0);
823
824                 feat.globalInit(null, SRC_TEST_RESOURCES);
825
826                 setUpKie("myname", 999L, true);
827
828                 // reset
829                 feat.beforeStart(null);
830
831                 feat.activatePolicySession(polcont, "myname", "mybase");
832                 verify(s, times(1)).executeUpdate();
833
834                 // should not clean-up again
835                 feat.activatePolicySession(polcont, "myname", "mybase");
836                 feat.activatePolicySession(polcont, "myname", "mybase");
837                 verify(s, times(1)).executeUpdate();
838
839                 // reset
840                 feat.beforeStart(null);
841
842                 feat.activatePolicySession(polcont, "myname", "mybase");
843                 verify(s, times(2)).executeUpdate();
844
845                 // should not clean-up again
846                 feat.activatePolicySession(polcont, "myname", "mybase");
847                 feat.activatePolicySession(polcont, "myname", "mybase");
848                 verify(s, times(2)).executeUpdate();
849         }
850
851         @Test
852         public void testCleanUpSessionInfo_WithBeforeActivate() throws Exception {
853                 PreparedStatement s = mockDbConn(0);
854
855                 feat.globalInit(null, SRC_TEST_RESOURCES);
856
857                 setUpKie("myname", 999L, true);
858
859                 // reset
860                 feat.beforeActivate(null);
861
862                 feat.activatePolicySession(polcont, "myname", "mybase");
863                 verify(s, times(1)).executeUpdate();
864
865                 // should not clean-up again
866                 feat.activatePolicySession(polcont, "myname", "mybase");
867                 feat.activatePolicySession(polcont, "myname", "mybase");
868                 verify(s, times(1)).executeUpdate();
869
870                 // reset
871                 feat.beforeActivate(null);
872
873                 feat.activatePolicySession(polcont, "myname", "mybase");
874                 verify(s, times(2)).executeUpdate();
875
876                 // should not clean-up again
877                 feat.activatePolicySession(polcont, "myname", "mybase");
878                 feat.activatePolicySession(polcont, "myname", "mybase");
879                 verify(s, times(2)).executeUpdate();
880         }
881
882         @Test
883         public void testCleanUpSessionInfo_NoTimeout() throws Exception {
884
885                 props.remove(DroolsPersistenceProperties.DB_SESSIONINFO_TIMEOUT);
886
887                 PreparedStatement s = mockDbConn(0);
888
889                 feat.globalInit(null, SRC_TEST_RESOURCES);
890
891                 setUpKie("myname", 999L, true);
892
893                 feat.activatePolicySession(polcont, "myname", "mybase");
894
895                 verify(s, never()).executeUpdate();
896         }
897
898         @Test
899         public void testCleanUpSessionInfo_NoUrl() throws Exception {
900                 PreparedStatement s = mockDbConn(0);
901
902                 props.remove(DroolsPersistenceProperties.DB_URL);
903
904                 feat.globalInit(null, SRC_TEST_RESOURCES);
905
906                 setUpKie("myname", 999L, true);
907
908                 try {
909                         feat.activatePolicySession(polcont, "myname", "mybase");
910                         fail("missing exception");
911                 } catch (RuntimeException e) {
912                         logger.trace("expected exception", e);
913                 }
914
915                 verify(s, never()).executeUpdate();
916         }
917
918         @Test
919         public void testCleanUpSessionInfo_NoUser() throws Exception {
920                 PreparedStatement s = mockDbConn(0);
921
922                 props.remove(DroolsPersistenceProperties.DB_USER);
923
924                 feat.globalInit(null, SRC_TEST_RESOURCES);
925
926                 setUpKie("myname", 999L, true);
927
928                 try {
929                         feat.activatePolicySession(polcont, "myname", "mybase");
930                         fail("missing exception");
931                 } catch (RuntimeException e) {
932                         logger.trace("expected exception", e);
933                 }
934
935                 verify(s, never()).executeUpdate();
936         }
937
938         @Test
939         public void testCleanUpSessionInfo_NoPassword() throws Exception {
940                 PreparedStatement s = mockDbConn(0);
941
942                 props.remove(DroolsPersistenceProperties.DB_PWD);
943
944                 feat.globalInit(null, SRC_TEST_RESOURCES);
945
946                 setUpKie("myname", 999L, true);
947
948                 try {
949                         feat.activatePolicySession(polcont, "myname", "mybase");
950                         fail("missing exception");
951                 } catch (RuntimeException e) {
952                         logger.trace("expected exception", e);
953                 }
954
955                 verify(s, never()).executeUpdate();
956         }
957
958         @Test
959         public void testCleanUpSessionInfo_SqlEx() throws Exception {
960                 PreparedStatement s = mockDbConn(-1);
961
962                 feat.globalInit(null, SRC_TEST_RESOURCES);
963
964                 setUpKie("myname", 999L, true);
965
966                 feat.activatePolicySession(polcont, "myname", "mybase");
967
968                 verify(s).executeUpdate();
969         }
970
971         @Test
972         public void testGetDroolsSessionConnector() throws Exception {
973                 feat.globalInit(null, SRC_TEST_RESOURCES);
974
975                 mockDbConn(5);
976                 setUpKie("myname", 999L, true);
977
978                 feat.activatePolicySession(polcont, "myname", "mybase");
979
980                 verify(fact).makeJpaConnector(emf);
981         }
982
983         @Test
984         public void testReplaceSession() throws Exception {
985                 feat.globalInit(null, SRC_TEST_RESOURCES);
986
987                 ArgumentCaptor<DroolsSession> sesscap = ArgumentCaptor.forClass(DroolsSession.class);
988
989                 mockDbConn(5);
990                 setUpKie("myname", 999L, true);
991
992                 feat.activatePolicySession(polcont, "myname", "mybase");
993
994                 verify(jpa).replace(sesscap.capture());
995
996                 assertEquals("myname", sesscap.getValue().getSessionName());
997                 assertEquals(999L, sesscap.getValue().getSessionId());
998         }
999
1000         @Test
1001         public void testIsPersistenceEnabled_Auto() throws Exception {
1002                 feat.globalInit(null, SRC_TEST_RESOURCES);
1003
1004                 mockDbConn(5);
1005                 setUpKie("myname", 999L, true);
1006
1007                 props.setProperty("persistence.type", "auto");
1008
1009                 assertNotNull(feat.activatePolicySession(polcont, "myname", "mybase"));
1010         }
1011
1012         @Test
1013         public void testIsPersistenceEnabled_Native() throws Exception {
1014                 feat.globalInit(null, SRC_TEST_RESOURCES);
1015
1016                 mockDbConn(5);
1017                 setUpKie("myname", 999L, true);
1018
1019                 props.setProperty("persistence.type", "native");
1020
1021                 assertNotNull(feat.activatePolicySession(polcont, "myname", "mybase"));
1022         }
1023
1024         @Test
1025         public void testIsPersistenceEnabled_None() throws Exception {
1026                 feat.globalInit(null, SRC_TEST_RESOURCES);
1027
1028                 mockDbConn(5);
1029                 setUpKie("myname", 999L, true);
1030
1031                 props.remove("persistence.type");
1032
1033                 assertNull(feat.activatePolicySession(polcont, "myname", "mybase"));
1034         }
1035
1036         @Test
1037         public void testGetProperties_Ex() throws Exception {
1038                 feat.globalInit(null, SRC_TEST_RESOURCES);
1039
1040                 mockDbConn(5);
1041                 setUpKie("myname", 999L, true);
1042
1043                 when(fact.getPolicyController(polcont)).thenThrow(new IllegalArgumentException("expected exception"));
1044
1045                 assertNull(feat.activatePolicySession(polcont, "myname", "mybase"));
1046         }
1047
1048         @Test
1049         public void testGetProperty_Specific() throws Exception {
1050                 feat.globalInit(null, SRC_TEST_RESOURCES);
1051
1052                 mockDbConn(5);
1053                 setUpKie("myname", 999L, true);
1054
1055                 props.remove("persistence.type");
1056                 props.setProperty("persistence.myname.type", "auto");
1057
1058                 assertNotNull(feat.activatePolicySession(polcont, "myname", "mybase"));
1059         }
1060
1061         @Test
1062         public void testGetProperty_Specific_None() throws Exception {
1063                 feat.globalInit(null, SRC_TEST_RESOURCES);
1064
1065                 mockDbConn(5);
1066                 setUpKie("myname", 999L, true);
1067
1068                 props.remove("persistence.type");
1069                 props.setProperty("persistence.xxx.type", "auto");
1070
1071                 assertNull(feat.activatePolicySession(polcont, "myname", "mybase"));
1072         }
1073
1074         @Test
1075         public void testGetProperty_Both_SpecificOn() throws Exception {
1076                 feat.globalInit(null, SRC_TEST_RESOURCES);
1077
1078                 mockDbConn(5);
1079                 setUpKie("myname", 999L, true);
1080
1081                 props.setProperty("persistence.type", "other");
1082                 props.setProperty("persistence.myname.type", "auto");
1083
1084                 assertNotNull(feat.activatePolicySession(polcont, "myname", "mybase"));
1085         }
1086
1087         @Test
1088         public void testGetProperty_Both_SpecificDisabledOff() throws Exception {
1089                 feat.globalInit(null, SRC_TEST_RESOURCES);
1090
1091                 mockDbConn(5);
1092                 setUpKie("myname", 999L, true);
1093
1094                 props.setProperty("persistence.type", "auto");
1095                 props.setProperty("persistence.myname.type", "other");
1096
1097                 assertNull(feat.activatePolicySession(polcont, "myname", "mybase"));
1098         }
1099
1100         @Test
1101         public void testGetProperty_None() throws Exception {
1102                 feat.globalInit(null, SRC_TEST_RESOURCES);
1103
1104                 mockDbConn(5);
1105                 setUpKie("myname", 999L, true);
1106
1107                 props.remove("persistence.type");
1108
1109                 assertNull(feat.activatePolicySession(polcont, "myname", "mybase"));
1110         }
1111
1112         @Test
1113         public void testPersistenceFeatureException() {
1114                 SecurityException secex = new SecurityException("expected exception");
1115                 PersistenceFeatureException ex = new PersistenceFeatureException(secex);
1116
1117                 assertEquals(secex, ex.getCause());
1118
1119         }
1120
1121         @Test
1122         public void testDsEmf_RtEx() throws Exception {
1123                 feat.globalInit(null, SRC_TEST_RESOURCES);
1124
1125                 mockDbConn(5);
1126                 setUpKie("myname", 999L, false);
1127                 
1128                 when(fact.makeEntMgrFact(any())).thenThrow(new IllegalArgumentException("expected exception"));
1129
1130                 try {
1131                         feat.activatePolicySession(polcont, "myname", "mybase");
1132                         fail("missing exception");
1133                         
1134                 } catch(IllegalArgumentException ex) {
1135                         logger.trace("expected exception", ex);
1136                 }
1137
1138                 verify(bds, times(2)).close();
1139         }
1140
1141         @Test
1142         public void testDsEmf_Close_RtEx() throws Exception {
1143                 feat.globalInit(null, SRC_TEST_RESOURCES);
1144
1145                 mockDbConn(5);
1146                 setUpKie("myname", 999L, false);
1147                 
1148                 feat.activatePolicySession(polcont, "myname", "mybase");
1149
1150                 ArgumentCaptor<PersistenceFeature.ContainerAdjunct> adjcap = ArgumentCaptor
1151                                 .forClass(PersistenceFeature.ContainerAdjunct.class);
1152
1153                 verify(polcont, times(1)).setAdjunct(any(), adjcap.capture());
1154
1155                 // return adjunct on next call
1156                 when(polcont.getAdjunct(any())).thenReturn(adjcap.getValue());
1157
1158                 try {
1159                         doThrow(new IllegalArgumentException("expected exception")).when(emf).close();
1160                         
1161                         feat.destroyKieSession(polsess);
1162                         fail("missing exception");
1163                         
1164                 } catch(IllegalArgumentException ex) {
1165                         logger.trace("expected exception", ex);
1166                 }
1167
1168                 verify(bds, times(2)).close();
1169         }
1170
1171         @Test
1172         public void testDsEmf_CloseDataSource_RtEx() throws Exception {
1173                 feat.globalInit(null, SRC_TEST_RESOURCES);
1174
1175                 mockDbConn(5);
1176                 setUpKie("myname", 999L, false);
1177                 
1178                 feat.activatePolicySession(polcont, "myname", "mybase");
1179
1180                 ArgumentCaptor<PersistenceFeature.ContainerAdjunct> adjcap = ArgumentCaptor
1181                                 .forClass(PersistenceFeature.ContainerAdjunct.class);
1182
1183                 verify(polcont, times(1)).setAdjunct(any(), adjcap.capture());
1184
1185                 // return adjunct on next call
1186                 when(polcont.getAdjunct(any())).thenReturn(adjcap.getValue());
1187
1188                 try {
1189                         doThrow(new SQLException("expected exception")).when(bds).close();
1190                         
1191                         feat.destroyKieSession(polsess);
1192                         fail("missing exception");
1193                         
1194                 } catch(PersistenceFeatureException ex) {
1195                         logger.trace("expected exception", ex);
1196                 }
1197         }
1198
1199         /**
1200          * Gets an ordered list of ids of the current SessionInfo records.
1201          * 
1202          * @return ordered list of SessInfo IDs
1203          * @throws SQLException
1204          * @throws IOException
1205          */
1206         private List<Integer> getSessions() throws SQLException, IOException {
1207                 attachDb();
1208
1209                 ArrayList<Integer> lst = new ArrayList<>(5);
1210
1211                 try (PreparedStatement stmt = conn.prepareStatement("SELECT id from sessioninfo order by id");
1212                                 ResultSet rs = stmt.executeQuery()) {
1213
1214                         while (rs.next()) {
1215                                 lst.add(rs.getInt(1));
1216                         }
1217                 }
1218
1219                 return lst;
1220         }
1221
1222         /**
1223          * Sets up for doing invoking the newKieSession() method.
1224          * 
1225          * @param sessnm
1226          *            name to which JPA should respond with a session
1227          * @param sessid
1228          *            session id to be returned by the session
1229          * @param loadOk
1230          *            {@code true} if loadKieSession() should return a value,
1231          *            {@code false} to return null
1232          * @throws Exception 
1233          */
1234         private void setUpKie(String sessnm, long sessid, boolean loadOk) throws Exception {
1235
1236                 when(fact.makeJpaConnector(emf)).thenReturn(jpa);
1237                 when(fact.makeEntMgrFact(any())).thenReturn(emf);
1238                 when(fact.getPolicyController(polcont)).thenReturn(polctlr);
1239
1240                 props.setProperty("persistence.type", "auto");
1241
1242                 when(polctlr.getProperties()).thenReturn(props);
1243
1244                 when(jpa.get(sessnm)).thenReturn(sess);
1245
1246                 when(sess.getSessionId()).thenReturn(sessid);
1247
1248                 when(polsess.getPolicyContainer()).thenReturn(polcont);
1249                 when(polsess.getName()).thenReturn(sessnm);
1250
1251                 if (loadOk) {
1252                         when(kiesess.getIdentifier()).thenReturn(sessid);
1253                         when(kiestore.loadKieSession(anyLong(), any(), any(), any())).thenReturn(kiesess);
1254
1255                 } else {
1256                         // use an alternate id for the new session
1257                         when(kiesess.getIdentifier()).thenReturn(100L);
1258                         when(kiestore.loadKieSession(anyLong(), any(), any(), any())).thenReturn(null);
1259                 }
1260
1261                 when(kiestore.newKieSession(any(), any(), any())).thenReturn(kiesess);
1262         }
1263
1264         /**
1265          * Creates the SessionInfo DB table and populates it with some data.
1266          * 
1267          * @param expMs
1268          *            number of milli-seconds for expired sessioninfo records
1269          * @throws SQLException
1270          * @throws IOException
1271          */
1272         private void makeSessionInfoTbl(int expMs) throws SQLException, IOException {
1273
1274                 attachDb();
1275
1276                 try (PreparedStatement stmt = conn
1277                                 .prepareStatement("CREATE TABLE sessioninfo(id int, lastmodificationdate timestamp)")) {
1278
1279                         stmt.executeUpdate();
1280                 }
1281
1282                 try (PreparedStatement stmt = conn
1283                                 .prepareStatement("INSERT into sessioninfo(id, lastmodificationdate) values(?, ?)")) {
1284
1285                         Timestamp ts;
1286
1287                         // current data
1288                         ts = new Timestamp(System.currentTimeMillis());
1289                         stmt.setTimestamp(2, ts);
1290
1291                         stmt.setInt(1, 1);
1292                         stmt.executeUpdate();
1293
1294                         stmt.setInt(1, 4);
1295                         stmt.executeUpdate();
1296
1297                         stmt.setInt(1, 5);
1298                         stmt.executeUpdate();
1299
1300                         // expired data
1301                         ts = new Timestamp(System.currentTimeMillis() - expMs);
1302                         stmt.setTimestamp(2, ts);
1303
1304                         stmt.setInt(1, 2);
1305                         stmt.executeUpdate();
1306
1307                         stmt.setInt(1, 3);
1308                         stmt.executeUpdate();
1309                 }
1310         }
1311
1312         /**
1313          * Attaches {@link #conn} to the DB, if it isn't already attached.
1314          * 
1315          * @throws SQLException
1316          * @throws IOException
1317          *             if the property file cannot be read
1318          */
1319         private void attachDb() throws SQLException, IOException {
1320                 if (conn == null) {
1321                         Properties p = loadDbProps();
1322
1323                         conn = DriverManager.getConnection(p.getProperty(DroolsPersistenceProperties.DB_URL),
1324                                         p.getProperty(DroolsPersistenceProperties.DB_USER),
1325                                         p.getProperty(DroolsPersistenceProperties.DB_PWD));
1326                         conn.setAutoCommit(true);
1327                 }
1328         }
1329
1330         /**
1331          * Loads the DB properties from the file,
1332          * <i>feature-session-persistence.properties</i>.
1333          * 
1334          * @return the properties that were loaded
1335          * @throws IOException
1336          *             if the property file cannot be read
1337          * @throws FileNotFoundException
1338          *             if the property file does not exist
1339          */
1340         private Properties loadDbProps() throws IOException, FileNotFoundException {
1341
1342                 Properties p = new Properties();
1343
1344                 try (FileReader rdr = new FileReader("src/test/resources/feature-session-persistence.properties")) {
1345                         p.load(rdr);
1346                 }
1347
1348                 return p;
1349         }
1350
1351         /**
1352          * Create a mock DB connection and statement.
1353          * 
1354          * @param retval
1355          *            value to be returned when the statement is executed, or
1356          *            negative to throw an exception
1357          * @return the statement that will be returned by the connection
1358          * @throws SQLException
1359          */
1360         private PreparedStatement mockDbConn(int retval) throws SQLException {
1361                 Connection c = mock(Connection.class);
1362                 PreparedStatement s = mock(PreparedStatement.class);
1363
1364                 when(bds.getConnection()).thenReturn(c);
1365                 when(fact.makeDataSource(any())).thenReturn(bds);
1366                 when(c.prepareStatement(anyString())).thenReturn(s);
1367
1368                 if (retval < 0) {
1369                         // should throw an exception
1370                         when(s.executeUpdate()).thenThrow(new SQLException("expected exception"));
1371
1372                 } else {
1373                         // should return the value
1374                         when(s.executeUpdate()).thenReturn(retval);
1375                 }
1376
1377                 return s;
1378         }
1379
1380         /**
1381          * A partial factory, which exports a few of the real methods, but overrides
1382          * the rest.
1383          */
1384         private class PartialFactory extends PersistenceFeature.Factory {
1385
1386                 @Override
1387                 public TransactionManager getTransMgr() {
1388                         return transmgr;
1389                 }
1390
1391                 @Override
1392                 public UserTransaction getUserTrans() {
1393                         return usertrans;
1394                 }
1395
1396                 @Override
1397                 public TransactionSynchronizationRegistry getTransSyncReg() {
1398                         return transreg;
1399                 }
1400
1401                 @Override
1402                 public KieServices getKieServices() {
1403                         return kiesvc;
1404                 }
1405
1406                 @Override
1407                 public EntityManagerFactory makeEntMgrFact(Map<String, Object> props) {
1408                         return emf;
1409                 }
1410
1411                 @Override
1412                 public PolicyController getPolicyController(PolicyContainer container) {
1413                         return polctlr;
1414                 }
1415
1416         }
1417 }