aboutsummaryrefslogtreecommitdiffstats
path: root/feature-session-persistence/src/main/java
diff options
context:
space:
mode:
authorJim Hahn <jrh3@att.com>2018-02-14 12:52:31 -0500
committerJim Hahn <jrh3@att.com>2018-02-14 16:14:17 -0500
commitc83e35bab5aa44f01cb7a9089701ef963ee0c131 (patch)
treed76dfcdb85ecdde91202da22053876ab57f46204 /feature-session-persistence/src/main/java
parentc5d5a9058d47eca9d4ac90308514ff8f1f9d0ca3 (diff)
Replace bitronix and eclipselink in persistence
Replaced bitronix transaction manager, which is not intended for production, with jboss transaction manager. Eliminated eclipselink so that only hibernate is used for persistence for both JPA and drools-persistence. Added more test cases to EntityMgrTrans to provide coverage for various exception types. Moved object store to features/session-persistence/jta. Wrapped RuntimeException in specific type. Modified test to throw specific exception type. Converted GenSchema from an @Test to a main(). Logged caught exceptions in junit tests. Change-Id: I4b02efc8da43d20b2dbb3c0b25adc382e80474ec Issue-ID: POLICY-191 Signed-off-by: Jim Hahn <jrh3@att.com>
Diffstat (limited to 'feature-session-persistence/src/main/java')
-rw-r--r--feature-session-persistence/src/main/java/org/onap/policy/drools/persistence/DroolsPersistenceProperties.java5
-rw-r--r--feature-session-persistence/src/main/java/org/onap/policy/drools/persistence/DroolsSessionEntity.java55
-rw-r--r--feature-session-persistence/src/main/java/org/onap/policy/drools/persistence/EntityMgrCloser.java49
-rw-r--r--feature-session-persistence/src/main/java/org/onap/policy/drools/persistence/EntityMgrTrans.java83
-rw-r--r--feature-session-persistence/src/main/java/org/onap/policy/drools/persistence/JpaDroolsSessionConnector.java68
-rw-r--r--feature-session-persistence/src/main/java/org/onap/policy/drools/persistence/PersistenceFeature.java492
6 files changed, 383 insertions, 369 deletions
diff --git a/feature-session-persistence/src/main/java/org/onap/policy/drools/persistence/DroolsPersistenceProperties.java b/feature-session-persistence/src/main/java/org/onap/policy/drools/persistence/DroolsPersistenceProperties.java
index 1c935b0c..42a638a0 100644
--- a/feature-session-persistence/src/main/java/org/onap/policy/drools/persistence/DroolsPersistenceProperties.java
+++ b/feature-session-persistence/src/main/java/org/onap/policy/drools/persistence/DroolsPersistenceProperties.java
@@ -27,10 +27,9 @@ public class DroolsPersistenceProperties {
* feature-session-persistence.properties parameter key values
*/
public static final String DB_DRIVER = "javax.persistence.jdbc.driver";
- public static final String DB_DATA_SOURCE = "hibernate.dataSource";
public static final String DB_URL = "javax.persistence.jdbc.url";
public static final String DB_USER = "javax.persistence.jdbc.user";
public static final String DB_PWD = "javax.persistence.jdbc.password";
- public static final String DB_SESSIONINFO_TIMEOUT =
- "persistence.sessioninfo.timeout";
+ public static final String DB_SESSIONINFO_TIMEOUT = "persistence.sessioninfo.timeout";
+ public static final String JTA_OBJECTSTORE_DIR = "persistence.objectstore.dir";
}
diff --git a/feature-session-persistence/src/main/java/org/onap/policy/drools/persistence/DroolsSessionEntity.java b/feature-session-persistence/src/main/java/org/onap/policy/drools/persistence/DroolsSessionEntity.java
index e9c5b33b..b3616c43 100644
--- a/feature-session-persistence/src/main/java/org/onap/policy/drools/persistence/DroolsSessionEntity.java
+++ b/feature-session-persistence/src/main/java/org/onap/policy/drools/persistence/DroolsSessionEntity.java
@@ -35,53 +35,53 @@ import javax.persistence.TemporalType;
public class DroolsSessionEntity implements Serializable, DroolsSession {
private static final long serialVersionUID = -5495057038819948709L;
-
+
@Id
- @Column(name="sessionName", nullable=false)
+ @Column(name = "sessionName", nullable = false)
private String sessionName = "-1";
-
- @Column(name="sessionId", nullable=false)
+
+ @Column(name = "sessionId", nullable = false)
private long sessionId = -1L;
-
+
@Temporal(TemporalType.TIMESTAMP)
- @Column(name="createdDate", nullable=false)
+ @Column(name = "createdDate", nullable = false)
private Date createdDate;
-
+
@Temporal(TemporalType.TIMESTAMP)
- @Column(name="updatedDate", nullable=false)
+ @Column(name = "updatedDate", nullable = false)
private Date updatedDate;
-
-
+
public DroolsSessionEntity() {
-
+
}
-
- public DroolsSessionEntity(String sessionName,
- long sessionId) {
+
+ public DroolsSessionEntity(String sessionName, long sessionId) {
this.sessionName = sessionName;
this.sessionId = sessionId;
-
+
}
-
+
@PrePersist
- public void prePersist() {
+ public void prePersist() {
this.createdDate = new Date();
this.updatedDate = new Date();
}
-
+
@PreUpdate
public void preUpdate() {
this.updatedDate = new Date();
}
-
+
@Override
public String getSessionName() {
return sessionName;
}
+
@Override
public void setSessionName(String sessionName) {
this.sessionName = sessionName;
}
+
@Override
public long getSessionId() {
return sessionId;
@@ -92,7 +92,7 @@ public class DroolsSessionEntity implements Serializable, DroolsSession {
this.sessionId = sessionId;
}
- @Override
+ @Override
public Date getCreatedDate() {
return createdDate;
}
@@ -112,17 +112,16 @@ public class DroolsSessionEntity implements Serializable, DroolsSession {
this.updatedDate = updatedDate;
}
-
@Override
- public boolean equals(Object other){
- if(other instanceof DroolsSession){
+ public boolean equals(Object other) {
+ if (other instanceof DroolsSession) {
DroolsSession p = (DroolsSession) other;
return this.getSessionName().equals(p.getSessionName());
- }else{
+ } else {
return false;
}
}
-
+
@Override
public int hashCode() {
final int prime = 31;
@@ -130,12 +129,10 @@ public class DroolsSessionEntity implements Serializable, DroolsSession {
result = prime * result + getSessionName().hashCode();
return result;
}
-
+
@Override
public String toString() {
- return "{name=" + getSessionName()
- + ", id=" + getSessionId() + "}";
+ return "{name=" + getSessionName() + ", id=" + getSessionId() + "}";
}
-
}
diff --git a/feature-session-persistence/src/main/java/org/onap/policy/drools/persistence/EntityMgrCloser.java b/feature-session-persistence/src/main/java/org/onap/policy/drools/persistence/EntityMgrCloser.java
deleted file mode 100644
index 58292117..00000000
--- a/feature-session-persistence/src/main/java/org/onap/policy/drools/persistence/EntityMgrCloser.java
+++ /dev/null
@@ -1,49 +0,0 @@
-/*-
- * ============LICENSE_START=======================================================
- * feature-session-persistence
- * ================================================================================
- * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
- * ================================================================================
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- * ============LICENSE_END=========================================================
- */
-
-package org.onap.policy.drools.persistence;
-
-import javax.persistence.EntityManager;
-
-/**
- * Wrapper for an <i>EntityManager</i>, providing auto-close functionality.
- */
-public class EntityMgrCloser implements AutoCloseable {
-
- /**
- * The wrapper manager.
- */
- private final EntityManager em;
-
- /**
- *
- * @param em
- * manager to be auto-closed
- */
- public EntityMgrCloser(EntityManager em) {
- this.em = em;
- }
-
- @Override
- public void close() {
- em.close();
- }
-
-}
diff --git a/feature-session-persistence/src/main/java/org/onap/policy/drools/persistence/EntityMgrTrans.java b/feature-session-persistence/src/main/java/org/onap/policy/drools/persistence/EntityMgrTrans.java
index 79b620d3..9bb26ac1 100644
--- a/feature-session-persistence/src/main/java/org/onap/policy/drools/persistence/EntityMgrTrans.java
+++ b/feature-session-persistence/src/main/java/org/onap/policy/drools/persistence/EntityMgrTrans.java
@@ -21,10 +21,18 @@
package org.onap.policy.drools.persistence;
import javax.persistence.EntityManager;
-import javax.persistence.EntityTransaction;
+import javax.transaction.HeuristicMixedException;
+import javax.transaction.HeuristicRollbackException;
+import javax.transaction.NotSupportedException;
+import javax.transaction.RollbackException;
+import javax.transaction.Status;
+import javax.transaction.SystemException;
+import javax.transaction.UserTransaction;
+
+import org.onap.policy.common.utils.jpa.EntityMgrCloser;
/**
- * Wrapper for an <i>EntityManager</i> that creates a transaction that is
+ * Wrapper for an <i>EntityManager</i> that creates a JTA transaction that is
* auto-rolled back when closed.
*/
public class EntityMgrTrans extends EntityMgrCloser {
@@ -32,7 +40,7 @@ public class EntityMgrTrans extends EntityMgrCloser {
/**
* Transaction to be rolled back.
*/
- private EntityTransaction trans;
+ private static UserTransaction userTrans = com.arjuna.ats.jta.UserTransaction.userTransaction();
/**
*
@@ -43,39 +51,94 @@ public class EntityMgrTrans extends EntityMgrCloser {
super(em);
try {
- trans = em.getTransaction();
- trans.begin();
+ userTrans.begin();
+ em.joinTransaction();
} catch (RuntimeException e) {
em.close();
- throw e;
+ throw new EntityMgrException(e);
+
+ } catch (NotSupportedException | SystemException e) {
+ em.close();
+ throw new EntityMgrException(e);
}
}
/**
+ * Gets the user transaction. For use by junit tests.
+ *
+ * @return the user transaction
+ */
+ protected static UserTransaction getUserTrans() {
+ return userTrans;
+ }
+
+ /**
+ * Sets the user transaction. For use by junit tests.
+ *
+ * @param userTrans
+ * the new user transaction
+ */
+ protected static void setUserTrans(UserTransaction userTrans) {
+ EntityMgrTrans.userTrans = userTrans;
+ }
+
+ /**
* Commits the transaction.
*/
public void commit() {
- trans.commit();
+ try {
+ userTrans.commit();
+
+ } catch (SecurityException | IllegalStateException | RollbackException | HeuristicMixedException
+ | HeuristicRollbackException | SystemException e) {
+
+ throw new EntityMgrException(e);
+ }
}
/**
* Rolls back the transaction.
*/
public void rollback() {
- trans.rollback();
+ try {
+ userTrans.rollback();
+
+ } catch (IllegalStateException | SecurityException | SystemException e) {
+ throw new EntityMgrException(e);
+ }
}
@Override
public void close() {
try {
- if (trans.isActive()) {
- trans.rollback();
+ if (userTrans.getStatus() == Status.STATUS_ACTIVE) {
+ userTrans.rollback();
}
+ } catch (IllegalStateException | SecurityException | SystemException e) {
+ throw new EntityMgrException(e);
+
} finally {
super.close();
}
}
+ /**
+ * Runtime exceptions generated by this class. Wraps exceptions generated by
+ * delegated operations, particularly when they are not, themselves, Runtime
+ * exceptions.
+ */
+ public static class EntityMgrException extends RuntimeException {
+ private static final long serialVersionUID = 1L;
+
+ /**
+ *
+ * @param e
+ * exception to be wrapped
+ */
+ public EntityMgrException(Exception e) {
+ super(e);
+ }
+ }
}
diff --git a/feature-session-persistence/src/main/java/org/onap/policy/drools/persistence/JpaDroolsSessionConnector.java b/feature-session-persistence/src/main/java/org/onap/policy/drools/persistence/JpaDroolsSessionConnector.java
index 76c09681..cd76ae8d 100644
--- a/feature-session-persistence/src/main/java/org/onap/policy/drools/persistence/JpaDroolsSessionConnector.java
+++ b/feature-session-persistence/src/main/java/org/onap/policy/drools/persistence/JpaDroolsSessionConnector.java
@@ -26,14 +26,12 @@ import javax.persistence.EntityManagerFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-
public class JpaDroolsSessionConnector implements DroolsSessionConnector {
private static Logger logger = LoggerFactory.getLogger(JpaDroolsSessionConnector.class);
-
+
private final EntityManagerFactory emf;
-
-
+
public JpaDroolsSessionConnector(EntityManagerFactory emf) {
this.emf = emf;
}
@@ -43,11 +41,11 @@ public class JpaDroolsSessionConnector implements DroolsSessionConnector {
EntityManager em = emf.createEntityManager();
DroolsSessionEntity s = null;
-
- try(EntityMgrTrans trans = new EntityMgrTrans(em)) {
-
+
+ try (EntityMgrTrans trans = new EntityMgrTrans(em)) {
+
s = em.find(DroolsSessionEntity.class, sessName);
- if(s != null) {
+ if (s != null) {
em.refresh(s);
}
@@ -60,57 +58,59 @@ public class JpaDroolsSessionConnector implements DroolsSessionConnector {
@Override
public void replace(DroolsSession sess) {
String sessName = sess.getSessionName();
-
+
logger.info("replace: Entering and manually updating session name= {}", sessName);
-
+
EntityManager em = emf.createEntityManager();
-
- try(EntityMgrTrans trans = new EntityMgrTrans(em)) {
-
- if( ! update(em, sess)) {
+
+ try (EntityMgrTrans trans = new EntityMgrTrans(em)) {
+
+ if (!update(em, sess)) {
add(em, sess);
}
-
+
trans.commit();
}
-
+
logger.info("replace: Exiting");
}
/**
* Adds a session to the persistent store.
- * @param em entity manager
- * @param sess session to be added
+ *
+ * @param em
+ * entity manager
+ * @param sess
+ * session to be added
*/
private void add(EntityManager em, DroolsSession sess) {
logger.info("add: Inserting session id={}", sess.getSessionId());
- DroolsSessionEntity ent =
- new DroolsSessionEntity(
- sess.getSessionName(),
- sess.getSessionId());
-
+ DroolsSessionEntity ent = new DroolsSessionEntity(sess.getSessionName(), sess.getSessionId());
+
em.persist(ent);
}
-
+
/**
* Updates a session, if it exists within the persistent store.
- * @param em entity manager
- * @param sess session data to be persisted
- * @return {@code true} if a record was updated, {@code false} if it
- * was not found
+ *
+ * @param em
+ * entity manager
+ * @param sess
+ * session data to be persisted
+ * @return {@code true} if a record was updated, {@code false} if it was not
+ * found
*/
private boolean update(EntityManager em, DroolsSession sess) {
-
- DroolsSessionEntity s =
- em.find(DroolsSessionEntity.class, sess.getSessionName());
- if(s == null) {
+
+ DroolsSessionEntity s = em.find(DroolsSessionEntity.class, sess.getSessionName());
+ if (s == null) {
return false;
}
logger.info("update: Updating session id to {}", sess.getSessionId());
- s.setSessionId( sess.getSessionId());
-
+ s.setSessionId(sess.getSessionId());
+
return true;
}
}
diff --git a/feature-session-persistence/src/main/java/org/onap/policy/drools/persistence/PersistenceFeature.java b/feature-session-persistence/src/main/java/org/onap/policy/drools/persistence/PersistenceFeature.java
index db33d05a..032383b4 100644
--- a/feature-session-persistence/src/main/java/org/onap/policy/drools/persistence/PersistenceFeature.java
+++ b/feature-session-persistence/src/main/java/org/onap/policy/drools/persistence/PersistenceFeature.java
@@ -21,10 +21,7 @@
package org.onap.policy.drools.persistence;
import java.io.IOException;
-import java.net.InetAddress;
-import java.net.UnknownHostException;
import java.sql.Connection;
-import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.util.HashMap;
@@ -35,8 +32,12 @@ import java.util.concurrent.TimeUnit;
import javax.persistence.EntityManagerFactory;
import javax.persistence.Persistence;
+import javax.transaction.TransactionManager;
+import javax.transaction.TransactionSynchronizationRegistry;
+import javax.transaction.UserTransaction;
-import org.eclipse.persistence.config.PersistenceUnitProperties;
+import org.apache.commons.dbcp2.BasicDataSource;
+import org.apache.commons.dbcp2.BasicDataSourceFactory;
import org.kie.api.KieServices;
import org.kie.api.runtime.Environment;
import org.kie.api.runtime.EnvironmentName;
@@ -52,11 +53,6 @@ import org.onap.policy.drools.utils.PropertyUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import bitronix.tm.BitronixTransactionManager;
-import bitronix.tm.Configuration;
-import bitronix.tm.TransactionManagerServices;
-import bitronix.tm.resource.jdbc.PoolingDataSource;
-
/**
* If this feature is supported, there is a single instance of it. It adds
* persistence to Drools sessions. In addition, if an active-standby feature
@@ -71,7 +67,6 @@ public class PersistenceFeature implements PolicySessionFeatureAPI, PolicyEngine
private static final Logger logger = LoggerFactory.getLogger(PersistenceFeature.class);
-
/**
* Standard factory used to get various items.
*/
@@ -88,11 +83,6 @@ public class PersistenceFeature implements PolicySessionFeatureAPI, PolicyEngine
private KieServices kieSvcFact;
/**
- * Host name.
- */
- private String hostName;
-
- /**
* Persistence properties.
*/
private Properties persistProps;
@@ -159,10 +149,8 @@ public class PersistenceFeature implements PolicySessionFeatureAPI, PolicyEngine
*/
@Override
public void globalInit(String args[], String configDir) {
-
- kieSvcFact = fact.getKieServices();
- initHostName();
+ kieSvcFact = fact.getKieServices();
try {
persistProps = fact.loadProperties(configDir + "/feature-session-persistence.properties");
@@ -172,10 +160,6 @@ public class PersistenceFeature implements PolicySessionFeatureAPI, PolicyEngine
}
sessionInfoTimeoutMs = getPersistenceTimeout();
-
- Configuration bitronixConfiguration = fact.getTransMgrConfig();
- bitronixConfiguration.setJournal(null);
- bitronixConfiguration.setServerId(hostName);
}
/**
@@ -199,6 +183,7 @@ public class PersistenceFeature implements PolicySessionFeatureAPI, PolicyEngine
*/
@Override
public PolicySession.ThreadModel selectThreadModel(PolicySession session) {
+
PolicyContainer policyContainer = session.getPolicyContainer();
if (isPersistenceEnabled(policyContainer, session.getName())) {
return new PersistentThreadModel(session, getProperties(policyContainer));
@@ -211,10 +196,10 @@ public class PersistenceFeature implements PolicySessionFeatureAPI, PolicyEngine
*/
@Override
public void disposeKieSession(PolicySession policySession) {
-
+
ContainerAdjunct contAdj = (ContainerAdjunct) policySession.getPolicyContainer().getAdjunct(this);
- if(contAdj != null) {
- contAdj.disposeKieSession( policySession.getName());
+ if (contAdj != null) {
+ contAdj.disposeKieSession(policySession.getName());
}
}
@@ -225,8 +210,8 @@ public class PersistenceFeature implements PolicySessionFeatureAPI, PolicyEngine
public void destroyKieSession(PolicySession policySession) {
ContainerAdjunct contAdj = (ContainerAdjunct) policySession.getPolicyContainer().getAdjunct(this);
- if(contAdj != null) {
- contAdj.destroyKieSession( policySession.getName());
+ if (contAdj != null) {
+ contAdj.destroyKieSession(policySession.getName());
}
}
@@ -291,25 +276,12 @@ public class PersistenceFeature implements PolicySessionFeatureAPI, PolicyEngine
} catch (NumberFormatException e) {
logger.error("Invalid value for Drools persistence property persistence.sessioninfo.timeout: {}",
- timeoutString, e);
+ timeoutString, e);
}
return -1;
}
- /**
- * Initializes {@link #hostName}.
- */
- private void initHostName() {
-
- try {
- hostName = fact.getHostName();
-
- } catch (UnknownHostException e) {
- throw new RuntimeException("cannot determine local hostname", e);
- }
- }
-
/* ============================================================ */
/**
@@ -322,11 +294,11 @@ public class PersistenceFeature implements PolicySessionFeatureAPI, PolicyEngine
* 'PolicyContainer' instance that this adjunct is extending.
*/
private PolicyContainer policyContainer;
-
+
/**
* Maps a KIE session name to its data source.
*/
- private Map<String,PoolingDataSource> name2ds = new HashMap<>();
+ private Map<String, DsEmf> name2ds = new HashMap<>();
/**
* Constructor - initialize a new 'ContainerAdjunct'
@@ -352,89 +324,48 @@ public class PersistenceFeature implements PolicySessionFeatureAPI, PolicyEngine
*/
private KieSession newPersistentKieSession(String name, String kieBaseName) {
- long desiredSessionId;
-
- DroolsSessionConnector conn = getDroolsSessionConnector("onapPU");
+ configureSysProps();
- desiredSessionId = getSessionId(conn, name);
+ BasicDataSource ds = fact.makeDataSource(getDataSourceProperties());
+ DsEmf dsemf = new DsEmf(ds);
- logger.info("\n\nThis controller is primary... coming up with session {} \n\n", desiredSessionId);
+ try {
+ EntityManagerFactory emf = dsemf.emf;
+ DroolsSessionConnector conn = fact.makeJpaConnector(emf);
- // session does not exist -- attempt to create one
- logger.info("getPolicySession:session does not exist -- attempt to create one with name {}", name);
+ long desiredSessionId = getSessionId(conn, name);
- System.getProperties().put("java.naming.factory.initial", "bitronix.tm.jndi.BitronixInitialContextFactory");
+ logger.info("\n\nThis controller is primary... coming up with session {} \n\n", desiredSessionId);
- Environment env = kieSvcFact.newEnvironment();
- String dsName = loadDataSource(name);
+ // session does not exist -- attempt to create one
+ logger.info("getPolicySession:session does not exist -- attempt to create one with name {}", name);
- configureKieEnv(name, env, dsName);
+ Environment env = kieSvcFact.newEnvironment();
- KieSessionConfiguration kConf = kieSvcFact.newKieSessionConfiguration();
+ configureKieEnv(env, emf);
- KieSession kieSession = desiredSessionId >= 0 ? loadKieSession(kieBaseName, desiredSessionId, env, kConf)
- : null;
+ KieSessionConfiguration kConf = kieSvcFact.newKieSessionConfiguration();
- if (kieSession == null) {
- // loadKieSession() returned null or desiredSessionId < 0
- logger.info("LOADING We cannot load session {}. Going to create a new one", desiredSessionId);
+ KieSession kieSession = (desiredSessionId >= 0
+ ? loadKieSession(kieBaseName, desiredSessionId, env, kConf) : null);
- kieSession = newKieSession(kieBaseName, env);
- }
+ if (kieSession == null) {
+ // loadKieSession() returned null or desiredSessionId < 0
+ logger.info("LOADING We cannot load session {}. Going to create a new one", desiredSessionId);
- replaceSession(conn, name, kieSession);
+ kieSession = newKieSession(kieBaseName, env);
+ }
- return kieSession;
- }
+ replaceSession(conn, name, kieSession);
- /**
- * Loads a data source into {@link #name2ds}, if one doesn't exist
- * yet.
- * @param sessName session name
- * @return the unique data source name
- */
- private String loadDataSource(String sessName) {
- PoolingDataSource ds = name2ds.get(sessName);
-
- if(ds == null) {
- Properties props = new Properties();
- addOptProp(props, "URL", persistProps.getProperty(DroolsPersistenceProperties.DB_URL));
- addOptProp(props, "user", persistProps.getProperty(DroolsPersistenceProperties.DB_USER));
- addOptProp(props, "password", persistProps.getProperty(DroolsPersistenceProperties.DB_PWD));
-
- ds = fact.makePoolingDataSource();
- ds.setUniqueName("jdbc/BitronixJTADataSource/" + sessName);
- ds.setClassName(persistProps.getProperty(DroolsPersistenceProperties.DB_DATA_SOURCE));
- ds.setMaxPoolSize(3);
- ds.setIsolationLevel("SERIALIZABLE");
- ds.setAllowLocalTransactions(true);
- ds.getDriverProperties().putAll(props);
- ds.init();
-
- name2ds.put(sessName, ds);
- }
-
- return ds.getUniqueName();
- }
+ name2ds.put(name, dsemf);
- /**
- * Configures a Kie Environment
- *
- * @param name
- * session name
- * @param env
- * environment to be configured
- * @param dsName
- * data source name
- */
- private void configureKieEnv(String name, Environment env, String dsName) {
- Properties emfProperties = new Properties();
- emfProperties.setProperty(PersistenceUnitProperties.JTA_DATASOURCE, dsName);
-
- EntityManagerFactory emfact = fact.makeEntMgrFact("onapsessionsPU", emfProperties);
+ return kieSession;
- env.set(EnvironmentName.ENTITY_MANAGER_FACTORY, emfact);
- env.set(EnvironmentName.TRANSACTION_MANAGER, fact.getTransMgr());
+ } catch (RuntimeException e) {
+ dsemf.close();
+ throw e;
+ }
}
/**
@@ -487,7 +418,9 @@ public class PersistenceFeature implements PolicySessionFeatureAPI, PolicyEngine
/**
* Closes the data source associated with a session.
- * @param name name of the session being destroyed
+ *
+ * @param name
+ * name of the session being destroyed
*/
private void destroyKieSession(String name) {
closeDataSource(name);
@@ -495,7 +428,9 @@ public class PersistenceFeature implements PolicySessionFeatureAPI, PolicyEngine
/**
* Closes the data source associated with a session.
- * @param name name of the session being disposed of
+ *
+ * @param name
+ * name of the session being disposed of
*/
private void disposeKieSession(String name) {
closeDataSource(name);
@@ -503,11 +438,13 @@ public class PersistenceFeature implements PolicySessionFeatureAPI, PolicyEngine
/**
* Closes the data source associated with a session.
- * @param name name of the session whose data source is to be closed
+ *
+ * @param name
+ * name of the session whose data source is to be closed
*/
private void closeDataSource(String name) {
- PoolingDataSource ds = name2ds.remove(name);
- if(ds != null) {
+ DsEmf ds = name2ds.remove(name);
+ if (ds != null) {
ds.close();
}
}
@@ -516,6 +453,53 @@ public class PersistenceFeature implements PolicySessionFeatureAPI, PolicyEngine
/* ============================================================ */
/**
+ * Configures java system properties for JPA/JTA.
+ */
+ private void configureSysProps() {
+ System.setProperty("com.arjuna.ats.arjuna.coordinator.defaultTimeout", "60");
+ System.setProperty("com.arjuna.ats.arjuna.objectstore.objectStoreDir",
+ persistProps.getProperty(DroolsPersistenceProperties.JTA_OBJECTSTORE_DIR));
+ System.setProperty("ObjectStoreEnvironmentBean.objectStoreDir",
+ persistProps.getProperty(DroolsPersistenceProperties.JTA_OBJECTSTORE_DIR));
+ }
+
+ /**
+ * Gets the data source properties.
+ *
+ * @return the data source properties
+ */
+ private Properties getDataSourceProperties() {
+ Properties props = new Properties();
+ props.put("driverClassName", persistProps.getProperty(DroolsPersistenceProperties.DB_DRIVER));
+ props.put("url", persistProps.getProperty(DroolsPersistenceProperties.DB_URL));
+ props.put("username", persistProps.getProperty(DroolsPersistenceProperties.DB_USER));
+ props.put("password", persistProps.getProperty(DroolsPersistenceProperties.DB_PWD));
+ props.put("maxActive", "3");
+ props.put("maxIdle", "1");
+ props.put("maxWait", "120000");
+ props.put("whenExhaustedAction", "2");
+ props.put("testOnBorrow", "false");
+ props.put("poolPreparedStatements", "true");
+
+ return props;
+ }
+
+ /**
+ * Configures a Kie Environment
+ *
+ * @param env
+ * environment to be configured
+ * @param emf
+ * entity manager factory
+ */
+ private void configureKieEnv(Environment env, EntityManagerFactory emf) {
+ env.set(EnvironmentName.ENTITY_MANAGER_FACTORY, emf);
+ env.set(EnvironmentName.TRANSACTION, fact.getUserTrans());
+ env.set(EnvironmentName.TRANSACTION_SYNCHRONIZATION_REGISTRY, fact.getTransSyncReg());
+ env.set(EnvironmentName.TRANSACTION_MANAGER, fact.getTransMgr());
+ }
+
+ /**
* Removes "old" Drools 'sessioninfo' records, so they aren't used to
* restore data to Drools sessions. This also has the useful side-effect of
* removing abandoned records as well.
@@ -534,21 +518,15 @@ public class PersistenceFeature implements PolicySessionFeatureAPI, PolicyEngine
return;
}
- // get DB connection properties
- String url = persistProps.getProperty(DroolsPersistenceProperties.DB_URL);
- String user = persistProps.getProperty(DroolsPersistenceProperties.DB_USER);
- String password = persistProps.getProperty(DroolsPersistenceProperties.DB_PWD);
-
- if (url == null || user == null || password == null) {
- logger.error("Missing DB properties for clean up of sessioninfo table");
- return;
- }
-
// now do the record deletion
- try (Connection connection = fact.makeDbConnection(url, user, password);
+ try (BasicDataSource ds = fact.makeDataSource(getDataSourceProperties());
+ Connection connection = ds.getConnection();
PreparedStatement statement = connection.prepareStatement(
"DELETE FROM sessioninfo WHERE timestampdiff(second,lastmodificationdate,now()) > ?")) {
- statement.setLong(1, sessionInfoTimeoutMs/1000);
+
+ connection.setAutoCommit(true);
+
+ statement.setLong(1, sessionInfoTimeoutMs / 1000);
int count = statement.executeUpdate();
logger.info("Cleaning up sessioninfo table -- {} records removed", count);
@@ -565,40 +543,6 @@ public class PersistenceFeature implements PolicySessionFeatureAPI, PolicyEngine
}
/**
- * Gets a connector for manipulating DroolsSession objects within the
- * persistent store.
- *
- * @param pu
- * @return a connector for DroolsSession objects
- */
- private DroolsSessionConnector getDroolsSessionConnector(String pu) {
-
- Properties propMap = new Properties();
- addOptProp(propMap, "javax.persistence.jdbc.driver",
- persistProps.getProperty(DroolsPersistenceProperties.DB_DRIVER));
- addOptProp(propMap, "javax.persistence.jdbc.url", persistProps.getProperty(DroolsPersistenceProperties.DB_URL));
- addOptProp(propMap, "javax.persistence.jdbc.user",
- persistProps.getProperty(DroolsPersistenceProperties.DB_USER));
- addOptProp(propMap, "javax.persistence.jdbc.password",
- persistProps.getProperty(DroolsPersistenceProperties.DB_PWD));
-
- return fact.makeJpaConnector(pu, propMap);
- }
-
- /**
- * Adds an optional property to a set of properties.
- * @param propMap map into which the property should be added
- * @param name property name
- * @param value property value, or {@code null} if it should not
- * be added
- */
- private void addOptProp(Properties propMap, String name, String value) {
- if (value != null) {
- propMap.put(name, value);
- }
- }
-
- /**
* Gets a session's ID from the persistent store.
*
* @param conn
@@ -613,8 +557,8 @@ public class PersistenceFeature implements PolicySessionFeatureAPI, PolicyEngine
}
/**
- * Replaces a session within the persistent store, if it exists. Adds
- * it otherwise.
+ * Replaces a session within the persistent store, if it exists. Adds it
+ * otherwise.
*
* @param conn
* persistence connector
@@ -665,7 +609,7 @@ public class PersistenceFeature implements PolicySessionFeatureAPI, PolicyEngine
*/
private Properties getProperties(PolicyContainer container) {
try {
- return fact.getPolicyContainer(container).getProperties();
+ return fact.getPolicyController(container).getProperties();
} catch (IllegalArgumentException e) {
logger.error("getProperties exception: ", e);
return null;
@@ -705,7 +649,7 @@ public class PersistenceFeature implements PolicySessionFeatureAPI, PolicyEngine
* compatible with persistence.
*/
public class PersistentThreadModel implements Runnable, PolicySession.ThreadModel {
-
+
/**
* Session associated with this persistent thread.
*/
@@ -715,22 +659,22 @@ public class PersistenceFeature implements PolicySessionFeatureAPI, PolicyEngine
* The session thread.
*/
private final Thread thread;
-
+
/**
* Used to indicate that processing should stop.
*/
private final CountDownLatch stopped = new CountDownLatch(1);
-
+
/**
- * Minimum time, in milli-seconds, that the thread should sleep
- * before firing rules again.
+ * Minimum time, in milli-seconds, that the thread should sleep before
+ * firing rules again.
*/
long minSleepTime = 100;
-
+
/**
- * Maximum time, in milli-seconds, that the thread should sleep
- * before firing rules again. This is a "half" time, so that
- * we can multiply it by two without overflowing the word size.
+ * Maximum time, in milli-seconds, that the thread should sleep before
+ * firing rules again. This is a "half" time, so that we can multiply it
+ * by two without overflowing the word size.
*/
long halfMaxSleepTime = 5000L / 2L;
@@ -745,11 +689,11 @@ public class PersistenceFeature implements PolicySessionFeatureAPI, PolicyEngine
public PersistentThreadModel(PolicySession session, Properties properties) {
this.session = session;
this.thread = new Thread(this, getThreadName());
-
+
if (properties == null) {
return;
}
-
+
// extract 'minSleepTime' and/or 'maxSleepTime'
String name = session.getName();
@@ -782,8 +726,8 @@ public class PersistenceFeature implements PolicySessionFeatureAPI, PolicyEngine
minSleepTime = maxSleepTime;
maxSleepTime = tmp;
}
-
- halfMaxSleepTime = Math.max(1, maxSleepTime/2);
+
+ halfMaxSleepTime = Math.max(1, maxSleepTime / 2);
}
/**
@@ -812,18 +756,18 @@ public class PersistenceFeature implements PolicySessionFeatureAPI, PolicyEngine
public void stop() {
// tell the thread to stop
stopped.countDown();
-
+
// wait up to 10 seconds for the thread to stop
try {
thread.join(10000);
-
+
} catch (InterruptedException e) {
logger.error("stopThread exception: ", e);
Thread.currentThread().interrupt();
}
-
+
// verify that it's done
- if(thread.isAlive()) {
+ if (thread.isAlive()) {
logger.error("stopThread: still running");
}
}
@@ -847,7 +791,7 @@ public class PersistenceFeature implements PolicySessionFeatureAPI, PolicyEngine
@Override
public void run() {
logger.info("PersistentThreadModel running");
-
+
// set thread local variable
session.setPolicySession();
@@ -856,33 +800,34 @@ public class PersistenceFeature implements PolicySessionFeatureAPI, PolicyEngine
// We want to continue, despite any exceptions that occur
// while rules are fired.
-
- for(;;) {
-
+
+ for (;;) {
+
try {
if (kieSession.fireAllRules() > 0) {
// some rules fired -- reduce poll delay
- sleepTime = Math.max(minSleepTime, sleepTime/2);
+ sleepTime = Math.max(minSleepTime, sleepTime / 2);
} else {
// no rules fired -- increase poll delay
sleepTime = 2 * Math.min(halfMaxSleepTime, sleepTime);
}
+
} catch (Exception | LinkageError e) {
logger.error("Exception during kieSession.fireAllRules", e);
- }
-
+ }
+
try {
- if(stopped.await(sleepTime, TimeUnit.MILLISECONDS)) {
+ if (stopped.await(sleepTime, TimeUnit.MILLISECONDS)) {
break;
}
-
+
} catch (InterruptedException e) {
logger.error("startThread exception: ", e);
Thread.currentThread().interrupt();
break;
}
}
-
+
logger.info("PersistentThreadModel completed");
}
}
@@ -890,46 +835,104 @@ public class PersistenceFeature implements PolicySessionFeatureAPI, PolicyEngine
/* ============================================================ */
/**
- * Factory for various items. Methods can be overridden for junit testing.
+ * DataSource-EntityManagerFactory pair.
*/
- protected static class Factory {
+ private class DsEmf {
+ private BasicDataSource bds;
+ private EntityManagerFactory emf;
/**
- * Gets the configuration for the transaction manager.
+ * Makes an entity manager factory for the given data source.
*
- * @return the configuration for the transaction manager
+ * @param bds
+ * pooled data source
+ */
+ public DsEmf(BasicDataSource bds) {
+ try {
+ Map<String, Object> props = new HashMap<>();
+ props.put(org.hibernate.cfg.Environment.JPA_JTA_DATASOURCE, bds);
+
+ this.bds = bds;
+ this.emf = fact.makeEntMgrFact(props);
+
+ } catch (RuntimeException e) {
+ closeDataSource();
+ throw e;
+ }
+ }
+
+ /**
+ * Closes the entity manager factory and the data source.
*/
- public Configuration getTransMgrConfig() {
- return TransactionManagerServices.getConfiguration();
+ public void close() {
+ try {
+ emf.close();
+
+ } catch (RuntimeException e) {
+ closeDataSource();
+ throw e;
+ }
+
+ closeDataSource();
}
/**
+ * Closes the data source only.
+ */
+ private void closeDataSource() {
+ try {
+ bds.close();
+
+ } catch (SQLException e) {
+ throw new PersistenceFeatureException(e);
+ }
+
+ }
+ }
+
+ private static class SingletonRegistry {
+ private static final TransactionSynchronizationRegistry transreg = new com.arjuna.ats.internal.jta.transaction.arjunacore.TransactionSynchronizationRegistryImple();
+ }
+
+ /**
+ * Factory for various items. Methods can be overridden for junit testing.
+ */
+ protected static class Factory {
+
+ /**
* Gets the transaction manager.
*
* @return the transaction manager
*/
- public BitronixTransactionManager getTransMgr() {
- return TransactionManagerServices.getTransactionManager();
+ public TransactionManager getTransMgr() {
+ return com.arjuna.ats.jta.TransactionManager.transactionManager();
}
/**
- * Gets the KIE services.
+ * Gets the user transaction.
*
- * @return the KIE services
+ * @return the user transaction
*/
- public KieServices getKieServices() {
- return KieServices.Factory.get();
+ public UserTransaction getUserTrans() {
+ return com.arjuna.ats.jta.UserTransaction.userTransaction();
}
/**
- * Gets the current host name.
+ * Gets the transaction synchronization registry.
*
- * @return the current host name, associated with the IP address of the
- * local machine
- * @throws UnknownHostException
+ * @return the transaction synchronization registry
*/
- public String getHostName() throws UnknownHostException {
- return InetAddress.getLocalHost().getHostName();
+ public TransactionSynchronizationRegistry getTransSyncReg() {
+ return SingletonRegistry.transreg;
+ }
+
+ /**
+ * Gets the KIE services.
+ *
+ * @return the KIE services
+ */
+ public KieServices getKieServices() {
+ return KieServices.Factory.get();
}
/**
@@ -946,58 +949,41 @@ public class PersistenceFeature implements PolicySessionFeatureAPI, PolicyEngine
}
/**
- * Makes a connection to the DB.
+ * Makes a Data Source.
*
- * @param url
- * DB URL
- * @param user
- * user name
- * @param pass
- * password
- * @return a new DB connection
- * @throws SQLException
+ * @param dsProps
+ * data source properties
+ * @return a new data source
*/
- public Connection makeDbConnection(String url, String user, String pass) throws SQLException {
-
- return DriverManager.getConnection(url, user, pass);
- }
+ public BasicDataSource makeDataSource(Properties dsProps) {
+ try {
+ return BasicDataSourceFactory.createDataSource(dsProps);
- /**
- * Makes a new pooling data source.
- *
- * @return a new pooling data source
- */
- public PoolingDataSource makePoolingDataSource() {
- return new PoolingDataSource();
+ } catch (Exception e) {
+ throw new PersistenceFeatureException(e);
+ }
}
/**
* Makes a new JPA connector for drools sessions.
*
- * @param pu
- * PU for the entity manager factory
- * @param propMap
- * properties with which the factory should be configured
+ * @param emf
+ * entity manager factory
* @return a new JPA connector for drools sessions
*/
- public DroolsSessionConnector makeJpaConnector(String pu, Properties propMap) {
-
- EntityManagerFactory emf = makeEntMgrFact(pu, propMap);
-
+ public DroolsSessionConnector makeJpaConnector(EntityManagerFactory emf) {
return new JpaDroolsSessionConnector(emf);
}
/**
* Makes a new entity manager factory.
*
- * @param pu
- * PU for the entity manager factory
- * @param propMap
+ * @param props
* properties with which the factory should be configured
* @return a new entity manager factory
*/
- public EntityManagerFactory makeEntMgrFact(String pu, Properties propMap) {
- return Persistence.createEntityManagerFactory(pu, propMap);
+ public EntityManagerFactory makeEntMgrFact(Map<String, Object> props) {
+ return Persistence.createEntityManagerFactory("onapsessionsPU", props);
}
/**
@@ -1007,8 +993,26 @@ public class PersistenceFeature implements PolicySessionFeatureAPI, PolicyEngine
* container whose controller is to be retrieved
* @return the container's controller
*/
- public PolicyController getPolicyContainer(PolicyContainer container) {
+ public PolicyController getPolicyController(PolicyContainer container) {
return PolicyController.factory.get(container.getGroupId(), container.getArtifactId());
}
}
+
+ /**
+ * Runtime exceptions generated by this class. Wraps exceptions generated by
+ * delegated operations, particularly when they are not, themselves, Runtime
+ * exceptions.
+ */
+ public static class PersistenceFeatureException extends RuntimeException {
+ private static final long serialVersionUID = 1L;
+
+ /**
+ *
+ * @param e
+ * exception to be wrapped
+ */
+ public PersistenceFeatureException(Exception e) {
+ super(e);
+ }
+ }
}