diff options
Diffstat (limited to 'feature-session-persistence')
15 files changed, 2966 insertions, 3038 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 c3f00359..4700e8ae 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 @@ -21,17 +21,17 @@ package org.onap.policy.drools.persistence; 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_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 JTA_OBJECTSTORE_DIR = "persistence.objectstore.dir"; + /* + * feature-session-persistence.properties parameter key values + */ + public static final String DB_DRIVER = "javax.persistence.jdbc.driver"; + 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 JTA_OBJECTSTORE_DIR = "persistence.objectstore.dir"; - private DroolsPersistenceProperties() { - super(); - } + private DroolsPersistenceProperties() { + super(); + } } diff --git a/feature-session-persistence/src/main/java/org/onap/policy/drools/persistence/DroolsSession.java b/feature-session-persistence/src/main/java/org/onap/policy/drools/persistence/DroolsSession.java index a012f3c2..e8b50817 100644 --- a/feature-session-persistence/src/main/java/org/onap/policy/drools/persistence/DroolsSession.java +++ b/feature-session-persistence/src/main/java/org/onap/policy/drools/persistence/DroolsSession.java @@ -2,7 +2,7 @@ * ============LICENSE_START======================================================= * feature-session-persistence * ================================================================================ - * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * Copyright (C) 2017-2018 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. @@ -24,12 +24,19 @@ import java.util.Date; public interface DroolsSession { - public String getSessionName(); - public void setSessionName(String sessionName); - public long getSessionId(); - public void setSessionId(long sessionId); - public Date getCreatedDate(); - public void setCreatedDate(Date createdDate); - public Date getUpdatedDate(); - public void setUpdatedDate(Date updatedDate); + public String getSessionName(); + + public void setSessionName(String sessionName); + + public long getSessionId(); + + public void setSessionId(long sessionId); + + public Date getCreatedDate(); + + public void setCreatedDate(Date createdDate); + + public Date getUpdatedDate(); + + public void setUpdatedDate(Date updatedDate); } diff --git a/feature-session-persistence/src/main/java/org/onap/policy/drools/persistence/DroolsSessionConnector.java b/feature-session-persistence/src/main/java/org/onap/policy/drools/persistence/DroolsSessionConnector.java index e2f4ac54..3a8885f8 100644 --- a/feature-session-persistence/src/main/java/org/onap/policy/drools/persistence/DroolsSessionConnector.java +++ b/feature-session-persistence/src/main/java/org/onap/policy/drools/persistence/DroolsSessionConnector.java @@ -2,7 +2,7 @@ * ============LICENSE_START======================================================= * feature-session-persistence * ================================================================================ - * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * Copyright (C) 2017-2018 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. @@ -20,19 +20,18 @@ package org.onap.policy.drools.persistence; -public interface DroolsSessionConnector -{ - /** - * Gets a session by PDP id and name. - * @param sessName - * @return a session, or {@code null} if it is not found - */ - public DroolsSession get(String sessName); - - /** - * Replaces a session, adding it if it does not exist. - * @param sess session to be replaced - */ - public void replace(DroolsSession sess); +public interface DroolsSessionConnector { + /** + * Gets a session by PDP id and name. + * @param sessName session name + * @return a session, or {@code null} if it is not found + */ + public DroolsSession get(String sessName); + + /** + * Replaces a session, adding it if it does not exist. + * @param sess session to be replaced + */ + public void replace(DroolsSession sess); } 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 b3616c43..117e6410 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 @@ -2,14 +2,14 @@ * ============LICENSE_START======================================================= * feature-session-persistence * ================================================================================ - * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * Copyright (C) 2017-2018 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. @@ -34,105 +34,101 @@ import javax.persistence.TemporalType; @Entity public class DroolsSessionEntity implements Serializable, DroolsSession { - private static final long serialVersionUID = -5495057038819948709L; - - @Id - @Column(name = "sessionName", nullable = false) - private String sessionName = "-1"; - - @Column(name = "sessionId", nullable = false) - private long sessionId = -1L; - - @Temporal(TemporalType.TIMESTAMP) - @Column(name = "createdDate", nullable = false) - private Date createdDate; - - @Temporal(TemporalType.TIMESTAMP) - @Column(name = "updatedDate", nullable = false) - private Date updatedDate; - - public DroolsSessionEntity() { - - } - - public DroolsSessionEntity(String sessionName, long sessionId) { - this.sessionName = sessionName; - this.sessionId = sessionId; - - } - - @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; - } - - @Override - public void setSessionId(long sessionId) { - this.sessionId = sessionId; - } - - @Override - public Date getCreatedDate() { - return createdDate; - } - - @Override - public void setCreatedDate(Date createdDate) { - this.createdDate = createdDate; - } - - @Override - public Date getUpdatedDate() { - return updatedDate; - } - - @Override - public void setUpdatedDate(Date updatedDate) { - this.updatedDate = updatedDate; - } - - @Override - public boolean equals(Object other) { - if (other instanceof DroolsSession) { - DroolsSession p = (DroolsSession) other; - return this.getSessionName().equals(p.getSessionName()); - } else { - return false; - } - } - - @Override - public int hashCode() { - final int prime = 31; - int result = 1; - result = prime * result + getSessionName().hashCode(); - return result; - } - - @Override - public String toString() { - return "{name=" + getSessionName() + ", id=" + getSessionId() + "}"; - } - + private static final long serialVersionUID = -5495057038819948709L; + + @Id + @Column(name = "sessionName", nullable = false) + private String sessionName = "-1"; + + @Column(name = "sessionId", nullable = false) + private long sessionId = -1L; + + @Temporal(TemporalType.TIMESTAMP) + @Column(name = "createdDate", nullable = false) + private Date createdDate; + + @Temporal(TemporalType.TIMESTAMP) + @Column(name = "updatedDate", nullable = false) + private Date updatedDate; + + public DroolsSessionEntity() {} + + public DroolsSessionEntity(String sessionName, long sessionId) { + this.sessionName = sessionName; + this.sessionId = sessionId; + } + + @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; + } + + @Override + public void setSessionId(long sessionId) { + this.sessionId = sessionId; + } + + @Override + public Date getCreatedDate() { + return createdDate; + } + + @Override + public void setCreatedDate(Date createdDate) { + this.createdDate = createdDate; + } + + @Override + public Date getUpdatedDate() { + return updatedDate; + } + + @Override + public void setUpdatedDate(Date updatedDate) { + this.updatedDate = updatedDate; + } + + @Override + public boolean equals(Object other) { + if (other instanceof DroolsSession) { + DroolsSession session = (DroolsSession) other; + return this.getSessionName().equals(session.getSessionName()); + } else { + return false; + } + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + getSessionName().hashCode(); + return result; + } + + @Override + public String toString() { + return "{name=" + getSessionName() + ", id=" + getSessionId() + "}"; + } } 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 47ed221e..3d276519 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 @@ -7,9 +7,9 @@ * 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. @@ -32,109 +32,99 @@ import javax.transaction.UserTransaction; import org.onap.policy.common.utils.jpa.EntityMgrCloser; /** - * Wrapper for an <i>EntityManager</i> that creates a JTA transaction that is - * auto-rolled back when closed. + * Wrapper for an <i>EntityManager</i> that creates a JTA transaction that is auto-rolled back when + * closed. */ public class EntityMgrTrans extends EntityMgrCloser { - /** - * Transaction to be rolled back. - */ - private static UserTransaction userTrans = com.arjuna.ats.jta.UserTransaction.userTransaction(); - - /** - * - * @param em - * entity for which a transaction is to be begun - */ - public EntityMgrTrans(EntityManager em) { - super(em); - - try { - userTrans.begin(); - em.joinTransaction(); - - } catch (RuntimeException |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() { - try { - userTrans.commit(); - - } catch (SecurityException | IllegalStateException | RollbackException | HeuristicMixedException - | HeuristicRollbackException | SystemException e) { - - throw new EntityMgrException(e); - } - } - - /** - * Rolls back the transaction. - */ - public void rollback() { - try { - userTrans.rollback(); - - } catch (IllegalStateException | SecurityException | SystemException e) { - throw new EntityMgrException(e); - } - } - - @Override - public void close() { - try { - 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); - } - } + /** Transaction to be rolled back. */ + private static UserTransaction userTrans = com.arjuna.ats.jta.UserTransaction.userTransaction(); + + /** + * Constructor. + * + * @param em entity for which a transaction is to be begun */ + public EntityMgrTrans(EntityManager em) { + super(em); + + try { + userTrans.begin(); + em.joinTransaction(); + + } catch (RuntimeException | 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() { + try { + userTrans.commit(); + + } catch (SecurityException + | IllegalStateException + | RollbackException + | HeuristicMixedException + | HeuristicRollbackException + | SystemException e) { + + throw new EntityMgrException(e); + } + } + + /** Rolls back the transaction. */ + public void rollback() { + try { + userTrans.rollback(); + + } catch (IllegalStateException | SecurityException | SystemException e) { + throw new EntityMgrException(e); + } + } + + @Override + public void close() { + try { + 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; + + public EntityMgrException(Exception ex) { + super(ex); + } + } } 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 cd76ae8d..381a896e 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 @@ -2,14 +2,14 @@ * ============LICENSE_START======================================================= * feature-session-persistence * ================================================================================ - * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * Copyright (C) 2017-2018 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. @@ -28,89 +28,84 @@ import org.slf4j.LoggerFactory; public class JpaDroolsSessionConnector implements DroolsSessionConnector { - private static Logger logger = LoggerFactory.getLogger(JpaDroolsSessionConnector.class); + private static Logger logger = LoggerFactory.getLogger(JpaDroolsSessionConnector.class); - private final EntityManagerFactory emf; + private final EntityManagerFactory emf; - public JpaDroolsSessionConnector(EntityManagerFactory emf) { - this.emf = emf; - } + public JpaDroolsSessionConnector(EntityManagerFactory emf) { + this.emf = emf; + } - @Override - public DroolsSession get(String sessName) { + @Override + public DroolsSession get(String sessName) { - EntityManager em = emf.createEntityManager(); - DroolsSessionEntity s = null; + EntityManager em = emf.createEntityManager(); + DroolsSessionEntity entity = null; - try (EntityMgrTrans trans = new EntityMgrTrans(em)) { + try (EntityMgrTrans trans = new EntityMgrTrans(em)) { - s = em.find(DroolsSessionEntity.class, sessName); - if (s != null) { - em.refresh(s); - } + entity = em.find(DroolsSessionEntity.class, sessName); + if (entity != null) { + em.refresh(entity); + } - trans.commit(); - } + trans.commit(); + } - return s; - } + return entity; + } - @Override - public void replace(DroolsSession sess) { - String sessName = sess.getSessionName(); + @Override + public void replace(DroolsSession sess) { + String sessName = sess.getSessionName(); - logger.info("replace: Entering and manually updating session name= {}", sessName); + logger.info("replace: Entering and manually updating session name= {}", sessName); - EntityManager em = emf.createEntityManager(); + EntityManager em = emf.createEntityManager(); - try (EntityMgrTrans trans = new EntityMgrTrans(em)) { + try (EntityMgrTrans trans = new EntityMgrTrans(em)) { - if (!update(em, sess)) { - add(em, sess); - } + if (!update(em, sess)) { + add(em, sess); + } - trans.commit(); - } + trans.commit(); + } - logger.info("replace: Exiting"); - } + logger.info("replace: Exiting"); + } - /** - * Adds a session to the persistent store. - * - * @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()); + /** + * Adds a session to the persistent store. + * + * @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); - } + 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 - */ - private boolean update(EntityManager em, DroolsSession sess) { + /** + * 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 + */ + private boolean update(EntityManager em, DroolsSession sess) { - DroolsSessionEntity s = em.find(DroolsSessionEntity.class, sess.getSessionName()); - if (s == null) { - return false; - } + 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()); + logger.info("update: Updating session id to {}", sess.getSessionId()); + s.setSessionId(sess.getSessionId()); - return true; - } + 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 129be8a7..7b17de6c 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 @@ -7,9 +7,9 @@ * 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. @@ -54,971 +54,898 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** - * 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 - * exists, then that is used to determine the active and last-active PDP. If it - * does not exist, then the current host name is used as the PDP id. + * 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 exists, then that is used to determine the + * active and last-active PDP. If it does not exist, then the current host name is used as the PDP + * id. * - * The bulk of the code here was once in other classes, such as - * 'PolicyContainer' and 'Main'. It was moved here as part of making this a - * separate optional feature. + * <p>The bulk of the code here was once in other classes, such as 'PolicyContainer' and 'Main'. It + * was moved here as part of making this a separate optional feature. */ public class PersistenceFeature implements PolicySessionFeatureAPI, PolicyEngineFeatureAPI { - private static final Logger logger = LoggerFactory.getLogger(PersistenceFeature.class); - - /** - * Standard factory used to get various items. - */ - private static Factory stdFactory = new Factory(); - - /** - * Factory used to get various items. - */ - private Factory fact = stdFactory; - - /** - * KieService factory. - */ - private KieServices kieSvcFact; - - /** - * Persistence properties. - */ - private Properties persistProps; - - /** - * Whether or not the SessionInfo records should be cleaned out. - */ - private boolean sessInfoCleaned; - - /** - * SessionInfo timeout, in milli-seconds, as read from - * {@link #persistProps}. - */ - private long sessionInfoTimeoutMs; - - /** - * Object used to serialize cleanup of sessioninfo table. - */ - private Object cleanupLock = new Object(); - - /** - * Sets the factory to be used during junit testing. - * - * @param fact - * factory to be used - */ - protected void setFactory(Factory fact) { - this.fact = fact; - } - - /** - * Lookup the adjunct for this feature that is associated with the specified - * PolicyContainer. If not found, create one. - * - * @param policyContainer - * the container whose adjunct we are looking up, and possibly - * creating - * @return the associated 'ContainerAdjunct' instance, which may be new - */ - private ContainerAdjunct getContainerAdjunct(PolicyContainer policyContainer) { - - Object rval = policyContainer.getAdjunct(this); - - if (rval == null || !(rval instanceof ContainerAdjunct)) { - // adjunct does not exist, or has the wrong type (should never - // happen) - rval = new ContainerAdjunct(policyContainer); - policyContainer.setAdjunct(this, rval); - } - - return (ContainerAdjunct) rval; - } - - /** - * {@inheritDoc} - */ - @Override - public int getSequenceNumber() { - return 1; - } - - /** - * {@inheritDoc} - */ - @Override - public void globalInit(String[] args, String configDir) { - - kieSvcFact = fact.getKieServices(); - - try { - persistProps = fact.loadProperties(configDir + "/feature-session-persistence.properties"); - - } catch (IOException e1) { - logger.error("initializePersistence: ", e1); - } - - sessionInfoTimeoutMs = getPersistenceTimeout(); - } - - /** - * Creates a persistent KieSession, loading it from the persistent store, or - * creating one, if it does not exist yet. - */ - @Override - public KieSession activatePolicySession(PolicyContainer policyContainer, String name, String kieBaseName) { - - if (isPersistenceEnabled(policyContainer, name)) { - cleanUpSessionInfo(); - - return getContainerAdjunct(policyContainer).newPersistentKieSession(name, kieBaseName); - } - - return null; - } - - /** - * {@inheritDoc} - */ - @Override - public PolicySession.ThreadModel selectThreadModel(PolicySession session) { - - PolicyContainer policyContainer = session.getPolicyContainer(); - if (isPersistenceEnabled(policyContainer, session.getName())) { - return new PersistentThreadModel(session, getProperties(policyContainer)); - } - return null; - } - - /** - * {@inheritDoc} - */ - @Override - public void disposeKieSession(PolicySession policySession) { - - ContainerAdjunct contAdj = (ContainerAdjunct) policySession.getPolicyContainer().getAdjunct(this); - if (contAdj != null) { - contAdj.disposeKieSession(policySession.getName()); - } - } - - /** - * {@inheritDoc} - */ - @Override - public void destroyKieSession(PolicySession policySession) { - - ContainerAdjunct contAdj = (ContainerAdjunct) policySession.getPolicyContainer().getAdjunct(this); - if (contAdj != null) { - contAdj.destroyKieSession(policySession.getName()); - } - } - - /** - * {@inheritDoc} - */ - @Override - public boolean afterStart(PolicyEngine engine) { - return false; - } - - /** - * {@inheritDoc} - */ - @Override - public boolean beforeStart(PolicyEngine engine) { - synchronized (cleanupLock) { - sessInfoCleaned = false; - } - - return false; - } - - /** - * {@inheritDoc} - */ - @Override - public boolean beforeActivate(PolicyEngine engine) { - synchronized (cleanupLock) { - sessInfoCleaned = false; - } - - return false; - } - - /** - * {@inheritDoc} - */ - @Override - public boolean afterActivate(PolicyEngine engine) { - return false; - } - - /* ============================================================ */ - - /** - * Gets the persistence timeout value for sessioninfo records. - * - * @return the timeout value, in milli-seconds, or {@code -1} if it is - * unspecified or invalid - */ - private long getPersistenceTimeout() { - String timeoutString = null; - - try { - timeoutString = persistProps.getProperty(DroolsPersistenceProperties.DB_SESSIONINFO_TIMEOUT); - - if (timeoutString != null) { - // timeout parameter is specified - return Long.valueOf(timeoutString) * 1000; - } - - } catch (NumberFormatException e) { - logger.error("Invalid value for Drools persistence property persistence.sessioninfo.timeout: {}", - timeoutString, e); - } - - return -1; - } - - /* ============================================================ */ - - /** - * Each instance of this class is a logical extension of a 'PolicyContainer' - * instance. Its reference is stored in the 'adjuncts' table within the - * 'PolicyContainer', and will be garbage-collected with the container. - */ - protected class ContainerAdjunct { - /** - * 'PolicyContainer' instance that this adjunct is extending. - */ - private PolicyContainer policyContainer; - - /** - * Maps a KIE session name to its data source. - */ - private Map<String, DsEmf> name2ds = new HashMap<>(); - - /** - * Constructor - initialize a new 'ContainerAdjunct' - * - * @param policyContainer - * the 'PolicyContainer' instance this adjunct is extending - */ - private ContainerAdjunct(PolicyContainer policyContainer) { - this.policyContainer = policyContainer; - } - - /** - * Create a new persistent KieSession. If there is already a - * corresponding entry in the database, it is used to initialize the - * KieSession. If not, a completely new session is created. - * - * @param name - * the name of the KieSession (which is also the name of the - * associated PolicySession) - * @param kieBaseName - * the name of the 'KieBase' instance containing this session - * @return a new KieSession with persistence enabled - */ - private KieSession newPersistentKieSession(String name, String kieBaseName) { - - configureSysProps(); - - BasicDataSource ds = fact.makeDataSource(getDataSourceProperties()); - DsEmf dsemf = new DsEmf(ds); - - try { - EntityManagerFactory emf = dsemf.emf; - DroolsSessionConnector conn = fact.makeJpaConnector(emf); - - long desiredSessionId = getSessionId(conn, name); - - logger.info("\n\nThis controller is primary... coming up with session {} \n\n", desiredSessionId); - - // session does not exist -- attempt to create one - logger.info("getPolicySession:session does not exist -- attempt to create one with name {}", name); - - Environment env = kieSvcFact.newEnvironment(); - - configureKieEnv(env, emf); - - KieSessionConfiguration kConf = kieSvcFact.newKieSessionConfiguration(); - - KieSession kieSession = (desiredSessionId >= 0 - ? loadKieSession(kieBaseName, desiredSessionId, env, kConf) : null); - - if (kieSession == null) { - // loadKieSession() returned null or desiredSessionId < 0 - logger.info("LOADING We cannot load session {}. Going to create a new one", desiredSessionId); - - kieSession = newKieSession(kieBaseName, env); - } - - replaceSession(conn, name, kieSession); - - name2ds.put(name, dsemf); - - return kieSession; - - } catch (RuntimeException e) { - dsemf.close(); - throw e; - } - } - - /** - * Loads an existing KieSession from the persistent store. - * - * @param kieBaseName - * the name of the 'KieBase' instance containing this session - * @param desiredSessionId - * id of the desired KieSession - * @param env - * Kie Environment for the session - * @param kConf - * Kie Configuration for the session - * @return the persistent session, or {@code null} if it could not be - * loaded - */ - private KieSession loadKieSession(String kieBaseName, long desiredSessionId, Environment env, - KieSessionConfiguration kConf) { - try { - KieSession kieSession = kieSvcFact.getStoreServices().loadKieSession(desiredSessionId, - policyContainer.getKieContainer().getKieBase(kieBaseName), kConf, env); - - logger.info("LOADING Loaded session {}", desiredSessionId); - - return kieSession; - - } catch (Exception e) { - logger.error("loadKieSession error: ", e); - return null; - } - } - - /** - * Creates a new, persistent KieSession. - * - * @param kieBaseName - * the name of the 'KieBase' instance containing this session - * @param env - * Kie Environment for the session - * @return a new, persistent session - */ - private KieSession newKieSession(String kieBaseName, Environment env) { - KieSession kieSession = kieSvcFact.getStoreServices() - .newKieSession(policyContainer.getKieContainer().getKieBase(kieBaseName), null, env); - - logger.info("LOADING CREATED {}", kieSession.getIdentifier()); - - return kieSession; - } - - /** - * Closes the data source associated with a session. - * - * @param name - * name of the session being destroyed - */ - private void destroyKieSession(String name) { - closeDataSource(name); - } - - /** - * Closes the data source associated with a session. - * - * @param name - * name of the session being disposed of - */ - private void disposeKieSession(String name) { - closeDataSource(name); - } - - /** - * Closes the data source associated with a session. - * - * @param name - * name of the session whose data source is to be closed - */ - private void closeDataSource(String name) { - DsEmf ds = name2ds.remove(name); - if (ds != null) { - ds.close(); - } - } - - /** - * 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)); - } - - /** - * 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()); - } - - /** - * Gets a session's ID from the persistent store. - * - * @param conn - * persistence connector - * @param sessnm - * name of the session - * @return the session's id, or {@code -1} if the session is not found - */ - private long getSessionId(DroolsSessionConnector conn, String sessnm) { - DroolsSession sess = conn.get(sessnm); - return sess != null ? sess.getSessionId() : -1; - } - - /** - * Replaces a session within the persistent store, if it exists. Adds it - * otherwise. - * - * @param conn - * persistence connector - * @param sessnm - * name of session to be updated - * @param kieSession - * new session information - */ - private void replaceSession(DroolsSessionConnector conn, String sessnm, KieSession kieSession) { - - DroolsSessionEntity sess = new DroolsSessionEntity(); - - sess.setSessionName(sessnm); - sess.setSessionId(kieSession.getIdentifier()); - - conn.replace(sess); - } - } - - /* ============================================================ */ - - /** - * 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; - } - - /** - * 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. - */ - private void cleanUpSessionInfo() { - - synchronized (cleanupLock) { - - if (sessInfoCleaned) { - logger.info("Clean up of sessioninfo table: already done"); - return; - } - - if (sessionInfoTimeoutMs < 0) { - logger.info("Clean up of sessioninfo table: no timeout specified"); - return; - } - - // now do the record deletion - try (BasicDataSource ds = fact.makeDataSource(getDataSourceProperties()); - Connection connection = ds.getConnection(); - PreparedStatement statement = connection.prepareStatement( - "DELETE FROM sessioninfo WHERE timestampdiff(second,lastmodificationdate,now()) > ?")) { - - connection.setAutoCommit(true); - - statement.setLong(1, sessionInfoTimeoutMs / 1000); - - int count = statement.executeUpdate(); - logger.info("Cleaning up sessioninfo table -- {} records removed", count); - - } catch (SQLException e) { - logger.error("Clean up of sessioninfo table failed", e); - } - - // TODO: delete DroolsSessionEntity where sessionId not in - // (sessinfo.xxx) - - sessInfoCleaned = true; - } - } - - /** - * Determine whether persistence is enabled for a specific container - * - * @param container - * container to be checked - * @param sessionName - * name of the session to be checked - * @return {@code true} if persistence is enabled for this container, and - * {@code false} if not - */ - private boolean isPersistenceEnabled(PolicyContainer container, String sessionName) { - Properties properties = getProperties(container); - boolean rval = false; - - if (properties != null) { - // fetch the 'type' property - String type = getProperty(properties, sessionName, "type"); - rval = "auto".equals(type) || "native".equals(type); - } - - return rval; - } - - /** - * Determine the controller properties associated with the policy container. - * - * @param container - * container whose properties are to be retrieved - * @return the container's properties, or {@code null} if not found - */ - private Properties getProperties(PolicyContainer container) { - try { - return fact.getPolicyController(container).getProperties(); - } catch (IllegalArgumentException e) { - logger.error("getProperties exception: ", e); - return null; - } - } - - /** - * Fetch the persistence property associated with a session. The name may - * have the form: - * <ul> - * <li>persistence.SESSION-NAME.PROPERTY</li> - * <li>persistence.PROPERTY</li> - * </ul> - * - * @param properties - * properties from which the value is to be retrieved - * @param sessionName - * session name of interest - * @param property - * property name of interest - * @return the property value, or {@code null} if not found - */ - private String getProperty(Properties properties, String sessionName, String property) { - String value = properties.getProperty("persistence." + sessionName + "." + property); - if (value == null) { - value = properties.getProperty("persistence." + property); - } - - return value; - } - - /* ============================================================ */ - - /** - * This 'ThreadModel' variant periodically calls - * 'KieSession.fireAllRules()', because the 'fireUntilHalt' method isn't - * compatible with persistence. - */ - public class PersistentThreadModel implements Runnable, PolicySession.ThreadModel { - - /** - * Session associated with this persistent thread. - */ - private final PolicySession session; - - /** - * 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. - */ - 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. - */ - long halfMaxSleepTime = 5000L / 2L; - - /** - * Constructor - initialize variables and create thread - * - * @param session - * the 'PolicySession' instance - * @param properties - * may contain additional session properties - */ - 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(); - - // fetch 'minSleepTime' value, and update if defined - String sleepTimeString = getProperty(properties, name, "minSleepTime"); - if (sleepTimeString != null) { - try { - minSleepTime = Math.max(1, Integer.valueOf(sleepTimeString)); - } catch (Exception e) { - logger.error(sleepTimeString + ": Illegal value for 'minSleepTime'", e); - } - } - - // fetch 'maxSleepTime' value, and update if defined - long maxSleepTime = 2 * halfMaxSleepTime; - sleepTimeString = getProperty(properties, name, "maxSleepTime"); - if (sleepTimeString != null) { - try { - maxSleepTime = Math.max(1, Integer.valueOf(sleepTimeString)); - } catch (Exception e) { - logger.error(sleepTimeString + ": Illegal value for 'maxSleepTime'", e); - } - } - - // swap values if needed - if (minSleepTime > maxSleepTime) { - logger.error("minSleepTime(" + minSleepTime + ") is greater than maxSleepTime(" + maxSleepTime - + ") -- swapping"); - long tmp = minSleepTime; - minSleepTime = maxSleepTime; - maxSleepTime = tmp; - } - - halfMaxSleepTime = Math.max(1, maxSleepTime / 2); - } - - /** - * @return the String to use as the thread name - */ - private String getThreadName() { - return "Session " + session.getFullName() + " (persistent)"; - } - - /***************************/ - /* 'ThreadModel' interface */ - /***************************/ - - /** - * {@inheritDoc} - */ - @Override - public void start() { - thread.start(); - } - - /** - * {@inheritDoc} - */ - @Override - 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()) { - logger.error("stopThread: still running"); - } - } - - /** - * {@inheritDoc} - */ - @Override - public void updated() { - // the container artifact has been updated -- adjust the thread name - thread.setName(getThreadName()); - } - - /************************/ - /* 'Runnable' interface */ - /************************/ - - /** - * {@inheritDoc} - */ - @Override - public void run() { - logger.info("PersistentThreadModel running"); - - // set thread local variable - session.setPolicySession(); - - KieSession kieSession = session.getKieSession(); - long sleepTime = 2 * halfMaxSleepTime; - - // We want to continue, despite any exceptions that occur - // while rules are fired. - - boolean cont = true; - while(cont) { - - try { - if (kieSession.fireAllRules() > 0) { - // some rules fired -- reduce poll delay - 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)) { - cont = false; - } - - } catch (InterruptedException e) { - logger.error("startThread exception: ", e); - Thread.currentThread().interrupt(); - cont = false; - } - } - - logger.info("PersistentThreadModel completed"); - } - } - - /* ============================================================ */ - - /** - * DataSource-EntityManagerFactory pair. - */ - private class DsEmf { - private BasicDataSource bds; - private EntityManagerFactory emf; - - /** - * Makes an entity manager factory for the given data source. - * - * @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 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(); - - private SingletonRegistry() { - super(); - } - } - - /** - * Factory for various items. Methods can be overridden for junit testing. - */ - protected static class Factory { - - /** - * Gets the transaction manager. - * - * @return the transaction manager - */ - public TransactionManager getTransMgr() { - return com.arjuna.ats.jta.TransactionManager.transactionManager(); - } - - /** - * Gets the user transaction. - * - * @return the user transaction - */ - public UserTransaction getUserTrans() { - return com.arjuna.ats.jta.UserTransaction.userTransaction(); - } - - /** - * Gets the transaction synchronization registry. - * - * @return the transaction synchronization registry - */ - public TransactionSynchronizationRegistry getTransSyncReg() { - return SingletonRegistry.transreg; - } - - /** - * Gets the KIE services. - * - * @return the KIE services - */ - public KieServices getKieServices() { - return KieServices.Factory.get(); - } - - /** - * Loads properties from a file. - * - * @param filenm - * name of the file to load - * @return properties, as loaded from the file - * @throws IOException - * if an error occurs reading from the file - */ - public Properties loadProperties(String filenm) throws IOException { - return PropertyUtil.getProperties(filenm); - } - - /** - * Makes a Data Source. - * - * @param dsProps - * data source properties - * @return a new data source - */ - public BasicDataSource makeDataSource(Properties dsProps) { - try { - return BasicDataSourceFactory.createDataSource(dsProps); - - } catch (Exception e) { - throw new PersistenceFeatureException(e); - } - } - - /** - * Makes a new JPA connector for drools sessions. - * - * @param emf - * entity manager factory - * @return a new JPA connector for drools sessions - */ - public DroolsSessionConnector makeJpaConnector(EntityManagerFactory emf) { - return new JpaDroolsSessionConnector(emf); - } - - /** - * Makes a new entity manager factory. - * - * @param props - * properties with which the factory should be configured - * @return a new entity manager factory - */ - public EntityManagerFactory makeEntMgrFact(Map<String, Object> props) { - return Persistence.createEntityManagerFactory("onapsessionsPU", props); - } - - /** - * Gets the policy controller associated with a given policy container. - * - * @param container - * container whose controller is to be retrieved - * @return the container's controller - */ - 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); - } - } + private static final Logger logger = LoggerFactory.getLogger(PersistenceFeature.class); + + /** Standard factory used to get various items. */ + private static Factory stdFactory = new Factory(); + + /** Factory used to get various items. */ + private Factory fact = stdFactory; + + /** KieService factory. */ + private KieServices kieSvcFact; + + /** Persistence properties. */ + private Properties persistProps; + + /** Whether or not the SessionInfo records should be cleaned out. */ + private boolean sessInfoCleaned; + + /** SessionInfo timeout, in milli-seconds, as read from + * {@link #persistProps}. */ + private long sessionInfoTimeoutMs; + + /** Object used to serialize cleanup of sessioninfo table. */ + private Object cleanupLock = new Object(); + + /** + * Sets the factory to be used during junit testing. + * + * @param fact factory to be used + */ + protected void setFactory(Factory fact) { + this.fact = fact; + } + + /** + * Lookup the adjunct for this feature that is associated with the specified PolicyContainer. If + * not found, create one. + * + * @param policyContainer the container whose adjunct we are looking up, and possibly creating + * @return the associated 'ContainerAdjunct' instance, which may be new + */ + private ContainerAdjunct getContainerAdjunct(PolicyContainer policyContainer) { + + Object rval = policyContainer.getAdjunct(this); + + if (rval == null || !(rval instanceof ContainerAdjunct)) { + // adjunct does not exist, or has the wrong type (should never + // happen) + rval = new ContainerAdjunct(policyContainer); + policyContainer.setAdjunct(this, rval); + } + + return (ContainerAdjunct) rval; + } + + /** + * {@inheritDoc} */ + @Override + public int getSequenceNumber() { + return 1; + } + + /** + * {@inheritDoc} */ + @Override + public void globalInit(String[] args, String configDir) { + + kieSvcFact = fact.getKieServices(); + + try { + persistProps = fact.loadProperties(configDir + "/feature-session-persistence.properties"); + + } catch (IOException e1) { + logger.error("initializePersistence: ", e1); + } + + sessionInfoTimeoutMs = getPersistenceTimeout(); + } + + /** + * Creates a persistent KieSession, loading it from the persistent store, or creating one, if it + * does not exist yet. + */ + @Override + public KieSession activatePolicySession( + PolicyContainer policyContainer, String name, String kieBaseName) { + + if (isPersistenceEnabled(policyContainer, name)) { + cleanUpSessionInfo(); + + return getContainerAdjunct(policyContainer).newPersistentKieSession(name, kieBaseName); + } + + return null; + } + + /** + * {@inheritDoc} */ + @Override + public PolicySession.ThreadModel selectThreadModel(PolicySession session) { + + PolicyContainer policyContainer = session.getPolicyContainer(); + if (isPersistenceEnabled(policyContainer, session.getName())) { + return new PersistentThreadModel(session, getProperties(policyContainer)); + } + return null; + } + + /** + * {@inheritDoc} */ + @Override + public void disposeKieSession(PolicySession policySession) { + + ContainerAdjunct contAdj = + (ContainerAdjunct) policySession.getPolicyContainer().getAdjunct(this); + if (contAdj != null) { + contAdj.disposeKieSession(policySession.getName()); + } + } + + /** + * {@inheritDoc} */ + @Override + public void destroyKieSession(PolicySession policySession) { + + ContainerAdjunct contAdj = + (ContainerAdjunct) policySession.getPolicyContainer().getAdjunct(this); + if (contAdj != null) { + contAdj.destroyKieSession(policySession.getName()); + } + } + + /** + * {@inheritDoc} */ + @Override + public boolean afterStart(PolicyEngine engine) { + return false; + } + + /** + * {@inheritDoc} */ + @Override + public boolean beforeStart(PolicyEngine engine) { + synchronized (cleanupLock) { + sessInfoCleaned = false; + } + + return false; + } + + /** + * {@inheritDoc} */ + @Override + public boolean beforeActivate(PolicyEngine engine) { + synchronized (cleanupLock) { + sessInfoCleaned = false; + } + + return false; + } + + /** + * {@inheritDoc} */ + @Override + public boolean afterActivate(PolicyEngine engine) { + return false; + } + + /* ============================================================ */ + + /** + * Gets the persistence timeout value for sessioninfo records. + * + * @return the timeout value, in milli-seconds, or {@code -1} if it is unspecified or invalid + */ + private long getPersistenceTimeout() { + String timeoutString = null; + + try { + timeoutString = persistProps.getProperty(DroolsPersistenceProperties.DB_SESSIONINFO_TIMEOUT); + + if (timeoutString != null) { + // timeout parameter is specified + return Long.valueOf(timeoutString) * 1000; + } + + } catch (NumberFormatException e) { + logger.error( + "Invalid value for Drools persistence property persistence.sessioninfo.timeout: {}", + timeoutString, + e); + } + + return -1; + } + + /* ============================================================ */ + + /** + * Each instance of this class is a logical extension of a 'PolicyContainer' instance. Its + * reference is stored in the 'adjuncts' table within the 'PolicyContainer', and will be + * garbage-collected with the container. + */ + protected class ContainerAdjunct { + /** 'PolicyContainer' instance that this adjunct is extending. */ + private PolicyContainer policyContainer; + + /** Maps a KIE session name to its data source. */ + private Map<String, DsEmf> name2ds = new HashMap<>(); + + /** + * Constructor - initialize a new 'ContainerAdjunct'. + * + * @param policyContainer the 'PolicyContainer' instance this adjunct is extending + */ + private ContainerAdjunct(PolicyContainer policyContainer) { + this.policyContainer = policyContainer; + } + + /** + * Create a new persistent KieSession. If there is already a corresponding entry in the + * database, it is used to initialize the KieSession. If not, a completely new session is + * created. + * + * @param name the name of the KieSession (which is also the name of the associated + * PolicySession) + * @param kieBaseName the name of the 'KieBase' instance containing this session + * @return a new KieSession with persistence enabled + */ + private KieSession newPersistentKieSession(String name, String kieBaseName) { + + configureSysProps(); + + BasicDataSource ds = fact.makeDataSource(getDataSourceProperties()); + DsEmf dsemf = new DsEmf(ds); + + try { + EntityManagerFactory emf = dsemf.emf; + DroolsSessionConnector conn = fact.makeJpaConnector(emf); + + long desiredSessionId = getSessionId(conn, name); + + logger.info( + "\n\nThis controller is primary... coming up with session {} \n\n", desiredSessionId); + + // session does not exist -- attempt to create one + logger.info( + "getPolicySession:session does not exist -- attempt to create one with name {}", name); + + Environment env = kieSvcFact.newEnvironment(); + + configureKieEnv(env, emf); + + KieSessionConfiguration kieConf = kieSvcFact.newKieSessionConfiguration(); + + KieSession kieSession = + (desiredSessionId >= 0 + ? loadKieSession(kieBaseName, desiredSessionId, env, kieConf) + : null); + + if (kieSession == null) { + // loadKieSession() returned null or desiredSessionId < 0 + logger.info( + "LOADING We cannot load session {}. Going to create a new one", desiredSessionId); + + kieSession = newKieSession(kieBaseName, env); + } + + replaceSession(conn, name, kieSession); + + name2ds.put(name, dsemf); + + return kieSession; + + } catch (RuntimeException e) { + dsemf.close(); + throw e; + } + } + + /** + * Loads an existing KieSession from the persistent store. + * + * @param kieBaseName the name of the 'KieBase' instance containing this session + * @param desiredSessionId id of the desired KieSession + * @param env Kie Environment for the session + * @param kConf Kie Configuration for the session + * @return the persistent session, or {@code null} if it could not be loaded + */ + private KieSession loadKieSession( + String kieBaseName, long desiredSessionId, Environment env, KieSessionConfiguration kieConf) { + try { + KieSession kieSession = + kieSvcFact + .getStoreServices() + .loadKieSession( + desiredSessionId, + policyContainer.getKieContainer().getKieBase(kieBaseName), + kieConf, + env); + + logger.info("LOADING Loaded session {}", desiredSessionId); + + return kieSession; + + } catch (Exception e) { + logger.error("loadKieSession error: ", e); + return null; + } + } + + /** + * Creates a new, persistent KieSession. + * + * @param kieBaseName the name of the 'KieBase' instance containing this session + * @param env Kie Environment for the session + * @return a new, persistent session + */ + private KieSession newKieSession(String kieBaseName, Environment env) { + KieSession kieSession = + kieSvcFact + .getStoreServices() + .newKieSession(policyContainer.getKieContainer().getKieBase(kieBaseName), null, env); + + logger.info("LOADING CREATED {}", kieSession.getIdentifier()); + + return kieSession; + } + + /** + * Closes the data source associated with a session. + * + * @param name name of the session being destroyed + */ + private void destroyKieSession(String name) { + closeDataSource(name); + } + + /** + * Closes the data source associated with a session. + * + * @param name name of the session being disposed of + */ + private void disposeKieSession(String name) { + closeDataSource(name); + } + + /** + * Closes the data source associated with a session. + * + * @param name name of the session whose data source is to be closed + */ + private void closeDataSource(String name) { + DsEmf ds = name2ds.remove(name); + if (ds != null) { + ds.close(); + } + } + + /** 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)); + } + + /** + * 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()); + } + + /** + * Gets a session's ID from the persistent store. + * + * @param conn persistence connector + * @param sessnm name of the session + * @return the session's id, or {@code -1} if the session is not found + */ + private long getSessionId(DroolsSessionConnector conn, String sessnm) { + DroolsSession sess = conn.get(sessnm); + return sess != null ? sess.getSessionId() : -1; + } + + /** + * Replaces a session within the persistent store, if it exists. Adds it otherwise. + * + * @param conn persistence connector + * @param sessnm name of session to be updated + * @param kieSession new session information + */ + private void replaceSession(DroolsSessionConnector conn, String sessnm, KieSession kieSession) { + + DroolsSessionEntity sess = new DroolsSessionEntity(); + + sess.setSessionName(sessnm); + sess.setSessionId(kieSession.getIdentifier()); + + conn.replace(sess); + } + } + + /* ============================================================ */ + + /** + * 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; + } + + /** + * 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. + */ + private void cleanUpSessionInfo() { + + synchronized (cleanupLock) { + if (sessInfoCleaned) { + logger.info("Clean up of sessioninfo table: already done"); + return; + } + + if (sessionInfoTimeoutMs < 0) { + logger.info("Clean up of sessioninfo table: no timeout specified"); + return; + } + + // now do the record deletion + try (BasicDataSource ds = fact.makeDataSource(getDataSourceProperties()); + Connection connection = ds.getConnection(); + PreparedStatement statement = + connection.prepareStatement( + "DELETE FROM sessioninfo WHERE timestampdiff(second,lastmodificationdate,now()) > ?")) { + + connection.setAutoCommit(true); + + statement.setLong(1, sessionInfoTimeoutMs / 1000); + + int count = statement.executeUpdate(); + logger.info("Cleaning up sessioninfo table -- {} records removed", count); + + } catch (SQLException e) { + logger.error("Clean up of sessioninfo table failed", e); + } + + // TODO: delete DroolsSessionEntity where sessionId not in + // (sessinfo.xxx) + + sessInfoCleaned = true; + } + } + + /** + * Determine whether persistence is enabled for a specific container. + * + * @param container container to be checked + * @param sessionName name of the session to be checked + * @return {@code true} if persistence is enabled for this container, and {@code false} if not + */ + private boolean isPersistenceEnabled(PolicyContainer container, String sessionName) { + Properties properties = getProperties(container); + boolean rval = false; + + if (properties != null) { + // fetch the 'type' property + String type = getProperty(properties, sessionName, "type"); + rval = "auto".equals(type) || "native".equals(type); + } + + return rval; + } + + /** + * Determine the controller properties associated with the policy container. + * + * @param container container whose properties are to be retrieved + * @return the container's properties, or {@code null} if not found + */ + private Properties getProperties(PolicyContainer container) { + try { + return fact.getPolicyController(container).getProperties(); + } catch (IllegalArgumentException e) { + logger.error("getProperties exception: ", e); + return null; + } + } + + /** + * Fetch the persistence property associated with a session. The name may have the form: + * + * <ul> + * <li>persistence.SESSION-NAME.PROPERTY + * <li>persistence.PROPERTY + * </ul> + * + * @param properties properties from which the value is to be retrieved + * @param sessionName session name of interest + * @param property property name of interest + * @return the property value, or {@code null} if not found + */ + private String getProperty(Properties properties, String sessionName, String property) { + String value = properties.getProperty("persistence." + sessionName + "." + property); + if (value == null) { + value = properties.getProperty("persistence." + property); + } + + return value; + } + + /* ============================================================ */ + + /** + * This 'ThreadModel' variant periodically calls 'KieSession.fireAllRules()', because the + * 'fireUntilHalt' method isn't compatible with persistence. + */ + public class PersistentThreadModel implements Runnable, PolicySession.ThreadModel { + + /** Session associated with this persistent thread. */ + private final PolicySession session; + + /** 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. */ + 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. + */ + long halfMaxSleepTime = 5000L / 2L; + + /** + * Constructor - initialize variables and create thread. + * + * @param session the 'PolicySession' instance + * @param properties may contain additional session properties + */ + 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(); + + // fetch 'minSleepTime' value, and update if defined + String sleepTimeString = getProperty(properties, name, "minSleepTime"); + if (sleepTimeString != null) { + try { + minSleepTime = Math.max(1, Integer.valueOf(sleepTimeString)); + } catch (Exception e) { + logger.error(sleepTimeString + ": Illegal value for 'minSleepTime'", e); + } + } + + // fetch 'maxSleepTime' value, and update if defined + long maxSleepTime = 2 * halfMaxSleepTime; + sleepTimeString = getProperty(properties, name, "maxSleepTime"); + if (sleepTimeString != null) { + try { + maxSleepTime = Math.max(1, Integer.valueOf(sleepTimeString)); + } catch (Exception e) { + logger.error(sleepTimeString + ": Illegal value for 'maxSleepTime'", e); + } + } + + // swap values if needed + if (minSleepTime > maxSleepTime) { + logger.error( + "minSleepTime(" + + minSleepTime + + ") is greater than maxSleepTime(" + + maxSleepTime + + ") -- swapping"); + long tmp = minSleepTime; + minSleepTime = maxSleepTime; + maxSleepTime = tmp; + } + + halfMaxSleepTime = Math.max(1, maxSleepTime / 2); + } + + /** + * Get thread name. + * + * @return the String to use as the thread name */ + private String getThreadName() { + return "Session " + session.getFullName() + " (persistent)"; + } + + /** ************************ */ + /* 'ThreadModel' interface */ + /** ************************ */ + + /** + * {@inheritDoc} */ + @Override + public void start() { + thread.start(); + } + + /** + * {@inheritDoc} */ + @Override + 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()) { + logger.error("stopThread: still running"); + } + } + + /** + * {@inheritDoc} */ + @Override + public void updated() { + // the container artifact has been updated -- adjust the thread name + thread.setName(getThreadName()); + } + + /** ********************* */ + /* 'Runnable' interface */ + /** ********************* */ + + /** + * {@inheritDoc} */ + @Override + public void run() { + logger.info("PersistentThreadModel running"); + + // set thread local variable + session.setPolicySession(); + + KieSession kieSession = session.getKieSession(); + long sleepTime = 2 * halfMaxSleepTime; + + // We want to continue, despite any exceptions that occur + // while rules are fired. + + boolean cont = true; + while (cont) { + + try { + if (kieSession.fireAllRules() > 0) { + // some rules fired -- reduce poll delay + 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)) { + cont = false; + } + + } catch (InterruptedException e) { + logger.error("startThread exception: ", e); + Thread.currentThread().interrupt(); + cont = false; + } + } + + logger.info("PersistentThreadModel completed"); + } + } + + /* ============================================================ */ + + /** DataSource-EntityManagerFactory pair. */ + private class DsEmf { + private BasicDataSource bds; + private EntityManagerFactory emf; + + /** + * Makes an entity manager factory for the given data source. + * + * @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 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(); + + private SingletonRegistry() { + super(); + } + } + + /** Factory for various items. Methods can be overridden for junit testing. */ + protected static class Factory { + + /** + * Gets the transaction manager. + * + * @return the transaction manager + */ + public TransactionManager getTransMgr() { + return com.arjuna.ats.jta.TransactionManager.transactionManager(); + } + + /** + * Gets the user transaction. + * + * @return the user transaction + */ + public UserTransaction getUserTrans() { + return com.arjuna.ats.jta.UserTransaction.userTransaction(); + } + + /** + * Gets the transaction synchronization registry. + * + * @return the transaction synchronization registry + */ + public TransactionSynchronizationRegistry getTransSyncReg() { + return SingletonRegistry.transreg; + } + + /** + * Gets the KIE services. + * + * @return the KIE services + */ + public KieServices getKieServices() { + return KieServices.Factory.get(); + } + + /** + * Loads properties from a file. + * + * @param filenm name of the file to load + * @return properties, as loaded from the file + * @throws IOException if an error occurs reading from the file + */ + public Properties loadProperties(String filenm) throws IOException { + return PropertyUtil.getProperties(filenm); + } + + /** + * Makes a Data Source. + * + * @param dsProps data source properties + * @return a new data source + */ + public BasicDataSource makeDataSource(Properties dsProps) { + try { + return BasicDataSourceFactory.createDataSource(dsProps); + + } catch (Exception e) { + throw new PersistenceFeatureException(e); + } + } + + /** + * Makes a new JPA connector for drools sessions. + * + * @param emf entity manager factory + * @return a new JPA connector for drools sessions + */ + public DroolsSessionConnector makeJpaConnector(EntityManagerFactory emf) { + return new JpaDroolsSessionConnector(emf); + } + + /** + * Makes a new entity manager factory. + * + * @param props properties with which the factory should be configured + * @return a new entity manager factory + */ + public EntityManagerFactory makeEntMgrFact(Map<String, Object> props) { + return Persistence.createEntityManagerFactory("onapsessionsPU", props); + } + + /** + * Gets the policy controller associated with a given policy container. + * + * @param container container whose controller is to be retrieved + * @return the container's controller + */ + 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; + + /** + * Constructor. + * */ + public PersistenceFeatureException(Exception ex) { + super(ex); + } + } } 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 6b8345c3..661803a5 100644 --- a/feature-session-persistence/src/main/resources/META-INF/persistence.xml +++ b/feature-session-persistence/src/main/resources/META-INF/persistence.xml @@ -3,7 +3,7 @@ ============LICENSE_START======================================================= policy-core ================================================================================ - Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + Copyright (C) 2017-2018 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. @@ -20,37 +20,54 @@ --> <persistence version="2.1" - 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"> + 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="onapsessionsPU" transaction-type="JTA"> - <!-- Used for drools session data access --> - <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="hibernate.max_fetch_depth" value="3" /> - <property name="hibernate.hbm2ddl.auto" value="update" /> - <property name="hibernate.show_sql" value="false" /> - <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.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"/> + <persistence-unit name="onapsessionsPU" + transaction-type="JTA"> + <!-- Used for drools session data access --> + <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="hibernate.max_fetch_depth" + value="3" /> + <property name="hibernate.hbm2ddl.auto" + value="update" /> + <property name="hibernate.show_sql" value="false" /> + <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> + + <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.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" /> + </properties> + </persistence-unit> + </persistence> diff --git a/feature-session-persistence/src/test/java/org/onap/policy/drools/persistence/DroolsSessionEntityTest.java b/feature-session-persistence/src/test/java/org/onap/policy/drools/persistence/DroolsSessionEntityTest.java index 7624d043..b2dcfb52 100644 --- a/feature-session-persistence/src/test/java/org/onap/policy/drools/persistence/DroolsSessionEntityTest.java +++ b/feature-session-persistence/src/test/java/org/onap/policy/drools/persistence/DroolsSessionEntityTest.java @@ -2,14 +2,14 @@ * ============LICENSE_START======================================================= * feature-session-persistence * ================================================================================ - * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * Copyright (C) 2017-2018 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. @@ -31,173 +31,162 @@ import org.onap.policy.drools.persistence.DroolsSessionEntity; public class DroolsSessionEntityTest { - @Test - public void testHashCode() { - DroolsSessionEntity e = makeEnt("mynameA", 1); + @Test + public void testHashCode() { + DroolsSessionEntity entity = makeEnt("mynameA", 1); - DroolsSessionEntity e2 = makeEnt("mynameA", 2); + DroolsSessionEntity e2 = makeEnt("mynameA", 2); - // session id is not part of hash code - assertTrue(e.hashCode() == e2.hashCode()); + // session id is not part of hash code + assertTrue(entity.hashCode() == e2.hashCode()); - // diff sess name - e2 = makeEnt("mynameB", 1); - assertTrue(e.hashCode() != e2.hashCode()); - } + // diff sess name + e2 = makeEnt("mynameB", 1); + assertTrue(entity.hashCode() != e2.hashCode()); + } - /** - * Ensures that hashCode() functions as expected when the getXxx methods are - * overridden. - */ - @Test - public void testHashCode_Subclass() { - DroolsSessionEntity e = makeEnt2("mynameA", 1); + /** Ensures that hashCode() functions as expected when the getXxx methods are overridden. */ + @Test + public void testHashCode_Subclass() { + DroolsSessionEntity entity = makeEnt2("mynameA", 1); - DroolsSessionEntity e2 = makeEnt("mynameA", 2); + DroolsSessionEntity e2 = makeEnt("mynameA", 2); - // session id is not part of hash code - assertTrue(e.hashCode() == e2.hashCode()); + // session id is not part of hash code + assertTrue(entity.hashCode() == e2.hashCode()); - // diff sess name - e2 = makeEnt("mynameB", 1); - assertTrue(e.hashCode() != e2.hashCode()); - } + // diff sess name + e2 = makeEnt("mynameB", 1); + assertTrue(entity.hashCode() != e2.hashCode()); + } - @Test - public void testGetSessionName_testSetSessionName() { - DroolsSessionEntity e = makeEnt("mynameZ", 1); + @Test + public void testGetSessionName_testSetSessionName() { + DroolsSessionEntity entity = makeEnt("mynameZ", 1); - assertEquals("mynameZ", e.getSessionName()); + assertEquals("mynameZ", entity.getSessionName()); - e.setSessionName("another"); - assertEquals("another", e.getSessionName()); + entity.setSessionName("another"); + assertEquals("another", entity.getSessionName()); - // others unchanged - assertEquals(1, e.getSessionId()); - } + // others unchanged + assertEquals(1, entity.getSessionId()); + } - @Test - public void testGetSessionId_testSetSessionId() { - DroolsSessionEntity e = makeEnt("mynameA", 1); + @Test + public void testGetSessionId_testSetSessionId() { + DroolsSessionEntity entity = makeEnt("mynameA", 1); - assertEquals(1, e.getSessionId()); - - e.setSessionId(20); - assertEquals(20, e.getSessionId()); - - // others unchanged - assertEquals("mynameA", e.getSessionName()); - } + assertEquals(1, entity.getSessionId()); - @Test - public void testGetCreatedDate_testSetCreatedDate_testGetUpdatedDate_testSetUpdatedDate() { - DroolsSessionEntity e = new DroolsSessionEntity(); + entity.setSessionId(20); + assertEquals(20, entity.getSessionId()); - Date crtdt = new Date(System.currentTimeMillis() - 100); - e.setCreatedDate(crtdt); - - Date updt = new Date(System.currentTimeMillis() - 200); - e.setUpdatedDate(updt); - - assertEquals(crtdt, e.getCreatedDate()); - assertEquals(updt, e.getUpdatedDate()); - } - - @Test - public void testEqualsObject() { - DroolsSessionEntity e = makeEnt("mynameA", 1); - - // reflexive - assertTrue(e.equals(e)); - - DroolsSessionEntity e2 = makeEnt("mynameA", 2); - - // session id is not part of hash code - assertTrue(e.equals(e2)); - assertTrue(e.equals(e2)); - - // diff sess name - e2 = makeEnt("mynameB", 1); - assertFalse(e.equals(e2)); - assertFalse(e.equals(e2)); - } - - /** - * Ensures that equals() functions as expected when the getXxx methods are - * overridden. - */ - @Test - public void testEqualsObject_Subclass() { - DroolsSessionEntity e = makeEnt2("mynameA", 1); - - // reflexive - assertTrue(e.equals(e)); - - DroolsSessionEntity e2 = makeEnt("mynameA", 2); - - // session id is not part of hash code - assertTrue(e.equals(e2)); - assertTrue(e.equals(e2)); - - // diff sess name - e2 = makeEnt("mynameB", 1); - assertFalse(e.equals(e2)); - assertFalse(e.equals(e2)); - } - - @Test - public void testToString() { - DroolsSessionEntity e = makeEnt("mynameA", 23); - - assertEquals("{name=mynameA, id=23}", e.toString()); - } - - /** - * Makes a session Entity. The parameters are stored into the Entity object - * via the setXxx methods. - * - * @param sessnm - * session name - * @param sessid - * session id - * @return a new session Entity - */ - private DroolsSessionEntity makeEnt(String sessnm, long sessid) { - - DroolsSessionEntity e = new DroolsSessionEntity(); - - e.setSessionName(sessnm); - e.setSessionId(sessid); - - return e; - } - - /** - * Makes a session Entity that overrides the getXxx methods. The parameters - * that are provided are returned by the overridden methods, but they are - * <i>not</i> stored into the Entity object via the setXxx methods. - * - * @param sessnm - * session name - * @param sessid - * session id - * @return a new session Entity - */ - @SuppressWarnings("serial") - private DroolsSessionEntity makeEnt2(String sessnm, long sessid) { - - return new DroolsSessionEntity() { - - @Override - public String getSessionName() { - return sessnm; - } - - @Override - public long getSessionId() { - return sessid; - } - }; - } + // others unchanged + assertEquals("mynameA", entity.getSessionName()); + } + @Test + public void testGetCreatedDate_testSetCreatedDate_testGetUpdatedDate_testSetUpdatedDate() { + DroolsSessionEntity entity = new DroolsSessionEntity(); + + Date crtdt = new Date(System.currentTimeMillis() - 100); + entity.setCreatedDate(crtdt); + + Date updt = new Date(System.currentTimeMillis() - 200); + entity.setUpdatedDate(updt); + + assertEquals(crtdt, entity.getCreatedDate()); + assertEquals(updt, entity.getUpdatedDate()); + } + + @Test + public void testEqualsObject() { + DroolsSessionEntity entity = makeEnt("mynameA", 1); + + // reflexive + assertTrue(entity.equals(entity)); + + DroolsSessionEntity e2 = makeEnt("mynameA", 2); + + // session id is not part of hash code + assertTrue(entity.equals(e2)); + assertTrue(entity.equals(e2)); + + // diff sess name + e2 = makeEnt("mynameB", 1); + assertFalse(entity.equals(e2)); + assertFalse(entity.equals(e2)); + } + + /** Ensures that equals() functions as expected when the getXxx methods are overridden. */ + @Test + public void testEqualsObject_Subclass() { + DroolsSessionEntity entity = makeEnt2("mynameA", 1); + + // reflexive + assertTrue(entity.equals(entity)); + + DroolsSessionEntity e2 = makeEnt("mynameA", 2); + + // session id is not part of hash code + assertTrue(entity.equals(e2)); + assertTrue(entity.equals(e2)); + + // diff sess name + e2 = makeEnt("mynameB", 1); + assertFalse(entity.equals(e2)); + assertFalse(entity.equals(e2)); + } + + @Test + public void testToString() { + DroolsSessionEntity entity = makeEnt("mynameA", 23); + + assertEquals("{name=mynameA, id=23}", entity.toString()); + } + + /** + * Makes a session Entity. The parameters are stored into the Entity object via the setXxx + * methods. + * + * @param sessnm session name + * @param sessid session id + * @return a new session Entity + */ + private DroolsSessionEntity makeEnt(String sessnm, long sessid) { + + DroolsSessionEntity entity = new DroolsSessionEntity(); + + entity.setSessionName(sessnm); + entity.setSessionId(sessid); + + return entity; + } + + /** + * Makes a session Entity that overrides the getXxx methods. The parameters that are provided are + * returned by the overridden methods, but they are <i>not</i> stored into the Entity object via + * the setXxx methods. + * + * @param sessnm session name + * @param sessid session id + * @return a new session Entity + */ + @SuppressWarnings("serial") + private DroolsSessionEntity makeEnt2(String sessnm, long sessid) { + + return new DroolsSessionEntity() { + + @Override + public String getSessionName() { + return sessnm; + } + + @Override + public long getSessionId() { + return sessid; + } + }; + } } diff --git a/feature-session-persistence/src/test/java/org/onap/policy/drools/persistence/EntityMgrTransTest.java b/feature-session-persistence/src/test/java/org/onap/policy/drools/persistence/EntityMgrTransTest.java index 9c9a30b3..aba1d80e 100644 --- a/feature-session-persistence/src/test/java/org/onap/policy/drools/persistence/EntityMgrTransTest.java +++ b/feature-session-persistence/src/test/java/org/onap/policy/drools/persistence/EntityMgrTransTest.java @@ -2,14 +2,14 @@ * ============LICENSE_START======================================================= * feature-session-persistence * ================================================================================ - * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * Copyright (C) 2017-2018 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. @@ -20,13 +20,14 @@ package org.onap.policy.drools.persistence; +import static org.junit.Assert.assertEquals; + +import static org.mockito.Mockito.doThrow; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.never; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; -import static org.junit.Assert.assertEquals; -import static org.mockito.Mockito.doThrow; import javax.persistence.EntityManager; import javax.transaction.HeuristicMixedException; @@ -47,399 +48,402 @@ import org.slf4j.LoggerFactory; public class EntityMgrTransTest { - private static final Logger logger = LoggerFactory.getLogger(PersistenceFeatureTest.class); - - private static UserTransaction savetrans; - - private UserTransaction trans; - private EntityManager mgr; - - @BeforeClass - public static void setUpBeforeClass() { - System.setProperty("com.arjuna.ats.arjuna.objectstore.objectStoreDir", "target/tm"); - System.setProperty("ObjectStoreEnvironmentBean.objectStoreDir", "target/tm"); - - savetrans = EntityMgrTrans.getUserTrans(); - } - - @AfterClass - public static void tearDownAfterClass() { - EntityMgrTrans.setUserTrans(savetrans); - } - - @Before - public void setUp() throws Exception { - trans = mock(UserTransaction.class); - mgr = mock(EntityManager.class); - - EntityMgrTrans.setUserTrans(trans); - } - - /** - * Verifies that the constructor starts a transaction, but does not do - * anything extra before being closed. - * - * @throws Exception - */ - @Test - public void testEntityMgrTrans() throws Exception { - - when(trans.getStatus()).thenReturn(Status.STATUS_ACTIVE); - - EntityMgrTrans t = new EntityMgrTrans(mgr); - - // verify that transaction was started - verify(trans).begin(); - - // verify not closed, committed, or rolled back yet - verify(trans, never()).commit(); - verify(trans, never()).rollback(); - verify(mgr, never()).close(); - - t.close(); - } - - @Test(expected = EntityMgrException.class) - public void testEntityMgrTrans_RtEx() throws Exception { - - doThrow(new IllegalArgumentException("expected exception")).when(trans).begin(); - - try (EntityMgrTrans t = new EntityMgrTrans(mgr)) { - - } - } - - @Test(expected = EntityMgrException.class) - public void testEntityMgrTrans_NotSuppEx() throws Exception { - - doThrow(new NotSupportedException("expected exception")).when(trans).begin(); - - try (EntityMgrTrans t = new EntityMgrTrans(mgr)) { - - } - } - - @Test(expected = EntityMgrException.class) - public void testEntityMgrTrans_SysEx() throws Exception { - - doThrow(new SystemException("expected exception")).when(trans).begin(); - - try (EntityMgrTrans t = new EntityMgrTrans(mgr)) { - - } - } - - /** - * Verifies that the transaction is rolled back and the manager is closed - * when and a transaction is active. - */ - @Test - public void testClose_Active() throws Exception { - EntityMgrTrans t = new EntityMgrTrans(mgr); - - when(trans.getStatus()).thenReturn(Status.STATUS_ACTIVE); - - t.close(); - - // closed and rolled back, but not committed - verify(trans, never()).commit(); - verify(trans).rollback(); - verify(mgr).close(); - } - - /** - * Verifies that the manager is closed, but that the transaction is - * <i>not</i> rolled back when and no transaction is active. - */ - @Test - public void testClose_Inactive() throws Exception { - EntityMgrTrans t = new EntityMgrTrans(mgr); - - when(trans.getStatus()).thenReturn(Status.STATUS_NO_TRANSACTION); - - t.close(); - - // closed, but not committed or rolled back - verify(mgr).close(); - verify(trans, never()).commit(); - verify(trans, never()).rollback(); - } - - @Test(expected = EntityMgrException.class) - public void testClose_IllStateEx() throws Exception { - - when(trans.getStatus()).thenReturn(Status.STATUS_ACTIVE); - doThrow(new IllegalStateException("expected exception")).when(trans).rollback(); - - try (EntityMgrTrans t = new EntityMgrTrans(mgr)) { - - } - } - - @Test(expected = EntityMgrException.class) - public void testClose_SecEx() throws Exception { - - when(trans.getStatus()).thenReturn(Status.STATUS_ACTIVE); - doThrow(new SecurityException("expected exception")).when(trans).rollback(); - - try (EntityMgrTrans t = new EntityMgrTrans(mgr)) { - - } - } - - @Test(expected = EntityMgrException.class) - public void testClose_SysEx() throws Exception { - - when(trans.getStatus()).thenReturn(Status.STATUS_ACTIVE); - doThrow(new SystemException("expected exception")).when(trans).rollback(); - - try (EntityMgrTrans t = new EntityMgrTrans(mgr)) { - - } - } - - /** - * Verifies that the manager is closed and the transaction rolled back when - * "try" block exits normally and a transaction is active. - */ - @Test - public void testClose_TryWithoutExcept_Active() throws Exception { - when(trans.getStatus()).thenReturn(Status.STATUS_ACTIVE); - - try (EntityMgrTrans t = new EntityMgrTrans(mgr)) { - - } - - // closed and rolled back, but not committed - verify(trans, never()).commit(); - verify(trans).rollback(); - verify(mgr).close(); - } + private static final Logger logger = LoggerFactory.getLogger(PersistenceFeatureTest.class); - /** - * Verifies that the manager is closed, but that the transaction is - * <i>not</i> rolled back when "try" block exits normally and no transaction - * is active. - */ - @Test - public void testClose_TryWithoutExcept_Inactive() throws Exception { + private static UserTransaction savetrans; - when(trans.getStatus()).thenReturn(Status.STATUS_NO_TRANSACTION); + private UserTransaction trans; + private EntityManager mgr; - try (EntityMgrTrans t = new EntityMgrTrans(mgr)) { + /** + * Setup before the class. + * + */ + @BeforeClass + public static void setUpBeforeClass() { + System.setProperty("com.arjuna.ats.arjuna.objectstore.objectStoreDir", "target/tm"); + System.setProperty("ObjectStoreEnvironmentBean.objectStoreDir", "target/tm"); + + savetrans = EntityMgrTrans.getUserTrans(); + } - } + @AfterClass + public static void tearDownAfterClass() { + EntityMgrTrans.setUserTrans(savetrans); + } - // closed, but not rolled back or committed - verify(trans, never()).commit(); - verify(trans, never()).rollback(); - verify(mgr).close(); - } + /** + * Setup. + * + * @throws Exception exception + */ + @Before + public void setUp() throws Exception { + trans = mock(UserTransaction.class); + mgr = mock(EntityManager.class); - /** - * Verifies that the manager is closed and the transaction rolled back when - * "try" block throws an exception and a transaction is active. - */ - @Test - public void testClose_TryWithExcept_Active() throws Exception { + EntityMgrTrans.setUserTrans(trans); + } - when(trans.getStatus()).thenReturn(Status.STATUS_ACTIVE); + /** + * Verifies that the constructor starts a transaction, but does not do anything extra before being + * closed. + * + * @throws Exception exception + */ + @Test + public void testEntityMgrTrans() throws Exception { - try { - try (EntityMgrTrans t = new EntityMgrTrans(mgr)) { - throw new SystemException("expected exception"); - } + when(trans.getStatus()).thenReturn(Status.STATUS_ACTIVE); - } catch (Exception e) { - logger.trace("expected exception", e); - } + final EntityMgrTrans newTrans = new EntityMgrTrans(mgr); - // closed and rolled back, but not committed - verify(trans, never()).commit(); - verify(trans).rollback(); - verify(mgr).close(); - } + // verify that transaction was started + verify(trans).begin(); - /** - * Verifies that the manager is closed, but that the transaction is - * <i>not</i> rolled back when "try" block throws an exception and no - * transaction is active. - */ - @Test - public void testClose_TryWithExcept_Inactive() throws Exception { + // verify not closed, committed, or rolled back yet + verify(trans, never()).commit(); + verify(trans, never()).rollback(); + verify(mgr, never()).close(); - when(trans.getStatus()).thenReturn(Status.STATUS_NO_TRANSACTION); + newTrans.close(); + } - try { - try (EntityMgrTrans t = new EntityMgrTrans(mgr)) { - throw new SystemException("expected exception"); - } + @Test(expected = EntityMgrException.class) + public void testEntityMgrTrans_RtEx() throws Exception { - } catch (Exception e) { - logger.trace("expected exception", e); - } + doThrow(new IllegalArgumentException("expected exception")).when(trans).begin(); - // closed, but not rolled back or committed - verify(trans, never()).commit(); - verify(trans, never()).rollback(); - verify(mgr).close(); - } - - /** - * Verifies that commit() only commits, and that the subsequent close() does - * not re-commit. - */ - @Test - public void testCommit() throws Exception { - EntityMgrTrans t = new EntityMgrTrans(mgr); - when(trans.getStatus()).thenReturn(Status.STATUS_ACTIVE); - - t.commit(); - - when(trans.getStatus()).thenReturn(Status.STATUS_COMMITTED); - - // committed, but not closed or rolled back - verify(trans).commit(); - verify(trans, never()).rollback(); - verify(mgr, never()).close(); - - // closed, but not re-committed - t.close(); + try (EntityMgrTrans t = new EntityMgrTrans(mgr)) { + // Empty + } + } + + @Test(expected = EntityMgrException.class) + public void testEntityMgrTrans_NotSuppEx() throws Exception { - verify(trans, times(1)).commit(); - verify(mgr).close(); - } - - @Test(expected = EntityMgrException.class) - public void testCommit_SecEx() throws Exception { - - when(trans.getStatus()).thenReturn(Status.STATUS_ACTIVE); - doThrow(new SecurityException("expected exception")).when(trans).commit(); + doThrow(new NotSupportedException("expected exception")).when(trans).begin(); + + try (EntityMgrTrans t = new EntityMgrTrans(mgr)) { + // Empty + } + } + + @Test(expected = EntityMgrException.class) + public void testEntityMgrTrans_SysEx() throws Exception { + + doThrow(new SystemException("expected exception")).when(trans).begin(); + + try (EntityMgrTrans t = new EntityMgrTrans(mgr)) { + // Empty + } + } + + /** + * Verifies that the transaction is rolled back and the manager is closed when and a transaction + * is active. + */ + @Test + public void testClose_Active() throws Exception { + EntityMgrTrans newTrans = new EntityMgrTrans(mgr); + + when(trans.getStatus()).thenReturn(Status.STATUS_ACTIVE); + + newTrans.close(); + + // closed and rolled back, but not committed + verify(trans, never()).commit(); + verify(trans).rollback(); + verify(mgr).close(); + } + + /** + * Verifies that the manager is closed, but that the transaction is <i>not</i> rolled back when + * and no transaction is active. + */ + @Test + public void testClose_Inactive() throws Exception { + EntityMgrTrans newTrans = new EntityMgrTrans(mgr); + + when(trans.getStatus()).thenReturn(Status.STATUS_NO_TRANSACTION); + + newTrans.close(); + + // closed, but not committed or rolled back + verify(mgr).close(); + verify(trans, never()).commit(); + verify(trans, never()).rollback(); + } + + @Test(expected = EntityMgrException.class) + public void testClose_IllStateEx() throws Exception { + + when(trans.getStatus()).thenReturn(Status.STATUS_ACTIVE); + doThrow(new IllegalStateException("expected exception")).when(trans).rollback(); + + try (EntityMgrTrans t = new EntityMgrTrans(mgr)) { + // Empty + } + } + + @Test(expected = EntityMgrException.class) + public void testClose_SecEx() throws Exception { + + when(trans.getStatus()).thenReturn(Status.STATUS_ACTIVE); + doThrow(new SecurityException("expected exception")).when(trans).rollback(); + + try (EntityMgrTrans t = new EntityMgrTrans(mgr)) { + // Empty + } + } + + @Test(expected = EntityMgrException.class) + public void testClose_SysEx() throws Exception { + + when(trans.getStatus()).thenReturn(Status.STATUS_ACTIVE); + doThrow(new SystemException("expected exception")).when(trans).rollback(); + + try (EntityMgrTrans t = new EntityMgrTrans(mgr)) { + // Empty + } + } + + /** + * Verifies that the manager is closed and the transaction rolled back when "try" block exits + * normally and a transaction is active. + */ + @Test + public void testClose_TryWithoutExcept_Active() throws Exception { + when(trans.getStatus()).thenReturn(Status.STATUS_ACTIVE); + + try (EntityMgrTrans t = new EntityMgrTrans(mgr)) { + // Empty + } + + // closed and rolled back, but not committed + verify(trans, never()).commit(); + verify(trans).rollback(); + verify(mgr).close(); + } + + /** + * Verifies that the manager is closed, but that the transaction is <i>not</i> rolled back when + * "try" block exits normally and no transaction is active. + */ + @Test + public void testClose_TryWithoutExcept_Inactive() throws Exception { + + when(trans.getStatus()).thenReturn(Status.STATUS_NO_TRANSACTION); + + try (EntityMgrTrans t = new EntityMgrTrans(mgr)) { + // Empty + } + + // closed, but not rolled back or committed + verify(trans, never()).commit(); + verify(trans, never()).rollback(); + verify(mgr).close(); + } + + /** + * Verifies that the manager is closed and the transaction rolled back when "try" block throws an + * exception and a transaction is active. + */ + @Test + public void testClose_TryWithExcept_Active() throws Exception { + + when(trans.getStatus()).thenReturn(Status.STATUS_ACTIVE); + + try { + try (EntityMgrTrans t = new EntityMgrTrans(mgr)) { + throw new SystemException("expected exception"); + } + + } catch (Exception e) { + logger.trace("expected exception", e); + } + + // closed and rolled back, but not committed + verify(trans, never()).commit(); + verify(trans).rollback(); + verify(mgr).close(); + } + + /** + * Verifies that the manager is closed, but that the transaction is <i>not</i> rolled back when + * "try" block throws an exception and no transaction is active. + */ + @Test + public void testClose_TryWithExcept_Inactive() throws Exception { + + when(trans.getStatus()).thenReturn(Status.STATUS_NO_TRANSACTION); + + try { + try (EntityMgrTrans t = new EntityMgrTrans(mgr)) { + throw new SystemException("expected exception"); + } + + } catch (Exception e) { + logger.trace("expected exception", e); + } + + // closed, but not rolled back or committed + verify(trans, never()).commit(); + verify(trans, never()).rollback(); + verify(mgr).close(); + } + + /** Verifies that commit() only commits, and that the subsequent close() does not re-commit. */ + @Test + public void testCommit() throws Exception { + EntityMgrTrans newTrans = new EntityMgrTrans(mgr); + when(trans.getStatus()).thenReturn(Status.STATUS_ACTIVE); + + newTrans.commit(); + + when(trans.getStatus()).thenReturn(Status.STATUS_COMMITTED); + + // committed, but not closed or rolled back + verify(trans).commit(); + verify(trans, never()).rollback(); + verify(mgr, never()).close(); + + // closed, but not re-committed + newTrans.close(); + + verify(trans, times(1)).commit(); + verify(mgr).close(); + } + + @Test(expected = EntityMgrException.class) + public void testCommit_SecEx() throws Exception { + + when(trans.getStatus()).thenReturn(Status.STATUS_ACTIVE); + doThrow(new SecurityException("expected exception")).when(trans).commit(); + + try (EntityMgrTrans t = new EntityMgrTrans(mgr)) { + t.commit(); + } + } - try (EntityMgrTrans t = new EntityMgrTrans(mgr)) { - t.commit(); - } - } + @Test(expected = EntityMgrException.class) + public void testCommit_IllStateEx() throws Exception { - @Test(expected = EntityMgrException.class) - public void testCommit_IllStateEx() throws Exception { + when(trans.getStatus()).thenReturn(Status.STATUS_ACTIVE); + doThrow(new IllegalStateException("expected exception")).when(trans).commit(); - when(trans.getStatus()).thenReturn(Status.STATUS_ACTIVE); - doThrow(new IllegalStateException("expected exception")).when(trans).commit(); + try (EntityMgrTrans t = new EntityMgrTrans(mgr)) { + t.commit(); + } + } - try (EntityMgrTrans t = new EntityMgrTrans(mgr)) { - t.commit(); - } - } - - @Test(expected = EntityMgrException.class) - public void testCommit_RbEx() throws Exception { + @Test(expected = EntityMgrException.class) + public void testCommit_RbEx() throws Exception { - when(trans.getStatus()).thenReturn(Status.STATUS_ACTIVE); - doThrow(new RollbackException("expected exception")).when(trans).commit(); - - try (EntityMgrTrans t = new EntityMgrTrans(mgr)) { - t.commit(); - } - } + when(trans.getStatus()).thenReturn(Status.STATUS_ACTIVE); + doThrow(new RollbackException("expected exception")).when(trans).commit(); - @Test(expected = EntityMgrException.class) - public void testCommit_HmEx() throws Exception { + try (EntityMgrTrans t = new EntityMgrTrans(mgr)) { + t.commit(); + } + } - when(trans.getStatus()).thenReturn(Status.STATUS_ACTIVE); - doThrow(new HeuristicMixedException("expected exception")).when(trans).commit(); + @Test(expected = EntityMgrException.class) + public void testCommit_HmEx() throws Exception { - try (EntityMgrTrans t = new EntityMgrTrans(mgr)) { - t.commit(); - } - } + when(trans.getStatus()).thenReturn(Status.STATUS_ACTIVE); + doThrow(new HeuristicMixedException("expected exception")).when(trans).commit(); - @Test(expected = EntityMgrException.class) - public void testCommit_HrbEx() throws Exception { + try (EntityMgrTrans t = new EntityMgrTrans(mgr)) { + t.commit(); + } + } - when(trans.getStatus()).thenReturn(Status.STATUS_ACTIVE); - doThrow(new HeuristicRollbackException("expected exception")).when(trans).commit(); + @Test(expected = EntityMgrException.class) + public void testCommit_HrbEx() throws Exception { - try (EntityMgrTrans t = new EntityMgrTrans(mgr)) { - t.commit(); - } - } + when(trans.getStatus()).thenReturn(Status.STATUS_ACTIVE); + doThrow(new HeuristicRollbackException("expected exception")).when(trans).commit(); - @Test(expected = EntityMgrException.class) - public void testCommit_SysEx() throws Exception { + try (EntityMgrTrans t = new EntityMgrTrans(mgr)) { + t.commit(); + } + } - when(trans.getStatus()).thenReturn(Status.STATUS_ACTIVE); - doThrow(new SystemException("expected exception")).when(trans).commit(); + @Test(expected = EntityMgrException.class) + public void testCommit_SysEx() throws Exception { - try (EntityMgrTrans t = new EntityMgrTrans(mgr)) { - t.commit(); - } - } + when(trans.getStatus()).thenReturn(Status.STATUS_ACTIVE); + doThrow(new SystemException("expected exception")).when(trans).commit(); - /** - * Verifies that rollback() only rolls back, and that the subsequent close() - * does not re-roll back. - */ - @Test - public void testRollback() throws Exception { - EntityMgrTrans t = new EntityMgrTrans(mgr); - when(trans.getStatus()).thenReturn(Status.STATUS_ACTIVE); + try (EntityMgrTrans t = new EntityMgrTrans(mgr)) { + t.commit(); + } + } - t.rollback(); + /** + * Verifies that rollback() only rolls back, and that the subsequent close() does not re-roll + * back. + */ + @Test + public void testRollback() throws Exception { + EntityMgrTrans newTrans = new EntityMgrTrans(mgr); + when(trans.getStatus()).thenReturn(Status.STATUS_ACTIVE); - when(trans.getStatus()).thenReturn(Status.STATUS_ROLLEDBACK); + newTrans.rollback(); - // rolled back, but not closed or committed - verify(trans, never()).commit(); - verify(trans).rollback(); - verify(mgr, never()).close(); + when(trans.getStatus()).thenReturn(Status.STATUS_ROLLEDBACK); - // closed, but not re-rolled back - t.close(); + // rolled back, but not closed or committed + verify(trans, never()).commit(); + verify(trans).rollback(); + verify(mgr, never()).close(); - verify(trans, times(1)).rollback(); - verify(mgr).close(); - } + // closed, but not re-rolled back + newTrans.close(); - @Test(expected = EntityMgrException.class) - public void testRollback_IllStateEx() throws Exception { + verify(trans, times(1)).rollback(); + verify(mgr).close(); + } - when(trans.getStatus()).thenReturn(Status.STATUS_ACTIVE); - doThrow(new IllegalStateException("expected exception")).when(trans).rollback(); + @Test(expected = EntityMgrException.class) + public void testRollback_IllStateEx() throws Exception { - try (EntityMgrTrans t = new EntityMgrTrans(mgr)) { - t.rollback(); - } - } + when(trans.getStatus()).thenReturn(Status.STATUS_ACTIVE); + doThrow(new IllegalStateException("expected exception")).when(trans).rollback(); - @Test(expected = EntityMgrException.class) - public void testRollback_SecEx() throws Exception { + try (EntityMgrTrans t = new EntityMgrTrans(mgr)) { + t.rollback(); + } + } - when(trans.getStatus()).thenReturn(Status.STATUS_ACTIVE); - doThrow(new SecurityException("expected exception")).when(trans).rollback(); + @Test(expected = EntityMgrException.class) + public void testRollback_SecEx() throws Exception { - try (EntityMgrTrans t = new EntityMgrTrans(mgr)) { - t.rollback(); - } - } + when(trans.getStatus()).thenReturn(Status.STATUS_ACTIVE); + doThrow(new SecurityException("expected exception")).when(trans).rollback(); - @Test(expected = EntityMgrException.class) - public void testRollback_SysEx() throws Exception { + try (EntityMgrTrans t = new EntityMgrTrans(mgr)) { + t.rollback(); + } + } - when(trans.getStatus()).thenReturn(Status.STATUS_ACTIVE); - doThrow(new SystemException("expected exception")).when(trans).rollback(); + @Test(expected = EntityMgrException.class) + public void testRollback_SysEx() throws Exception { - try (EntityMgrTrans t = new EntityMgrTrans(mgr)) { - t.rollback(); - } - } + when(trans.getStatus()).thenReturn(Status.STATUS_ACTIVE); + doThrow(new SystemException("expected exception")).when(trans).rollback(); - @Test - public void testEntityMgrException() { - SecurityException secex = new SecurityException("expected exception"); - EntityMgrException ex = new EntityMgrException(secex); + try (EntityMgrTrans t = new EntityMgrTrans(mgr)) { + t.rollback(); + } + } - assertEquals(secex, ex.getCause()); + @Test + public void testEntityMgrException() { + SecurityException secex = new SecurityException("expected exception"); + EntityMgrException ex = new EntityMgrException(secex); - } + assertEquals(secex, ex.getCause()); + } } diff --git a/feature-session-persistence/src/test/java/org/onap/policy/drools/persistence/GenSchema.java b/feature-session-persistence/src/test/java/org/onap/policy/drools/persistence/GenSchema.java index a0af2e6c..38e3ec23 100644 --- a/feature-session-persistence/src/test/java/org/onap/policy/drools/persistence/GenSchema.java +++ b/feature-session-persistence/src/test/java/org/onap/policy/drools/persistence/GenSchema.java @@ -2,14 +2,14 @@ * ============LICENSE_START======================================================= * feature-session-persistence * ================================================================================ - * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * Copyright (C) 2017-2018 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. @@ -29,41 +29,38 @@ import javax.persistence.Persistence; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -/** - * Generates the schema DDL files. - */ +/** Generates the schema DDL files. */ public class GenSchema { - private static final Logger logger = LoggerFactory.getLogger(PersistenceFeatureTest.class); + private static final Logger logger = LoggerFactory.getLogger(PersistenceFeatureTest.class); - private EntityManagerFactory emf; + private EntityManagerFactory emf; - /** - * Opens the EMF, which generates the schema, as a side-effect. - * - * @throws Exception - */ - private GenSchema() throws Exception { - Map<String, Object> propMap = new HashMap<>(); + /** + * Opens the EMF, which generates the schema, as a side-effect. + * + * @throws Exception exception + */ + private GenSchema() throws Exception { + Map<String, Object> propMap = new HashMap<>(); - propMap.put("javax.persistence.jdbc.driver", "org.h2.Driver"); - propMap.put("javax.persistence.jdbc.url", "jdbc:h2:mem:JpaDroolsSessionConnectorTest"); + propMap.put("javax.persistence.jdbc.driver", "org.h2.Driver"); + propMap.put("javax.persistence.jdbc.url", "jdbc:h2:mem:JpaDroolsSessionConnectorTest"); - emf = Persistence.createEntityManagerFactory("schemaDroolsPU", propMap); + emf = Persistence.createEntityManagerFactory("schemaDroolsPU", propMap); - emf.close(); - } + emf.close(); + } - /** - * This is is provided as a utility for producing a basic ddl schema file in - * the sql directory. - */ - public static void main(String[] args) { - try { - new GenSchema(); + /** + * This is is provided as a utility for producing a basic ddl schema file in the sql directory. + */ + public static void main(String[] args) { + try { + new GenSchema(); - } catch (Exception e) { - logger.error("failed to generate schema", e); - } - } + } catch (Exception e) { + logger.error("failed to generate schema", e); + } + } } diff --git a/feature-session-persistence/src/test/java/org/onap/policy/drools/persistence/JpaDroolsSessionConnectorTest.java b/feature-session-persistence/src/test/java/org/onap/policy/drools/persistence/JpaDroolsSessionConnectorTest.java index dd601dd3..def8f2ec 100644 --- a/feature-session-persistence/src/test/java/org/onap/policy/drools/persistence/JpaDroolsSessionConnectorTest.java +++ b/feature-session-persistence/src/test/java/org/onap/policy/drools/persistence/JpaDroolsSessionConnectorTest.java @@ -2,14 +2,14 @@ * ============LICENSE_START======================================================= * feature-session-persistence * ================================================================================ - * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * Copyright (C) 2017-2018 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. @@ -45,155 +45,158 @@ import org.onap.policy.drools.persistence.JpaDroolsSessionConnector; public class JpaDroolsSessionConnectorTest { - private EntityManagerFactory emf; - private JpaDroolsSessionConnector conn; + private EntityManagerFactory emf; + private JpaDroolsSessionConnector conn; - @BeforeClass - public static void setUpBeforeClass() { - System.setProperty("com.arjuna.ats.arjuna.objectstore.objectStoreDir", "target/tm"); - System.setProperty("ObjectStoreEnvironmentBean.objectStoreDir", "target/tm"); - } + @BeforeClass + public static void setUpBeforeClass() { + System.setProperty("com.arjuna.ats.arjuna.objectstore.objectStoreDir", "target/tm"); + System.setProperty("ObjectStoreEnvironmentBean.objectStoreDir", "target/tm"); + } - @Before - public void setUp() throws Exception { - Map<String, Object> propMap = new HashMap<>(); + /** + * Setup. + * + * @throws Exception exception + */ + @Before + public void setUp() throws Exception { + Map<String, Object> propMap = new HashMap<>(); - propMap.put("javax.persistence.jdbc.driver", "org.h2.Driver"); - propMap.put("javax.persistence.jdbc.url", "jdbc:h2:mem:JpaDroolsSessionConnectorTest"); + propMap.put("javax.persistence.jdbc.driver", "org.h2.Driver"); + propMap.put("javax.persistence.jdbc.url", "jdbc:h2:mem:JpaDroolsSessionConnectorTest"); - emf = Persistence.createEntityManagerFactory("junitDroolsSessionEntityPU", propMap); + emf = Persistence.createEntityManagerFactory("junitDroolsSessionEntityPU", propMap); - conn = new JpaDroolsSessionConnector(emf); - } + conn = new JpaDroolsSessionConnector(emf); + } - @After - public void tearDown() { - // this will cause the memory db to be dropped - emf.close(); - } + @After + public void tearDown() { + // this will cause the memory db to be dropped + emf.close(); + } - @Test - public void testGet() { - /* - * Load up the DB with some data. - */ + @Test + public void testGet() { + /* + * Load up the DB with some data. + */ - addSession("nameA", 10); - addSession("nameY", 20); + addSession("nameA", 10); + addSession("nameY", 20); - /* - * Now test the functionality. - */ + /* + * Now test the functionality. + */ - // not found - assertNull(conn.get("unknown")); + // not found + assertNull(conn.get("unknown")); - assertEquals("{name=nameA, id=10}", conn.get("nameA").toString()); + assertEquals("{name=nameA, id=10}", conn.get("nameA").toString()); - assertEquals("{name=nameY, id=20}", conn.get("nameY").toString()); - } + assertEquals("{name=nameY, id=20}", conn.get("nameY").toString()); + } - @Test(expected = IllegalArgumentException.class) - public void testGet_NewEx() { - EntityManagerFactory emf = mock(EntityManagerFactory.class); - EntityManager em = mock(EntityManager.class); + @Test(expected = IllegalArgumentException.class) + public void testGet_NewEx() { + EntityManagerFactory emf = mock(EntityManagerFactory.class); + EntityManager em = mock(EntityManager.class); - when(emf.createEntityManager()).thenReturn(em); - when(em.find(any(), any())).thenThrow(new IllegalArgumentException("expected exception")); + when(emf.createEntityManager()).thenReturn(em); + when(em.find(any(), any())).thenThrow(new IllegalArgumentException("expected exception")); - conn = new JpaDroolsSessionConnector(emf); - conn.get("xyz"); - } + conn = new JpaDroolsSessionConnector(emf); + conn.get("xyz"); + } - @Test(expected = IllegalArgumentException.class) - public void testGet_FindEx() { - EntityManagerFactory emf = mock(EntityManagerFactory.class); - EntityManager em = mock(EntityManager.class); - EntityTransaction tr = mock(EntityTransaction.class); + @Test(expected = IllegalArgumentException.class) + public void testGet_FindEx() { + EntityManagerFactory emf = mock(EntityManagerFactory.class); + EntityManager em = mock(EntityManager.class); + EntityTransaction tr = mock(EntityTransaction.class); - when(emf.createEntityManager()).thenReturn(em); - when(em.getTransaction()).thenReturn(tr); - when(em.find(any(), any())).thenThrow(new IllegalArgumentException("expected exception")); + when(emf.createEntityManager()).thenReturn(em); + when(em.getTransaction()).thenReturn(tr); + when(em.find(any(), any())).thenThrow(new IllegalArgumentException("expected exception")); - new JpaDroolsSessionConnector(emf).get("xyz"); - } + new JpaDroolsSessionConnector(emf).get("xyz"); + } - @Test(expected = IllegalArgumentException.class) - public void testGet_FindEx_CloseEx() { - EntityManagerFactory emf = mock(EntityManagerFactory.class); - EntityManager em = mock(EntityManager.class); - EntityTransaction tr = mock(EntityTransaction.class); + @Test(expected = IllegalArgumentException.class) + public void testGet_FindEx_CloseEx() { + EntityManagerFactory emf = mock(EntityManagerFactory.class); + EntityManager em = mock(EntityManager.class); + EntityTransaction tr = mock(EntityTransaction.class); - when(emf.createEntityManager()).thenReturn(em); - when(em.getTransaction()).thenReturn(tr); - when(em.find(any(), any())).thenThrow(new IllegalArgumentException("expected exception")); - doThrow(new IllegalArgumentException("expected exception #2")).when(em).close(); + when(emf.createEntityManager()).thenReturn(em); + when(em.getTransaction()).thenReturn(tr); + when(em.find(any(), any())).thenThrow(new IllegalArgumentException("expected exception")); + doThrow(new IllegalArgumentException("expected exception #2")).when(em).close(); - new JpaDroolsSessionConnector(emf).get("xyz"); - } + new JpaDroolsSessionConnector(emf).get("xyz"); + } - @Test - public void testReplace_Existing() { - addSession("nameA", 10); + @Test + public void testReplace_Existing() { + addSession("nameA", 10); - DroolsSessionEntity sess = new DroolsSessionEntity("nameA", 30); + DroolsSessionEntity sess = new DroolsSessionEntity("nameA", 30); - conn.replace(sess); + conn.replace(sess); - // id should be changed - assertEquals(sess.toString(), conn.get("nameA").toString()); - } + // id should be changed + assertEquals(sess.toString(), conn.get("nameA").toString()); + } - @Test - public void testReplace_New() { - DroolsSessionEntity sess = new DroolsSessionEntity("nameA", 30); + @Test + public void testReplace_New() { + DroolsSessionEntity sess = new DroolsSessionEntity("nameA", 30); - conn.replace(sess); + conn.replace(sess); - assertEquals(sess.toString(), conn.get("nameA").toString()); - } + assertEquals(sess.toString(), conn.get("nameA").toString()); + } - @Test - public void testAdd() { - DroolsSessionEntity sess = new DroolsSessionEntity("nameA", 30); + @Test + public void testAdd() { + DroolsSessionEntity sess = new DroolsSessionEntity("nameA", 30); - conn.replace(sess); + conn.replace(sess); - assertEquals(sess.toString(), conn.get("nameA").toString()); - } + assertEquals(sess.toString(), conn.get("nameA").toString()); + } - @Test - public void testUpdate() { - addSession("nameA", 10); + @Test + public void testUpdate() { + addSession("nameA", 10); - DroolsSessionEntity sess = new DroolsSessionEntity("nameA", 30); + DroolsSessionEntity sess = new DroolsSessionEntity("nameA", 30); - conn.replace(sess); + conn.replace(sess); - // id should be changed - assertEquals("{name=nameA, id=30}", conn.get("nameA").toString()); - } + // id should be changed + assertEquals("{name=nameA, id=30}", conn.get("nameA").toString()); + } - /** - * Adds a session to the DB. - * - * @param sessnm - * session name - * @param sessid - * session id - */ - private void addSession(String sessnm, int sessid) { - EntityManager em = emf.createEntityManager(); + /** + * Adds a session to the DB. + * + * @param sessnm session name + * @param sessid session id + */ + private void addSession(String sessnm, int sessid) { + EntityManager em = emf.createEntityManager(); - try (EntityMgrTrans trans = new EntityMgrTrans(em)) { - DroolsSessionEntity ent = new DroolsSessionEntity(); + try (EntityMgrTrans trans = new EntityMgrTrans(em)) { + DroolsSessionEntity ent = new DroolsSessionEntity(); - ent.setSessionName(sessnm); - ent.setSessionId(sessid); + ent.setSessionName(sessnm); + ent.setSessionId(sessid); - em.persist(ent); + em.persist(ent); - trans.commit(); - } - } + trans.commit(); + } + } } diff --git a/feature-session-persistence/src/test/java/org/onap/policy/drools/persistence/PersistenceFeatureTest.java b/feature-session-persistence/src/test/java/org/onap/policy/drools/persistence/PersistenceFeatureTest.java index a7c33aba..27ac2cc1 100644 --- a/feature-session-persistence/src/test/java/org/onap/policy/drools/persistence/PersistenceFeatureTest.java +++ b/feature-session-persistence/src/test/java/org/onap/policy/drools/persistence/PersistenceFeatureTest.java @@ -2,14 +2,14 @@ * ============LICENSE_START======================================================= * feature-session-persistence * ================================================================================ - * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * Copyright (C) 2017-2018 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. @@ -29,12 +29,12 @@ import static org.junit.Assert.fail; import static org.mockito.Matchers.any; import static org.mockito.Matchers.anyLong; import static org.mockito.Matchers.anyString; +import static org.mockito.Mockito.doThrow; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.never; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; -import static org.mockito.Mockito.doThrow; import java.io.FileNotFoundException; import java.io.FileReader; @@ -83,1335 +83,1332 @@ import org.slf4j.LoggerFactory; public class PersistenceFeatureTest { - private static final Logger logger = LoggerFactory.getLogger(PersistenceFeatureTest.class); - - private static final String JDBC_DRIVER = "fake.driver"; - private static final String JDBC_URL = "fake.url"; - private static final String JDBC_USER = "fake.user"; - private static final String JDBC_PASSWD = "fake.password"; - private static final String JTA_OSDIR = "target"; - private static final String SRC_TEST_RESOURCES = "src/test/resources"; - - private static Properties stdprops; - - private JpaDroolsSessionConnector jpa; - private DroolsSession sess; - private KieSession kiesess; - private BasicDataSource bds; - private EntityManagerFactory emf; - private Connection conn; - private Properties props; - private KieServices kiesvc; - private Environment kieenv; - private KieSessionConfiguration kiecfg; - private KieBase kiebase; - private KieStoreServices kiestore; - private KieContainer kiecont; - private TransactionManager transmgr; - private UserTransaction usertrans; - private TransactionSynchronizationRegistry transreg; - private PolicyController polctlr; - private PolicyContainer polcont; - private PolicySession polsess; - private PersistenceFeature.Factory fact; - - private PersistenceFeature feat; - - @BeforeClass - public static void setUpBeforeClass() throws Exception { - stdprops = new Properties(); - - stdprops.put(DroolsPersistenceProperties.DB_DRIVER, JDBC_DRIVER); - stdprops.put(DroolsPersistenceProperties.DB_URL, JDBC_URL); - stdprops.put(DroolsPersistenceProperties.DB_USER, JDBC_USER); - stdprops.put(DroolsPersistenceProperties.DB_PWD, JDBC_PASSWD); - stdprops.put(DroolsPersistenceProperties.JTA_OBJECTSTORE_DIR, JTA_OSDIR); - stdprops.put(DroolsPersistenceProperties.DB_SESSIONINFO_TIMEOUT, "50"); - - System.setProperty("com.arjuna.ats.arjuna.objectstore.objectStoreDir", "target/tm"); - System.setProperty("ObjectStoreEnvironmentBean.objectStoreDir", "target/tm"); - } - - @Before - public void setUp() throws Exception { - jpa = mock(JpaDroolsSessionConnector.class); - sess = mock(DroolsSession.class); - bds = mock(BasicDataSource.class); - emf = mock(EntityManagerFactory.class); - kiesess = mock(KieSession.class); - conn = null; - props = new Properties(); - kiesvc = mock(KieServices.class); - kieenv = mock(Environment.class); - kiecfg = mock(KieSessionConfiguration.class); - kiebase = mock(KieBase.class); - kiestore = mock(KieStoreServices.class); - kiecont = mock(KieContainer.class); - transmgr = mock(TransactionManager.class); - usertrans = mock(UserTransaction.class); - transreg = mock(TransactionSynchronizationRegistry.class); - polcont = mock(PolicyContainer.class); - polctlr = mock(PolicyController.class); - polsess = mock(PolicySession.class); - fact = mock(PersistenceFeature.Factory.class); - - feat = new PersistenceFeature(); - feat.setFactory(fact); - - props.putAll(stdprops); - - System.setProperty("com.arjuna.ats.arjuna.objectstore.objectStoreDir", "target/tm"); - System.setProperty("ObjectStoreEnvironmentBean.objectStoreDir", "target/tm"); - - when(fact.getKieServices()).thenReturn(kiesvc); - when(fact.getTransMgr()).thenReturn(transmgr); - when(fact.getUserTrans()).thenReturn(usertrans); - when(fact.getTransSyncReg()).thenReturn(transreg); - when(fact.loadProperties(anyString())).thenReturn(props); - - when(kiesvc.newEnvironment()).thenReturn(kieenv); - when(kiesvc.getStoreServices()).thenReturn(kiestore); - when(kiesvc.newKieSessionConfiguration()).thenReturn(kiecfg); - - when(polcont.getKieContainer()).thenReturn(kiecont); - - when(polsess.getPolicyContainer()).thenReturn(polcont); - - when(kiecont.getKieBase(anyString())).thenReturn(kiebase); - } - - @After - public void tearDown() { - // this will cause the in-memory test DB to be dropped - if (conn != null) { - try { - conn.close(); - } catch (SQLException e) { - logger.warn("failed to close connection", e); - } - } - - if (emf != null) { - try { - emf.close(); - } catch (IllegalArgumentException e) { - logger.trace("ignored exception", e); - } - } - } - - @Test - public void testGetContainerAdjunct_New() throws Exception { - - feat.globalInit(null, SRC_TEST_RESOURCES); + private static final Logger logger = LoggerFactory.getLogger(PersistenceFeatureTest.class); + + private static final String JDBC_DRIVER = "fake.driver"; + private static final String JDBC_URL = "fake.url"; + private static final String JDBC_USER = "fake.user"; + private static final String JDBC_PASSWD = "fake.password"; + private static final String JTA_OSDIR = "target"; + private static final String SRC_TEST_RESOURCES = "src/test/resources"; + + private static Properties stdprops; + + private JpaDroolsSessionConnector jpa; + private DroolsSession sess; + private KieSession kiesess; + private BasicDataSource bds; + private EntityManagerFactory emf; + private Connection conn; + private Properties props; + private KieServices kiesvc; + private Environment kieenv; + private KieSessionConfiguration kiecfg; + private KieBase kiebase; + private KieStoreServices kiestore; + private KieContainer kiecont; + private TransactionManager transmgr; + private UserTransaction usertrans; + private TransactionSynchronizationRegistry transreg; + private PolicyController polctlr; + private PolicyContainer polcont; + private PolicySession polsess; + private PersistenceFeature.Factory fact; + + private PersistenceFeature feat; + + /** + * Setup before class. + * + * @throws Exception exception + */ + @BeforeClass + public static void setUpBeforeClass() throws Exception { + stdprops = new Properties(); + + stdprops.put(DroolsPersistenceProperties.DB_DRIVER, JDBC_DRIVER); + stdprops.put(DroolsPersistenceProperties.DB_URL, JDBC_URL); + stdprops.put(DroolsPersistenceProperties.DB_USER, JDBC_USER); + stdprops.put(DroolsPersistenceProperties.DB_PWD, JDBC_PASSWD); + stdprops.put(DroolsPersistenceProperties.JTA_OBJECTSTORE_DIR, JTA_OSDIR); + stdprops.put(DroolsPersistenceProperties.DB_SESSIONINFO_TIMEOUT, "50"); + + System.setProperty("com.arjuna.ats.arjuna.objectstore.objectStoreDir", "target/tm"); + System.setProperty("ObjectStoreEnvironmentBean.objectStoreDir", "target/tm"); + } + + /** + * Setup. + * + * @throws Exception exception + */ + @Before + public void setUp() throws Exception { + jpa = mock(JpaDroolsSessionConnector.class); + sess = mock(DroolsSession.class); + bds = mock(BasicDataSource.class); + emf = mock(EntityManagerFactory.class); + kiesess = mock(KieSession.class); + conn = null; + props = new Properties(); + kiesvc = mock(KieServices.class); + kieenv = mock(Environment.class); + kiecfg = mock(KieSessionConfiguration.class); + kiebase = mock(KieBase.class); + kiestore = mock(KieStoreServices.class); + kiecont = mock(KieContainer.class); + transmgr = mock(TransactionManager.class); + usertrans = mock(UserTransaction.class); + transreg = mock(TransactionSynchronizationRegistry.class); + polcont = mock(PolicyContainer.class); + polctlr = mock(PolicyController.class); + polsess = mock(PolicySession.class); + fact = mock(PersistenceFeature.Factory.class); + + feat = new PersistenceFeature(); + feat.setFactory(fact); + + props.putAll(stdprops); + + System.setProperty("com.arjuna.ats.arjuna.objectstore.objectStoreDir", "target/tm"); + System.setProperty("ObjectStoreEnvironmentBean.objectStoreDir", "target/tm"); + + when(fact.getKieServices()).thenReturn(kiesvc); + when(fact.getTransMgr()).thenReturn(transmgr); + when(fact.getUserTrans()).thenReturn(usertrans); + when(fact.getTransSyncReg()).thenReturn(transreg); + when(fact.loadProperties(anyString())).thenReturn(props); + + when(kiesvc.newEnvironment()).thenReturn(kieenv); + when(kiesvc.getStoreServices()).thenReturn(kiestore); + when(kiesvc.newKieSessionConfiguration()).thenReturn(kiecfg); + + when(polcont.getKieContainer()).thenReturn(kiecont); + + when(polsess.getPolicyContainer()).thenReturn(polcont); + + when(kiecont.getKieBase(anyString())).thenReturn(kiebase); + } + + /** + * Tear down. + */ + @After + public void tearDown() { + // this will cause the in-memory test DB to be dropped + if (conn != null) { + try { + conn.close(); + } catch (SQLException e) { + logger.warn("failed to close connection", e); + } + } + + if (emf != null) { + try { + emf.close(); + } catch (IllegalArgumentException e) { + logger.trace("ignored exception", e); + } + } + } + + @Test + public void testGetContainerAdjunct_New() throws Exception { + + feat.globalInit(null, SRC_TEST_RESOURCES); + + mockDbConn(5); + setUpKie("myname", 999L, true); + + // force getContainerAdjunct() to be invoked + feat.activatePolicySession(polcont, "myname", "mybase"); + + ArgumentCaptor<PersistenceFeature.ContainerAdjunct> adjcap = + ArgumentCaptor.forClass(PersistenceFeature.ContainerAdjunct.class); + + verify(polcont, times(1)).setAdjunct(any(), adjcap.capture()); + + assertNotNull(adjcap.getValue()); + } + + @Test + public void testGetContainerAdjunct_Existing() throws Exception { + + feat.globalInit(null, SRC_TEST_RESOURCES); + + mockDbConn(5); + setUpKie("myname", 999L, true); + + // force getContainerAdjunct() to be invoked + feat.activatePolicySession(polcont, "myname", "mybase"); + + ArgumentCaptor<PersistenceFeature.ContainerAdjunct> adjcap = + ArgumentCaptor.forClass(PersistenceFeature.ContainerAdjunct.class); + + verify(polcont, times(1)).setAdjunct(any(), adjcap.capture()); + + // return adjunct on next call + when(polcont.getAdjunct(any())).thenReturn(adjcap.getValue()); + + // force getContainerAdjunct() to be invoked again + setUpKie("myname2", 999L, true); + feat.activatePolicySession(polcont, "myname2", "mybase"); + + // ensure it isn't invoked again + verify(polcont, times(1)).setAdjunct(any(), any()); + } + + @Test + public void testGetContainerAdjunct_WrongType() throws Exception { + + feat.globalInit(null, SRC_TEST_RESOURCES); + + mockDbConn(5); + setUpKie("myname", 999L, true); + + // return false adjunct on next call + when(polcont.getAdjunct(any())).thenReturn("not-a-real-adjunct"); + + // force getContainerAdjunct() to be invoked + setUpKie("myname2", 999L, true); + feat.activatePolicySession(polcont, "myname2", "mybase"); + + ArgumentCaptor<PersistenceFeature.ContainerAdjunct> adjcap = + ArgumentCaptor.forClass(PersistenceFeature.ContainerAdjunct.class); + + verify(polcont, times(1)).setAdjunct(any(), adjcap.capture()); + + assertNotNull(adjcap.getValue()); + } + + @Test + public void testGetSequenceNumber() { + assertEquals(1, feat.getSequenceNumber()); + } + + @Test + public void testGlobalInit() throws Exception { + + feat.globalInit(null, SRC_TEST_RESOURCES); + + // verify that various factory methods were invoked + verify(fact).getKieServices(); + verify(fact).loadProperties("src/test/resources/feature-session-persistence.properties"); + } + + @Test(expected = NullPointerException.class) + public void testGlobalInitIoEx() throws Exception { + + when(fact.loadProperties(anyString())).thenThrow(new IOException("expected exception")); + + feat.globalInit(null, SRC_TEST_RESOURCES); + } + + @Test + public void testActivatePolicySession() throws Exception { + final PreparedStatement ps = mockDbConn(5); + setUpKie("myname", 999L, true); + + feat.globalInit(null, SRC_TEST_RESOURCES); + feat.beforeActivate(null); + + KieSession session = feat.activatePolicySession(polcont, "myname", "mybase"); + + verify(kiestore).loadKieSession(anyLong(), any(), any(), any()); + verify(kiestore, never()).newKieSession(any(), any(), any()); + + assertEquals(session, kiesess); + + verify(ps).executeUpdate(); + + verify(kieenv, times(4)).set(anyString(), any()); + + verify(jpa).get("myname"); + verify(jpa).replace(any()); + } + + @Test + public void testActivatePolicySession_NoPersistence() throws Exception { + feat.globalInit(null, SRC_TEST_RESOURCES); - mockDbConn(5); - setUpKie("myname", 999L, true); + final PreparedStatement ps = mockDbConn(5); + setUpKie("myname", 999L, true); - // force getContainerAdjunct() to be invoked - feat.activatePolicySession(polcont, "myname", "mybase"); + props.remove("persistence.type"); - ArgumentCaptor<PersistenceFeature.ContainerAdjunct> adjcap = ArgumentCaptor - .forClass(PersistenceFeature.ContainerAdjunct.class); + feat.beforeStart(null); - verify(polcont, times(1)).setAdjunct(any(), adjcap.capture()); + assertNull(feat.activatePolicySession(polcont, "myname", "mybase")); - assertNotNull(adjcap.getValue()); - } + verify(ps, never()).executeUpdate(); + verify(kiestore, never()).loadKieSession(anyLong(), any(), any(), any()); + verify(kiestore, never()).newKieSession(any(), any(), any()); + } - @Test - public void testGetContainerAdjunct_Existing() throws Exception { + /** Verifies that a new KIE session is created when there is no existing session entity. */ + @Test + public void testActivatePolicySession_New() throws Exception { + feat.globalInit(null, SRC_TEST_RESOURCES); - feat.globalInit(null, SRC_TEST_RESOURCES); + mockDbConn(5); + setUpKie("noName", 999L, true); - mockDbConn(5); - setUpKie("myname", 999L, true); + KieSession session = feat.activatePolicySession(polcont, "myname", "mybase"); - // force getContainerAdjunct() to be invoked - feat.activatePolicySession(polcont, "myname", "mybase"); + verify(kiestore, never()).loadKieSession(anyLong(), any(), any(), any()); + verify(kiestore).newKieSession(any(), any(), any()); - ArgumentCaptor<PersistenceFeature.ContainerAdjunct> adjcap = ArgumentCaptor - .forClass(PersistenceFeature.ContainerAdjunct.class); + assertEquals(session, kiesess); - verify(polcont, times(1)).setAdjunct(any(), adjcap.capture()); + verify(kieenv, times(4)).set(anyString(), any()); - // return adjunct on next call - when(polcont.getAdjunct(any())).thenReturn(adjcap.getValue()); + verify(jpa).get("myname"); + verify(jpa).replace(any()); + } - // force getContainerAdjunct() to be invoked again - setUpKie("myname2", 999L, true); - feat.activatePolicySession(polcont, "myname2", "mybase"); + /** + * Verifies that a new KIE session is created when there KIE fails to load an existing session. + */ + @Test + public void testActivatePolicySession_LoadFailed() throws Exception { + feat.globalInit(null, SRC_TEST_RESOURCES); - // ensure it isn't invoked again - verify(polcont, times(1)).setAdjunct(any(), any()); - } + mockDbConn(5); + setUpKie("myname", 999L, false); - @Test - public void testGetContainerAdjunct_WrongType() throws Exception { + KieSession session = feat.activatePolicySession(polcont, "myname", "mybase"); - feat.globalInit(null, SRC_TEST_RESOURCES); + verify(kiestore).loadKieSession(anyLong(), any(), any(), any()); + verify(kiestore).newKieSession(any(), any(), any()); - mockDbConn(5); - setUpKie("myname", 999L, true); + assertEquals(session, kiesess); - // return false adjunct on next call - when(polcont.getAdjunct(any())).thenReturn("not-a-real-adjunct"); + verify(kieenv, times(4)).set(anyString(), any()); - // force getContainerAdjunct() to be invoked - setUpKie("myname2", 999L, true); - feat.activatePolicySession(polcont, "myname2", "mybase"); + verify(jpa).get("myname"); - ArgumentCaptor<PersistenceFeature.ContainerAdjunct> adjcap = ArgumentCaptor - .forClass(PersistenceFeature.ContainerAdjunct.class); + ArgumentCaptor<DroolsSession> drools = ArgumentCaptor.forClass(DroolsSession.class); + verify(jpa).replace(drools.capture()); - verify(polcont, times(1)).setAdjunct(any(), adjcap.capture()); + assertEquals("myname", drools.getValue().getSessionName()); + assertEquals(100L, drools.getValue().getSessionId()); + } - assertNotNull(adjcap.getValue()); - } + @Test + public void testLoadDataSource() throws Exception { + feat.globalInit(null, SRC_TEST_RESOURCES); - @Test - public void testGetSequenceNumber() { - assertEquals(1, feat.getSequenceNumber()); - } + mockDbConn(5); + setUpKie("myname", 999L, false); - @Test - public void testGlobalInit() throws Exception { + feat.activatePolicySession(polcont, "myname", "mybase"); - feat.globalInit(null, SRC_TEST_RESOURCES); + verify(fact).makeEntMgrFact(any()); + } - // verify that various factory methods were invoked - verify(fact).getKieServices(); - verify(fact).loadProperties("src/test/resources/feature-session-persistence.properties"); - } + @Test + public void testConfigureSysProps() throws Exception { + feat.globalInit(null, SRC_TEST_RESOURCES); - @Test(expected = NullPointerException.class) - public void testGlobalInit_IOEx() throws Exception { - - when(fact.loadProperties(anyString())).thenThrow(new IOException("expected exception")); + mockDbConn(5); + setUpKie("myname", 999L, false); - feat.globalInit(null, SRC_TEST_RESOURCES); - } + feat.activatePolicySession(polcont, "myname", "mybase"); - @Test - public void testActivatePolicySession() throws Exception { - PreparedStatement ps = mockDbConn(5); - setUpKie("myname", 999L, true); + assertEquals("60", System.getProperty("com.arjuna.ats.arjuna.coordinator.defaultTimeout")); + assertEquals(JTA_OSDIR, System.getProperty("com.arjuna.ats.arjuna.objectstore.objectStoreDir")); + assertEquals(JTA_OSDIR, System.getProperty("ObjectStoreEnvironmentBean.objectStoreDir")); + } - feat.globalInit(null, SRC_TEST_RESOURCES); - feat.beforeActivate(null); + @Test + public void testConfigureKieEnv() throws Exception { + feat.globalInit(null, SRC_TEST_RESOURCES); - KieSession s = feat.activatePolicySession(polcont, "myname", "mybase"); + mockDbConn(5); + setUpKie("myname", 999L, false); - verify(kiestore).loadKieSession(anyLong(), any(), any(), any()); - verify(kiestore, never()).newKieSession(any(), any(), any()); + feat.activatePolicySession(polcont, "myname", "mybase"); - assertEquals(s, kiesess); + verify(kieenv, times(4)).set(any(), any()); - verify(ps).executeUpdate(); + verify(kieenv).set(EnvironmentName.ENTITY_MANAGER_FACTORY, emf); + verify(kieenv).set(EnvironmentName.TRANSACTION, usertrans); + verify(kieenv).set(EnvironmentName.TRANSACTION_MANAGER, transmgr); + verify(kieenv).set(EnvironmentName.TRANSACTION_SYNCHRONIZATION_REGISTRY, transreg); - verify(kieenv, times(4)).set(anyString(), any()); + verify(bds, times(1)).close(); + } - verify(jpa).get("myname"); - verify(jpa).replace(any()); - } + @Test + public void testConfigureKieEnv_RtEx() throws Exception { + feat.globalInit(null, SRC_TEST_RESOURCES); - @Test - public void testActivatePolicySession_NoPersistence() throws Exception { - feat.globalInit(null, SRC_TEST_RESOURCES); + mockDbConn(5); + setUpKie("myname", 999L, false); - PreparedStatement ps = mockDbConn(5); - setUpKie("myname", 999L, true); + when(fact.getUserTrans()).thenThrow(new IllegalArgumentException("expected exception")); - props.remove("persistence.type"); + try { + feat.activatePolicySession(polcont, "myname", "mybase"); + fail("missing exception"); - feat.beforeStart(null); + } catch (IllegalArgumentException ex) { + logger.trace("expected exception", ex); + } - assertNull(feat.activatePolicySession(polcont, "myname", "mybase")); + verify(bds, times(2)).close(); + } - verify(ps, never()).executeUpdate(); - verify(kiestore, never()).loadKieSession(anyLong(), any(), any(), any()); - verify(kiestore, never()).newKieSession(any(), any(), any()); - } + @Test + public void testLoadKieSession() throws Exception { + feat.globalInit(null, SRC_TEST_RESOURCES); - /** - * Verifies that a new KIE session is created when there is no existing - * session entity. - */ - @Test - public void testActivatePolicySession_New() throws Exception { - feat.globalInit(null, SRC_TEST_RESOURCES); + mockDbConn(5); + setUpKie("myname", 999L, true); - mockDbConn(5); - setUpKie("noName", 999L, true); + KieSession session = feat.activatePolicySession(polcont, "myname", "mybase"); - KieSession s = feat.activatePolicySession(polcont, "myname", "mybase"); + verify(kiestore).loadKieSession(999L, kiebase, kiecfg, kieenv); + verify(kiestore, never()).newKieSession(any(), any(), any()); - verify(kiestore, never()).loadKieSession(anyLong(), any(), any(), any()); - verify(kiestore).newKieSession(any(), any(), any()); + assertEquals(session, kiesess); + } - assertEquals(s, kiesess); + /* + * Verifies that loadKieSession() returns null (thus causing newKieSession() + * to be called) when an Exception occurs. + */ + @Test + public void testLoadKieSession_Ex() throws Exception { + feat.globalInit(null, SRC_TEST_RESOURCES); - verify(kieenv, times(4)).set(anyString(), any()); + mockDbConn(5); + setUpKie("myname", 999L, false); - verify(jpa).get("myname"); - verify(jpa).replace(any()); - } + when(kiestore.loadKieSession(anyLong(), any(), any(), any())) + .thenThrow(new IllegalArgumentException("expected exception")); - /** - * Verifies that a new KIE session is created when there KIE fails to load - * an existing session. - */ - @Test - public void testActivatePolicySession_LoadFailed() throws Exception { - feat.globalInit(null, SRC_TEST_RESOURCES); + KieSession session = feat.activatePolicySession(polcont, "myname", "mybase"); - mockDbConn(5); - setUpKie("myname", 999L, false); + verify(kiestore).loadKieSession(anyLong(), any(), any(), any()); + verify(kiestore).newKieSession(any(), any(), any()); - KieSession s = feat.activatePolicySession(polcont, "myname", "mybase"); + assertEquals(session, kiesess); + } - verify(kiestore).loadKieSession(anyLong(), any(), any(), any()); - verify(kiestore).newKieSession(any(), any(), any()); + @Test + public void testNewKieSession() throws Exception { + feat.globalInit(null, SRC_TEST_RESOURCES); - assertEquals(s, kiesess); + mockDbConn(5); + setUpKie("myname", 999L, false); - verify(kieenv, times(4)).set(anyString(), any()); + KieSession session = feat.activatePolicySession(polcont, "myname", "mybase"); - verify(jpa).get("myname"); + verify(kiestore).newKieSession(kiebase, null, kieenv); - ArgumentCaptor<DroolsSession> d = ArgumentCaptor.forClass(DroolsSession.class); - verify(jpa).replace(d.capture()); + assertEquals(session, kiesess); + } - assertEquals("myname", d.getValue().getSessionName()); - assertEquals(100L, d.getValue().getSessionId()); - } + @Test + public void testLoadDataSource_DiffSession() throws Exception { + feat.globalInit(null, SRC_TEST_RESOURCES); - @Test - public void testLoadDataSource() throws Exception { - feat.globalInit(null, SRC_TEST_RESOURCES); + mockDbConn(5); + setUpKie("myname", 999L, false); + feat.activatePolicySession(polcont, "myname", "mybase"); - mockDbConn(5); - setUpKie("myname", 999L, false); + ArgumentCaptor<PersistenceFeature.ContainerAdjunct> adjcap = + ArgumentCaptor.forClass(PersistenceFeature.ContainerAdjunct.class); - feat.activatePolicySession(polcont, "myname", "mybase"); + verify(polcont).setAdjunct(any(), adjcap.capture()); - verify(fact).makeEntMgrFact(any()); - } + when(polcont.getAdjunct(any())).thenReturn(adjcap.getValue()); - @Test - public void testConfigureSysProps() throws Exception { - feat.globalInit(null, SRC_TEST_RESOURCES); + setUpKie("myname2", 999L, false); - mockDbConn(5); - setUpKie("myname", 999L, false); + // invoke it again + feat.activatePolicySession(polcont, "myname2", "mybase"); - feat.activatePolicySession(polcont, "myname", "mybase"); + verify(fact, times(2)).makeEntMgrFact(any()); + } - assertEquals("60", System.getProperty("com.arjuna.ats.arjuna.coordinator.defaultTimeout")); - assertEquals(JTA_OSDIR, System.getProperty("com.arjuna.ats.arjuna.objectstore.objectStoreDir")); - assertEquals(JTA_OSDIR, System.getProperty("ObjectStoreEnvironmentBean.objectStoreDir")); - } + @Test + public void testSelectThreadModel_Persistent() throws Exception { + setUpKie("myname", 999L, true); - @Test - public void testConfigureKieEnv() throws Exception { - feat.globalInit(null, SRC_TEST_RESOURCES); + ThreadModel model = feat.selectThreadModel(polsess); + assertNotNull(model); + assertTrue(model instanceof PersistentThreadModel); + } - mockDbConn(5); - setUpKie("myname", 999L, false); + @Test + public void testSelectThreadModel_NotPersistent() throws Exception { + when(fact.getPolicyController(any())).thenReturn(polctlr); + assertNull(feat.selectThreadModel(polsess)); + } - feat.activatePolicySession(polcont, "myname", "mybase"); + @Test + public void testSelectThreadModel_Start__Run_Update_Stop() throws Exception { + setUpKie("myname", 999L, true); - verify(kieenv, times(4)).set(any(), any()); + ThreadModel model = feat.selectThreadModel(polsess); + assertNotNull(model); + assertTrue(model instanceof PersistentThreadModel); - verify(kieenv).set(EnvironmentName.ENTITY_MANAGER_FACTORY, emf); - verify(kieenv).set(EnvironmentName.TRANSACTION, usertrans); - verify(kieenv).set(EnvironmentName.TRANSACTION_MANAGER, transmgr); - verify(kieenv).set(EnvironmentName.TRANSACTION_SYNCHRONIZATION_REGISTRY, transreg); - - verify(bds, times(1)).close(); - } + when(polsess.getKieSession()).thenReturn(kiesess); - @Test - public void testConfigureKieEnv_RtEx() throws Exception { - feat.globalInit(null, SRC_TEST_RESOURCES); + model.start(); + new CountDownLatch(1).await(10, TimeUnit.MILLISECONDS); + model.updated(); + model.stop(); + } - mockDbConn(5); - setUpKie("myname", 999L, false); - - when(fact.getUserTrans()).thenThrow(new IllegalArgumentException("expected exception")); + @Test + public void testDisposeKieSession() throws Exception { + feat.globalInit(null, SRC_TEST_RESOURCES); - try { - feat.activatePolicySession(polcont, "myname", "mybase"); - fail("missing exception"); - - } catch(IllegalArgumentException ex) { - logger.trace("expected exception", ex); - } + final ArgumentCaptor<PersistenceFeature.ContainerAdjunct> adjcap = + ArgumentCaptor.forClass(PersistenceFeature.ContainerAdjunct.class); - verify(bds, times(2)).close(); - } + mockDbConn(5); + setUpKie("myname", 999L, false); - @Test - public void testLoadKieSession() throws Exception { - feat.globalInit(null, SRC_TEST_RESOURCES); + feat.activatePolicySession(polcont, "myname", "mybase"); - mockDbConn(5); - setUpKie("myname", 999L, true); + verify(emf, never()).close(); + verify(polcont).setAdjunct(any(), adjcap.capture()); - KieSession s = feat.activatePolicySession(polcont, "myname", "mybase"); + when(polcont.getAdjunct(any())).thenReturn(adjcap.getValue()); - verify(kiestore).loadKieSession(999L, kiebase, kiecfg, kieenv); - verify(kiestore, never()).newKieSession(any(), any(), any()); + feat.disposeKieSession(polsess); - assertEquals(s, kiesess); - } + // call twice to ensure it isn't re-closed + feat.disposeKieSession(polsess); - /* - * Verifies that loadKieSession() returns null (thus causing newKieSession() - * to be called) when an Exception occurs. - */ - @Test - public void testLoadKieSession_Ex() throws Exception { - feat.globalInit(null, SRC_TEST_RESOURCES); + verify(emf, times(1)).close(); + } - mockDbConn(5); - setUpKie("myname", 999L, false); + @Test + public void testDisposeKieSession_NoAdjunct() throws Exception { + feat.globalInit(null, SRC_TEST_RESOURCES); - when(kiestore.loadKieSession(anyLong(), any(), any(), any())) - .thenThrow(new IllegalArgumentException("expected exception")); + feat.disposeKieSession(polsess); + } - KieSession s = feat.activatePolicySession(polcont, "myname", "mybase"); + @Test + public void testDisposeKieSession_NoPersistence() throws Exception { + feat.globalInit(null, SRC_TEST_RESOURCES); - verify(kiestore).loadKieSession(anyLong(), any(), any(), any()); - verify(kiestore).newKieSession(any(), any(), any()); + final ArgumentCaptor<PersistenceFeature.ContainerAdjunct> adjcap = + ArgumentCaptor.forClass(PersistenceFeature.ContainerAdjunct.class); - assertEquals(s, kiesess); - } + mockDbConn(5); + setUpKie("myname", 999L, false); - @Test - public void testNewKieSession() throws Exception { - feat.globalInit(null, SRC_TEST_RESOURCES); + feat.activatePolicySession(polcont, "myname", "mybase"); - mockDbConn(5); - setUpKie("myname", 999L, false); + verify(emf, never()).close(); + verify(polcont).setAdjunct(any(), adjcap.capture()); - KieSession s = feat.activatePolicySession(polcont, "myname", "mybase"); + when(polcont.getAdjunct(any())).thenReturn(adjcap.getValue()); - verify(kiestore).newKieSession(kiebase, null, kieenv); + // specify a session that was never loaded + when(polsess.getName()).thenReturn("anotherName"); - assertEquals(s, kiesess); - } + feat.disposeKieSession(polsess); - @Test - public void testLoadDataSource_DiffSession() throws Exception { - feat.globalInit(null, SRC_TEST_RESOURCES); + verify(emf, never()).close(); + } - mockDbConn(5); - setUpKie("myname", 999L, false); - feat.activatePolicySession(polcont, "myname", "mybase"); + @Test + public void testDestroyKieSession() throws Exception { + feat.globalInit(null, SRC_TEST_RESOURCES); - ArgumentCaptor<PersistenceFeature.ContainerAdjunct> adjcap = ArgumentCaptor - .forClass(PersistenceFeature.ContainerAdjunct.class); + final ArgumentCaptor<PersistenceFeature.ContainerAdjunct> adjcap = + ArgumentCaptor.forClass(PersistenceFeature.ContainerAdjunct.class); - verify(polcont).setAdjunct(any(), adjcap.capture()); + mockDbConn(5); + setUpKie("myname", 999L, false); - when(polcont.getAdjunct(any())).thenReturn(adjcap.getValue()); + feat.activatePolicySession(polcont, "myname", "mybase"); - setUpKie("myname2", 999L, false); + verify(emf, never()).close(); + verify(polcont).setAdjunct(any(), adjcap.capture()); - // invoke it again - feat.activatePolicySession(polcont, "myname2", "mybase"); + when(polcont.getAdjunct(any())).thenReturn(adjcap.getValue()); - verify(fact, times(2)).makeEntMgrFact(any()); - } - - @Test - public void testSelectThreadModel_Persistent() throws Exception { - setUpKie("myname", 999L, true); - - ThreadModel m = feat.selectThreadModel(polsess); - assertNotNull(m); - assertTrue(m instanceof PersistentThreadModel); - - } - - @Test - public void testSelectThreadModel_NotPersistent() throws Exception { - when(fact.getPolicyController(any())).thenReturn(polctlr); - assertNull(feat.selectThreadModel(polsess)); - - } - - @Test - public void testSelectThreadModel_Start__Run_Update_Stop() throws Exception { - setUpKie("myname", 999L, true); - - ThreadModel m = feat.selectThreadModel(polsess); - assertNotNull(m); - assertTrue(m instanceof PersistentThreadModel); - - when(polsess.getKieSession()).thenReturn(kiesess); - - m.start(); - new CountDownLatch(1).await(10, TimeUnit.MILLISECONDS); - m.updated(); - m.stop(); - } + feat.destroyKieSession(polsess); - @Test - public void testDisposeKieSession() throws Exception { - feat.globalInit(null, SRC_TEST_RESOURCES); + // call twice to ensure it isn't re-closed + feat.destroyKieSession(polsess); - ArgumentCaptor<PersistenceFeature.ContainerAdjunct> adjcap = ArgumentCaptor - .forClass(PersistenceFeature.ContainerAdjunct.class); + verify(emf, times(1)).close(); + } - mockDbConn(5); - setUpKie("myname", 999L, false); + @Test + public void testDestroyKieSession_NoAdjunct() throws Exception { + feat.globalInit(null, SRC_TEST_RESOURCES); - feat.activatePolicySession(polcont, "myname", "mybase"); + feat.destroyKieSession(polsess); + } - verify(emf, never()).close(); - verify(polcont).setAdjunct(any(), adjcap.capture()); + @Test + public void testDestroyKieSession_NoPersistence() throws Exception { + feat.globalInit(null, SRC_TEST_RESOURCES); - when(polcont.getAdjunct(any())).thenReturn(adjcap.getValue()); + final ArgumentCaptor<PersistenceFeature.ContainerAdjunct> adjcap = + ArgumentCaptor.forClass(PersistenceFeature.ContainerAdjunct.class); - feat.disposeKieSession(polsess); + mockDbConn(5); + setUpKie("myname", 999L, false); - // call twice to ensure it isn't re-closed - feat.disposeKieSession(polsess); + feat.activatePolicySession(polcont, "myname", "mybase"); - verify(emf, times(1)).close(); - } + verify(emf, never()).close(); + verify(polcont).setAdjunct(any(), adjcap.capture()); - @Test - public void testDisposeKieSession_NoAdjunct() throws Exception { - feat.globalInit(null, SRC_TEST_RESOURCES); + when(polcont.getAdjunct(any())).thenReturn(adjcap.getValue()); - feat.disposeKieSession(polsess); - } + // specify a session that was never loaded + when(polsess.getName()).thenReturn("anotherName"); - @Test - public void testDisposeKieSession_NoPersistence() throws Exception { - feat.globalInit(null, SRC_TEST_RESOURCES); + feat.destroyKieSession(polsess); - ArgumentCaptor<PersistenceFeature.ContainerAdjunct> adjcap = ArgumentCaptor - .forClass(PersistenceFeature.ContainerAdjunct.class); + verify(emf, never()).close(); + } - mockDbConn(5); - setUpKie("myname", 999L, false); + @Test + public void testAfterStart() { + assertFalse(feat.afterStart(null)); + } - feat.activatePolicySession(polcont, "myname", "mybase"); + @Test + public void testBeforeStart() { + assertFalse(feat.beforeStart(null)); + } - verify(emf, never()).close(); - verify(polcont).setAdjunct(any(), adjcap.capture()); + @Test + public void testBeforeShutdown() { + assertFalse(feat.beforeShutdown(null)); + } - when(polcont.getAdjunct(any())).thenReturn(adjcap.getValue()); + @Test + public void testAfterShutdown() { + assertFalse(feat.afterShutdown(null)); + } - // specify a session that was never loaded - when(polsess.getName()).thenReturn("anotherName"); + @Test + public void testBeforeConfigure() { + assertFalse(feat.beforeConfigure(null, null)); + } - feat.disposeKieSession(polsess); + @Test + public void testAfterConfigure() { + assertFalse(feat.afterConfigure(null)); + } - verify(emf, never()).close(); - } + @Test + public void testBeforeActivate() { + assertFalse(feat.beforeActivate(null)); + } - @Test - public void testDestroyKieSession() throws Exception { - feat.globalInit(null, SRC_TEST_RESOURCES); + @Test + public void testAfterActivate() { + assertFalse(feat.afterActivate(null)); + } - ArgumentCaptor<PersistenceFeature.ContainerAdjunct> adjcap = ArgumentCaptor - .forClass(PersistenceFeature.ContainerAdjunct.class); + @Test + public void testBeforeDeactivate() { + assertFalse(feat.beforeDeactivate(null)); + } - mockDbConn(5); - setUpKie("myname", 999L, false); + @Test + public void testAfterDeactivate() { + assertFalse(feat.afterDeactivate(null)); + } - feat.activatePolicySession(polcont, "myname", "mybase"); + @Test + public void testBeforeStop() { + assertFalse(feat.beforeStop(null)); + } - verify(emf, never()).close(); - verify(polcont).setAdjunct(any(), adjcap.capture()); + @Test + public void testAfterStop() { + assertFalse(feat.afterStop(null)); + } - when(polcont.getAdjunct(any())).thenReturn(adjcap.getValue()); + @Test + public void testBeforeLock() { + assertFalse(feat.beforeLock(null)); + } - feat.destroyKieSession(polsess); + @Test + public void testAfterLock() { + assertFalse(feat.afterLock(null)); + } - // call twice to ensure it isn't re-closed - feat.destroyKieSession(polsess); + @Test + public void testBeforeUnlock() { + assertFalse(feat.beforeUnlock(null)); + } - verify(emf, times(1)).close(); - } + @Test + public void testAfterUnlock() { + assertFalse(feat.afterUnlock(null)); + } - @Test - public void testDestroyKieSession_NoAdjunct() throws Exception { - feat.globalInit(null, SRC_TEST_RESOURCES); + @Test + public void testGetPersistenceTimeout_Valid() throws Exception { + final PreparedStatement statement = mockDbConn(5); - feat.destroyKieSession(polsess); - } + feat.globalInit(null, SRC_TEST_RESOURCES); - @Test - public void testDestroyKieSession_NoPersistence() throws Exception { - feat.globalInit(null, SRC_TEST_RESOURCES); + setUpKie("myname", 999L, true); - ArgumentCaptor<PersistenceFeature.ContainerAdjunct> adjcap = ArgumentCaptor - .forClass(PersistenceFeature.ContainerAdjunct.class); + feat.activatePolicySession(polcont, "myname", "mybase"); - mockDbConn(5); - setUpKie("myname", 999L, false); + verify(statement).executeUpdate(); + } - feat.activatePolicySession(polcont, "myname", "mybase"); + @Test + public void testGetPersistenceTimeout_Missing() throws Exception { - verify(emf, never()).close(); - verify(polcont).setAdjunct(any(), adjcap.capture()); + props.remove(DroolsPersistenceProperties.DB_SESSIONINFO_TIMEOUT); - when(polcont.getAdjunct(any())).thenReturn(adjcap.getValue()); + final PreparedStatement statement = mockDbConn(0); - // specify a session that was never loaded - when(polsess.getName()).thenReturn("anotherName"); + feat.globalInit(null, SRC_TEST_RESOURCES); - feat.destroyKieSession(polsess); + setUpKie("myname", 999L, true); - verify(emf, never()).close(); - } + feat.activatePolicySession(polcont, "myname", "mybase"); - @Test - public void testAfterStart() { - assertFalse(feat.afterStart(null)); - } + verify(statement, never()).executeUpdate(); + } - @Test - public void testBeforeStart() { - assertFalse(feat.beforeStart(null)); - } + @Test + public void testGetPersistenceTimeout_Invalid() throws Exception { + props.setProperty(DroolsPersistenceProperties.DB_SESSIONINFO_TIMEOUT, "abc"); + final PreparedStatement s = mockDbConn(0); - @Test - public void testBeforeShutdown() { - assertFalse(feat.beforeShutdown(null)); - } + feat.globalInit(null, SRC_TEST_RESOURCES); - @Test - public void testAfterShutdown() { - assertFalse(feat.afterShutdown(null)); - } + setUpKie("myname", 999L, true); - @Test - public void testBeforeConfigure() { - assertFalse(feat.beforeConfigure(null, null)); - } + feat.activatePolicySession(polcont, "myname", "mybase"); - @Test - public void testAfterConfigure() { - assertFalse(feat.afterConfigure(null)); - } + verify(s, never()).executeUpdate(); + } - @Test - public void testBeforeActivate() { - assertFalse(feat.beforeActivate(null)); - } + @Test + public void testCleanUpSessionInfo() throws Exception { + setUpKie("myname", 999L, true); - @Test - public void testAfterActivate() { - assertFalse(feat.afterActivate(null)); - } + // use a real DB so we can verify that the "delete" works correctly + fact = new PartialFactory(); + feat.setFactory(fact); - @Test - public void testBeforeDeactivate() { - assertFalse(feat.beforeDeactivate(null)); - } + makeSessionInfoTbl(20000); - @Test - public void testAfterDeactivate() { - assertFalse(feat.afterDeactivate(null)); - } + // create mock entity manager for use by JPA connector + EntityManager em = mock(EntityManager.class); + when(emf.createEntityManager()).thenReturn(em); - @Test - public void testBeforeStop() { - assertFalse(feat.beforeStop(null)); - } + feat.globalInit(null, SRC_TEST_RESOURCES); - @Test - public void testAfterStop() { - assertFalse(feat.afterStop(null)); - } + feat.beforeStart(null); + feat.activatePolicySession(polcont, "myname", "mybase"); - @Test - public void testBeforeLock() { - assertFalse(feat.beforeLock(null)); - } + assertEquals("[1, 4, 5]", getSessions().toString()); + } - @Test - public void testAfterLock() { - assertFalse(feat.afterLock(null)); - } + @Test + public void testCleanUpSessionInfo_WithBeforeStart() throws Exception { + final PreparedStatement statement = mockDbConn(0); - @Test - public void testBeforeUnlock() { - assertFalse(feat.beforeUnlock(null)); - } + feat.globalInit(null, SRC_TEST_RESOURCES); - @Test - public void testAfterUnlock() { - assertFalse(feat.afterUnlock(null)); - } + setUpKie("myname", 999L, true); - @Test - public void testGetPersistenceTimeout_Valid() throws Exception { - PreparedStatement s = mockDbConn(5); + // reset + feat.beforeStart(null); - feat.globalInit(null, SRC_TEST_RESOURCES); + feat.activatePolicySession(polcont, "myname", "mybase"); + verify(statement, times(1)).executeUpdate(); - setUpKie("myname", 999L, true); + // should not clean-up again + feat.activatePolicySession(polcont, "myname", "mybase"); + feat.activatePolicySession(polcont, "myname", "mybase"); + verify(statement, times(1)).executeUpdate(); - feat.activatePolicySession(polcont, "myname", "mybase"); + // reset + feat.beforeStart(null); - verify(s).executeUpdate(); - } + feat.activatePolicySession(polcont, "myname", "mybase"); + verify(statement, times(2)).executeUpdate(); - @Test - public void testGetPersistenceTimeout_Missing() throws Exception { + // should not clean-up again + feat.activatePolicySession(polcont, "myname", "mybase"); + feat.activatePolicySession(polcont, "myname", "mybase"); + verify(statement, times(2)).executeUpdate(); + } - props.remove(DroolsPersistenceProperties.DB_SESSIONINFO_TIMEOUT); + @Test + public void testCleanUpSessionInfo_WithBeforeActivate() throws Exception { + final PreparedStatement statement = mockDbConn(0); - PreparedStatement s = mockDbConn(0); + feat.globalInit(null, SRC_TEST_RESOURCES); - feat.globalInit(null, SRC_TEST_RESOURCES); + setUpKie("myname", 999L, true); - setUpKie("myname", 999L, true); + // reset + feat.beforeActivate(null); - feat.activatePolicySession(polcont, "myname", "mybase"); + feat.activatePolicySession(polcont, "myname", "mybase"); + verify(statement, times(1)).executeUpdate(); - verify(s, never()).executeUpdate(); - } + // should not clean-up again + feat.activatePolicySession(polcont, "myname", "mybase"); + feat.activatePolicySession(polcont, "myname", "mybase"); + verify(statement, times(1)).executeUpdate(); - @Test - public void testGetPersistenceTimeout_Invalid() throws Exception { - props.setProperty(DroolsPersistenceProperties.DB_SESSIONINFO_TIMEOUT, "abc"); - PreparedStatement s = mockDbConn(0); + // reset + feat.beforeActivate(null); - feat.globalInit(null, SRC_TEST_RESOURCES); + feat.activatePolicySession(polcont, "myname", "mybase"); + verify(statement, times(2)).executeUpdate(); - setUpKie("myname", 999L, true); + // should not clean-up again + feat.activatePolicySession(polcont, "myname", "mybase"); + feat.activatePolicySession(polcont, "myname", "mybase"); + verify(statement, times(2)).executeUpdate(); + } - feat.activatePolicySession(polcont, "myname", "mybase"); + @Test + public void testCleanUpSessionInfo_NoTimeout() throws Exception { - verify(s, never()).executeUpdate(); - } + props.remove(DroolsPersistenceProperties.DB_SESSIONINFO_TIMEOUT); - @Test - public void testCleanUpSessionInfo() throws Exception { - setUpKie("myname", 999L, true); + final PreparedStatement statement = mockDbConn(0); - // use a real DB so we can verify that the "delete" works correctly - fact = new PartialFactory(); - feat.setFactory(fact); + feat.globalInit(null, SRC_TEST_RESOURCES); - makeSessionInfoTbl(20000); + setUpKie("myname", 999L, true); - // create mock entity manager for use by JPA connector - EntityManager em = mock(EntityManager.class); - when(emf.createEntityManager()).thenReturn(em); + feat.activatePolicySession(polcont, "myname", "mybase"); - feat.globalInit(null, SRC_TEST_RESOURCES); + verify(statement, never()).executeUpdate(); + } - feat.beforeStart(null); - feat.activatePolicySession(polcont, "myname", "mybase"); + @Test + public void testCleanUpSessionInfo_NoUrl() throws Exception { + final PreparedStatement statement = mockDbConn(0); - assertEquals("[1, 4, 5]", getSessions().toString()); - } + props.remove(DroolsPersistenceProperties.DB_URL); - @Test - public void testCleanUpSessionInfo_WithBeforeStart() throws Exception { - PreparedStatement s = mockDbConn(0); + feat.globalInit(null, SRC_TEST_RESOURCES); - feat.globalInit(null, SRC_TEST_RESOURCES); + setUpKie("myname", 999L, true); - setUpKie("myname", 999L, true); + try { + feat.activatePolicySession(polcont, "myname", "mybase"); + fail("missing exception"); + } catch (RuntimeException e) { + logger.trace("expected exception", e); + } - // reset - feat.beforeStart(null); + verify(statement, never()).executeUpdate(); + } - feat.activatePolicySession(polcont, "myname", "mybase"); - verify(s, times(1)).executeUpdate(); + @Test + public void testCleanUpSessionInfo_NoUser() throws Exception { + final PreparedStatement statement = mockDbConn(0); - // should not clean-up again - feat.activatePolicySession(polcont, "myname", "mybase"); - feat.activatePolicySession(polcont, "myname", "mybase"); - verify(s, times(1)).executeUpdate(); + props.remove(DroolsPersistenceProperties.DB_USER); - // reset - feat.beforeStart(null); + feat.globalInit(null, SRC_TEST_RESOURCES); - feat.activatePolicySession(polcont, "myname", "mybase"); - verify(s, times(2)).executeUpdate(); + setUpKie("myname", 999L, true); - // should not clean-up again - feat.activatePolicySession(polcont, "myname", "mybase"); - feat.activatePolicySession(polcont, "myname", "mybase"); - verify(s, times(2)).executeUpdate(); - } + try { + feat.activatePolicySession(polcont, "myname", "mybase"); + fail("missing exception"); + } catch (RuntimeException e) { + logger.trace("expected exception", e); + } - @Test - public void testCleanUpSessionInfo_WithBeforeActivate() throws Exception { - PreparedStatement s = mockDbConn(0); + verify(statement, never()).executeUpdate(); + } - feat.globalInit(null, SRC_TEST_RESOURCES); + @Test + public void testCleanUpSessionInfo_NoPassword() throws Exception { + final PreparedStatement statement = mockDbConn(0); - setUpKie("myname", 999L, true); + props.remove(DroolsPersistenceProperties.DB_PWD); - // reset - feat.beforeActivate(null); + feat.globalInit(null, SRC_TEST_RESOURCES); - feat.activatePolicySession(polcont, "myname", "mybase"); - verify(s, times(1)).executeUpdate(); + setUpKie("myname", 999L, true); - // should not clean-up again - feat.activatePolicySession(polcont, "myname", "mybase"); - feat.activatePolicySession(polcont, "myname", "mybase"); - verify(s, times(1)).executeUpdate(); + try { + feat.activatePolicySession(polcont, "myname", "mybase"); + fail("missing exception"); + } catch (RuntimeException e) { + logger.trace("expected exception", e); + } - // reset - feat.beforeActivate(null); + verify(statement, never()).executeUpdate(); + } - feat.activatePolicySession(polcont, "myname", "mybase"); - verify(s, times(2)).executeUpdate(); + @Test + public void testCleanUpSessionInfo_SqlEx() throws Exception { + final PreparedStatement statement = mockDbConn(-1); - // should not clean-up again - feat.activatePolicySession(polcont, "myname", "mybase"); - feat.activatePolicySession(polcont, "myname", "mybase"); - verify(s, times(2)).executeUpdate(); - } + feat.globalInit(null, SRC_TEST_RESOURCES); - @Test - public void testCleanUpSessionInfo_NoTimeout() throws Exception { + setUpKie("myname", 999L, true); - props.remove(DroolsPersistenceProperties.DB_SESSIONINFO_TIMEOUT); + feat.activatePolicySession(polcont, "myname", "mybase"); - PreparedStatement s = mockDbConn(0); + verify(statement).executeUpdate(); + } - feat.globalInit(null, SRC_TEST_RESOURCES); + @Test + public void testGetDroolsSessionConnector() throws Exception { + feat.globalInit(null, SRC_TEST_RESOURCES); - setUpKie("myname", 999L, true); + mockDbConn(5); + setUpKie("myname", 999L, true); - feat.activatePolicySession(polcont, "myname", "mybase"); + feat.activatePolicySession(polcont, "myname", "mybase"); - verify(s, never()).executeUpdate(); - } + verify(fact).makeJpaConnector(emf); + } - @Test - public void testCleanUpSessionInfo_NoUrl() throws Exception { - PreparedStatement s = mockDbConn(0); + @Test + public void testReplaceSession() throws Exception { + feat.globalInit(null, SRC_TEST_RESOURCES); - props.remove(DroolsPersistenceProperties.DB_URL); + final ArgumentCaptor<DroolsSession> sesscap = ArgumentCaptor.forClass(DroolsSession.class); - feat.globalInit(null, SRC_TEST_RESOURCES); + mockDbConn(5); + setUpKie("myname", 999L, true); - setUpKie("myname", 999L, true); + feat.activatePolicySession(polcont, "myname", "mybase"); - try { - feat.activatePolicySession(polcont, "myname", "mybase"); - fail("missing exception"); - } catch (RuntimeException e) { - logger.trace("expected exception", e); - } + verify(jpa).replace(sesscap.capture()); - verify(s, never()).executeUpdate(); - } + assertEquals("myname", sesscap.getValue().getSessionName()); + assertEquals(999L, sesscap.getValue().getSessionId()); + } - @Test - public void testCleanUpSessionInfo_NoUser() throws Exception { - PreparedStatement s = mockDbConn(0); + @Test + public void testIsPersistenceEnabled_Auto() throws Exception { + feat.globalInit(null, SRC_TEST_RESOURCES); - props.remove(DroolsPersistenceProperties.DB_USER); + mockDbConn(5); + setUpKie("myname", 999L, true); - feat.globalInit(null, SRC_TEST_RESOURCES); + props.setProperty("persistence.type", "auto"); - setUpKie("myname", 999L, true); + assertNotNull(feat.activatePolicySession(polcont, "myname", "mybase")); + } - try { - feat.activatePolicySession(polcont, "myname", "mybase"); - fail("missing exception"); - } catch (RuntimeException e) { - logger.trace("expected exception", e); - } + @Test + public void testIsPersistenceEnabled_Native() throws Exception { + feat.globalInit(null, SRC_TEST_RESOURCES); - verify(s, never()).executeUpdate(); - } + mockDbConn(5); + setUpKie("myname", 999L, true); - @Test - public void testCleanUpSessionInfo_NoPassword() throws Exception { - PreparedStatement s = mockDbConn(0); + props.setProperty("persistence.type", "native"); - props.remove(DroolsPersistenceProperties.DB_PWD); + assertNotNull(feat.activatePolicySession(polcont, "myname", "mybase")); + } - feat.globalInit(null, SRC_TEST_RESOURCES); + @Test + public void testIsPersistenceEnabled_None() throws Exception { + feat.globalInit(null, SRC_TEST_RESOURCES); - setUpKie("myname", 999L, true); + mockDbConn(5); + setUpKie("myname", 999L, true); - try { - feat.activatePolicySession(polcont, "myname", "mybase"); - fail("missing exception"); - } catch (RuntimeException e) { - logger.trace("expected exception", e); - } + props.remove("persistence.type"); - verify(s, never()).executeUpdate(); - } + assertNull(feat.activatePolicySession(polcont, "myname", "mybase")); + } - @Test - public void testCleanUpSessionInfo_SqlEx() throws Exception { - PreparedStatement s = mockDbConn(-1); + @Test + public void testGetProperties_Ex() throws Exception { + feat.globalInit(null, SRC_TEST_RESOURCES); - feat.globalInit(null, SRC_TEST_RESOURCES); + mockDbConn(5); + setUpKie("myname", 999L, true); - setUpKie("myname", 999L, true); + when(fact.getPolicyController(polcont)) + .thenThrow(new IllegalArgumentException("expected exception")); - feat.activatePolicySession(polcont, "myname", "mybase"); + assertNull(feat.activatePolicySession(polcont, "myname", "mybase")); + } - verify(s).executeUpdate(); - } + @Test + public void testGetProperty_Specific() throws Exception { + feat.globalInit(null, SRC_TEST_RESOURCES); - @Test - public void testGetDroolsSessionConnector() throws Exception { - feat.globalInit(null, SRC_TEST_RESOURCES); + mockDbConn(5); + setUpKie("myname", 999L, true); - mockDbConn(5); - setUpKie("myname", 999L, true); + props.remove("persistence.type"); + props.setProperty("persistence.myname.type", "auto"); - feat.activatePolicySession(polcont, "myname", "mybase"); + assertNotNull(feat.activatePolicySession(polcont, "myname", "mybase")); + } - verify(fact).makeJpaConnector(emf); - } + @Test + public void testGetProperty_Specific_None() throws Exception { + feat.globalInit(null, SRC_TEST_RESOURCES); - @Test - public void testReplaceSession() throws Exception { - feat.globalInit(null, SRC_TEST_RESOURCES); + mockDbConn(5); + setUpKie("myname", 999L, true); - ArgumentCaptor<DroolsSession> sesscap = ArgumentCaptor.forClass(DroolsSession.class); + props.remove("persistence.type"); + props.setProperty("persistence.xxx.type", "auto"); - mockDbConn(5); - setUpKie("myname", 999L, true); + assertNull(feat.activatePolicySession(polcont, "myname", "mybase")); + } - feat.activatePolicySession(polcont, "myname", "mybase"); + @Test + public void testGetProperty_Both_SpecificOn() throws Exception { + feat.globalInit(null, SRC_TEST_RESOURCES); - verify(jpa).replace(sesscap.capture()); + mockDbConn(5); + setUpKie("myname", 999L, true); - assertEquals("myname", sesscap.getValue().getSessionName()); - assertEquals(999L, sesscap.getValue().getSessionId()); - } + props.setProperty("persistence.type", "other"); + props.setProperty("persistence.myname.type", "auto"); - @Test - public void testIsPersistenceEnabled_Auto() throws Exception { - feat.globalInit(null, SRC_TEST_RESOURCES); + assertNotNull(feat.activatePolicySession(polcont, "myname", "mybase")); + } - mockDbConn(5); - setUpKie("myname", 999L, true); + @Test + public void testGetProperty_Both_SpecificDisabledOff() throws Exception { + feat.globalInit(null, SRC_TEST_RESOURCES); - props.setProperty("persistence.type", "auto"); + mockDbConn(5); + setUpKie("myname", 999L, true); - assertNotNull(feat.activatePolicySession(polcont, "myname", "mybase")); - } + props.setProperty("persistence.type", "auto"); + props.setProperty("persistence.myname.type", "other"); - @Test - public void testIsPersistenceEnabled_Native() throws Exception { - feat.globalInit(null, SRC_TEST_RESOURCES); + assertNull(feat.activatePolicySession(polcont, "myname", "mybase")); + } - mockDbConn(5); - setUpKie("myname", 999L, true); + @Test + public void testGetProperty_None() throws Exception { + feat.globalInit(null, SRC_TEST_RESOURCES); - props.setProperty("persistence.type", "native"); + mockDbConn(5); + setUpKie("myname", 999L, true); - assertNotNull(feat.activatePolicySession(polcont, "myname", "mybase")); - } + props.remove("persistence.type"); - @Test - public void testIsPersistenceEnabled_None() throws Exception { - feat.globalInit(null, SRC_TEST_RESOURCES); + assertNull(feat.activatePolicySession(polcont, "myname", "mybase")); + } - mockDbConn(5); - setUpKie("myname", 999L, true); + @Test + public void testPersistenceFeatureException() { + SecurityException secex = new SecurityException("expected exception"); + PersistenceFeatureException ex = new PersistenceFeatureException(secex); - props.remove("persistence.type"); + assertEquals(secex, ex.getCause()); + } - assertNull(feat.activatePolicySession(polcont, "myname", "mybase")); - } + @Test + public void testDsEmf_RtEx() throws Exception { + feat.globalInit(null, SRC_TEST_RESOURCES); - @Test - public void testGetProperties_Ex() throws Exception { - feat.globalInit(null, SRC_TEST_RESOURCES); + mockDbConn(5); + setUpKie("myname", 999L, false); - mockDbConn(5); - setUpKie("myname", 999L, true); + when(fact.makeEntMgrFact(any())).thenThrow(new IllegalArgumentException("expected exception")); - when(fact.getPolicyController(polcont)).thenThrow(new IllegalArgumentException("expected exception")); + try { + feat.activatePolicySession(polcont, "myname", "mybase"); + fail("missing exception"); - assertNull(feat.activatePolicySession(polcont, "myname", "mybase")); - } + } catch (IllegalArgumentException ex) { + logger.trace("expected exception", ex); + } - @Test - public void testGetProperty_Specific() throws Exception { - feat.globalInit(null, SRC_TEST_RESOURCES); + verify(bds, times(2)).close(); + } - mockDbConn(5); - setUpKie("myname", 999L, true); + @Test + public void testDsEmf_Close_RtEx() throws Exception { + feat.globalInit(null, SRC_TEST_RESOURCES); - props.remove("persistence.type"); - props.setProperty("persistence.myname.type", "auto"); + mockDbConn(5); + setUpKie("myname", 999L, false); - assertNotNull(feat.activatePolicySession(polcont, "myname", "mybase")); - } + feat.activatePolicySession(polcont, "myname", "mybase"); - @Test - public void testGetProperty_Specific_None() throws Exception { - feat.globalInit(null, SRC_TEST_RESOURCES); + ArgumentCaptor<PersistenceFeature.ContainerAdjunct> adjcap = + ArgumentCaptor.forClass(PersistenceFeature.ContainerAdjunct.class); - mockDbConn(5); - setUpKie("myname", 999L, true); + verify(polcont, times(1)).setAdjunct(any(), adjcap.capture()); - props.remove("persistence.type"); - props.setProperty("persistence.xxx.type", "auto"); + // return adjunct on next call + when(polcont.getAdjunct(any())).thenReturn(adjcap.getValue()); - assertNull(feat.activatePolicySession(polcont, "myname", "mybase")); - } + try { + doThrow(new IllegalArgumentException("expected exception")).when(emf).close(); - @Test - public void testGetProperty_Both_SpecificOn() throws Exception { - feat.globalInit(null, SRC_TEST_RESOURCES); + feat.destroyKieSession(polsess); + fail("missing exception"); - mockDbConn(5); - setUpKie("myname", 999L, true); + } catch (IllegalArgumentException ex) { + logger.trace("expected exception", ex); + } - props.setProperty("persistence.type", "other"); - props.setProperty("persistence.myname.type", "auto"); + verify(bds, times(2)).close(); + } - assertNotNull(feat.activatePolicySession(polcont, "myname", "mybase")); - } + @Test + public void testDsEmf_CloseDataSource_RtEx() throws Exception { + feat.globalInit(null, SRC_TEST_RESOURCES); - @Test - public void testGetProperty_Both_SpecificDisabledOff() throws Exception { - feat.globalInit(null, SRC_TEST_RESOURCES); + mockDbConn(5); + setUpKie("myname", 999L, false); - mockDbConn(5); - setUpKie("myname", 999L, true); + feat.activatePolicySession(polcont, "myname", "mybase"); - props.setProperty("persistence.type", "auto"); - props.setProperty("persistence.myname.type", "other"); + ArgumentCaptor<PersistenceFeature.ContainerAdjunct> adjcap = + ArgumentCaptor.forClass(PersistenceFeature.ContainerAdjunct.class); - assertNull(feat.activatePolicySession(polcont, "myname", "mybase")); - } + verify(polcont, times(1)).setAdjunct(any(), adjcap.capture()); - @Test - public void testGetProperty_None() throws Exception { - feat.globalInit(null, SRC_TEST_RESOURCES); + // return adjunct on next call + when(polcont.getAdjunct(any())).thenReturn(adjcap.getValue()); - mockDbConn(5); - setUpKie("myname", 999L, true); + try { + doThrow(new SQLException("expected exception")).when(bds).close(); - props.remove("persistence.type"); + feat.destroyKieSession(polsess); + fail("missing exception"); - assertNull(feat.activatePolicySession(polcont, "myname", "mybase")); - } + } catch (PersistenceFeatureException ex) { + logger.trace("expected exception", ex); + } + } - @Test - public void testPersistenceFeatureException() { - SecurityException secex = new SecurityException("expected exception"); - PersistenceFeatureException ex = new PersistenceFeatureException(secex); + /** + * Gets an ordered list of ids of the current SessionInfo records. + * + * @return ordered list of SessInfo IDs + * @throws SQLException sql exception + * @throws IOException io exception + */ + private List<Integer> getSessions() throws SQLException, IOException { + attachDb(); - assertEquals(secex, ex.getCause()); + ArrayList<Integer> lst = new ArrayList<>(5); - } + try (PreparedStatement stmt = conn.prepareStatement("SELECT id from sessioninfo order by id"); + ResultSet rs = stmt.executeQuery()) { - @Test - public void testDsEmf_RtEx() throws Exception { - feat.globalInit(null, SRC_TEST_RESOURCES); + while (rs.next()) { + lst.add(rs.getInt(1)); + } + } - mockDbConn(5); - setUpKie("myname", 999L, false); - - when(fact.makeEntMgrFact(any())).thenThrow(new IllegalArgumentException("expected exception")); + return lst; + } - try { - feat.activatePolicySession(polcont, "myname", "mybase"); - fail("missing exception"); - - } catch(IllegalArgumentException ex) { - logger.trace("expected exception", ex); - } + /** + * Sets up for doing invoking the newKieSession() method. + * + * @param sessnm name to which JPA should respond with a session + * @param sessid session id to be returned by the session + * @param loadOk {@code true} if loadKieSession() should return a value, {@code false} to return + * null + * @throws Exception exception + */ + private void setUpKie(String sessnm, long sessid, boolean loadOk) throws Exception { - verify(bds, times(2)).close(); - } + when(fact.makeJpaConnector(emf)).thenReturn(jpa); + when(fact.makeEntMgrFact(any())).thenReturn(emf); + when(fact.getPolicyController(polcont)).thenReturn(polctlr); - @Test - public void testDsEmf_Close_RtEx() throws Exception { - feat.globalInit(null, SRC_TEST_RESOURCES); + props.setProperty("persistence.type", "auto"); - mockDbConn(5); - setUpKie("myname", 999L, false); - - feat.activatePolicySession(polcont, "myname", "mybase"); + when(polctlr.getProperties()).thenReturn(props); - ArgumentCaptor<PersistenceFeature.ContainerAdjunct> adjcap = ArgumentCaptor - .forClass(PersistenceFeature.ContainerAdjunct.class); + when(jpa.get(sessnm)).thenReturn(sess); - verify(polcont, times(1)).setAdjunct(any(), adjcap.capture()); + when(sess.getSessionId()).thenReturn(sessid); - // return adjunct on next call - when(polcont.getAdjunct(any())).thenReturn(adjcap.getValue()); + when(polsess.getPolicyContainer()).thenReturn(polcont); + when(polsess.getName()).thenReturn(sessnm); - try { - doThrow(new IllegalArgumentException("expected exception")).when(emf).close(); - - feat.destroyKieSession(polsess); - fail("missing exception"); - - } catch(IllegalArgumentException ex) { - logger.trace("expected exception", ex); - } + if (loadOk) { + when(kiesess.getIdentifier()).thenReturn(sessid); + when(kiestore.loadKieSession(anyLong(), any(), any(), any())).thenReturn(kiesess); - verify(bds, times(2)).close(); - } - - @Test - public void testDsEmf_CloseDataSource_RtEx() throws Exception { - feat.globalInit(null, SRC_TEST_RESOURCES); - - mockDbConn(5); - setUpKie("myname", 999L, false); - - feat.activatePolicySession(polcont, "myname", "mybase"); - - ArgumentCaptor<PersistenceFeature.ContainerAdjunct> adjcap = ArgumentCaptor - .forClass(PersistenceFeature.ContainerAdjunct.class); - - verify(polcont, times(1)).setAdjunct(any(), adjcap.capture()); - - // return adjunct on next call - when(polcont.getAdjunct(any())).thenReturn(adjcap.getValue()); - - try { - doThrow(new SQLException("expected exception")).when(bds).close(); - - feat.destroyKieSession(polsess); - fail("missing exception"); - - } catch(PersistenceFeatureException ex) { - logger.trace("expected exception", ex); - } - } - - /** - * Gets an ordered list of ids of the current SessionInfo records. - * - * @return ordered list of SessInfo IDs - * @throws SQLException - * @throws IOException - */ - private List<Integer> getSessions() throws SQLException, IOException { - attachDb(); - - ArrayList<Integer> lst = new ArrayList<>(5); - - try (PreparedStatement stmt = conn.prepareStatement("SELECT id from sessioninfo order by id"); - ResultSet rs = stmt.executeQuery()) { - - while (rs.next()) { - lst.add(rs.getInt(1)); - } - } - - return lst; - } - - /** - * Sets up for doing invoking the newKieSession() method. - * - * @param sessnm - * name to which JPA should respond with a session - * @param sessid - * session id to be returned by the session - * @param loadOk - * {@code true} if loadKieSession() should return a value, - * {@code false} to return null - * @throws Exception - */ - private void setUpKie(String sessnm, long sessid, boolean loadOk) throws Exception { - - when(fact.makeJpaConnector(emf)).thenReturn(jpa); - when(fact.makeEntMgrFact(any())).thenReturn(emf); - when(fact.getPolicyController(polcont)).thenReturn(polctlr); - - props.setProperty("persistence.type", "auto"); - - when(polctlr.getProperties()).thenReturn(props); - - when(jpa.get(sessnm)).thenReturn(sess); - - when(sess.getSessionId()).thenReturn(sessid); - - when(polsess.getPolicyContainer()).thenReturn(polcont); - when(polsess.getName()).thenReturn(sessnm); - - if (loadOk) { - when(kiesess.getIdentifier()).thenReturn(sessid); - when(kiestore.loadKieSession(anyLong(), any(), any(), any())).thenReturn(kiesess); - - } else { - // use an alternate id for the new session - when(kiesess.getIdentifier()).thenReturn(100L); - when(kiestore.loadKieSession(anyLong(), any(), any(), any())).thenReturn(null); - } - - when(kiestore.newKieSession(any(), any(), any())).thenReturn(kiesess); - } - - /** - * Creates the SessionInfo DB table and populates it with some data. - * - * @param expMs - * number of milli-seconds for expired sessioninfo records - * @throws SQLException - * @throws IOException - */ - private void makeSessionInfoTbl(int expMs) throws SQLException, IOException { - - attachDb(); - - try (PreparedStatement stmt = conn - .prepareStatement("CREATE TABLE sessioninfo(id int, lastmodificationdate timestamp)")) { - - stmt.executeUpdate(); - } - - try (PreparedStatement stmt = conn - .prepareStatement("INSERT into sessioninfo(id, lastmodificationdate) values(?, ?)")) { - - Timestamp ts; - - // current data - ts = new Timestamp(System.currentTimeMillis()); - stmt.setTimestamp(2, ts); - - stmt.setInt(1, 1); - stmt.executeUpdate(); - - stmt.setInt(1, 4); - stmt.executeUpdate(); - - stmt.setInt(1, 5); - stmt.executeUpdate(); - - // expired data - ts = new Timestamp(System.currentTimeMillis() - expMs); - stmt.setTimestamp(2, ts); - - stmt.setInt(1, 2); - stmt.executeUpdate(); - - stmt.setInt(1, 3); - stmt.executeUpdate(); - } - } - - /** - * Attaches {@link #conn} to the DB, if it isn't already attached. - * - * @throws SQLException - * @throws IOException - * if the property file cannot be read - */ - private void attachDb() throws SQLException, IOException { - if (conn == null) { - Properties p = loadDbProps(); - - conn = DriverManager.getConnection(p.getProperty(DroolsPersistenceProperties.DB_URL), - p.getProperty(DroolsPersistenceProperties.DB_USER), - p.getProperty(DroolsPersistenceProperties.DB_PWD)); - conn.setAutoCommit(true); - } - } - - /** - * Loads the DB properties from the file, - * <i>feature-session-persistence.properties</i>. - * - * @return the properties that were loaded - * @throws IOException - * if the property file cannot be read - * @throws FileNotFoundException - * if the property file does not exist - */ - private Properties loadDbProps() throws IOException, FileNotFoundException { - - Properties p = new Properties(); - - try (FileReader rdr = new FileReader("src/test/resources/feature-session-persistence.properties")) { - p.load(rdr); - } - - return p; - } - - /** - * Create a mock DB connection and statement. - * - * @param retval - * value to be returned when the statement is executed, or - * negative to throw an exception - * @return the statement that will be returned by the connection - * @throws SQLException - */ - private PreparedStatement mockDbConn(int retval) throws SQLException { - Connection c = mock(Connection.class); - PreparedStatement s = mock(PreparedStatement.class); - - when(bds.getConnection()).thenReturn(c); - when(fact.makeDataSource(any())).thenReturn(bds); - when(c.prepareStatement(anyString())).thenReturn(s); - - if (retval < 0) { - // should throw an exception - when(s.executeUpdate()).thenThrow(new SQLException("expected exception")); - - } else { - // should return the value - when(s.executeUpdate()).thenReturn(retval); - } - - return s; - } - - /** - * A partial factory, which exports a few of the real methods, but overrides - * the rest. - */ - private class PartialFactory extends PersistenceFeature.Factory { - - @Override - public TransactionManager getTransMgr() { - return transmgr; - } - - @Override - public UserTransaction getUserTrans() { - return usertrans; - } - - @Override - public TransactionSynchronizationRegistry getTransSyncReg() { - return transreg; - } - - @Override - public KieServices getKieServices() { - return kiesvc; - } - - @Override - public EntityManagerFactory makeEntMgrFact(Map<String, Object> props) { - return emf; - } - - @Override - public PolicyController getPolicyController(PolicyContainer container) { - return polctlr; - } - - } + } else { + // use an alternate id for the new session + when(kiesess.getIdentifier()).thenReturn(100L); + when(kiestore.loadKieSession(anyLong(), any(), any(), any())).thenReturn(null); + } + + when(kiestore.newKieSession(any(), any(), any())).thenReturn(kiesess); + } + + /** + * Creates the SessionInfo DB table and populates it with some data. + * + * @param expMs number of milli-seconds for expired sessioninfo records + * @throws SQLException exception + * @throws IOException exception + */ + private void makeSessionInfoTbl(int expMs) throws SQLException, IOException { + + attachDb(); + + try (PreparedStatement stmt = + conn.prepareStatement("CREATE TABLE sessioninfo(id int, lastmodificationdate timestamp)")) { + + stmt.executeUpdate(); + } + + try (PreparedStatement stmt = + conn.prepareStatement("INSERT into sessioninfo(id, lastmodificationdate) values(?, ?)")) { + + Timestamp ts; + + // current data + ts = new Timestamp(System.currentTimeMillis()); + stmt.setTimestamp(2, ts); + + stmt.setInt(1, 1); + stmt.executeUpdate(); + + stmt.setInt(1, 4); + stmt.executeUpdate(); + + stmt.setInt(1, 5); + stmt.executeUpdate(); + + // expired data + ts = new Timestamp(System.currentTimeMillis() - expMs); + stmt.setTimestamp(2, ts); + + stmt.setInt(1, 2); + stmt.executeUpdate(); + + stmt.setInt(1, 3); + stmt.executeUpdate(); + } + } + + /** + * Attaches {@link #conn} to the DB, if it isn't already attached. + * + * @throws SQLException sql exception + * @throws IOException if the property file cannot be read + */ + private void attachDb() throws SQLException, IOException { + if (conn == null) { + Properties props = loadDbProps(); + + conn = + DriverManager.getConnection( + props.getProperty(DroolsPersistenceProperties.DB_URL), + props.getProperty(DroolsPersistenceProperties.DB_USER), + props.getProperty(DroolsPersistenceProperties.DB_PWD)); + conn.setAutoCommit(true); + } + } + + /** + * Loads the DB properties from the file, <i>feature-session-persistence.properties</i>. + * + * @return the properties that were loaded + * @throws IOException if the property file cannot be read + * @throws FileNotFoundException if the property file does not exist + */ + private Properties loadDbProps() throws IOException, FileNotFoundException { + + Properties props = new Properties(); + + try (FileReader rdr = + new FileReader("src/test/resources/feature-session-persistence.properties")) { + props.load(rdr); + } + + return props; + } + + /** + * Create a mock DB connection and statement. + * + * @param retval value to be returned when the statement is executed, or negative to throw an + * exception + * @return the statement that will be returned by the connection + * @throws SQLException sql exception + */ + private PreparedStatement mockDbConn(int retval) throws SQLException { + Connection connection = mock(Connection.class); + PreparedStatement statement = mock(PreparedStatement.class); + + when(bds.getConnection()).thenReturn(connection); + when(fact.makeDataSource(any())).thenReturn(bds); + when(connection.prepareStatement(anyString())).thenReturn(statement); + + if (retval < 0) { + // should throw an exception + when(statement.executeUpdate()).thenThrow(new SQLException("expected exception")); + + } else { + // should return the value + when(statement.executeUpdate()).thenReturn(retval); + } + + return statement; + } + + /** A partial factory, which exports a few of the real methods, but overrides the rest. */ + private class PartialFactory extends PersistenceFeature.Factory { + + @Override + public TransactionManager getTransMgr() { + return transmgr; + } + + @Override + public UserTransaction getUserTrans() { + return usertrans; + } + + @Override + public TransactionSynchronizationRegistry getTransSyncReg() { + return transreg; + } + + @Override + public KieServices getKieServices() { + return kiesvc; + } + + @Override + public EntityManagerFactory makeEntMgrFact(Map<String, Object> props) { + return emf; + } + + @Override + public PolicyController getPolicyController(PolicyContainer container) { + return polctlr; + } + } } diff --git a/feature-session-persistence/src/test/resources/META-INF/persistence.xml b/feature-session-persistence/src/test/resources/META-INF/persistence.xml index 5cc1badc..0fc695d3 100644 --- a/feature-session-persistence/src/test/resources/META-INF/persistence.xml +++ b/feature-session-persistence/src/test/resources/META-INF/persistence.xml @@ -3,7 +3,7 @@ ============LICENSE_START======================================================= feature-session-persistence ================================================================================ - Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + Copyright (C) 2017-2018 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. @@ -20,15 +20,19 @@ --> <persistence version="2.1" - 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"> + 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="junitDroolsSessionEntityPU" transaction-type="JTA"> - <provider>org.hibernate.jpa.HibernatePersistenceProvider</provider> - <class>org.onap.policy.drools.persistence.DroolsSessionEntity</class> - <properties> - <property name="javax.persistence.schema-generation.database.action" value="create"/> + <persistence-unit name="junitDroolsSessionEntityPU" + transaction-type="JTA"> + <provider>org.hibernate.jpa.HibernatePersistenceProvider</provider> + <class>org.onap.policy.drools.persistence.DroolsSessionEntity</class> + <properties> + <property + name="javax.persistence.schema-generation.database.action" + value="create" /> </properties> - </persistence-unit> + </persistence-unit> </persistence> diff --git a/feature-session-persistence/src/test/resources/logback-test.xml b/feature-session-persistence/src/test/resources/logback-test.xml index 6e919eb9..7f151173 100644 --- a/feature-session-persistence/src/test/resources/logback-test.xml +++ b/feature-session-persistence/src/test/resources/logback-test.xml @@ -2,7 +2,7 @@ ============LICENSE_START======================================================= feature-session-persistence ================================================================================ - Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + Copyright (C) 2017-2018 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. @@ -22,25 +22,28 @@ <configuration> - <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender"> - <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder"> - <Pattern> - %d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{36}.%M\(%line\) - %msg%n - </Pattern> - </encoder> - </appender> - <appender name="FILE" class="ch.qos.logback.core.FileAppender"> - <file>logs/debug.log</file> - <encoder> - <Pattern> - %d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{36}.%M\(%line\) - %msg%n - </Pattern> - </encoder> - </appender> - - <root level="debug"> - <appender-ref ref="STDOUT" /> - <appender-ref ref="FILE" /> - </root> + <appender name="STDOUT" + class="ch.qos.logback.core.ConsoleAppender"> + <encoder + class="ch.qos.logback.classic.encoder.PatternLayoutEncoder"> + <Pattern> + %d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{36}.%M\(%line\) - %msg%n + </Pattern> + </encoder> + </appender> + <appender name="FILE" + class="ch.qos.logback.core.FileAppender"> + <file>logs/debug.log</file> + <encoder> + <Pattern> + %d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{36}.%M\(%line\) - %msg%n + </Pattern> + </encoder> + </appender> + + <root level="debug"> + <appender-ref ref="STDOUT" /> + <appender-ref ref="FILE" /> + </root> </configuration> |