aboutsummaryrefslogtreecommitdiffstats
path: root/feature-session-persistence/src/main
diff options
context:
space:
mode:
Diffstat (limited to 'feature-session-persistence/src/main')
-rw-r--r--feature-session-persistence/src/main/feature/config/feature-session-persistence.properties5
-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
-rw-r--r--feature-session-persistence/src/main/resources/META-INF/persistence.xml21
8 files changed, 392 insertions, 386 deletions
diff --git a/feature-session-persistence/src/main/feature/config/feature-session-persistence.properties b/feature-session-persistence/src/main/feature/config/feature-session-persistence.properties
index 6204b5ed..0f15e3aa 100644
--- a/feature-session-persistence/src/main/feature/config/feature-session-persistence.properties
+++ b/feature-session-persistence/src/main/feature/config/feature-session-persistence.properties
@@ -22,7 +22,8 @@ javax.persistence.jdbc.driver= org.mariadb.jdbc.Driver
javax.persistence.jdbc.url=jdbc:mariadb://${{SQL_HOST}}:3306/sessionpersistence
javax.persistence.jdbc.user=${{SQL_USER}}
javax.persistence.jdbc.password=${{SQL_PASSWORD}}
-hibernate.dataSource=org.mariadb.jdbc.MySQLDataSource
#Seconds timeout - 15 minutes
-persistence.sessioninfo.timeout=900 \ No newline at end of file
+persistence.sessioninfo.timeout=900
+
+persistence.objectstore.dir=features/session-persistence/jta
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);
+ }
+ }
}
diff --git a/feature-session-persistence/src/main/resources/META-INF/persistence.xml b/feature-session-persistence/src/main/resources/META-INF/persistence.xml
index 7ddd2fd3..6b8345c3 100644
--- a/feature-session-persistence/src/main/resources/META-INF/persistence.xml
+++ b/feature-session-persistence/src/main/resources/META-INF/persistence.xml
@@ -23,20 +23,10 @@
xmlns="http://xmlns.jcp.org/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/persistence http://xmlns.jcp.org/xml/ns/persistence/persistence_2_1.xsd">
- <persistence-unit name="onapPU" transaction-type="RESOURCE_LOCAL">
- <!-- This is for database access by non-drools methods -->
- <provider>org.eclipse.persistence.jpa.PersistenceProvider</provider>
- <class>org.onap.policy.drools.persistence.DroolsSessionEntity</class>
- <class>org.drools.persistence.info.SessionInfo</class>
- <class>org.drools.persistence.info.WorkItemInfo</class>
- <properties>
- <!-- Properties are passed in -->
- </properties>
- </persistence-unit>
-
<persistence-unit name="onapsessionsPU" transaction-type="JTA">
<!-- Used for drools session data access -->
- <provider>org.hibernate.jpa.HibernatePersistenceProvider</provider>
+ <provider>org.hibernate.jpa.HibernatePersistenceProvider</provider>
+ <class>org.onap.policy.drools.persistence.DroolsSessionEntity</class>
<class>org.drools.persistence.info.SessionInfo</class>
<class>org.drools.persistence.info.WorkItemInfo</class>
<properties>
@@ -44,18 +34,19 @@
<property name="hibernate.max_fetch_depth" value="3" />
<property name="hibernate.hbm2ddl.auto" value="update" />
<property name="hibernate.show_sql" value="false" />
- <property name="hibernate.transaction.manager_lookup_class"
- value="org.hibernate.transaction.BTMTransactionManagerLookup" />
+ <property name="hibernate.transaction.factory_class" value="org.hibernate.transaction.JTATransactionFactory" />
+ <property name="hibernate.transaction.manager_lookup_class" value="org.hibernate.transaction.JBossTransactionManagerLookup" />
</properties>
</persistence-unit>
<persistence-unit name="schemaDroolsPU" transaction-type="RESOURCE_LOCAL">
<!-- Limited use for generating the DB and schema files for drools DB - uses eclipselink for convenience -->
- <provider>org.eclipse.persistence.jpa.PersistenceProvider</provider>
+ <provider>org.hibernate.jpa.HibernatePersistenceProvider</provider>
<class>org.onap.policy.drools.persistence.DroolsSessionEntity</class>
<class>org.drools.persistence.info.SessionInfo</class>
<class>org.drools.persistence.info.WorkItemInfo</class>
<properties>
+ <property name="hibernate.dialect" value="org.hibernate.dialect.MariaDBDialect" />
<property name="javax.persistence.schema-generation.scripts.action" value="drop-and-create"/>
<property name="javax.persistence.schema-generation.scripts.create-target" value="sql/generatedCreateDrools.ddl"/>
<property name="javax.persistence.schema-generation.scripts.drop-target" value="sql/generatedDropDrools.ddl"/>