Removed checkstyle warnings 73/37073/3
authormmis <michael.morris@ericsson.com>
Tue, 20 Mar 2018 11:46:13 +0000 (11:46 +0000)
committermmis <michael.morris@ericsson.com>
Tue, 20 Mar 2018 23:32:47 +0000 (23:32 +0000)
Removed checkstyle warnings in policy/common/ia

Issue-ID: POLICY-695
Change-Id: I25f589dff5ce1dba0681ba549a53087426593d71
Signed-off-by: mmis <michael.morris@ericsson.com>
20 files changed:
integrity-audit/src/main/java/org/onap/policy/common/ia/AuditThread.java
integrity-audit/src/main/java/org/onap/policy/common/ia/DbAudit.java
integrity-audit/src/main/java/org/onap/policy/common/ia/DbAuditException.java
integrity-audit/src/main/java/org/onap/policy/common/ia/DbDAO.java
integrity-audit/src/main/java/org/onap/policy/common/ia/DbDaoTransactionException.java
integrity-audit/src/main/java/org/onap/policy/common/ia/IntegrityAudit.java
integrity-audit/src/main/java/org/onap/policy/common/ia/IntegrityAuditException.java
integrity-audit/src/main/java/org/onap/policy/common/ia/IntegrityAuditProperties.java
integrity-audit/src/main/java/org/onap/policy/common/ia/IntegrityAuditPropertiesException.java
integrity-audit/src/main/java/org/onap/policy/common/ia/jpa/IntegrityAuditEntity.java
integrity-audit/src/test/java/org/onap/policy/common/ia/AuditPeriodTest.java
integrity-audit/src/test/java/org/onap/policy/common/ia/DbAuditCompareEntriesTest.java
integrity-audit/src/test/java/org/onap/policy/common/ia/DbAuditTest.java
integrity-audit/src/test/java/org/onap/policy/common/ia/DbDAOTest.java
integrity-audit/src/test/java/org/onap/policy/common/ia/ExceptionsTest.java
integrity-audit/src/test/java/org/onap/policy/common/ia/IntegrityAuditDesignationTest.java
integrity-audit/src/test/java/org/onap/policy/common/ia/IntegrityAuditTest.java
integrity-audit/src/test/java/org/onap/policy/common/ia/IntegrityAuditTestBase.java
integrity-audit/src/test/java/org/onap/policy/common/ia/jpa/IaTestEntity.java
integrity-audit/src/test/java/org/onap/policy/common/ia/jpa/PersonSample.java

index efa1b1d..f1839b1 100644 (file)
@@ -35,869 +35,794 @@ import org.onap.policy.common.logging.flexlogger.FlexLogger;
 import org.onap.policy.common.logging.flexlogger.Logger;
 
 /**
- * AuditThread is the main thread for the IntegrityAudit
+ * AuditThread is the main thread for the IntegrityAudit.
  * 
  */
 public class AuditThread extends Thread {
 
-       private static final Logger logger = FlexLogger.getLogger(AuditThread.class);
-
-       /*
-        * Number of milliseconds that must elapse for audit to be considered
-        * complete. It's public for access by JUnit test logic.
-        */
-       public static final long AUDIT_COMPLETION_INTERVAL = 30000;
-
-       /*
-        * Number of iterations for audit simulation.
-        */
-       public static final long AUDIT_SIMULATION_ITERATIONS = 3;
-
-       /*
-        * Number of milliseconds to sleep between audit simulation iterations. It's
-        * public for access by JUnit test logic.
-        */
-       public static final long AUDIT_SIMULATION_SLEEP_INTERVAL = 5000;
-
-       /*
-        * Unless audit has already been run on this entity, number of milliseconds
-        * to sleep between audit thread iterations. If audit has already been run,
-        * we sleep integrityAuditPeriodMillis.  May be modified by JUnit tests.
-        */
-       private static long auditThreadSleepIntervalMillis = 5000;
-
-       /*
-        * Number of milliseconds that must elapse for audit to be considered
-        * complete.  May be modified by JUnit tests.
-        */
-       private static long auditCompletionIntervalMillis = AUDIT_COMPLETION_INTERVAL;
-
-       /*
-        * DB access class.
-        */
-       private DbDAO dbDAO;
-
-       /*
-        * E.g. pdp_xacml
-        */
-       private String nodeType;
-
-       /*
-        * Persistence unit for which this audit is being run.
-        */
-       private String persistenceUnit;
-
-       /*
-        * Name of this resource
-        */
-       private String resourceName;
-
-       /*
-        * E.g. DB_DRIVER, SITE_NAME, NODE_TYPE
-        */
-       private Properties properties;
-
-       /*
-        * See IntegrityAudit class for usage.
-        */
-       private long integrityAuditPeriodMillis;
-       
-       /*
-        * The containing IntegrityAudit instance
-        */
-       private IntegrityAudit integrityAudit;
-
-       /**
-        * A latch is taken from this queue before starting an audit.  May be
-        * {@code null}. Used by JUnit tests.
-        */
-       private BlockingQueue<CountDownLatch> auditLatchQueue;
-
-       /**
-        * Latch to be decremented when the next audit completes.  May be
-        * {@code null}. Used by JUnit tests to wait for an audit to complete.
-        */
-       private CountDownLatch auditCompletionLatch = null;
-
-       /**
-        * AuditThread constructor
-        * @param resourceName
-        * @param persistenceUnit
-        * @param properties
-        * @param integrityAuditPeriodSeconds
-        * @param integrityAudit
-        * @throws IntegrityAuditException
-        */
-       public AuditThread(String resourceName, String persistenceUnit,
-                       Properties properties, int integrityAuditPeriodSeconds, IntegrityAudit integrityAudit)
-                       throws IntegrityAuditException {
-
-               this(resourceName, persistenceUnit, properties, TimeUnit.SECONDS.toMillis(integrityAuditPeriodSeconds),
-                               integrityAudit, null);
-       }
-
-       /**
-        * AuditThread constructor
-        * @param resourceName
-        * @param persistenceUnit
-        * @param properties
-        * @param integrityAuditMillis
-        * @param integrityAudit
-        * @param queue 
-        * @throws IntegrityAuditException
-        */
-       public AuditThread(String resourceName, String persistenceUnit,
-                       Properties properties, long integrityAuditMillis, IntegrityAudit integrityAudit,
-                       BlockingQueue<CountDownLatch> queue)
-                       throws IntegrityAuditException {
-               this.resourceName = resourceName;
-               this.persistenceUnit = persistenceUnit;
-               this.properties = properties;
-               this.integrityAuditPeriodMillis = integrityAuditMillis;
-               this.integrityAudit = integrityAudit;
-               this.auditLatchQueue = queue;
-
-               /*
-                * The DbDAO Constructor registers this node in the IntegrityAuditEntity
-                * table. Each resource (node) inserts its own name, persistenceUnit, DB
-                * access properties and other pertinent properties in the table. This
-                * allows the audit on each node to compare its own version of the
-                * entities for the persistenceUnit in question with the versions from
-                * all other nodes of similar type.
-                */
-               dbDAO = new DbDAO(this.resourceName, this.persistenceUnit,
-                               this.properties);
-               this.nodeType = properties.getProperty(IntegrityAuditProperties.NODE_TYPE);
-
-       }
-
-       @Override
-       public void run() {
-
-               logger.info("AuditThread.run: Entering");
-
-               try {                   
-                       /*
-                        * For JUnit testing: wait for the first latch, decrement it to
-                        * indicate that the thread has started, and then wait for the
-                        * next latch, before we actually start doing anything. These
-                        * simply return if there is no latch queue defined.
-                        */
-                       getNextLatch();
-                       decrementLatch();
-                       getNextLatch();
-                       
-                       /*
-                        * Triggers change in designation, unless no other viable candidate.
-                        */
-                       boolean auditCompleted = false;
-
-                       DbAudit dbAudit = new DbAudit(dbDAO);
-
-                       IntegrityAuditEntity entityCurrentlyDesignated;
-                       IntegrityAuditEntity thisEntity;
-                       integrityAudit.setThreadInitialized(true); // An exception will set
-                                                                                                               // it to false
-
-                       while (true) {
-                               try{
-                                       /*
-                                        * It may have been awhile since we last cycled through this
-                                        * loop, so refresh the list of IntegrityAuditEntities.
-                                        */
-                                       List<IntegrityAuditEntity> integrityAuditEntityList = getIntegrityAuditEntityList();
-
-                                       /*
-                                        * We could've set entityCurrentlyDesignated as a side effect of
-                                        * getIntegrityAuditEntityList(), but then we would've had to
-                                        * make entityCurrentlyDesignated a class level attribute. Using
-                                        * this approach, we can keep it local to the run() method.
-                                        */
-                                       entityCurrentlyDesignated = getEntityCurrentlyDesignated(integrityAuditEntityList);
-
-                                       /*
-                                        * Need to refresh thisEntity each time through loop, because we
-                                        * need a fresh version of lastUpdated.
-                                        */
-                                       thisEntity = getThisEntity(integrityAuditEntityList);
-
-                                       /*
-                                        * If we haven't done the audit yet, note that we're current and
-                                        * see if we're designated.
-                                        */
-                                       if (!auditCompleted) {
-                                               dbDAO.setLastUpdated();
-
-                                               /*
-                                                * If no current designation or currently designated node is
-                                                * stale, see if we're the next node to be designated.
-                                                */
-                                               if (entityCurrentlyDesignated == null
-                                                               || isStale(entityCurrentlyDesignated)) {
-                                                       IntegrityAuditEntity designationCandidate = getDesignationCandidate(integrityAuditEntityList);
-
-                                                       /*
-                                                        * If we're the next node to be designated, run the
-                                                        * audit.
-                                                        */
-                                                       if (designationCandidate.getResourceName().equals(
-                                                                       this.resourceName)) {
-                                                               runAudit(dbAudit);
-                                                               auditCompleted = true;
-                                                       } else {
-                                                               if (logger.isDebugEnabled()) {
-                                                                       logger.debug("AuditThread.run: designationCandidate, "
-                                                                                       + designationCandidate
-                                                                                       .getResourceName()
-                                                                                       + ", not this entity, "
-                                                                                       + thisEntity.getResourceName());
-                                                               }
-                                                       }
-
-                                                       /*
-                                                        * Application may have been stopped and restarted, in
-                                                        * which case we might be designated but auditCompleted
-                                                        * will have been reset to false, so account for this.
-                                                        */
-                                               } else if (thisEntity.getResourceName().equals(
-                                                               entityCurrentlyDesignated.getResourceName())) {
-
-                                                       if (logger.isDebugEnabled()) {
-                                                               logger.debug("AuditThread.run: Re-running audit for "
-                                                                               + thisEntity.getResourceName());
-                                                       }
-                                                       runAudit(dbAudit);
-                                                       auditCompleted = true;
-
-                                               } else {
-                                                       if (logger.isDebugEnabled()) {
-                                                               logger.debug("AuditThread.run: Currently designated node, "
-                                                                               + entityCurrentlyDesignated
-                                                                               .getResourceName()
-                                                                               + ", not yet stale and not this node");
-                                                       }
-                                               }
-
-
-                                               /*
-                                                * Audit already completed on this node, so allow the node
-                                                * to go stale until twice the AUDIT_COMPLETION_PERIOD has
-                                                * elapsed. This should give plenty of time for another node
-                                                * (if another node is out there) to pick up designation.
-                                                */
-                                       } else {
-
-                                               auditCompleted = resetAuditCompleted(auditCompleted,
-                                                               thisEntity);
-
-                                       }
-
-                                       /*
-                                        * If we've just run audit, sleep per the
-                                        * integrity_audit_period_seconds property, otherwise just sleep
-                                        * the normal interval.
-                                        */
-                                       if (auditCompleted) {
-                                               // indicate that an audit has completed
-                                               decrementLatch();
-
-                                               // don't start the next audit cycle until a latch has been provided
-                                               getNextLatch();
-
-                                               if (logger.isDebugEnabled()) {
-                                                       logger.debug("AuditThread.run: Audit completed; resourceName="
-                                                                       + this.resourceName
-                                                                       + " sleeping "
-                                                                       + integrityAuditPeriodMillis + "ms");
-                                               }
-                                               Thread.sleep(integrityAuditPeriodMillis);
-                                               if (logger.isDebugEnabled()) {
-                                                       logger.debug("AuditThread.run: resourceName="
-                                                                       + this.resourceName + " awaking from "
-                                                                       + integrityAuditPeriodMillis + "ms sleep");
-                                               }
-
-                                       } else {
-
-                                               if (logger.isDebugEnabled()) {
-                                                       logger.debug("AuditThread.run: resourceName="
-                                                                       + this.resourceName + ": Sleeping "
-                                                                       + AuditThread.auditThreadSleepIntervalMillis
-                                                                       + "ms");
-                                               }
-                                               Thread.sleep(AuditThread.auditThreadSleepIntervalMillis);
-                                               if (logger.isDebugEnabled()) {
-                                                       logger.debug("AuditThread.run: resourceName="
-                                                                       + this.resourceName + ": Awaking from "
-                                                                       + AuditThread.auditThreadSleepIntervalMillis
-                                                                       + "ms sleep");
-                                               }
-
-                                       }
-                               
-                               } catch (Exception e){
-                                       if(isInterruptedException(e)) {
-                                               String msg = "AuditThread.run loop - Exception thrown: " + e.getMessage() 
-                                                               + "; Stopping.";
-                                               logger.error(MessageCodes.EXCEPTION_ERROR, e, msg);
-                                               break;
-                                       }
-                                       
-                                       String msg = "AuditThread.run loop - Exception thrown: " + e.getMessage() 
-                                                       + "; Will try audit again in " + (integrityAuditPeriodMillis/1000) + " seconds";
-                                       logger.error(MessageCodes.EXCEPTION_ERROR, e, msg);
-                                       // Sleep and try again later
-                                       Thread.sleep(integrityAuditPeriodMillis);
-                               }
-
-                       }
-
-               } catch (Exception e) {
-                       String msg = "AuditThread.run: Could not start audit loop. Exception thrown; message="+ e.getMessage();
-                       logger.error(MessageCodes.EXCEPTION_ERROR, e, msg);
-                       integrityAudit.setThreadInitialized(false);
-               }
-               
-               dbDAO.destroy();
-
-               logger.info("AuditThread.run: Exiting");
-       }
-
-       /**
-        * Gets the next audit-completion latch from the queue. Blocks, if the
-        * queue is empty.
-        * @throws InterruptedException
-        */
-       private void getNextLatch() throws InterruptedException {
-               BlockingQueue<CountDownLatch> queue = this.auditLatchQueue;
-               if(queue != null) {
-                       this.auditCompletionLatch = queue.take();
-               }
-       }
-
-       /**
-        * Decrements the current audit-completion latch, if any.
-        */
-       private void decrementLatch() {
-               CountDownLatch latch = this.auditCompletionLatch;
-               if(latch != null) {
-                       this.auditCompletionLatch = null;
-                       latch.countDown();
-               }
-       }
-
-       /**
-        * Determines if an exception is an InterruptedException or was caused
-        * by an InterruptedException.
-        * @param ex    exception to be examined
-        * @return {@code true} if it's an InterruptedException, {@code false} otherwise
-        */
-       private boolean isInterruptedException(Throwable ex) {
-               while(ex != null) {
-                       if(ex instanceof InterruptedException) {
-                               return true;
-                       }
-                       
-                       ex = ex.getCause();
-               }
-               
-               return false;
-       }
-
-       /*
-        * Used to create a list that is sorted lexicographically by resourceName.
-        */
-       Comparator<IntegrityAuditEntity> comparator = new Comparator<IntegrityAuditEntity>() {
-               @Override
-               public int compare(final IntegrityAuditEntity r1,
-                               final IntegrityAuditEntity r2) {
-                       return r1.getResourceName().compareTo(r2.getResourceName());
-               }
-       };
-
-       /**
-        * getDesignationCandidate()
-        * Using round robin algorithm, gets next candidate to be designated. Assumes
-        * list is sorted lexicographically by resourceName.
-        */
-       private IntegrityAuditEntity getDesignationCandidate(
-                       List<IntegrityAuditEntity> integrityAuditEntityList) {
-               
-               //Note: assumes integrityAuditEntityList is already lexicographically sorted by resourceName
-
-               if (logger.isDebugEnabled()) {
-                       logger.debug("getDesignationCandidate: Entering, integrityAuditEntityList.size()="
-                                       + integrityAuditEntityList.size());
-               }
-
-               IntegrityAuditEntity designationCandidate;
-               IntegrityAuditEntity thisEntity = null;
-
-               int designatedEntityIndex = -1;
-               int entityIndex = 0;
-               int priorCandidateIndex = -1;
-               int subsequentCandidateIndex = -1;
-
-               for (IntegrityAuditEntity integrityAuditEntity : integrityAuditEntityList) {
-
-                       if (logger.isDebugEnabled()) {
-                               logIntegrityAuditEntity(integrityAuditEntity);
-                       }
-
-                       if (integrityAuditEntity.getResourceName()
-                                       .equals(this.resourceName)) {
-                               if (logger.isDebugEnabled()) {
-                                       logger.debug("getDesignationCandidate: thisEntity="
-                                                       + integrityAuditEntity.getResourceName());
-                               }
-                               thisEntity = integrityAuditEntity;
-                       }
-
-                       if (integrityAuditEntity.isDesignated()) {
-                               if (logger.isDebugEnabled()) {
-                                       logger.debug("getDesignationCandidate: Currently designated entity resourceName="
-                                                       + integrityAuditEntity.getResourceName()
-                                                       + ", persistenceUnit="
-                                                       + integrityAuditEntity.getPersistenceUnit()
-                                                       + ", lastUpdated="
-                                                       + integrityAuditEntity.getLastUpdated()
-                                                       + ", entityIndex=" + entityIndex);
-                               }
-                               designatedEntityIndex = entityIndex;
-
-                               /*
-                                * Entity not currently designated
-                                */
-                       } else {
-
-                               /*
-                                * See if non-designated entity is stale.
-                                */
-                               if (isStale(integrityAuditEntity)) {
-
-                                       if (logger.isDebugEnabled()) {
-                                               logger.debug("getDesignationCandidate: Entity is stale; resourceName="
-                                                               + integrityAuditEntity.getResourceName()
-                                                               + ", persistenceUnit="
-                                                               + integrityAuditEntity.getPersistenceUnit()
-                                                               + ", lastUpdated="
-                                                               + integrityAuditEntity.getLastUpdated()
-                                                               + ", entityIndex=" + entityIndex);
-                                       }
-
-                                       /*
-                                        * Entity is current.
-                                        */
-                               } else {
-
-                                       if (designatedEntityIndex == -1) {
-
-                                               if (priorCandidateIndex == -1) {
-                                                       if (logger.isDebugEnabled()) {
-                                                               logger.debug("getDesignationCandidate: Prior candidate found, resourceName="
-                                                                               + integrityAuditEntity
-                                                                                               .getResourceName()
-                                                                               + ", persistenceUnit="
-                                                                               + integrityAuditEntity
-                                                                                               .getPersistenceUnit()
-                                                                               + ", lastUpdated="
-                                                                               + integrityAuditEntity.getLastUpdated()
-                                                                               + ", entityIndex=" + entityIndex);
-                                                       }
-                                                       priorCandidateIndex = entityIndex;
-                                               } else {
-                                                       if (logger.isDebugEnabled()) {
-                                                               logger.debug("getDesignationCandidate: Prior entity current but prior candidate already found; resourceName="
-                                                                               + integrityAuditEntity
-                                                                                               .getResourceName()
-                                                                               + ", persistenceUnit="
-                                                                               + integrityAuditEntity
-                                                                                               .getPersistenceUnit()
-                                                                               + ", lastUpdated="
-                                                                               + integrityAuditEntity.getLastUpdated()
-                                                                               + ", entityIndex=" + entityIndex);
-                                                       }
-                                               }
-                                       } else {
-                                               if (subsequentCandidateIndex == -1) {
-                                                       if (logger.isDebugEnabled()) {
-                                                               logger.debug("getDesignationCandidate: Subsequent candidate found, resourceName="
-                                                                               + integrityAuditEntity
-                                                                                               .getResourceName()
-                                                                               + ", persistenceUnit="
-                                                                               + integrityAuditEntity
-                                                                                               .getPersistenceUnit()
-                                                                               + ", lastUpdated="
-                                                                               + integrityAuditEntity.getLastUpdated()
-                                                                               + ", entityIndex=" + entityIndex);
-                                                       }
-                                                       subsequentCandidateIndex = entityIndex;
-                                               } else {
-                                                       if (logger.isDebugEnabled()) {
-                                                               logger.debug("getDesignationCandidate: Subsequent entity current but subsequent candidate already found; resourceName="
-                                                                               + integrityAuditEntity
-                                                                                               .getResourceName()
-                                                                               + ", persistenceUnit="
-                                                                               + integrityAuditEntity
-                                                                                               .getPersistenceUnit()
-                                                                               + ", lastUpdated="
-                                                                               + integrityAuditEntity.getLastUpdated()
-                                                                               + ", entityIndex=" + entityIndex);
-                                                       }
-                                               }
-                                       }
-
-                               } // end entity is current
-
-                       } // end entity not currently designated
-
-                       entityIndex++;
-
-               } // end for loop
-
-               /*
-                * Per round robin algorithm, if a current entity is found that is
-                * lexicographically after the currently designated entity, this entity
-                * becomes the designation candidate. If no current entity is found that
-                * is lexicographically after currently designated entity, we cycle back
-                * to beginning of list and pick the first current entity as the
-                * designation candidate.
-                */
-               if (subsequentCandidateIndex != -1) {
-                       designationCandidate = integrityAuditEntityList
-                                       .get(subsequentCandidateIndex);
-                       if (logger.isDebugEnabled()) {
-                               logger.debug("getDesignationCandidate: Exiting and returning subsequent designationCandidate="
-                                               + designationCandidate.getResourceName());
-                       }
-               } else {
-                       if (priorCandidateIndex != -1) {
-                               designationCandidate = integrityAuditEntityList
-                                               .get(priorCandidateIndex);
-                               if (logger.isDebugEnabled()) {
-                                       logger.debug("getDesignationCandidate: Exiting and returning prior designationCandidate="
-                                                       + designationCandidate.getResourceName());
-                               }
-                       } else {
-                               logger.debug("getDesignationCandidate: No subsequent or prior candidate found; designating thisEntity, resourceName="
-                                               + thisEntity.getResourceName());
-                               designationCandidate = thisEntity;
-                       }
-               }
-
-               return designationCandidate;
-
-       }
-
-       /**
-        * getEntityCurrentlyDesignated()
-        * Returns entity that is currently designated.
-        * @param integrityAuditEntityList
-        * @return
-        */
-       private IntegrityAuditEntity getEntityCurrentlyDesignated(
-                       List<IntegrityAuditEntity> integrityAuditEntityList) {
-
-               if (logger.isDebugEnabled()) {
-                       logger.debug("getEntityCurrentlyDesignated: Entering, integrityAuditEntityList.size="
-                                       + integrityAuditEntityList.size());
-               }
-
-               IntegrityAuditEntity entityCurrentlyDesignated = null;
-
-               for (IntegrityAuditEntity integrityAuditEntity : integrityAuditEntityList) {
-
-                       if (integrityAuditEntity.isDesignated()) {
-                               if (logger.isDebugEnabled()) {
-                                       logger.debug("getEntityCurrentlyDesignated: Currently designated entity resourceName="
-                                                       + integrityAuditEntity.getResourceName()
-                                                       + ", persistenceUnit="
-                                                       + integrityAuditEntity.getPersistenceUnit()
-                                                       + ", lastUpdated="
-                                                       + integrityAuditEntity.getLastUpdated());
-                               }
-                               entityCurrentlyDesignated = integrityAuditEntity;
-                       }
-
-               } // end for loop
-
-               if (logger.isDebugEnabled()) {
-                       if (entityCurrentlyDesignated != null) {
-                               logger.debug("getEntityCurrentlyDesignated: Exiting and returning entityCurrentlyDesignated="
-                                               + entityCurrentlyDesignated.getResourceName());
-                       } else {
-                               logger.debug("getEntityCurrentlyDesignated: Exiting and returning entityCurrentlyDesignated="
-                                               + entityCurrentlyDesignated);
-                       }
-               }
-               return entityCurrentlyDesignated;
-
-       }
-
-       /**
-        * getIntegrityAuditEnityList gets the list of IntegrityAuditEntity 
-        * @return
-        * @throws DbDaoTransactionException
-        */
-       private List<IntegrityAuditEntity> getIntegrityAuditEntityList()
-                       throws DbDaoTransactionException {
-
-               if (logger.isDebugEnabled()) {
-                       logger.debug("getIntegrityAuditEntityList: Entering");
-               }
-
-               /*
-                * Get all records for this nodeType and persistenceUnit and then sort
-                * them lexicographically by resourceName. Get index of designated
-                * entity, if any.
-                */
-               /*
-                * Sorted list of entities for a particular nodeType and
-                * persistenceUnit.
-                */
-               List<IntegrityAuditEntity> integrityAuditEntityList = dbDAO.getIntegrityAuditEntities(
-                               this.persistenceUnit, this.nodeType);
-               int listSize = integrityAuditEntityList.size();
-               if (logger.isDebugEnabled()) {
-                       logger.debug("getIntegrityAuditEntityList: Got " + listSize
-                                       + " IntegrityAuditEntity records");
-               }
-               Collections.sort((List<IntegrityAuditEntity>) integrityAuditEntityList,
-                               comparator);
-
-               if (logger.isDebugEnabled()) {
-                       logger.debug("getIntegrityAuditEntityList: Exiting and returning integrityAuditEntityList, size="
-                                       + listSize);
-               }
-               return integrityAuditEntityList;
-
-       }
-
-
-       /**
-        * Returns the IntegrityAuditEntity for this entity.
-        * @param integrityAuditEntityList
-        * @return
-        */
-       private IntegrityAuditEntity getThisEntity(
-                       List<IntegrityAuditEntity> integrityAuditEntityList) {
-
-               if (logger.isDebugEnabled()) {
-                       logger.debug("getThisEntity: Entering, integrityAuditEntityList.size="
-                                       + integrityAuditEntityList.size());
-               }
-
-               IntegrityAuditEntity thisEntity = null;
-
-               for (IntegrityAuditEntity integrityAuditEntity : integrityAuditEntityList) {
-
-                       if (integrityAuditEntity.getResourceName().equals(this.resourceName)) {
-                               if (logger.isDebugEnabled()) {
-                                       logger.debug("getThisEntity: For this entity, resourceName="
-                                                       + integrityAuditEntity.getResourceName()
-                                                       + ", persistenceUnit="
-                                                       + integrityAuditEntity.getPersistenceUnit()
-                                                       + ", lastUpdated="
-                                                       + integrityAuditEntity.getLastUpdated());
-                               }
-                               thisEntity = integrityAuditEntity;
-                       }
-
-               } // end for loop
-
-               if (logger.isDebugEnabled()) {
-                       if (thisEntity != null) {
-                               logger.debug("getThisEntity: Exiting and returning thisEntity="
-                                               + thisEntity.getResourceName());
-                       } else {
-                               logger.debug("getThisEntity: Exiting and returning thisEntity="
-                                               + thisEntity);
-                       }
-               }
-               return thisEntity;
-
-       }
-
-
-       /**
-        * Returns false if the lastUpdated time for the record in question is more
-        * than auditCompletionIntervalMillis seconds ago. During an audit, lastUpdated is updated every five
-        * seconds or so, but when an audit finishes, the node doing the audit stops
-        * updating lastUpdated.
-        * @param integrityAuditEntity
-        * @return
-        */
-       private boolean isStale(IntegrityAuditEntity integrityAuditEntity) {
-
-               if (logger.isDebugEnabled()) {
-                       logger.debug("isStale: Entering, resourceName="
-                                       + integrityAuditEntity.getResourceName()
-                                       + ", persistenceUnit="
-                                       + integrityAuditEntity.getPersistenceUnit()
-                                       + ", lastUpdated=" + integrityAuditEntity.getLastUpdated());
-               }
-
-               boolean stale = false;
-
-               Date currentTime = new Date();
-               Date lastUpdated = integrityAuditEntity.getLastUpdated();
-
-               /*
-                * If lastUpdated is null, we assume that the audit never ran for that
-                * node.
-                */
-               long lastUpdatedTime = 0;
-               if (lastUpdated != null) {
-                       lastUpdatedTime = lastUpdated.getTime();
-               }
-               long timeDifference = currentTime.getTime() - lastUpdatedTime;
-               if (timeDifference > auditCompletionIntervalMillis) {
-                       stale = true;
-               }
-
-               if (logger.isDebugEnabled()) {
-                       logger.debug("isStale: Exiting and returning stale=" + stale
-                                       + ", timeDifference=" + timeDifference);
-               }
-
-               return stale;
-       }
-
-       private void logIntegrityAuditEntity(
-                       IntegrityAuditEntity integrityAuditEntity) {
-
-               logger.debug("logIntegrityAuditEntity: id="
-                               + integrityAuditEntity.getId() + ", jdbcDriver="
-                               + integrityAuditEntity.getJdbcDriver() + ", jdbcPassword="
-                               + integrityAuditEntity.getJdbcPassword() + ", jdbcUrl="
-                               + integrityAuditEntity.getJdbcUrl() + ", jdbcUser="
-                               + integrityAuditEntity.getJdbcUser() + ", nodeType="
-                               + integrityAuditEntity.getNodeType() + ", persistenceUnit="
-                               + integrityAuditEntity.getPersistenceUnit() + ", resourceName="
-                               + integrityAuditEntity.getResourceName() + ", site="
-                               + integrityAuditEntity.getSite() + ", createdDate="
-                               + integrityAuditEntity.getCreatedDate() + ", lastUpdated="
-                               + integrityAuditEntity.getLastUpdated() + ", designated="
-                               + integrityAuditEntity.isDesignated());
-       }
-       
-       /*
-        * If more than (auditCompletionIntervalMillis * 2) milliseconds have elapsed
-        * since we last ran the audit, reset auditCompleted, so
-        * 
-        * 1) we'll eventually re-run the audit, if no other node picks up the
-        * designation.
-        * 
-        * or
-        * 
-        * 2) We'll run the audit when the round robin comes back to us.
-        */
-       private boolean resetAuditCompleted(boolean auditCompleted,
-                       IntegrityAuditEntity thisEntity) {
-
-               if (logger.isDebugEnabled()) {
-                       logger.debug("resetAuditCompleted: auditCompleted="
-                                       + auditCompleted + "; for thisEntity, resourceName="
-                                       + thisEntity.getResourceName() + ", persistenceUnit="
-                                       + thisEntity.getPersistenceUnit() + ", lastUpdated="
-                                       + thisEntity.getLastUpdated());
-               }
-
-               long timeDifference;
-
-               Date currentTime = new Date();
-               Date lastUpdated = thisEntity.getLastUpdated();
-
-               long lastUpdatedTime = lastUpdated.getTime();
-               timeDifference = currentTime.getTime() - lastUpdatedTime;
-
-               if (timeDifference > (auditCompletionIntervalMillis * 2)) {
-                       if (logger.isDebugEnabled()) {
-                               logger.debug("resetAuditCompleted: Resetting auditCompleted for resourceName="
-                                               + this.resourceName);
-                       }
-                       auditCompleted = false;
-               } else {
-                       if (logger.isDebugEnabled()) {
-                               logger.debug("resetAuditCompleted: For resourceName="
-                                               + resourceName
-                                               + ", time since last update is only "
-                                               + timeDifference + "; retaining current value for auditCompleted");
-                       }
-               }
-
-               if (logger.isDebugEnabled()) {
-                       logger.debug("resetAuditCompleted: Exiting and returning auditCompleted="
-                                       + auditCompleted + ", timeDifference=" + timeDifference);
-               }
-               return auditCompleted;
-       }
-
-       private void runAudit(DbAudit dbAudit) throws IntegrityAuditException {
-
-               if (logger.isDebugEnabled()) {
-                       logger.debug("runAudit: Entering, dbAudit=" + dbAudit
-                                       + "; notifying other resources that resourceName="
-                                       + this.resourceName + " is current");
-               }
-
-               /*
-                * changeDesignated marks all other nodes as non-designated and this
-                * node as designated.
-                */
-               dbDAO.changeDesignated(this.resourceName, this.persistenceUnit,
-                               this.nodeType);
-
-               if (logger.isDebugEnabled()) {
-                       logger.debug("runAudit: Running audit for persistenceUnit="
-                                       + this.persistenceUnit + " on resourceName="
-                                       + this.resourceName);
-               }
-               if (IntegrityAudit.isUnitTesting()) {
-                       dbAudit.dbAuditSimulate(this.resourceName, this.persistenceUnit, AuditThread.AUDIT_SIMULATION_ITERATIONS, AuditThread.auditThreadSleepIntervalMillis);
-               } else {
-                       dbAudit.dbAudit(this.resourceName, this.persistenceUnit,
-                                       this.nodeType);
-               }
-
-               if (logger.isDebugEnabled()) {
-                       logger.debug("runAudit: Exiting");
-               }
-
-       }
-
-       /**
-        * Adjusts the thread-sleep-interval to be used when an audit has
-        * <i>not</i> been completed.  Used by JUnit tests.
-        * @param auditThreadSleepIntervalMillis
-        */
-       protected static void setAuditThreadSleepIntervalMillis(long auditThreadSleepIntervalMillis) {
-               AuditThread.auditThreadSleepIntervalMillis = auditThreadSleepIntervalMillis;
-       }
-
-       /**
-        * Gets the current thread-sleep-interval to be used when an audit has
-        * <i>not</i> been completed.  Used by JUnit tests.
-        * @return the current sleep interval, in milli-seconds
-        */
-       protected static long getAuditThreadSleepIntervalMillis() {
-               return auditThreadSleepIntervalMillis;
-       }
-
-       /**
-        * Adjusts the audit-completion-interval.  Used by JUnit tests.
-        * @param auditThreadSleepIntervalMillis
-        */
-       protected static void setAuditCompletionIntervalMillis(long auditThreadSleepIntervalMillis) {
-               AuditThread.auditCompletionIntervalMillis = auditThreadSleepIntervalMillis;
-       }
-
-       /**
-        * Gets the audit-completion-interval.  Used by JUnit tests.
-        * @return the current audit-completion interval, in milli-seconds
-        */
-       protected static long getAuditCompletionIntervalMillis() {
-               return auditCompletionIntervalMillis;
-       }
+    private static final Logger logger = FlexLogger.getLogger(AuditThread.class);
+
+    /*
+     * Number of milliseconds that must elapse for audit to be considered complete. It's public for
+     * access by JUnit test logic.
+     */
+    public static final long AUDIT_COMPLETION_INTERVAL = 30000;
+
+    /*
+     * Number of iterations for audit simulation.
+     */
+    public static final long AUDIT_SIMULATION_ITERATIONS = 3;
+
+    /*
+     * Number of milliseconds to sleep between audit simulation iterations. It's public for access
+     * by JUnit test logic.
+     */
+    public static final long AUDIT_SIMULATION_SLEEP_INTERVAL = 5000;
+
+    /*
+     * Unless audit has already been run on this entity, number of milliseconds to sleep between
+     * audit thread iterations. If audit has already been run, we sleep integrityAuditPeriodMillis.
+     * May be modified by JUnit tests.
+     */
+    private static long auditThreadSleepIntervalMillis = 5000;
+
+    /*
+     * Number of milliseconds that must elapse for audit to be considered complete. May be modified
+     * by JUnit tests.
+     */
+    private static long auditCompletionIntervalMillis = AUDIT_COMPLETION_INTERVAL;
+
+    /*
+     * DB access class.
+     */
+    private DbDAO dbDao;
+
+    /*
+     * E.g. pdp_xacml
+     */
+    private String nodeType;
+
+    /*
+     * Persistence unit for which this audit is being run.
+     */
+    private String persistenceUnit;
+
+    /*
+     * Name of this resource
+     */
+    private String resourceName;
+
+    /*
+     * E.g. DB_DRIVER, SITE_NAME, NODE_TYPE
+     */
+    private Properties properties;
+
+    /*
+     * See IntegrityAudit class for usage.
+     */
+    private long integrityAuditPeriodMillis;
+
+    /*
+     * The containing IntegrityAudit instance
+     */
+    private IntegrityAudit integrityAudit;
+
+    /**
+     * A latch is taken from this queue before starting an audit. May be {@code null}. Used by JUnit
+     * tests.
+     */
+    private BlockingQueue<CountDownLatch> auditLatchQueue;
+
+    /**
+     * Latch to be decremented when the next audit completes. May be {@code null}. Used by JUnit
+     * tests to wait for an audit to complete.
+     */
+    private CountDownLatch auditCompletionLatch = null;
+
+    /**
+     * AuditThread constructor.
+     * 
+     * @param resourceName the resource name
+     * @param persistenceUnit the persistence unit
+     * @param properties the properties
+     * @param integrityAuditPeriodSeconds the integrity audit period in seconds
+     * @param integrityAudit the integrity audit
+     * @throws IntegrityAuditException if an error occurs
+     */
+    public AuditThread(String resourceName, String persistenceUnit, Properties properties,
+            int integrityAuditPeriodSeconds, IntegrityAudit integrityAudit) throws IntegrityAuditException {
+
+        this(resourceName, persistenceUnit, properties, TimeUnit.SECONDS.toMillis(integrityAuditPeriodSeconds),
+                integrityAudit, null);
+    }
+
+    /**
+     * AuditThread constructor.
+     * 
+     * @param resourceName the resource name
+     * @param persistenceUnit the persistence unit
+     * @param properties the properties
+     * @param integrityAuditMillis the integrity audit period in milliseconds
+     * @param integrityAudit the integrity audit
+     * @param queue the queue
+     * @throws IntegrityAuditException if an error occurs
+     */
+    public AuditThread(String resourceName, String persistenceUnit, Properties properties, long integrityAuditMillis,
+            IntegrityAudit integrityAudit, BlockingQueue<CountDownLatch> queue) throws IntegrityAuditException {
+        this.resourceName = resourceName;
+        this.persistenceUnit = persistenceUnit;
+        this.properties = properties;
+        this.integrityAuditPeriodMillis = integrityAuditMillis;
+        this.integrityAudit = integrityAudit;
+        this.auditLatchQueue = queue;
+
+        /*
+         * The DbDAO Constructor registers this node in the IntegrityAuditEntity table. Each
+         * resource (node) inserts its own name, persistenceUnit, DB access properties and other
+         * pertinent properties in the table. This allows the audit on each node to compare its own
+         * version of the entities for the persistenceUnit in question with the versions from all
+         * other nodes of similar type.
+         */
+        dbDao = new DbDAO(this.resourceName, this.persistenceUnit, this.properties);
+        this.nodeType = properties.getProperty(IntegrityAuditProperties.NODE_TYPE);
+
+    }
+
+    @Override
+    public void run() {
+
+        logger.info("AuditThread.run: Entering");
+
+        try {
+            /*
+             * For JUnit testing: wait for the first latch, decrement it to indicate that the thread
+             * has started, and then wait for the next latch, before we actually start doing
+             * anything. These simply return if there is no latch queue defined.
+             */
+            getNextLatch();
+            decrementLatch();
+            getNextLatch();
+
+            /*
+             * Triggers change in designation, unless no other viable candidate.
+             */
+            boolean auditCompleted = false;
+
+            DbAudit dbAudit = new DbAudit(dbDao);
+
+            IntegrityAuditEntity entityCurrentlyDesignated;
+            IntegrityAuditEntity thisEntity;
+            integrityAudit.setThreadInitialized(true); // An exception will set it to false
+
+            while (true) {
+                try {
+                    /*
+                     * It may have been awhile since we last cycled through this loop, so refresh
+                     * the list of IntegrityAuditEntities.
+                     */
+                    List<IntegrityAuditEntity> integrityAuditEntityList = getIntegrityAuditEntityList();
+
+                    /*
+                     * We could've set entityCurrentlyDesignated as a side effect of
+                     * getIntegrityAuditEntityList(), but then we would've had to make
+                     * entityCurrentlyDesignated a class level attribute. Using this approach, we
+                     * can keep it local to the run() method.
+                     */
+                    entityCurrentlyDesignated = getEntityCurrentlyDesignated(integrityAuditEntityList);
+
+                    /*
+                     * Need to refresh thisEntity each time through loop, because we need a fresh
+                     * version of lastUpdated.
+                     */
+                    thisEntity = getThisEntity(integrityAuditEntityList);
+
+                    /*
+                     * If we haven't done the audit yet, note that we're current and see if we're
+                     * designated.
+                     */
+                    if (!auditCompleted) {
+                        dbDao.setLastUpdated();
+
+                        /*
+                         * If no current designation or currently designated node is stale, see if
+                         * we're the next node to be designated.
+                         */
+                        if (entityCurrentlyDesignated == null || isStale(entityCurrentlyDesignated)) {
+                            IntegrityAuditEntity designationCandidate =
+                                    getDesignationCandidate(integrityAuditEntityList);
+
+                            /*
+                             * If we're the next node to be designated, run the audit.
+                             */
+                            if (designationCandidate.getResourceName().equals(this.resourceName)) {
+                                runAudit(dbAudit);
+                                auditCompleted = true;
+                            } else {
+                                if (logger.isDebugEnabled()) {
+                                    logger.debug("AuditThread.run: designationCandidate, "
+                                            + designationCandidate.getResourceName() + ", not this entity, "
+                                            + thisEntity.getResourceName());
+                                }
+                            }
+
+                            /*
+                             * Application may have been stopped and restarted, in which case we
+                             * might be designated but auditCompleted will have been reset to false,
+                             * so account for this.
+                             */
+                        } else if (thisEntity.getResourceName().equals(entityCurrentlyDesignated.getResourceName())) {
+
+                            if (logger.isDebugEnabled()) {
+                                logger.debug("AuditThread.run: Re-running audit for " + thisEntity.getResourceName());
+                            }
+                            runAudit(dbAudit);
+                            auditCompleted = true;
+
+                        } else {
+                            if (logger.isDebugEnabled()) {
+                                logger.debug("AuditThread.run: Currently designated node, "
+                                        + entityCurrentlyDesignated.getResourceName()
+                                        + ", not yet stale and not this node");
+                            }
+                        }
+
+
+                        /*
+                         * Audit already completed on this node, so allow the node to go stale until
+                         * twice the AUDIT_COMPLETION_PERIOD has elapsed. This should give plenty of
+                         * time for another node (if another node is out there) to pick up
+                         * designation.
+                         */
+                    } else {
+
+                        auditCompleted = resetAuditCompleted(auditCompleted, thisEntity);
+
+                    }
+
+                    /*
+                     * If we've just run audit, sleep per the integrity_audit_period_seconds
+                     * property, otherwise just sleep the normal interval.
+                     */
+                    if (auditCompleted) {
+                        // indicate that an audit has completed
+                        decrementLatch();
+
+                        // don't start the next audit cycle until a latch has been provided
+                        getNextLatch();
+
+                        if (logger.isDebugEnabled()) {
+                            logger.debug("AuditThread.run: Audit completed; resourceName=" + this.resourceName
+                                    + " sleeping " + integrityAuditPeriodMillis + "ms");
+                        }
+                        Thread.sleep(integrityAuditPeriodMillis);
+                        if (logger.isDebugEnabled()) {
+                            logger.debug("AuditThread.run: resourceName=" + this.resourceName + " awaking from "
+                                    + integrityAuditPeriodMillis + "ms sleep");
+                        }
+
+                    } else {
+
+                        if (logger.isDebugEnabled()) {
+                            logger.debug("AuditThread.run: resourceName=" + this.resourceName + ": Sleeping "
+                                    + AuditThread.auditThreadSleepIntervalMillis + "ms");
+                        }
+                        Thread.sleep(AuditThread.auditThreadSleepIntervalMillis);
+                        if (logger.isDebugEnabled()) {
+                            logger.debug("AuditThread.run: resourceName=" + this.resourceName + ": Awaking from "
+                                    + AuditThread.auditThreadSleepIntervalMillis + "ms sleep");
+                        }
+
+                    }
+
+                } catch (Exception e) {
+                    if (isInterruptedException(e)) {
+                        String msg = "AuditThread.run loop - Exception thrown: " + e.getMessage() + "; Stopping.";
+                        logger.error(MessageCodes.EXCEPTION_ERROR, e, msg);
+                        break;
+                    }
+
+                    String msg = "AuditThread.run loop - Exception thrown: " + e.getMessage()
+                            + "; Will try audit again in " + (integrityAuditPeriodMillis / 1000) + " seconds";
+                    logger.error(MessageCodes.EXCEPTION_ERROR, e, msg);
+                    // Sleep and try again later
+                    Thread.sleep(integrityAuditPeriodMillis);
+                }
+
+            }
+
+        } catch (Exception e) {
+            String msg = "AuditThread.run: Could not start audit loop. Exception thrown; message=" + e.getMessage();
+            logger.error(MessageCodes.EXCEPTION_ERROR, e, msg);
+            integrityAudit.setThreadInitialized(false);
+        }
+
+        dbDao.destroy();
+
+        logger.info("AuditThread.run: Exiting");
+    }
+
+    /**
+     * Gets the next audit-completion latch from the queue. Blocks, if the queue is empty.
+     * 
+     * @throws InterruptedException if interrupted while waiting
+     */
+    private void getNextLatch() throws InterruptedException {
+        BlockingQueue<CountDownLatch> queue = this.auditLatchQueue;
+        if (queue != null) {
+            this.auditCompletionLatch = queue.take();
+        }
+    }
+
+    /**
+     * Decrements the current audit-completion latch, if any.
+     */
+    private void decrementLatch() {
+        CountDownLatch latch = this.auditCompletionLatch;
+        if (latch != null) {
+            this.auditCompletionLatch = null;
+            latch.countDown();
+        }
+    }
+
+    /**
+     * Determines if an exception is an InterruptedException or was caused by an
+     * InterruptedException.
+     * 
+     * @param ex exception to be examined
+     * @return {@code true} if it's an InterruptedException, {@code false} otherwise
+     */
+    private boolean isInterruptedException(Throwable ex) {
+        while (ex != null) {
+            if (ex instanceof InterruptedException) {
+                return true;
+            }
+
+            ex = ex.getCause();
+        }
+
+        return false;
+    }
+
+    /*
+     * Used to create a list that is sorted lexicographically by resourceName.
+     */
+    Comparator<IntegrityAuditEntity> comparator = new Comparator<IntegrityAuditEntity>() {
+        @Override
+        public int compare(final IntegrityAuditEntity r1, final IntegrityAuditEntity r2) {
+            return r1.getResourceName().compareTo(r2.getResourceName());
+        }
+    };
+
+    /**
+     * getDesignationCandidate() Using round robin algorithm, gets next candidate to be designated.
+     * Assumes list is sorted lexicographically by resourceName.
+     */
+    private IntegrityAuditEntity getDesignationCandidate(List<IntegrityAuditEntity> integrityAuditEntityList) {
+
+        // Note: assumes integrityAuditEntityList is already lexicographically sorted by
+        // resourceName
+
+        if (logger.isDebugEnabled()) {
+            logger.debug("getDesignationCandidate: Entering, integrityAuditEntityList.size()="
+                    + integrityAuditEntityList.size());
+        }
+
+        IntegrityAuditEntity designationCandidate;
+        IntegrityAuditEntity thisEntity = null;
+
+        int designatedEntityIndex = -1;
+        int entityIndex = 0;
+        int priorCandidateIndex = -1;
+        int subsequentCandidateIndex = -1;
+
+        for (IntegrityAuditEntity integrityAuditEntity : integrityAuditEntityList) {
+
+            if (logger.isDebugEnabled()) {
+                logIntegrityAuditEntity(integrityAuditEntity);
+            }
+
+            if (integrityAuditEntity.getResourceName().equals(this.resourceName)) {
+                if (logger.isDebugEnabled()) {
+                    logger.debug("getDesignationCandidate: thisEntity=" + integrityAuditEntity.getResourceName());
+                }
+                thisEntity = integrityAuditEntity;
+            }
+
+            if (integrityAuditEntity.isDesignated()) {
+                if (logger.isDebugEnabled()) {
+                    logger.debug("getDesignationCandidate: Currently designated entity resourceName="
+                            + integrityAuditEntity.getResourceName() + ", persistenceUnit="
+                            + integrityAuditEntity.getPersistenceUnit() + ", lastUpdated="
+                            + integrityAuditEntity.getLastUpdated() + ", entityIndex=" + entityIndex);
+                }
+                designatedEntityIndex = entityIndex;
+
+                /*
+                 * Entity not currently designated
+                 */
+            } else {
+
+                /*
+                 * See if non-designated entity is stale.
+                 */
+                if (isStale(integrityAuditEntity)) {
+
+                    if (logger.isDebugEnabled()) {
+                        logger.debug("getDesignationCandidate: Entity is stale; resourceName="
+                                + integrityAuditEntity.getResourceName() + ", persistenceUnit="
+                                + integrityAuditEntity.getPersistenceUnit() + ", lastUpdated="
+                                + integrityAuditEntity.getLastUpdated() + ", entityIndex=" + entityIndex);
+                    }
+
+                    /*
+                     * Entity is current.
+                     */
+                } else {
+
+                    if (designatedEntityIndex == -1) {
+
+                        if (priorCandidateIndex == -1) {
+                            if (logger.isDebugEnabled()) {
+                                logger.debug("getDesignationCandidate: Prior candidate found, resourceName="
+                                        + integrityAuditEntity.getResourceName() + ", persistenceUnit="
+                                        + integrityAuditEntity.getPersistenceUnit() + ", lastUpdated="
+                                        + integrityAuditEntity.getLastUpdated() + ", entityIndex=" + entityIndex);
+                            }
+                            priorCandidateIndex = entityIndex;
+                        } else {
+                            if (logger.isDebugEnabled()) {
+                                logger.debug(
+                                        "getDesignationCandidate: Prior entity current but prior candidate already "
+                                                + "found; resourceName=" + integrityAuditEntity.getResourceName()
+                                                + ", persistenceUnit=" + integrityAuditEntity.getPersistenceUnit()
+                                                + ", lastUpdated=" + integrityAuditEntity.getLastUpdated()
+                                                + ", entityIndex=" + entityIndex);
+                            }
+                        }
+                    } else {
+                        if (subsequentCandidateIndex == -1) {
+                            if (logger.isDebugEnabled()) {
+                                logger.debug("getDesignationCandidate: Subsequent candidate found, resourceName="
+                                        + integrityAuditEntity.getResourceName() + ", persistenceUnit="
+                                        + integrityAuditEntity.getPersistenceUnit() + ", lastUpdated="
+                                        + integrityAuditEntity.getLastUpdated() + ", entityIndex=" + entityIndex);
+                            }
+                            subsequentCandidateIndex = entityIndex;
+                        } else {
+                            if (logger.isDebugEnabled()) {
+                                logger.debug(
+                                        "getDesignationCandidate: Subsequent entity current but subsequent candidate "
+                                                + "already found; resourceName="
+                                                + integrityAuditEntity.getResourceName() + ", persistenceUnit="
+                                                + integrityAuditEntity.getPersistenceUnit() + ", lastUpdated="
+                                                + integrityAuditEntity.getLastUpdated() + ", entityIndex="
+                                                + entityIndex);
+                            }
+                        }
+                    }
+
+                } // end entity is current
+
+            } // end entity not currently designated
+
+            entityIndex++;
+
+        } // end for loop
+
+        /*
+         * Per round robin algorithm, if a current entity is found that is lexicographically after
+         * the currently designated entity, this entity becomes the designation candidate. If no
+         * current entity is found that is lexicographically after currently designated entity, we
+         * cycle back to beginning of list and pick the first current entity as the designation
+         * candidate.
+         */
+        if (subsequentCandidateIndex != -1) {
+            designationCandidate = integrityAuditEntityList.get(subsequentCandidateIndex);
+            if (logger.isDebugEnabled()) {
+                logger.debug("getDesignationCandidate: Exiting and returning subsequent designationCandidate="
+                        + designationCandidate.getResourceName());
+            }
+        } else {
+            if (priorCandidateIndex != -1) {
+                designationCandidate = integrityAuditEntityList.get(priorCandidateIndex);
+                if (logger.isDebugEnabled()) {
+                    logger.debug("getDesignationCandidate: Exiting and returning prior designationCandidate="
+                            + designationCandidate.getResourceName());
+                }
+            } else {
+                logger.debug("getDesignationCandidate: No subsequent or prior candidate found; designating thisEntity, "
+                        + "resourceName=" + thisEntity.getResourceName());
+                designationCandidate = thisEntity;
+            }
+        }
+
+        return designationCandidate;
+
+    }
+
+    /**
+     * getEntityCurrentlyDesignated() Returns entity that is currently designated.
+     * 
+     * @param integrityAuditEntityList the integrity audit entity list
+     * @return the currently designated integrity audit entity
+     */
+    private IntegrityAuditEntity getEntityCurrentlyDesignated(List<IntegrityAuditEntity> integrityAuditEntityList) {
+
+        if (logger.isDebugEnabled()) {
+            logger.debug("getEntityCurrentlyDesignated: Entering, integrityAuditEntityList.size="
+                    + integrityAuditEntityList.size());
+        }
+
+        IntegrityAuditEntity entityCurrentlyDesignated = null;
+
+        for (IntegrityAuditEntity integrityAuditEntity : integrityAuditEntityList) {
+
+            if (integrityAuditEntity.isDesignated()) {
+                if (logger.isDebugEnabled()) {
+                    logger.debug("getEntityCurrentlyDesignated: Currently designated entity resourceName="
+                            + integrityAuditEntity.getResourceName() + ", persistenceUnit="
+                            + integrityAuditEntity.getPersistenceUnit() + ", lastUpdated="
+                            + integrityAuditEntity.getLastUpdated());
+                }
+                entityCurrentlyDesignated = integrityAuditEntity;
+            }
+
+        } // end for loop
+
+        if (logger.isDebugEnabled()) {
+            if (entityCurrentlyDesignated != null) {
+                logger.debug("getEntityCurrentlyDesignated: Exiting and returning entityCurrentlyDesignated="
+                        + entityCurrentlyDesignated.getResourceName());
+            } else {
+                logger.debug("getEntityCurrentlyDesignated: Exiting and returning entityCurrentlyDesignated="
+                        + entityCurrentlyDesignated);
+            }
+        }
+        return entityCurrentlyDesignated;
+
+    }
+
+    /**
+     * getIntegrityAuditEnityList gets the list of IntegrityAuditEntity.
+     * 
+     * @return the list of IntegrityAuditEntity
+     * @throws DbDaoTransactionException if an error occurs getting the list of IntegrityAuditEntity
+     */
+    private List<IntegrityAuditEntity> getIntegrityAuditEntityList() throws DbDaoTransactionException {
+
+        if (logger.isDebugEnabled()) {
+            logger.debug("getIntegrityAuditEntityList: Entering");
+        }
+
+        /*
+         * Get all records for this nodeType and persistenceUnit and then sort them
+         * lexicographically by resourceName. Get index of designated entity, if any.
+         */
+        /*
+         * Sorted list of entities for a particular nodeType and persistenceUnit.
+         */
+        List<IntegrityAuditEntity> integrityAuditEntityList =
+                dbDao.getIntegrityAuditEntities(this.persistenceUnit, this.nodeType);
+        int listSize = integrityAuditEntityList.size();
+        if (logger.isDebugEnabled()) {
+            logger.debug("getIntegrityAuditEntityList: Got " + listSize + " IntegrityAuditEntity records");
+        }
+        Collections.sort(integrityAuditEntityList, comparator);
+
+        if (logger.isDebugEnabled()) {
+            logger.debug(
+                    "getIntegrityAuditEntityList: Exiting and returning integrityAuditEntityList, size=" + listSize);
+        }
+        return integrityAuditEntityList;
+
+    }
+
+
+    /**
+     * Returns the IntegrityAuditEntity for this entity.
+     * 
+     * @param integrityAuditEntityList the list of IntegrityAuditEntity
+     * @return the IntegrityAuditEntity for this entity
+     */
+    private IntegrityAuditEntity getThisEntity(List<IntegrityAuditEntity> integrityAuditEntityList) {
+
+        if (logger.isDebugEnabled()) {
+            logger.debug("getThisEntity: Entering, integrityAuditEntityList.size=" + integrityAuditEntityList.size());
+        }
+
+        IntegrityAuditEntity thisEntity = null;
+
+        for (IntegrityAuditEntity integrityAuditEntity : integrityAuditEntityList) {
+
+            if (integrityAuditEntity.getResourceName().equals(this.resourceName)) {
+                if (logger.isDebugEnabled()) {
+                    logger.debug(
+                            "getThisEntity: For this entity, resourceName=" + integrityAuditEntity.getResourceName()
+                                    + ", persistenceUnit=" + integrityAuditEntity.getPersistenceUnit()
+                                    + ", lastUpdated=" + integrityAuditEntity.getLastUpdated());
+                }
+                thisEntity = integrityAuditEntity;
+            }
+
+        } // end for loop
+
+        if (logger.isDebugEnabled()) {
+            if (thisEntity != null) {
+                logger.debug("getThisEntity: Exiting and returning thisEntity=" + thisEntity.getResourceName());
+            } else {
+                logger.debug("getThisEntity: Exiting and returning thisEntity=" + thisEntity);
+            }
+        }
+        return thisEntity;
+
+    }
+
+
+    /**
+     * Returns false if the lastUpdated time for the record in question is more than
+     * auditCompletionIntervalMillis seconds ago. During an audit, lastUpdated is updated every five
+     * seconds or so, but when an audit finishes, the node doing the audit stops updating
+     * lastUpdated.
+     * 
+     * @param integrityAuditEntity the integrityAuditEntity
+     * @return false if the lastUpdated time for the record in question is more than
+     *         auditCompletionIntervalMillis seconds ago
+     */
+    private boolean isStale(IntegrityAuditEntity integrityAuditEntity) {
+
+        if (logger.isDebugEnabled()) {
+            logger.debug("isStale: Entering, resourceName=" + integrityAuditEntity.getResourceName()
+                    + ", persistenceUnit=" + integrityAuditEntity.getPersistenceUnit() + ", lastUpdated="
+                    + integrityAuditEntity.getLastUpdated());
+        }
+
+        boolean stale = false;
+
+        Date currentTime = new Date();
+        Date lastUpdated = integrityAuditEntity.getLastUpdated();
+
+        /*
+         * If lastUpdated is null, we assume that the audit never ran for that node.
+         */
+        long lastUpdatedTime = 0;
+        if (lastUpdated != null) {
+            lastUpdatedTime = lastUpdated.getTime();
+        }
+        long timeDifference = currentTime.getTime() - lastUpdatedTime;
+        if (timeDifference > auditCompletionIntervalMillis) {
+            stale = true;
+        }
+
+        if (logger.isDebugEnabled()) {
+            logger.debug("isStale: Exiting and returning stale=" + stale + ", timeDifference=" + timeDifference);
+        }
+
+        return stale;
+    }
+
+    private void logIntegrityAuditEntity(IntegrityAuditEntity integrityAuditEntity) {
+
+        logger.debug("logIntegrityAuditEntity: id=" + integrityAuditEntity.getId() + ", jdbcDriver="
+                + integrityAuditEntity.getJdbcDriver() + ", jdbcPassword=" + integrityAuditEntity.getJdbcPassword()
+                + ", jdbcUrl=" + integrityAuditEntity.getJdbcUrl() + ", jdbcUser=" + integrityAuditEntity.getJdbcUser()
+                + ", nodeType=" + integrityAuditEntity.getNodeType() + ", persistenceUnit="
+                + integrityAuditEntity.getPersistenceUnit() + ", resourceName=" + integrityAuditEntity.getResourceName()
+                + ", site=" + integrityAuditEntity.getSite() + ", createdDate=" + integrityAuditEntity.getCreatedDate()
+                + ", lastUpdated=" + integrityAuditEntity.getLastUpdated() + ", designated="
+                + integrityAuditEntity.isDesignated());
+    }
+
+    /*
+     * If more than (auditCompletionIntervalMillis * 2) milliseconds have elapsed since we last ran
+     * the audit, reset auditCompleted, so
+     * 
+     * 1) we'll eventually re-run the audit, if no other node picks up the designation.
+     * 
+     * or
+     * 
+     * 2) We'll run the audit when the round robin comes back to us.
+     */
+    private boolean resetAuditCompleted(boolean auditCompleted, IntegrityAuditEntity thisEntity) {
+
+        if (logger.isDebugEnabled()) {
+            logger.debug("resetAuditCompleted: auditCompleted=" + auditCompleted + "; for thisEntity, resourceName="
+                    + thisEntity.getResourceName() + ", persistenceUnit=" + thisEntity.getPersistenceUnit()
+                    + ", lastUpdated=" + thisEntity.getLastUpdated());
+        }
+
+        long timeDifference;
+
+        Date currentTime = new Date();
+        Date lastUpdated = thisEntity.getLastUpdated();
+
+        long lastUpdatedTime = lastUpdated.getTime();
+        timeDifference = currentTime.getTime() - lastUpdatedTime;
+
+        if (timeDifference > (auditCompletionIntervalMillis * 2)) {
+            if (logger.isDebugEnabled()) {
+                logger.debug("resetAuditCompleted: Resetting auditCompleted for resourceName=" + this.resourceName);
+            }
+            auditCompleted = false;
+        } else {
+            if (logger.isDebugEnabled()) {
+                logger.debug(
+                        "resetAuditCompleted: For resourceName=" + resourceName + ", time since last update is only "
+                                + timeDifference + "; retaining current value for auditCompleted");
+            }
+        }
+
+        if (logger.isDebugEnabled()) {
+            logger.debug("resetAuditCompleted: Exiting and returning auditCompleted=" + auditCompleted
+                    + ", timeDifference=" + timeDifference);
+        }
+        return auditCompleted;
+    }
+
+    private void runAudit(DbAudit dbAudit) throws IntegrityAuditException {
+
+        if (logger.isDebugEnabled()) {
+            logger.debug("runAudit: Entering, dbAudit=" + dbAudit + "; notifying other resources that resourceName="
+                    + this.resourceName + " is current");
+        }
+
+        /*
+         * changeDesignated marks all other nodes as non-designated and this node as designated.
+         */
+        dbDao.changeDesignated(this.resourceName, this.persistenceUnit, this.nodeType);
+
+        if (logger.isDebugEnabled()) {
+            logger.debug("runAudit: Running audit for persistenceUnit=" + this.persistenceUnit + " on resourceName="
+                    + this.resourceName);
+        }
+        if (IntegrityAudit.isUnitTesting()) {
+            dbAudit.dbAuditSimulate(this.resourceName, this.persistenceUnit, AuditThread.AUDIT_SIMULATION_ITERATIONS,
+                    AuditThread.auditThreadSleepIntervalMillis);
+        } else {
+            dbAudit.dbAudit(this.resourceName, this.persistenceUnit, this.nodeType);
+        }
+
+        if (logger.isDebugEnabled()) {
+            logger.debug("runAudit: Exiting");
+        }
+
+    }
+
+    /**
+     * Adjusts the thread-sleep-interval to be used when an audit has <i>not</i> been completed.
+     * Used by JUnit tests.
+     * 
+     * @param auditThreadSleepIntervalMillis the interval to use in milliseconds
+     */
+    protected static void setAuditThreadSleepIntervalMillis(long auditThreadSleepIntervalMillis) {
+        AuditThread.auditThreadSleepIntervalMillis = auditThreadSleepIntervalMillis;
+    }
+
+    /**
+     * Gets the current thread-sleep-interval to be used when an audit has <i>not</i> been
+     * completed. Used by JUnit tests.
+     * 
+     * @return the current sleep interval, in milli-seconds
+     */
+    protected static long getAuditThreadSleepIntervalMillis() {
+        return auditThreadSleepIntervalMillis;
+    }
+
+    /**
+     * Adjusts the audit-completion-interval. Used by JUnit tests.
+     * 
+     * @param auditThreadSleepIntervalMillis the interval to use in milliseconds
+     */
+    protected static void setAuditCompletionIntervalMillis(long auditThreadSleepIntervalMillis) {
+        AuditThread.auditCompletionIntervalMillis = auditThreadSleepIntervalMillis;
+    }
+
+    /**
+     * Gets the audit-completion-interval. Used by JUnit tests.
+     * 
+     * @return the current audit-completion interval, in milli-seconds
+     */
+    protected static long getAuditCompletionIntervalMillis() {
+        return auditCompletionIntervalMillis;
+    }
 
 }
index 6fb619e..4c4104f 100644 (file)
@@ -36,492 +36,501 @@ import org.apache.commons.lang3.SerializationUtils;
 import org.apache.commons.lang3.builder.RecursiveToStringStyle;
 import org.apache.commons.lang3.builder.ReflectionToStringBuilder;
 import org.apache.commons.lang3.builder.ToStringStyle;
-
-
-
-
-
 import org.onap.policy.common.ia.jpa.IntegrityAuditEntity;
 import org.onap.policy.common.logging.eelf.MessageCodes;
-import org.onap.policy.common.logging.flexlogger.FlexLogger; 
+import org.onap.policy.common.logging.flexlogger.FlexLogger;
 import org.onap.policy.common.logging.flexlogger.Logger;
 
 /**
  * class DbAudit does actual auditing of DB tables.
  */
 public class DbAudit {
-       
-       private static final Logger logger = FlexLogger.getLogger(DbAudit.class);
-       
-       private static long dbAuditUpdateMillis = 5000l;
-       private static long dbAuditSleepMillis = 2000l;
-       
-       DbDAO dbDAO = null;
-       
-       public DbAudit(DbDAO dbDAO) {
-               
-               if (logger.isDebugEnabled()) {
-                       logger.debug("Constructor: Entering");
-               }
-
-               this.dbDAO = dbDAO;
-               
-               if (logger.isDebugEnabled()) {
-                       logger.debug("Constructor: Exiting");
-               }
-
-       }
-       
-       /**
-        * dbAudit actually does the audit
-        * @param resourceName
-        * @param persistenceUnit
-        * @param nodeType
-        * @throws Exception
-        */
-       public void dbAudit(String resourceName, String persistenceUnit, String nodeType) throws IntegrityAuditException {
-               
-               if (logger.isDebugEnabled()) {
-                       logger.debug("dbAudit: Entering, resourceName=" + resourceName
-                                       + ", persistenceUnit=" + persistenceUnit + ", nodeType="
-                                       + nodeType);
-               }
-       
-               // Get all IntegrityAudit entries so we can get the DB access info
-               List<IntegrityAuditEntity> iaeList = dbDAO.getIntegrityAuditEntities(persistenceUnit, nodeType);
-               if(iaeList == null || iaeList.isEmpty()){
-                       
-                       String msg = "DbAudit: for node " + resourceName + " Found no IntegrityAuditEntity entries";
-                       logger.error(MessageCodes.ERROR_AUDIT,  msg);
-                       throw new DbAuditException(msg);
-                       
-               }else if(iaeList.size() == 1){
-                       
-                       Long iaeId = null;
-                       String iaeRN = null;
-                       String iaeNT = null;
-                       String iaeS = null;
-                       for (IntegrityAuditEntity iae : iaeList){
-                               iaeId = iae.getId();
-                               iaeRN = iae.getResourceName();
-                               iaeNT = iae.getNodeType();
-                               iaeS = iae.getSite();
-                       }
-                       String msg = "DbAudit: Found only one IntegrityAuditEntity entry:"
-                                       + " ID = " + iaeId
-                                       + " ResourceName = " + iaeRN
-                                       + " NodeType = " + iaeNT
-                                       + " Site = " + iaeS;
-                       logger.warn(msg);
-                       return;
-               }
-               
-               // Obtain all persistence class names for the PU we are auditing
-               Set<String> classNameSet = dbDAO.getPersistenceClassNames();
-               if(classNameSet == null || classNameSet.isEmpty()){
-                       
-                       String msg = "DbAudit: For node " + resourceName + " Found no persistence class names";
-                       logger.error(MessageCodes.ERROR_AUDIT,  msg);
-                       throw new DbAuditException(msg);
-                       
-               }
-               
-               /*
-                * Retrieve myIae.  We are going to compare the local class entries against
-                * all other DB nodes. Since the audit is run in a round-robin, every instance
-                * will be compared against every other instance.
-                */
-               IntegrityAuditEntity myIae = dbDAO.getMyIntegrityAuditEntity();
-
-               if(myIae == null){
-                       
-                       String msg = "DbAudit: Found no IntegrityAuditEntity entry for resourceName: " + resourceName
-                                       + " persistenceUnit: " + persistenceUnit;
-                       logger.error(MessageCodes.ERROR_AUDIT,  msg);
-                       throw new DbAuditException(msg);
-                       
-               }
-               /*
-                * This is the map of mismatched entries indexed by className. For
-                * each class name there is a list of mismatched entries
-                */
-               Map<String,Set<Object>> misMatchedMap = new HashMap<>();
-               
-               // We need to keep track of how long the audit is taking
-               long startTime = System.currentTimeMillis();
-               
-               // Retrieve all instances of the class for each node                    
-               if (logger.isDebugEnabled()) {
-                       logger.debug("dbAudit: Traversing classNameSet, size=" + classNameSet.size());
-               }
-               for(String clazzName: classNameSet){
-                       
-                       if (logger.isDebugEnabled()) {
-                               logger.debug("dbAudit: clazzName=" + clazzName);
-                       }
-       
-                       // all instances of the class for myIae
-                       Map<Object,Object> myEntries = dbDAO.getAllMyEntries(clazzName);
-                       //get a map of the objects indexed by id. Does not necessarily have any entries
-                       
-                       if (logger.isDebugEnabled()) {
-                               logger.debug("dbAudit: Traversing iaeList, size=" + iaeList.size());
-                       }
-                       for (IntegrityAuditEntity iae : iaeList){
-                               if(iae.getId() == myIae.getId()){
-                                       if (logger.isDebugEnabled()) {
-                                               logger.debug("dbAudit: My Id=" + iae.getId()
-                                                               + ", resourceName=" + iae.getResourceName());
-                                       }
-                                       continue; //no need to compare with self
-                               } else {
-                                       if (logger.isDebugEnabled()) {
-                                               logger.debug("dbAudit: Id=" + iae.getId()
-                                                               + ", resourceName=" + iae.getResourceName());
-                                       }
-                               }
-                               // Create properties for the other db node
-                               Properties theirProperties = new Properties();
-                               theirProperties.put(IntegrityAuditProperties.DB_DRIVER, iae.getJdbcDriver());
-                               theirProperties.put(IntegrityAuditProperties.DB_URL, iae.getJdbcUrl());
-                               theirProperties.put(IntegrityAuditProperties.DB_USER, iae.getJdbcUser());
-                               theirProperties.put(IntegrityAuditProperties.DB_PWD, iae.getJdbcPassword());
-                               theirProperties.put(IntegrityAuditProperties.SITE_NAME, iae.getSite());
-                               theirProperties.put(IntegrityAuditProperties.NODE_TYPE, iae.getNodeType());
-                               
-                               //get a map of the instances for their iae indexed by id
-                               Map<Object,Object> theirEntries = dbDAO.getAllEntries(persistenceUnit, theirProperties, clazzName);
-                               if (logger.isDebugEnabled()) {
-                                       logger.debug("dbAudit: For persistenceUnit="
-                                                       + persistenceUnit + ", clazzName=" + clazzName
-                                                       + ", theirEntries.size()="
-                                                       + theirEntries.size());
-                               }
-                               
-                               /*
-                                * Compare myEntries with theirEntries and get back a set of mismatched IDs.
-                                * Collect the IDs for the class where a mismatch occurred.  We will check
-                                * them again for all nodes later.
-                                */
-                               Set<Object> misMatchedKeySet = compareEntries(myEntries, theirEntries);
-                               if(!misMatchedKeySet.isEmpty()){
-                                       Set<Object> misMatchedEntry = misMatchedMap.get(clazzName);
-                                       if(misMatchedEntry == null){
-                                               misMatchedMap.put(clazzName, misMatchedKeySet);
-                                       }else{
-                                               misMatchedEntry.addAll(misMatchedKeySet);
-                                               misMatchedMap.put(clazzName, misMatchedEntry);
-                                       }
-                               }
-                       } //end for (IntegrityAuditEntity iae : iaeList)
-                       //Time check
-                       if((System.currentTimeMillis() - startTime) >= dbAuditUpdateMillis){
-                               //update the timestamp
-                               dbDAO.setLastUpdated();
-                               //reset the startTime
-                               startTime=System.currentTimeMillis();
-                       }else{
-                               //sleep a couple seconds to break up the activity
-                               if (logger.isDebugEnabled()) {
-                                       logger.debug("dbAudit: Sleeping " + dbAuditSleepMillis + "ms");
-                               }
-                               sleep();
-                               if (logger.isDebugEnabled()) {
-                                       logger.debug("dbAudit: Waking from sleep");
-                               }
-                       }
-               }//end: for(String clazzName: classNameList)
-               
-               //check if misMatchedMap is empty
-               if(misMatchedMap.isEmpty()){
-                       
-                       if (logger.isDebugEnabled()) {
-                               logger.debug("dbAudit: Exiting, misMatchedMap is empty");
-                       }
-                       //we are done
-                       return;
-               } else {
-                       if (logger.isDebugEnabled()) {
-                               logger.debug("dbAudit: Doing another comparison; misMatchedMap.size()=" + misMatchedMap.size());
-                       }
-               }
-               
-               // If misMatchedMap is not empty, retrieve the entries in each misMatched list and compare again
-               classNameSet = new HashSet<>(misMatchedMap.keySet());
-               // We need to keep track of how long the audit is taking
-               startTime = System.currentTimeMillis();
-               
-               // Retrieve all instances of the class for each node                    
-               if (logger.isDebugEnabled()) {
-                       logger.debug("dbAudit: Second comparison; traversing classNameSet, size=" + classNameSet.size());
-               }
-               
-               int errorCount = 0;
-               
-               for(String clazzName: classNameSet){
-                       
-                       if (logger.isDebugEnabled()) {
-                               logger.debug("dbAudit: Second comparison; clazzName=" + clazzName);
-                       }
-       
-                       // all instances of the class for myIae
-                       Set<Object> keySet = misMatchedMap.get(clazzName);
-                       Map<Object,Object> myEntries = dbDAO.getAllMyEntries(clazzName, keySet);
-                       //get a map of the objects indexed by id
-                       
-                       if (logger.isDebugEnabled()) {
-                               logger.debug("dbAudit: Second comparison; traversing iaeList, size=" + iaeList.size());
-                       }
-                       for (IntegrityAuditEntity iae : iaeList){
-                               if(iae.getId() == myIae.getId()){
-                                       if (logger.isDebugEnabled()) {
-                                               logger.debug("dbAudit: Second comparison; My Id=" + iae.getId()
-                                                               + ", resourceName=" + iae.getResourceName());
-                                       }
-                                       continue; //no need to compare with self
-                               } else {
-                                       if (logger.isDebugEnabled()) {
-                                               logger.debug("dbAudit: Second comparison; Id=" + iae.getId()
-                                                               + ", resourceName=" + iae.getResourceName());
-                                       }
-                               }
-                               // Create properties for the other db node
-                               Properties theirProperties = new Properties();
-                               theirProperties.put(IntegrityAuditProperties.DB_DRIVER, iae.getJdbcDriver());
-                               theirProperties.put(IntegrityAuditProperties.DB_URL, iae.getJdbcUrl());
-                               theirProperties.put(IntegrityAuditProperties.DB_USER, iae.getJdbcUser());
-                               theirProperties.put(IntegrityAuditProperties.DB_PWD, iae.getJdbcPassword());
-                               theirProperties.put(IntegrityAuditProperties.SITE_NAME, iae.getSite());
-                               theirProperties.put(IntegrityAuditProperties.NODE_TYPE, iae.getNodeType());
-                               
-                               //get a map of the instances for their iae indexed by id
-                               Map<Object,Object> theirEntries = dbDAO.getAllEntries(persistenceUnit, theirProperties, clazzName, keySet);
-                               
-                               /*
-                                * Compare myEntries with theirEntries and get back a set of mismatched IDs.
-                                * Collect the IDs for the class where a mismatch occurred.  We will now
-                                * write an error log for each.
-                                */
-                               Set<Object> misMatchedKeySet = compareEntries(myEntries, theirEntries);
-                               if(!misMatchedKeySet.isEmpty()){
-                                       String keysString = "";
-                                       for(Object key: misMatchedKeySet){
-                                               keysString = keysString.concat(key.toString() + ", ");
-                                               errorCount ++;
-                                       }
-                                       writeAuditSummaryLog(clazzName, resourceName, iae.getResourceName(), keysString);
-                                       if(logger.isDebugEnabled()){
-                                               for(Object key : misMatchedKeySet){
-                                                       writeAuditDebugLog(clazzName, resourceName, iae.getResourceName(), myEntries.get(key), theirEntries.get(key));
-                                               }
-                                       }
-                               }
-                       }
-                       //Time check
-                       if((System.currentTimeMillis() - startTime) >= dbAuditUpdateMillis){
-                               //update the timestamp
-                               dbDAO.setLastUpdated();
-                               //reset the startTime
-                               startTime=System.currentTimeMillis();
-                       }else{
-                               //sleep a couple seconds to break up the activity
-                               if (logger.isDebugEnabled()) {
-                                       logger.debug("dbAudit: Second comparison; sleeping " + dbAuditSleepMillis + "ms");
-                               }
-                               sleep();
-                               if (logger.isDebugEnabled()) {
-                                       logger.debug("dbAudit: Second comparison; waking from sleep");
-                               }
-                       }
-               }//end: for(String clazzName: classNameList)
-               
-               if(errorCount != 0){
-                       String msg = " DB Audit: " + errorCount + " errors found. A large number of errors may indicate DB replication has stopped";
-                       logger.error(MessageCodes.ERROR_AUDIT,  msg);
-               }
-               
-               if (logger.isDebugEnabled()) {
-                       logger.debug("dbAudit: Exiting");
-               }
-       
-               return; //all done
-       }
-
-       /**
-        * Sleeps a bit.
-        * @throws IntegrityAuditException
-        */
-       private void sleep() throws IntegrityAuditException {
-               try {
-                       Thread.sleep(dbAuditSleepMillis);
-                       
-               } catch (InterruptedException e) {
-                       Thread.currentThread().interrupt();
-                       throw new IntegrityAuditException(e);
-               }
-       }
-
-       /**
-        * dbAuditSimulate simulates the DB audit
-        * @param resourceName
-        * @param persistenceUnit 
-        * @param simulationIterations
-        * @param simulationIntervalMs 
-        * @param nodeType
-        * @throws DbAuditException
-        */
-       public void dbAuditSimulate(String resourceName, String persistenceUnit, long simulationIterations, long simulationIntervalMs) throws DbAuditException {
-
-               try {
-                       logger.info("dbAuditSimulate: Starting audit simulation for resourceName="
-                                       + resourceName + ", persistenceUnit=" + persistenceUnit);
-
-                       for (int i = 0; i < simulationIterations; i++) {
-                               dbDAO.setLastUpdated();
-                               logger.info("dbAuditSimulate: i=" + i + ", sleeping "
-                                               + simulationIntervalMs + "ms");
-                               Thread.sleep(simulationIntervalMs);
-                       }
-
-                       logger.info("dbAuditSimulate: Finished audit simulation for resourceName="
-                                       + resourceName + ", persistenceUnit=" + persistenceUnit);
-                       
-               } catch(DbDaoTransactionException e) {
-                       throw new DbAuditException(e);
-                       
-               } catch (InterruptedException e) {
-                       Thread.currentThread().interrupt();
-                       throw new DbAuditException(e);
-               }
-       }
-       
-       /**
-        * compareEntries() will compare the lists of entries from the DB
-        * @param myEntries
-        * @param theirEntries
-        * @return
-        */
-       public Set<Object> compareEntries(Map<Object,Object> myEntries, Map<Object,Object> theirEntries){
-               /*
-                * Compare the entries for the same key in each of the hashmaps.  The comparison will be done by serializing the objects 
-                * (create a byte array) and then do a byte array comparison.  The audit will walk the local repository hash map comparing 
-                * to the remote cluster hashmap and then turn it around and walk the remote hashmap and look for any entries that are not 
-                * present in the local cluster hashmap. 
-                * 
-                * If the objects are not identical, the audit will put the object IDs on a list to try after completing the audit of the table 
-                * it is currently working on.
-                * 
-                */
-               HashSet<Object> misMatchedKeySet = new HashSet<>();
-               for(Entry<Object, Object> ent: myEntries.entrySet()) {
-                       Object key = ent.getKey();
-                       byte[] mySerializedEntry = SerializationUtils.serialize((Serializable) ent.getValue());
-                       byte[] theirSerializedEntry = SerializationUtils.serialize((Serializable) theirEntries.get(key));
-                       if(!Arrays.equals(mySerializedEntry, theirSerializedEntry)){
-                               logger.debug("compareEntries: For myEntries.key=" + key + ", entries do not match");
-                               misMatchedKeySet.add(key);
-                       } else {
-                               logger.debug("compareEntries: For myEntries.key=" + key + ", entries match");
-                       }
-               }
-               //now compare it in the other direction to catch entries in their set that is not in my set
-               for(Entry<Object, Object> ent: theirEntries.entrySet()) {
-                       Object key = ent.getKey();
-                       byte[] mySerializedEntry = SerializationUtils.serialize((Serializable) myEntries.get(key));
-                       byte[] theirSerializedEntry = SerializationUtils.serialize((Serializable) ent.getValue());
-                       if(!Arrays.equals(mySerializedEntry, theirSerializedEntry)){
-                               logger.debug("compareEntries: For theirEntries.key=" + key + ", entries do not match");
-                               misMatchedKeySet.add(key);
-                       } else {
-                               logger.debug("compareEntries: For theirEntries.key=" + key + ", entries match");
-                       }
-               }
-               
-               //return a Set of the object IDs
-               logger.debug("compareEntries: misMatchedKeySet.size()=" + misMatchedKeySet.size());
-               return misMatchedKeySet;
-       }
-       
-       /**
-        * writeAuditDebugLog() writes the mismatched entry details to the debug log
-        * @param clazzName
-        * @param resourceName1
-        * @param resourceName2
-        * @param entry1
-        * @param entry2
-        * @throws IntegrityAuditException
-        */
-       public void writeAuditDebugLog(String clazzName, String resourceName1,
-                       String resourceName2, Object entry1, Object entry2) throws IntegrityAuditException{
-               try {
-                       Class<?> entityClass = Class.forName(clazzName);
-                       String tableName = entityClass.getAnnotation(Table.class).name();
-                       String msg = "\nDB Audit Error: "
-                                       + "\n    Table Name: " + tableName
-                                       + "\n    Entry 1 (short prefix style): " + resourceName1 + ": " + new ReflectionToStringBuilder(entry1,ToStringStyle.SHORT_PREFIX_STYLE).toString()
-                                       + "\n    Entry 2 (short prefix style): " + resourceName2 + ": " + new ReflectionToStringBuilder(entry2,ToStringStyle.SHORT_PREFIX_STYLE).toString()
-                                       + "\n    Entry 1 (recursive style): " + resourceName1 + ": " + new ReflectionToStringBuilder(entry1, new RecursiveToStringStyle()).toString()
-                                       + "\n    Entry 2 (recursive style): " + resourceName2 + ": " + new ReflectionToStringBuilder(entry2, new RecursiveToStringStyle()).toString();
-                       logger.debug(msg);
-                       
-               } catch (ClassNotFoundException e) {
-                       throw new IntegrityAuditException(e);
-               }
-               
-       }
-       
-       /**
-        * writeAuditSummaryLog() writes a summary of the DB mismatches to the error log
-        * @param clazzName
-        * @param resourceName1
-        * @param resourceName2
-        * @param keys
-        * @throws IntegrityAuditException
-        */
-       public void writeAuditSummaryLog(String clazzName, String resourceName1, 
-                       String resourceName2, String keys) throws IntegrityAuditException{
-               try {
-                       Class<?> entityClass = Class.forName(clazzName);
-                       String tableName = entityClass.getAnnotation(Table.class).name();
-                       String msg = " DB Audit Error: Table Name: " + tableName
-                                       + ";  Mismatch between nodes: " + resourceName1 +" and " + resourceName2
-                                       + ";  Mismatched entries (keys): " + keys;
-                       logger.info(msg);
-               } catch (ClassNotFoundException e) {
-                       throw new IntegrityAuditException(e);
-               }
-       }
-
-       /**
-        * Gets the audit-update time.
-        * @return the audit-update time, in milliseconds
-        */
-       protected static long getDbAuditUpdateMillis() {
-               return dbAuditUpdateMillis;
-       }
-
-       /**
-        * Sets the audit-update time.
-        * @param dbAuditUpdateMillis   the new audit update time, in milliseconds
-        */
-       protected static void setDbAuditUpdateMillis(long dbAuditUpdateMillis) {
-               DbAudit.dbAuditUpdateMillis = dbAuditUpdateMillis;
-       }
-
-       /**
-        * Gets the audit-sleep time.
-        * @return the audit-sleep time, in milliseconds
-        */
-       protected static long getDbAuditSleepMillis() {
-               return dbAuditSleepMillis;
-       }
-
-       /**
-        * Sets the audit-sleep time.
-        * @param dbAuditSleepMillis    the new audit sleep time, in milliseconds
-        */
-       protected static void setDbAuditSleepMillis(long dbAuditSleepMillis) {
-               DbAudit.dbAuditSleepMillis = dbAuditSleepMillis;
-       }
+
+    private static final Logger logger = FlexLogger.getLogger(DbAudit.class);
+
+    private static long dbAuditUpdateMillis = 5000L;
+    private static long dbAuditSleepMillis = 2000L;
+
+    DbDAO dbDao = null;
+
+    /**
+     * Construct an instance with the given DbDAO.
+     * 
+     * @param dbDao the DbDAO
+     */
+    public DbAudit(DbDAO dbDao) {
+
+        if (logger.isDebugEnabled()) {
+            logger.debug("Constructor: Entering");
+        }
+
+        this.dbDao = dbDao;
+
+        if (logger.isDebugEnabled()) {
+            logger.debug("Constructor: Exiting");
+        }
+
+    }
+
+    /**
+     * dbAudit actually does the audit.
+     * 
+     * @param resourceName the resource name
+     * @param persistenceUnit the persistence unit
+     * @param nodeType the node type
+     * @throws IntegrityAuditException if an error occurs
+     */
+    public void dbAudit(String resourceName, String persistenceUnit, String nodeType) throws IntegrityAuditException {
+
+        if (logger.isDebugEnabled()) {
+            logger.debug("dbAudit: Entering, resourceName=" + resourceName + ", persistenceUnit=" + persistenceUnit
+                    + ", nodeType=" + nodeType);
+        }
+
+        // Get all IntegrityAudit entries so we can get the DB access info
+        List<IntegrityAuditEntity> iaeList = dbDao.getIntegrityAuditEntities(persistenceUnit, nodeType);
+        if (iaeList == null || iaeList.isEmpty()) {
+
+            String msg = "DbAudit: for node " + resourceName + " Found no IntegrityAuditEntity entries";
+            logger.error(MessageCodes.ERROR_AUDIT, msg);
+            throw new DbAuditException(msg);
+
+        } else if (iaeList.size() == 1) {
+
+            Long iaeId = null;
+            String iaeRn = null;
+            String iaeNt = null;
+            String iaeS = null;
+            for (IntegrityAuditEntity iae : iaeList) {
+                iaeId = iae.getId();
+                iaeRn = iae.getResourceName();
+                iaeNt = iae.getNodeType();
+                iaeS = iae.getSite();
+            }
+            String msg = "DbAudit: Found only one IntegrityAuditEntity entry:" + " ID = " + iaeId + " ResourceName = "
+                    + iaeRn + " NodeType = " + iaeNt + " Site = " + iaeS;
+            logger.warn(msg);
+            return;
+        }
+
+        // Obtain all persistence class names for the PU we are auditing
+        Set<String> classNameSet = dbDao.getPersistenceClassNames();
+        if (classNameSet == null || classNameSet.isEmpty()) {
+
+            String msg = "DbAudit: For node " + resourceName + " Found no persistence class names";
+            logger.error(MessageCodes.ERROR_AUDIT, msg);
+            throw new DbAuditException(msg);
+
+        }
+
+        /*
+         * Retrieve myIae. We are going to compare the local class entries against all other DB
+         * nodes. Since the audit is run in a round-robin, every instance will be compared against
+         * every other instance.
+         */
+        IntegrityAuditEntity myIae = dbDao.getMyIntegrityAuditEntity();
+
+        if (myIae == null) {
+
+            String msg = "DbAudit: Found no IntegrityAuditEntity entry for resourceName: " + resourceName
+                    + " persistenceUnit: " + persistenceUnit;
+            logger.error(MessageCodes.ERROR_AUDIT, msg);
+            throw new DbAuditException(msg);
+
+        }
+        /*
+         * This is the map of mismatched entries indexed by className. For each class name there is
+         * a list of mismatched entries
+         */
+        Map<String, Set<Object>> misMatchedMap = new HashMap<>();
+
+        // We need to keep track of how long the audit is taking
+        long startTime = System.currentTimeMillis();
+
+        // Retrieve all instances of the class for each node
+        if (logger.isDebugEnabled()) {
+            logger.debug("dbAudit: Traversing classNameSet, size=" + classNameSet.size());
+        }
+        for (String clazzName : classNameSet) {
+
+            if (logger.isDebugEnabled()) {
+                logger.debug("dbAudit: clazzName=" + clazzName);
+            }
+
+            // all instances of the class for myIae
+            Map<Object, Object> myEntries = dbDao.getAllMyEntries(clazzName);
+            // get a map of the objects indexed by id. Does not necessarily have any entries
+
+            if (logger.isDebugEnabled()) {
+                logger.debug("dbAudit: Traversing iaeList, size=" + iaeList.size());
+            }
+            for (IntegrityAuditEntity iae : iaeList) {
+                if (iae.getId() == myIae.getId()) {
+                    if (logger.isDebugEnabled()) {
+                        logger.debug("dbAudit: My Id=" + iae.getId() + ", resourceName=" + iae.getResourceName());
+                    }
+                    continue; // no need to compare with self
+                } else {
+                    if (logger.isDebugEnabled()) {
+                        logger.debug("dbAudit: Id=" + iae.getId() + ", resourceName=" + iae.getResourceName());
+                    }
+                }
+                // Create properties for the other db node
+                Properties theirProperties = new Properties();
+                theirProperties.put(IntegrityAuditProperties.DB_DRIVER, iae.getJdbcDriver());
+                theirProperties.put(IntegrityAuditProperties.DB_URL, iae.getJdbcUrl());
+                theirProperties.put(IntegrityAuditProperties.DB_USER, iae.getJdbcUser());
+                theirProperties.put(IntegrityAuditProperties.DB_PWD, iae.getJdbcPassword());
+                theirProperties.put(IntegrityAuditProperties.SITE_NAME, iae.getSite());
+                theirProperties.put(IntegrityAuditProperties.NODE_TYPE, iae.getNodeType());
+
+                // get a map of the instances for their iae indexed by id
+                Map<Object, Object> theirEntries = dbDao.getAllEntries(persistenceUnit, theirProperties, clazzName);
+                if (logger.isDebugEnabled()) {
+                    logger.debug("dbAudit: For persistenceUnit=" + persistenceUnit + ", clazzName=" + clazzName
+                            + ", theirEntries.size()=" + theirEntries.size());
+                }
+
+                /*
+                 * Compare myEntries with theirEntries and get back a set of mismatched IDs. Collect
+                 * the IDs for the class where a mismatch occurred. We will check them again for all
+                 * nodes later.
+                 */
+                Set<Object> misMatchedKeySet = compareEntries(myEntries, theirEntries);
+                if (!misMatchedKeySet.isEmpty()) {
+                    Set<Object> misMatchedEntry = misMatchedMap.get(clazzName);
+                    if (misMatchedEntry == null) {
+                        misMatchedMap.put(clazzName, misMatchedKeySet);
+                    } else {
+                        misMatchedEntry.addAll(misMatchedKeySet);
+                        misMatchedMap.put(clazzName, misMatchedEntry);
+                    }
+                }
+            } // end for (IntegrityAuditEntity iae : iaeList)
+
+            // Time check
+            if ((System.currentTimeMillis() - startTime) >= dbAuditUpdateMillis) {
+                // update the timestamp
+                dbDao.setLastUpdated();
+                // reset the startTime
+                startTime = System.currentTimeMillis();
+            } else {
+                // sleep a couple seconds to break up the activity
+                if (logger.isDebugEnabled()) {
+                    logger.debug("dbAudit: Sleeping " + dbAuditSleepMillis + "ms");
+                }
+                sleep();
+                if (logger.isDebugEnabled()) {
+                    logger.debug("dbAudit: Waking from sleep");
+                }
+            }
+        } // end: for(String clazzName: classNameList)
+
+        // check if misMatchedMap is empty
+        if (misMatchedMap.isEmpty()) {
+
+            if (logger.isDebugEnabled()) {
+                logger.debug("dbAudit: Exiting, misMatchedMap is empty");
+            }
+            // we are done
+            return;
+        } else {
+            if (logger.isDebugEnabled()) {
+                logger.debug("dbAudit: Doing another comparison; misMatchedMap.size()=" + misMatchedMap.size());
+            }
+        }
+
+        // If misMatchedMap is not empty, retrieve the entries in each misMatched list and compare
+        // again
+        classNameSet = new HashSet<>(misMatchedMap.keySet());
+        // We need to keep track of how long the audit is taking
+        startTime = System.currentTimeMillis();
+
+        // Retrieve all instances of the class for each node
+        if (logger.isDebugEnabled()) {
+            logger.debug("dbAudit: Second comparison; traversing classNameSet, size=" + classNameSet.size());
+        }
+
+        int errorCount = 0;
+
+        for (String clazzName : classNameSet) {
+
+            if (logger.isDebugEnabled()) {
+                logger.debug("dbAudit: Second comparison; clazzName=" + clazzName);
+            }
+
+            // all instances of the class for myIae
+            Set<Object> keySet = misMatchedMap.get(clazzName);
+            Map<Object, Object> myEntries = dbDao.getAllMyEntries(clazzName, keySet);
+            // get a map of the objects indexed by id
+
+            if (logger.isDebugEnabled()) {
+                logger.debug("dbAudit: Second comparison; traversing iaeList, size=" + iaeList.size());
+            }
+            for (IntegrityAuditEntity iae : iaeList) {
+                if (iae.getId() == myIae.getId()) {
+                    if (logger.isDebugEnabled()) {
+                        logger.debug("dbAudit: Second comparison; My Id=" + iae.getId() + ", resourceName="
+                                + iae.getResourceName());
+                    }
+                    continue; // no need to compare with self
+                } else {
+                    if (logger.isDebugEnabled()) {
+                        logger.debug("dbAudit: Second comparison; Id=" + iae.getId() + ", resourceName="
+                                + iae.getResourceName());
+                    }
+                }
+                // Create properties for the other db node
+                Properties theirProperties = new Properties();
+                theirProperties.put(IntegrityAuditProperties.DB_DRIVER, iae.getJdbcDriver());
+                theirProperties.put(IntegrityAuditProperties.DB_URL, iae.getJdbcUrl());
+                theirProperties.put(IntegrityAuditProperties.DB_USER, iae.getJdbcUser());
+                theirProperties.put(IntegrityAuditProperties.DB_PWD, iae.getJdbcPassword());
+                theirProperties.put(IntegrityAuditProperties.SITE_NAME, iae.getSite());
+                theirProperties.put(IntegrityAuditProperties.NODE_TYPE, iae.getNodeType());
+
+                // get a map of the instances for their iae indexed by id
+                Map<Object, Object> theirEntries =
+                        dbDao.getAllEntries(persistenceUnit, theirProperties, clazzName, keySet);
+
+                /*
+                 * Compare myEntries with theirEntries and get back a set of mismatched IDs. Collect
+                 * the IDs for the class where a mismatch occurred. We will now write an error log
+                 * for each.
+                 */
+                Set<Object> misMatchedKeySet = compareEntries(myEntries, theirEntries);
+                if (!misMatchedKeySet.isEmpty()) {
+                    String keysString = "";
+                    for (Object key : misMatchedKeySet) {
+                        keysString = keysString.concat(key.toString() + ", ");
+                        errorCount++;
+                    }
+                    writeAuditSummaryLog(clazzName, resourceName, iae.getResourceName(), keysString);
+                    if (logger.isDebugEnabled()) {
+                        for (Object key : misMatchedKeySet) {
+                            writeAuditDebugLog(clazzName, resourceName, iae.getResourceName(), myEntries.get(key),
+                                    theirEntries.get(key));
+                        }
+                    }
+                }
+            }
+            // Time check
+            if ((System.currentTimeMillis() - startTime) >= dbAuditUpdateMillis) {
+                // update the timestamp
+                dbDao.setLastUpdated();
+                // reset the startTime
+                startTime = System.currentTimeMillis();
+            } else {
+                // sleep a couple seconds to break up the activity
+                if (logger.isDebugEnabled()) {
+                    logger.debug("dbAudit: Second comparison; sleeping " + dbAuditSleepMillis + "ms");
+                }
+                sleep();
+                if (logger.isDebugEnabled()) {
+                    logger.debug("dbAudit: Second comparison; waking from sleep");
+                }
+            }
+        } // end: for(String clazzName: classNameList)
+
+        if (errorCount != 0) {
+            String msg = " DB Audit: " + errorCount
+                    + " errors found. A large number of errors may indicate DB replication has stopped";
+            logger.error(MessageCodes.ERROR_AUDIT, msg);
+        }
+
+        if (logger.isDebugEnabled()) {
+            logger.debug("dbAudit: Exiting");
+        }
+
+        return; // all done
+    }
+
+    /**
+     * Sleeps a bit.
+     * 
+     * @throws IntegrityAuditException if interrupted
+     */
+    private void sleep() throws IntegrityAuditException {
+        try {
+            Thread.sleep(dbAuditSleepMillis);
+
+        } catch (InterruptedException e) {
+            Thread.currentThread().interrupt();
+            throw new IntegrityAuditException(e);
+        }
+    }
+
+    /**
+     * dbAuditSimulate simulates the DB audit.
+     * 
+     * @param resourceName the resouce name
+     * @param persistenceUnit the persistence unit
+     * @param simulationIterations the simulations iterations
+     * @param simulationIntervalMs the simulation interval in milliseconds
+     * @throws DbAuditException if an error occurs
+     */
+    public void dbAuditSimulate(String resourceName, String persistenceUnit, long simulationIterations,
+            long simulationIntervalMs) throws DbAuditException {
+
+        try {
+            logger.info("dbAuditSimulate: Starting audit simulation for resourceName=" + resourceName
+                    + ", persistenceUnit=" + persistenceUnit);
+
+            for (int i = 0; i < simulationIterations; i++) {
+                dbDao.setLastUpdated();
+                logger.info("dbAuditSimulate: i=" + i + ", sleeping " + simulationIntervalMs + "ms");
+                Thread.sleep(simulationIntervalMs);
+            }
+
+            logger.info("dbAuditSimulate: Finished audit simulation for resourceName=" + resourceName
+                    + ", persistenceUnit=" + persistenceUnit);
+
+        } catch (DbDaoTransactionException e) {
+            throw new DbAuditException(e);
+
+        } catch (InterruptedException e) {
+            Thread.currentThread().interrupt();
+            throw new DbAuditException(e);
+        }
+    }
+
+    /**
+     * compareEntries() will compare the lists of entries from the DB.
+     * 
+     * @param myEntries the entries
+     * @param theirEntries the entries to compare against myEntries
+     * @return the set of differences
+     */
+    public Set<Object> compareEntries(Map<Object, Object> myEntries, Map<Object, Object> theirEntries) {
+        /*
+         * Compare the entries for the same key in each of the hashmaps. The comparison will be done
+         * by serializing the objects (create a byte array) and then do a byte array comparison. The
+         * audit will walk the local repository hash map comparing to the remote cluster hashmap and
+         * then turn it around and walk the remote hashmap and look for any entries that are not
+         * present in the local cluster hashmap.
+         * 
+         * If the objects are not identical, the audit will put the object IDs on a list to try
+         * after completing the audit of the table it is currently working on.
+         * 
+         */
+        HashSet<Object> misMatchedKeySet = new HashSet<>();
+        for (Entry<Object, Object> ent : myEntries.entrySet()) {
+            Object key = ent.getKey();
+            byte[] mySerializedEntry = SerializationUtils.serialize((Serializable) ent.getValue());
+            byte[] theirSerializedEntry = SerializationUtils.serialize((Serializable) theirEntries.get(key));
+            if (!Arrays.equals(mySerializedEntry, theirSerializedEntry)) {
+                logger.debug("compareEntries: For myEntries.key=" + key + ", entries do not match");
+                misMatchedKeySet.add(key);
+            } else {
+                logger.debug("compareEntries: For myEntries.key=" + key + ", entries match");
+            }
+        }
+        // now compare it in the other direction to catch entries in their set that is not in my set
+        for (Entry<Object, Object> ent : theirEntries.entrySet()) {
+            Object key = ent.getKey();
+            byte[] mySerializedEntry = SerializationUtils.serialize((Serializable) myEntries.get(key));
+            byte[] theirSerializedEntry = SerializationUtils.serialize((Serializable) ent.getValue());
+            if (!Arrays.equals(mySerializedEntry, theirSerializedEntry)) {
+                logger.debug("compareEntries: For theirEntries.key=" + key + ", entries do not match");
+                misMatchedKeySet.add(key);
+            } else {
+                logger.debug("compareEntries: For theirEntries.key=" + key + ", entries match");
+            }
+        }
+
+        // return a Set of the object IDs
+        logger.debug("compareEntries: misMatchedKeySet.size()=" + misMatchedKeySet.size());
+        return misMatchedKeySet;
+    }
+
+    /**
+     * writeAuditDebugLog() writes the mismatched entry details to the debug log.
+     * 
+     * @param clazzName the class name
+     * @param resourceName1 resource name 1
+     * @param resourceName2 resource name 2
+     * @param entry1 entry 1
+     * @param entry2 entry 2
+     * @throws IntegrityAuditException if the given class cannot be found
+     */
+    public void writeAuditDebugLog(String clazzName, String resourceName1, String resourceName2, Object entry1,
+            Object entry2) throws IntegrityAuditException {
+        try {
+            Class<?> entityClass = Class.forName(clazzName);
+            String tableName = entityClass.getAnnotation(Table.class).name();
+            String msg = "\nDB Audit Error: " + "\n    Table Name: " + tableName
+                    + "\n    Entry 1 (short prefix style): " + resourceName1 + ": "
+                    + new ReflectionToStringBuilder(entry1, ToStringStyle.SHORT_PREFIX_STYLE).toString()
+                    + "\n    Entry 2 (short prefix style): " + resourceName2 + ": "
+                    + new ReflectionToStringBuilder(entry2, ToStringStyle.SHORT_PREFIX_STYLE).toString()
+                    + "\n    Entry 1 (recursive style): " + resourceName1 + ": "
+                    + new ReflectionToStringBuilder(entry1, new RecursiveToStringStyle()).toString()
+                    + "\n    Entry 2 (recursive style): " + resourceName2 + ": "
+                    + new ReflectionToStringBuilder(entry2, new RecursiveToStringStyle()).toString();
+            logger.debug(msg);
+
+        } catch (ClassNotFoundException e) {
+            throw new IntegrityAuditException(e);
+        }
+
+    }
+
+    /**
+     * writeAuditSummaryLog() writes a summary of the DB mismatches to the error log.
+     * 
+     * @param clazzName the name of the class
+     * @param resourceName1 resource name 1
+     * @param resourceName2 resource name 2
+     * @param keys the mismatched entry keys
+     * @throws IntegrityAuditException if the given class cannot be found
+     */
+    public void writeAuditSummaryLog(String clazzName, String resourceName1, String resourceName2, String keys)
+            throws IntegrityAuditException {
+        try {
+            Class<?> entityClass = Class.forName(clazzName);
+            String tableName = entityClass.getAnnotation(Table.class).name();
+            String msg = " DB Audit Error: Table Name: " + tableName + ";  Mismatch between nodes: " + resourceName1
+                    + " and " + resourceName2 + ";  Mismatched entries (keys): " + keys;
+            logger.info(msg);
+        } catch (ClassNotFoundException e) {
+            throw new IntegrityAuditException(e);
+        }
+    }
+
+    /**
+     * Gets the audit-update time.
+     * 
+     * @return the audit-update time, in milliseconds
+     */
+    protected static long getDbAuditUpdateMillis() {
+        return dbAuditUpdateMillis;
+    }
+
+    /**
+     * Sets the audit-update time.
+     * 
+     * @param dbAuditUpdateMillis the new audit update time, in milliseconds
+     */
+    protected static void setDbAuditUpdateMillis(long dbAuditUpdateMillis) {
+        DbAudit.dbAuditUpdateMillis = dbAuditUpdateMillis;
+    }
+
+    /**
+     * Gets the audit-sleep time.
+     * 
+     * @return the audit-sleep time, in milliseconds
+     */
+    protected static long getDbAuditSleepMillis() {
+        return dbAuditSleepMillis;
+    }
+
+    /**
+     * Sets the audit-sleep time.
+     * 
+     * @param dbAuditSleepMillis the new audit sleep time, in milliseconds
+     */
+    protected static void setDbAuditSleepMillis(long dbAuditSleepMillis) {
+        DbAudit.dbAuditSleepMillis = dbAuditSleepMillis;
+    }
 
 }
index dc629c6..a539f6b 100644 (file)
 package org.onap.policy.common.ia;
 
 public class DbAuditException extends IntegrityAuditException {
-       private static final long serialVersionUID = 1L;
-       public DbAuditException() {
-               super();
-       }
-       public DbAuditException(String message) {
-               super(message);
-       }
+    private static final long serialVersionUID = 1L;
 
-       public DbAuditException(Throwable cause) {
-               super(cause);
-       }
-       public DbAuditException(String message, Throwable cause) {
-               super(message, cause);
-       }
+    public DbAuditException() {
+        super();
+    }
+
+    public DbAuditException(String message) {
+        super(message);
+    }
+
+    public DbAuditException(Throwable cause) {
+        super(cause);
+    }
+
+    public DbAuditException(String message, Throwable cause) {
+        super(message, cause);
+    }
 }
index 73beda7..864adac 100644 (file)
@@ -42,9 +42,8 @@ import javax.persistence.criteria.Root;
 import javax.persistence.metamodel.ManagedType;
 import javax.persistence.metamodel.Metamodel;
 
-
 import org.onap.policy.common.ia.jpa.IntegrityAuditEntity;
-import org.onap.policy.common.logging.flexlogger.FlexLogger; 
+import org.onap.policy.common.logging.flexlogger.FlexLogger;
 import org.onap.policy.common.logging.flexlogger.Logger;
 
 /**
@@ -52,703 +51,718 @@ import org.onap.policy.common.logging.flexlogger.Logger;
  * 
  */
 public class DbDAO {
-       private static final Logger logger = FlexLogger.getLogger(DbDAO.class.getName());
-       private String resourceName;
-       private String persistenceUnit;
-       private String dbDriver;
-       private String dbUrl;
-       private String dbUser;
-       private String siteName;
-       private String nodeType;
-       private Properties properties=null;
-       
-       private EntityManagerFactory emf;
-       
-       /*
-        * Supports designation serialization.
-        */
+    private static final Logger logger = FlexLogger.getLogger(DbDAO.class.getName());
+    private String resourceName;
+    private String persistenceUnit;
+    private String dbDriver;
+    private String dbUrl;
+    private String dbUser;
+    private String siteName;
+    private String nodeType;
+    private Properties properties = null;
+
+    private EntityManagerFactory emf;
+
+    /*
+     * Supports designation serialization.
+     */
     private static final Object lock = new Object();
 
-       /**
-        * DbDAO Constructor
-        * 
-        * @param resourceName
-        * @param persistenceUnit
-        * @param properties
-        * @throws IntegrityAuditException
-        */
-       public DbDAO(String resourceName, String persistenceUnit, Properties properties) throws IntegrityAuditException {
-               this(resourceName, persistenceUnit, properties, null);
-       }
-
-       /**
-        * DbDAO Constructor
-        * 
-        * @param resourceName
-        * @param persistenceUnit
-        * @param properties
-        * @param lastUpdateDate        may be {@code null}
-        * @param altDbUrl                      may be {@code null}
-        * @throws IntegrityAuditException
-        */
-       protected DbDAO(String resourceName, String persistenceUnit, Properties properties, String altDbUrl)
-                       throws IntegrityAuditException {
-               logger.debug("DbDAO contructor: enter");
-
-               validateProperties(resourceName, persistenceUnit, properties);
-
-               emf = Persistence.createEntityManagerFactory(persistenceUnit, properties);
-
-               register(altDbUrl);
-
-               logger.debug("DbDAO contructor: exit");
-       }
-       
-       /**
-        * Release resources (i.e., the EntityManagerFactory).
-        */
-       public void destroy() {
-               emf.close();
-       }
-       
-       /**
-        * validateProperties will validate the properties
-        * @param resourceName
-        * @param persistenceUnit
-        * @param properties
-        * @throws IntegrityAuditPropertiesException
-        */
-       private void validateProperties(String resourceName, String persistenceUnit, Properties properties) throws IntegrityAuditPropertiesException{
-               StringBuilder badparams= new StringBuilder();
-               if(IntegrityAudit.parmsAreBad(resourceName, persistenceUnit, properties, badparams)){
-                       String msg = "DbDAO: Bad parameters: badparams" + badparams;
-                       throw new IntegrityAuditPropertiesException(msg);
-               }
-               this.resourceName = resourceName;
-               this.persistenceUnit = persistenceUnit;
-               this.dbDriver = properties.getProperty(IntegrityAuditProperties.DB_DRIVER).trim();
-               this.dbUrl = properties.getProperty(IntegrityAuditProperties.DB_URL).trim();
-               this.dbUser = properties.getProperty(IntegrityAuditProperties.DB_USER).trim();
-               this.siteName = properties.getProperty(IntegrityAuditProperties.SITE_NAME).trim();
-               this.nodeType = properties.getProperty(IntegrityAuditProperties.NODE_TYPE).trim();
-               this.properties = properties;
-               logger.debug("DbDAO.assignProperties: exit:" 
-                               + "\nresourceName: " + this.resourceName
-                               + "\npersistenceUnit: " + this.persistenceUnit
-                               + "\nproperties: " + this.properties);
-       }
-       
-       /**
-        * getAllMyEntries gets all the DB entries for a particular class
-        * @param className
-        * @return
-        */
-       public Map<Object, Object> getAllMyEntries(String className) {
-               logger.debug("getAllMyEntries: Entering, className="
-                               + className);
-               HashMap<Object, Object> resultMap = new HashMap<>();
-               EntityManager em = emf.createEntityManager();
-               try{
-                       CriteriaBuilder cb = em.getCriteriaBuilder();
-                       CriteriaQuery<Object> cq = cb.createQuery();
-                       Root<?> rootEntry = cq.from(Class.forName(className));
-                       CriteriaQuery<Object> all = cq.select(rootEntry);
-                       TypedQuery<Object> allQuery = em.createQuery(all);
-                       List<Object> objectList = allQuery.getResultList();
-                       //Now create the map
-
-                       PersistenceUnitUtil util = emf.getPersistenceUnitUtil();
-                       for (Object o: objectList){
-                               Object key = util.getIdentifier(o);
-                               resultMap.put(key, o);
-                       }
-               }catch(Exception e){
-                       logger.error("getAllEntries encountered exception: ", e);
-               }
-               em.close();
-               logger.debug("getAllMyEntries: Exit, resultMap.keySet()=" + resultMap.keySet());
-               return resultMap;               
-       }
-       
-       /**
-        * getAllMyEntries gets all entries for a class
-        * @param className
-        * @param keySet
-        * @return
-        */
-       public Map<Object, Object> getAllMyEntries(String className, Set<Object> keySet){
-               logger.debug("getAllMyEntries: Entering, className="
-                               + className + ",\n keySet=" + keySet);
-
-               HashMap<Object, Object> resultMap = new HashMap<>();
-               EntityManager em = emf.createEntityManager();
-               try{
-                       Class<?> clazz = Class.forName(className);
-                       for(Object key : keySet){
-                               Object entry = em.find(clazz, key);
-                               resultMap.put(key, entry);
-                       }
-               }catch(Exception e){
-                       logger.error("getAllMyEntries encountered exception: ", e);
-               }
-               em.close();
-
-               logger.debug("getAllMyEntries: Returning resultMap, size=" + resultMap.size());
-               return resultMap;
-       }
-       
-       /**
-        * getAllEntries gets all entriesfor a particular persistence unit adn className
-        * @param persistenceUnit
-        * @param properties
-        * @param className
-        * @return
-        */
-       public Map<Object,Object> getAllEntries(String persistenceUnit, Properties properties, String className){
-               
-               logger.debug("getAllEntries: Entering, persistenceUnit="
-                               + persistenceUnit + ",\n className=" + className);
-               HashMap<Object, Object> resultMap = new HashMap<>();
-
-               EntityManagerFactory theEmf = Persistence.createEntityManagerFactory(persistenceUnit, properties);
-               EntityManager em = theEmf.createEntityManager();
-               try{
-                       CriteriaBuilder cb = em.getCriteriaBuilder();
-                       CriteriaQuery<Object> cq = cb.createQuery();
-                       Root<?> rootEntry = cq.from(Class.forName(className));
-                       CriteriaQuery<Object> all = cq.select(rootEntry);
-                       TypedQuery<Object> allQuery = em.createQuery(all);
-                       List<Object> objectList = allQuery.getResultList();
-
-                       PersistenceUnitUtil util = theEmf.getPersistenceUnitUtil();
-                       for (Object o: objectList){
-                               Object key = util.getIdentifier(o);
-                               resultMap.put(key, o);
-                       }
-               }catch(Exception e){
-                       logger.error("getAllEntries encountered exception:", e);
-               }
-               em.close();
-               theEmf.close();
-               
-               logger.debug("getAllEntries: Returning resultMap, size=" + resultMap.size());
-               
-               return resultMap;               
-       }
-       
-
-       /**
-        * getAllEntries gest all entries for a persistence unit
-        * @param persistenceUnit
-        * @param properties
-        * @param className
-        * @param keySet
-        * @return
-        */
-
-       public Map<Object,Object> getAllEntries(String persistenceUnit, Properties properties, String className, Set<Object> keySet){
-               logger.debug("getAllEntries: Entering, persistenceUnit="
-                               + persistenceUnit + ",\n properties= " + properties + ",\n className=" + className + ",\n keySet= " + keySet);
-               EntityManagerFactory theEmf = Persistence.createEntityManagerFactory(persistenceUnit, properties);
-               EntityManager em = theEmf.createEntityManager();
-               HashMap<Object, Object> resultMap = new HashMap<>();
-               try{
-                       Class<?> clazz = Class.forName(className);
-                       for(Object key : keySet){
-                               Object entry = em.find(clazz, key);
-                               resultMap.put(key, entry);
-                       }
-               }catch(Exception e){
-                       String msg = "getAllEntries encountered exception: " + e;
-                       logger.error(msg, e);
-               }
-               em.close();
-               theEmf.close();
-               logger.debug("getAllEntries: Exit, resultMap, size=" + resultMap.size());
-               return resultMap;       
-       }
-       
-       /**
-        * getIntegrityAuditEntities() Get all the IntegrityAuditEntities for a particular persistence unit
-        * and node type
-        * @param persistenceUnit
-        * @param nodeType
-        * @return
-        * @throws DbDaoTransactionException
-        */
-       @SuppressWarnings("unchecked")
-       public List<IntegrityAuditEntity> getIntegrityAuditEntities(String persistenceUnit, String nodeType) throws DbDaoTransactionException {
-               logger.debug("getIntegrityAuditEntities: Entering, persistenceUnit="
-                               + persistenceUnit + ",\n nodeType= " + nodeType);
-               try{
-                       EntityManager em = emf.createEntityManager();
-                       // Start a transaction
-                       EntityTransaction et = em.getTransaction();
-
-                       et.begin();
-
-                       // if IntegrityAuditEntity entry exists for resourceName and PU, update it. If not found, create a new entry
-                       Query iaequery = em.createQuery("Select i from IntegrityAuditEntity i where i.persistenceUnit=:pu and i.nodeType=:nt");
-                       iaequery.setParameter("pu", persistenceUnit);
-                       iaequery.setParameter("nt", nodeType);
-
-                       List<IntegrityAuditEntity> iaeList = iaequery.getResultList();
-
-                       // commit transaction
-                       et.commit();
-                       em.close();
-                       logger.debug("getIntegrityAuditEntities: Exit, iaeList=" + iaeList);
-                       return iaeList;
-               }catch (Exception e){
-                       String msg = "DbDAO: " + "getIntegrityAuditEntities() " + "ecountered a problem in execution: ";
-                       logger.error(msg, e);
-                       throw new DbDaoTransactionException(e);
-               }
-               
-       }
-
-       /**
-        * getMyIntegrityAuditEntity() gets my IntegrityAuditEntity
-        * @return
-        * @throws DbDaoTransactionException
-        */
-       public IntegrityAuditEntity getMyIntegrityAuditEntity() throws DbDaoTransactionException{
-               try{
-                       EntityManager em = emf.createEntityManager();
-
-                       // Start a transaction
-                       EntityTransaction et = em.getTransaction();
-
-                       et.begin();
-
-                       // if IntegrityAuditEntity entry exists for resourceName and PU, retrieve it
-                       Query iaequery = em.createQuery("Select i from IntegrityAuditEntity i where i.resourceName=:rn and i.persistenceUnit=:pu");
-                       iaequery.setParameter("rn", this.resourceName);
-                       iaequery.setParameter("pu", this.persistenceUnit);
-
-                       @SuppressWarnings("rawtypes")
-                       List iaeList = iaequery.getResultList();
-                       IntegrityAuditEntity iae = null;
-
-                       if(!iaeList.isEmpty()){
-                               //ignores multiple results
-                               iae = (IntegrityAuditEntity) iaeList.get(0);
-                               // refresh the object from DB in case cached data was returned
-                               em.refresh(iae);
-                               logger.info("Resource: " + this.resourceName + " with PersistenceUnit: " + this.persistenceUnit
-                                               + " exists");
-                       }else{
-                               // If it does not exist, log an error
-                               logger.error("Attempting to setLastUpdated"
-                                               + " on an entry that does not exist:"
-                                               +" resource " + this.resourceName + " with PersistenceUnit: " + this.persistenceUnit);
-                       }
-
-                       // close the transaction
-                       et.commit();
-                       // close the EntityManager
-                       em.close();
-                       
-                       return iae;
-               }catch (Exception e){
-                       String msg = "DbDAO: " + "setLastUpdated() " + "ecountered a problem in execution: ";
-                       logger.error(msg + e);
-                       throw new DbDaoTransactionException(e);
-               }       
-       }
-
-       
-       /**
-        * getIntegrityAuditEntity() gets the IntegrityAuditEntity with a particular ID
-        * @param id
-        * @return
-        * @throws DbDaoTransactionException
-        */
-       public IntegrityAuditEntity getIntegrityAuditEntity(long id) throws DbDaoTransactionException{
-               try{
-                       EntityManager em = emf.createEntityManager();
-
-                       // Start a transaction
-                       EntityTransaction et = em.getTransaction();
-
-                       et.begin();
-
-                       IntegrityAuditEntity iae = em.find(IntegrityAuditEntity.class, id);
-
-                       et.commit();
-                       em.close();
-
-                       return iae;
-               }catch (Exception e){
-                       String msg = "DbDAO: " + "getIntegrityAuditEntity() " + "ecountered a problem in execution: ";
-                       logger.error(msg + e);
-                       throw new DbDaoTransactionException(e);
-               }
-       }
-       
-       /**
-        * getPersistenceClassNames() gets all the persistence class names.
-        * @return
-        */
-       public Set<String> getPersistenceClassNames(){
-               logger.debug("DbDAO: getPersistenceClassNames() entry");
-               HashSet<String> returnList = new HashSet<>();
-               final Metamodel mm = emf.getMetamodel();
-               logger.debug("\n" + persistenceUnit +" persistence unit classes:");
-               for (final ManagedType<?> managedType : mm.getManagedTypes()) {
-                       Class<?> c = managedType.getJavaType();
-                       logger.debug("    " + c.getSimpleName());
-                       returnList.add(c.getName()); //the full class name needed to make a query using jpa
-               }
-               logger.debug("DbDAO: getPersistenceClassNames() exit");
-               return returnList;
-       }
-       
-       /**
-        * Register the IntegrityAudit instance
-        * @param altDbUrl                      alternate DB URL to be placed into the record,
-        *                                                      or {@code null} to use the default
-        */
-       private void register(String altDbUrl) throws DbDaoTransactionException {
-               try{
-                       EntityManager em = emf.createEntityManager();
-
-                       // Start a transaction
-                       EntityTransaction et = em.getTransaction();
-
-                       et.begin();
-
-                       // if IntegrityAuditEntity entry exists for resourceName and PU, update it. If not found, create a new entry
-                       Query iaequery = em.createQuery("Select i from IntegrityAuditEntity i where i.resourceName=:rn and i.persistenceUnit=:pu");
-                       iaequery.setParameter("rn", this.resourceName);
-                       iaequery.setParameter("pu", this.persistenceUnit);
-
-                       @SuppressWarnings("rawtypes")
-                       List iaeList = iaequery.getResultList();
-                       IntegrityAuditEntity iae;
-
-                       //If it already exists, we just want to update the properties and lastUpdated date
-                       if(!iaeList.isEmpty()){
-                               //ignores multiple results
-                               iae = (IntegrityAuditEntity) iaeList.get(0);
-                               // refresh the object from DB in case cached data was returned
-                               em.refresh(iae);
-                               logger.info("Resource: " + this.resourceName + " with PersistenceUnit: " + this.persistenceUnit 
-                                               + " exists and entry be updated");
-                       }else{
-                               // If it does not exist, we also must add teh resourceName, persistenceUnit and designated values
-                               logger.info("Adding resource " + resourceName + " with PersistenceUnit: " + this.persistenceUnit
-                                               + " to IntegrityAuditEntity table");    
-                               iae = new IntegrityAuditEntity();
-                               iae.setResourceName(this.resourceName);
-                               iae.setPersistenceUnit(this.persistenceUnit);
-                               iae.setDesignated(false);
-                       }
-                       //update/set properties in entry
-                       iae.setSite(this.siteName);
-                       iae.setNodeType(this.nodeType);
-                       iae.setJdbcDriver(this.dbDriver);
-                       iae.setJdbcPassword(properties.getProperty(IntegrityAuditProperties.DB_PWD).trim());
-                       iae.setJdbcUrl(altDbUrl == null ? this.dbUrl : altDbUrl);
-                       iae.setJdbcUser(dbUser);
-
-                       em.persist(iae);
-                       // flush to the DB
-                       em.flush();
-
-                       // commit transaction
-                       et.commit();
-                       em.close();
-               }catch (Exception e){
-                       String msg = "DbDAO: " + "register() " + "encountered a problem in execution: ";
-                       logger.error(msg + e);
-                       throw new DbDaoTransactionException(e);
-               }
-
-       }
-       
-       public void setDesignated(boolean designated) throws DbDaoTransactionException{
-               setDesignated(this.resourceName, this.persistenceUnit, designated);
-       }
-       
-
-       public void setDesignated(String rName, String pUnit, boolean desig) throws DbDaoTransactionException{
-               logger.debug("setDesignated: enter, resourceName: " + rName + ", persistenceUnit: " 
-                               + pUnit + ", designated: " + desig);
-               try{
-
-                       EntityManager em = emf.createEntityManager();
-
-                       // Start a transaction
-                       EntityTransaction et = em.getTransaction();
-
-                       et.begin();
-
-                       // if IntegrityAuditEntity entry exists for resourceName and PU, update it. If not found, create a new entry
-                       Query iaequery = em.createQuery("Select i from IntegrityAuditEntity i where i.resourceName=:rn and i.persistenceUnit=:pu");
-                       iaequery.setParameter("rn", rName);
-                       iaequery.setParameter("pu", pUnit);
-
-                       @SuppressWarnings("rawtypes")
-                       List iaeList = iaequery.getResultList();
-                       IntegrityAuditEntity iae;
-
-                       if(!iaeList.isEmpty()){
-                               //ignores multiple results
-                               iae = (IntegrityAuditEntity) iaeList.get(0);
-                               // refresh the object from DB in case cached data was returned
-                               em.refresh(iae);
-                               logger.info("Resource: " + rName + " with PersistenceUnit: " + pUnit 
-                                               + " exists and designated be updated");
-                               iae.setDesignated(desig);
-
-                               em.persist(iae);
-                               // flush to the DB
-                               em.flush();
-                       }else{
-                               // If it does not exist, log an error
-                               logger.error("Attempting to setDesignated("
-                                               + desig + ") on an entry that does not exist:"
-                                               +" resource " + rName + " with PersistenceUnit: " + pUnit);
-                       }
-
-                       // close the transaction
-                       et.commit();
-                       // close the EntityManager
-                       em.close();
-               }catch (Exception e){
-                       String msg = "DbDAO: " + "setDesignated() " + "ecountered a problem in execution: ";
-                       logger.error(msg + e);
-                       throw new DbDaoTransactionException(e);
-               }
-
-       }
-       
-       public void setLastUpdated() throws DbDaoTransactionException{
-               logger.debug("setLastUpdated: enter, resourceName: " + this.resourceName + ", persistenceUnit: " 
-                               + this.persistenceUnit);
-               try{
-                       EntityManager em = emf.createEntityManager();
-
-                       // Start a transaction
-                       EntityTransaction et = em.getTransaction();
-
-                       et.begin();
-
-                       // if IntegrityAuditEntity entry exists for resourceName and PU, update it. If not found, create a new entry
-                       Query iaequery = em.createQuery("Select i from IntegrityAuditEntity i where i.resourceName=:rn and i.persistenceUnit=:pu");
-                       iaequery.setParameter("rn", this.resourceName);
-                       iaequery.setParameter("pu", this.persistenceUnit);
-
-                       @SuppressWarnings("rawtypes")
-                       List iaeList = iaequery.getResultList();
-                       IntegrityAuditEntity iae;
-
-                       if(!iaeList.isEmpty()){
-                               //ignores multiple results
-                               iae = (IntegrityAuditEntity) iaeList.get(0);
-                               // refresh the object from DB in case cached data was returned
-                               em.refresh(iae);
-                               logger.info("Resource: " + this.resourceName + " with PersistenceUnit: " + this.persistenceUnit
-                                               + " exists and lastUpdated be updated");
-                               iae.setLastUpdated(new Date());
-
-                               em.persist(iae);
-                               // flush to the DB
-                               em.flush();
-                       }else{
-                               // If it does not exist, log an error
-                               logger.error("Attempting to setLastUpdated"
-                                               + " on an entry that does not exist:"
-                                               +" resource " + this.resourceName + " with PersistenceUnit: " + this.persistenceUnit);
-                       }
-
-                       // close the transaction
-                       et.commit();
-                       // close the EntityManager
-                       em.close();
-               }catch (Exception e){
-                       String msg = "DbDAO: " + "setLastUpdated() " + "ecountered a problem in execution: ";
-                       logger.error(msg + e);
-                       throw new DbDaoTransactionException(e);
-               }
-
-       }
-       
-       /**
-        * Normally this method should only be used in a JUnit test environment.
-        * Manually deletes all PDP records in droolspdpentity table.
-        */
-       public int deleteAllIntegrityAuditEntities() throws DbDaoTransactionException {
-               
-               try{
-                       
-                       if (!IntegrityAudit.isUnitTesting()) {
-                               String msg = "DbDAO: " + "deleteAllIntegrityAuditEntities() " + "should only be invoked during JUnit testing";
-                               logger.error(msg);
-                               throw new DbDaoTransactionException(msg);
-                       }
-                       
-                       EntityManager em = emf.createEntityManager();
-                       // Start a transaction
-                       EntityTransaction et = em.getTransaction();
-
-                       et.begin();
-
-                       // if IntegrityAuditEntity entry exists for resourceName and PU, update it. If not found, create a new entry
-                       Query iaequery = em.createQuery("Delete from IntegrityAuditEntity");
-
-                       int returnCode = iaequery.executeUpdate();
-
-                       // commit transaction
-                       et.commit();
-                       em.close();
-                       
-                       logger.info("deleteAllIntegrityAuditEntities: returnCode=" + returnCode);
-
-                       return returnCode;
-
-               }catch (Exception e){
-                       String msg = "DbDAO: " + "deleteAllIntegrityAuditEntities() " + "encountered a problem in execution: ";
-                       logger.error(msg + e);
-                       throw new DbDaoTransactionException(e);
-               }
-               
-       }
-       
-       /**
-        * Changes designation to specified resourceName
-        * 
-        * static lock object in conjunction with synchronized keyword ensures that
-        * designation changes are done serially within a resource. I.e. static lock
-        * ensures that multiple instantiations of DbDAO don't interleave
-        * changeDesignated() invocations and potentially produce simultaneous
-        * designations.
-        * 
-        * Optimistic locking (the default, versus pessimistic) is sufficient to
-        * avoid simultaneous designations from interleaved changeDesignated()
-        * invocations from different resources (entities), because it prevents
-        * "dirty" and "non-repeatable" reads.
-        * 
-        * See http://www.objectdb.com/api/java/jpa/LockModeType
-        * 
-        * and
-        * 
-        * http://stackoverflow.com/questions/2120248/how-to-synchronize-a-static-
-        * variable-among-threads-running-different-instances-o
-        */
-       public void changeDesignated(String resourceName, String persistenceUnit,
-                       String nodeType) throws DbDaoTransactionException {
-
-               if (logger.isDebugEnabled()) {
-                       logger.debug("changeDesignated: Entering, resourceName="
-                                       + resourceName + ", persistenceUnit=" + persistenceUnit
-                                       + ", nodeType=" + nodeType);
-               }
-
-               long startTime = System.currentTimeMillis();
-
-               synchronized (lock) {
-
-                       EntityManager em = null;
-                       try {
-
-                               em = emf.createEntityManager();
-                               em.getTransaction().begin();
-
-                               /*
-                                * Define query
-                                */
-                               Query query = em
-                                               .createQuery("Select i from IntegrityAuditEntity i where i.persistenceUnit=:pu and i.nodeType=:nt");
-                               query.setParameter("pu", persistenceUnit);
-                               query.setParameter("nt", nodeType);
-
-                               /*
-                                * Execute query using pessimistic write lock.  This ensures that if anyone else is currently reading
-                                * the records we'll throw a LockTimeoutException.
-                                */
-                               @SuppressWarnings("unchecked")
-                               List<IntegrityAuditEntity> integrityAuditEntityList = (List<IntegrityAuditEntity>) query
-                                               .getResultList();
-                               for (Object o : integrityAuditEntityList) {
-                                       if (o instanceof IntegrityAuditEntity) {
-                                               IntegrityAuditEntity integrityAuditEntity = (IntegrityAuditEntity) o;
-                                               if (integrityAuditEntity.getResourceName().equals(
-                                                               resourceName)) {
-                                                       if (logger.isDebugEnabled()) {
-                                                               logger.debug("changeDesignated: Designating resourceName="
-                                                                               + integrityAuditEntity
-                                                                                               .getResourceName());
-                                                       }
-                                                       integrityAuditEntity.setDesignated(true);
-                                               } else {
-                                                       if (logger.isDebugEnabled()) {
-                                                               logger.debug("changeDesignated: Removing designation from resourceName="
-                                                                               + integrityAuditEntity
-                                                                                               .getResourceName());
-                                                       }
-                                                       integrityAuditEntity.setDesignated(false);
-                                               }
-                                       }
-                               }
-                               
-                               if (logger.isDebugEnabled()) {
-                                       logger.debug("changeDesignated: Committing designation to resourceName="
-                                                       + resourceName);
-                               }
-                               em.getTransaction().commit();
-
-                               /*
-                                * If we get a LockTimeoutException, no harm done really. We'll
-                                * probably be successful on the next attempt. The odds of
-                                * another DbDAO instance on this entity or another entity
-                                * attempting a simultaneous IntegrityAuditEntity table
-                                * read/update are pretty slim (we're only in this method for
-                                * two or three milliseconds)
-                                */
-                       } catch (LockTimeoutException e) {
-                               if (em != null) {
-                                       em.getTransaction().rollback();
-                               
-                                       String msg = "DbDAO: " + "changeDesignated() "
-                                                       + "caught LockTimeoutException, message=" + e.getMessage();
-                                       logger.error(msg + e);
-                                       throw new DbDaoTransactionException(msg, e);
-                               }
-                               else {
-                                       String msg = "DbDAO: " + "changeDesignated() "
-                                                       + "caught LockTimeoutException, message=" + e.getMessage()
-                                                       + ". Error rolling back transaction.";
-                                       logger.error(msg + e);
-                                       throw new DbDaoTransactionException(msg, e);    
-                               }
-                       } catch (Exception e) {
-                               if (em != null) {
-                                       em.getTransaction().rollback();
-                               
-                                       String msg = "DbDAO: " + "changeDesignated() "
-                                                       + "caught Exception, message=" + e.getMessage();
-                                       logger.error(msg + e);
-                                       throw new DbDaoTransactionException(msg, e);
-                               }
-                               else {
-                                       String msg = "DbDAO: " + "changeDesignated() "
-                                                       + "caught LockTimeoutException, message=" + e.getMessage()
-                                                       + ". Error rolling back transaction.";
-                                       logger.error(msg + e);
-                                       throw new DbDaoTransactionException(msg, e);    
-                               }
-                       }
-
-               } // end synchronized block
-
-               if (logger.isDebugEnabled()) {
-                       logger.debug("changeDesignated: Exiting; time expended="
-                                       + (System.currentTimeMillis() - startTime) + "ms");
-               }
-
-       }
+    /**
+     * DbDAO Constructor.
+     * 
+     * @param resourceName the resource name
+     * @param persistenceUnit the persistence unit
+     * @param properties the properties
+     * @throws IntegrityAuditException if an error occurs
+     */
+    public DbDAO(String resourceName, String persistenceUnit, Properties properties) throws IntegrityAuditException {
+        this(resourceName, persistenceUnit, properties, null);
+    }
+
+    /**
+     * DbDAO Constructor.
+     * 
+     * @param resourceName the resource name
+     * @param persistenceUnit the persistence unit
+     * @param properties the properties
+     * @param lastUpdateDate may be {@code null}
+     * @param altDbUrl may be {@code null}
+     * @throws IntegrityAuditException if an error occurs
+     */
+    protected DbDAO(String resourceName, String persistenceUnit, Properties properties, String altDbUrl)
+            throws IntegrityAuditException {
+        logger.debug("DbDAO contructor: enter");
+
+        validateProperties(resourceName, persistenceUnit, properties);
+
+        emf = Persistence.createEntityManagerFactory(persistenceUnit, properties);
+
+        register(altDbUrl);
+
+        logger.debug("DbDAO contructor: exit");
+    }
+
+    /**
+     * Release resources (i.e., the EntityManagerFactory).
+     */
+    public void destroy() {
+        emf.close();
+    }
+
+    /**
+     * validateProperties will validate the properties.
+     * 
+     * @param resourceName the rseource name
+     * @param persistenceUnit the persistence unit
+     * @param properties the properties
+     * @throws IntegrityAuditPropertiesException if an error occurs
+     */
+    private void validateProperties(String resourceName, String persistenceUnit, Properties properties)
+            throws IntegrityAuditPropertiesException {
+        StringBuilder badparams = new StringBuilder();
+        if (IntegrityAudit.parmsAreBad(resourceName, persistenceUnit, properties, badparams)) {
+            String msg = "DbDAO: Bad parameters: badparams" + badparams;
+            throw new IntegrityAuditPropertiesException(msg);
+        }
+        this.resourceName = resourceName;
+        this.persistenceUnit = persistenceUnit;
+        this.dbDriver = properties.getProperty(IntegrityAuditProperties.DB_DRIVER).trim();
+        this.dbUrl = properties.getProperty(IntegrityAuditProperties.DB_URL).trim();
+        this.dbUser = properties.getProperty(IntegrityAuditProperties.DB_USER).trim();
+        this.siteName = properties.getProperty(IntegrityAuditProperties.SITE_NAME).trim();
+        this.nodeType = properties.getProperty(IntegrityAuditProperties.NODE_TYPE).trim();
+        this.properties = properties;
+        logger.debug("DbDAO.assignProperties: exit:" + "\nresourceName: " + this.resourceName + "\npersistenceUnit: "
+                + this.persistenceUnit + "\nproperties: " + this.properties);
+    }
+
+    /**
+     * getAllMyEntries gets all the DB entries for a particular class.
+     * 
+     * @param className the class name
+     * @return all the DB entries for the given class
+     */
+    public Map<Object, Object> getAllMyEntries(String className) {
+        logger.debug("getAllMyEntries: Entering, className=" + className);
+        HashMap<Object, Object> resultMap = new HashMap<>();
+        EntityManager em = emf.createEntityManager();
+        try {
+            CriteriaBuilder cb = em.getCriteriaBuilder();
+            CriteriaQuery<Object> cq = cb.createQuery();
+            Root<?> rootEntry = cq.from(Class.forName(className));
+            CriteriaQuery<Object> all = cq.select(rootEntry);
+            TypedQuery<Object> allQuery = em.createQuery(all);
+            List<Object> objectList = allQuery.getResultList();
+            // Now create the map
+
+            PersistenceUnitUtil util = emf.getPersistenceUnitUtil();
+            for (Object o : objectList) {
+                Object key = util.getIdentifier(o);
+                resultMap.put(key, o);
+            }
+        } catch (Exception e) {
+            logger.error("getAllEntries encountered exception: ", e);
+        }
+        em.close();
+        logger.debug("getAllMyEntries: Exit, resultMap.keySet()=" + resultMap.keySet());
+        return resultMap;
+    }
+
+    /**
+     * getAllMyEntries gets all entries for a class.
+     * 
+     * @param className the name of the class
+     * @param keySet the keys to get the entries for
+     * @return the map of requested entries
+     */
+    public Map<Object, Object> getAllMyEntries(String className, Set<Object> keySet) {
+        logger.debug("getAllMyEntries: Entering, className=" + className + ",\n keySet=" + keySet);
+
+        HashMap<Object, Object> resultMap = new HashMap<>();
+        EntityManager em = emf.createEntityManager();
+        try {
+            Class<?> clazz = Class.forName(className);
+            for (Object key : keySet) {
+                Object entry = em.find(clazz, key);
+                resultMap.put(key, entry);
+            }
+        } catch (Exception e) {
+            logger.error("getAllMyEntries encountered exception: ", e);
+        }
+        em.close();
+
+        logger.debug("getAllMyEntries: Returning resultMap, size=" + resultMap.size());
+        return resultMap;
+    }
+
+    /**
+     * getAllEntries gets all entriesfor a particular persistence unit adn className.
+     * 
+     * @param persistenceUnit the persistence unit
+     * @param properties the properties
+     * @param className the class name
+     * @return the map of entries
+     */
+    public Map<Object, Object> getAllEntries(String persistenceUnit, Properties properties, String className) {
+
+        logger.debug("getAllEntries: Entering, persistenceUnit=" + persistenceUnit + ",\n className=" + className);
+        HashMap<Object, Object> resultMap = new HashMap<>();
+
+        EntityManagerFactory theEmf = Persistence.createEntityManagerFactory(persistenceUnit, properties);
+        EntityManager em = theEmf.createEntityManager();
+        try {
+            CriteriaBuilder cb = em.getCriteriaBuilder();
+            CriteriaQuery<Object> cq = cb.createQuery();
+            Root<?> rootEntry = cq.from(Class.forName(className));
+            CriteriaQuery<Object> all = cq.select(rootEntry);
+            TypedQuery<Object> allQuery = em.createQuery(all);
+            List<Object> objectList = allQuery.getResultList();
+
+            PersistenceUnitUtil util = theEmf.getPersistenceUnitUtil();
+            for (Object o : objectList) {
+                Object key = util.getIdentifier(o);
+                resultMap.put(key, o);
+            }
+        } catch (Exception e) {
+            logger.error("getAllEntries encountered exception:", e);
+        }
+        em.close();
+        theEmf.close();
+
+        logger.debug("getAllEntries: Returning resultMap, size=" + resultMap.size());
+
+        return resultMap;
+    }
+
+
+    /**
+     * getAllEntries gets all entries for a persistence unit.
+     * 
+     * @param persistenceUnit the persistence unit
+     * @param properties the properties
+     * @param className the class name
+     * @param keySet the keys
+     * @return the map of entries
+     */
+
+    public Map<Object, Object> getAllEntries(String persistenceUnit, Properties properties, String className,
+            Set<Object> keySet) {
+        logger.debug("getAllEntries: Entering, persistenceUnit=" + persistenceUnit + ",\n properties= " + properties
+                + ",\n className=" + className + ",\n keySet= " + keySet);
+        EntityManagerFactory theEmf = Persistence.createEntityManagerFactory(persistenceUnit, properties);
+        EntityManager em = theEmf.createEntityManager();
+        HashMap<Object, Object> resultMap = new HashMap<>();
+        try {
+            Class<?> clazz = Class.forName(className);
+            for (Object key : keySet) {
+                Object entry = em.find(clazz, key);
+                resultMap.put(key, entry);
+            }
+        } catch (Exception e) {
+            String msg = "getAllEntries encountered exception: " + e;
+            logger.error(msg, e);
+        }
+        em.close();
+        theEmf.close();
+        logger.debug("getAllEntries: Exit, resultMap, size=" + resultMap.size());
+        return resultMap;
+    }
+
+    /**
+     * getIntegrityAuditEntities() Get all the IntegrityAuditEntities for a particular persistence
+     * unit and node type.
+     * 
+     * @param persistenceUnit the persistence unit
+     * @param nodeType the node type
+     * @return the list of IntegrityAuditEntity
+     * @throws DbDaoTransactionException if an error occurs
+     */
+    @SuppressWarnings("unchecked")
+    public List<IntegrityAuditEntity> getIntegrityAuditEntities(String persistenceUnit, String nodeType)
+            throws DbDaoTransactionException {
+        logger.debug("getIntegrityAuditEntities: Entering, persistenceUnit=" + persistenceUnit + ",\n nodeType= "
+                + nodeType);
+        try {
+            EntityManager em = emf.createEntityManager();
+            // Start a transaction
+            EntityTransaction et = em.getTransaction();
+
+            et.begin();
+
+            // if IntegrityAuditEntity entry exists for resourceName and PU, update it. If not
+            // found, create a new entry
+            Query iaequery = em
+                    .createQuery("Select i from IntegrityAuditEntity i where i.persistenceUnit=:pu and i.nodeType=:nt");
+            iaequery.setParameter("pu", persistenceUnit);
+            iaequery.setParameter("nt", nodeType);
+
+            List<IntegrityAuditEntity> iaeList = iaequery.getResultList();
+
+            // commit transaction
+            et.commit();
+            em.close();
+            logger.debug("getIntegrityAuditEntities: Exit, iaeList=" + iaeList);
+            return iaeList;
+        } catch (Exception e) {
+            String msg = "DbDAO: " + "getIntegrityAuditEntities() " + "ecountered a problem in execution: ";
+            logger.error(msg, e);
+            throw new DbDaoTransactionException(e);
+        }
+
+    }
+
+    /**
+     * getMyIntegrityAuditEntity() gets my IntegrityAuditEntity.
+     * 
+     * @return the IntegrityAuditEntity
+     * @throws DbDaoTransactionException if an error occurs
+     */
+    public IntegrityAuditEntity getMyIntegrityAuditEntity() throws DbDaoTransactionException {
+        try {
+            EntityManager em = emf.createEntityManager();
+
+            // Start a transaction
+            EntityTransaction et = em.getTransaction();
+
+            et.begin();
+
+            // if IntegrityAuditEntity entry exists for resourceName and PU, retrieve it
+            Query iaequery = em.createQuery(
+                    "Select i from IntegrityAuditEntity i where i.resourceName=:rn and i.persistenceUnit=:pu");
+            iaequery.setParameter("rn", this.resourceName);
+            iaequery.setParameter("pu", this.persistenceUnit);
+
+            @SuppressWarnings("rawtypes")
+            List iaeList = iaequery.getResultList();
+            IntegrityAuditEntity iae = null;
+
+            if (!iaeList.isEmpty()) {
+                // ignores multiple results
+                iae = (IntegrityAuditEntity) iaeList.get(0);
+                // refresh the object from DB in case cached data was returned
+                em.refresh(iae);
+                logger.info("Resource: " + this.resourceName + " with PersistenceUnit: " + this.persistenceUnit
+                        + " exists");
+            } else {
+                // If it does not exist, log an error
+                logger.error("Attempting to setLastUpdated" + " on an entry that does not exist:" + " resource "
+                        + this.resourceName + " with PersistenceUnit: " + this.persistenceUnit);
+            }
+
+            // close the transaction
+            et.commit();
+            // close the EntityManager
+            em.close();
+
+            return iae;
+        } catch (Exception e) {
+            String msg = "DbDAO: " + "setLastUpdated() " + "ecountered a problem in execution: ";
+            logger.error(msg + e);
+            throw new DbDaoTransactionException(e);
+        }
+    }
+
+
+    /**
+     * getIntegrityAuditEntity() gets the IntegrityAuditEntity with a particular ID.
+     * 
+     * @param id the ID
+     * @return the IntegrityAuditEntity
+     * @throws DbDaoTransactionException if an error occurs
+     */
+    public IntegrityAuditEntity getIntegrityAuditEntity(long id) throws DbDaoTransactionException {
+        try {
+            EntityManager em = emf.createEntityManager();
+
+            // Start a transaction
+            EntityTransaction et = em.getTransaction();
+
+            et.begin();
+
+            IntegrityAuditEntity iae = em.find(IntegrityAuditEntity.class, id);
+
+            et.commit();
+            em.close();
+
+            return iae;
+        } catch (Exception e) {
+            String msg = "DbDAO: " + "getIntegrityAuditEntity() " + "ecountered a problem in execution: ";
+            logger.error(msg + e);
+            throw new DbDaoTransactionException(e);
+        }
+    }
+
+    /**
+     * getPersistenceClassNames() gets all the persistence class names.
+     * 
+     * @return the persistence class names
+     */
+    public Set<String> getPersistenceClassNames() {
+        logger.debug("DbDAO: getPersistenceClassNames() entry");
+        HashSet<String> returnList = new HashSet<>();
+        final Metamodel mm = emf.getMetamodel();
+        logger.debug("\n" + persistenceUnit + " persistence unit classes:");
+        for (final ManagedType<?> managedType : mm.getManagedTypes()) {
+            Class<?> clazz = managedType.getJavaType();
+            logger.debug("    " + clazz.getSimpleName());
+            returnList.add(clazz.getName()); // the full class name needed to make a query using jpa
+        }
+        logger.debug("DbDAO: getPersistenceClassNames() exit");
+        return returnList;
+    }
+
+    /**
+     * Register the IntegrityAudit instance.
+     * 
+     * @param altDbUrl alternate DB URL to be placed into the record, or {@code null} to use the
+     *        default
+     */
+    private void register(String altDbUrl) throws DbDaoTransactionException {
+        try {
+            EntityManager em = emf.createEntityManager();
+
+            // Start a transaction
+            EntityTransaction et = em.getTransaction();
+
+            et.begin();
+
+            // if IntegrityAuditEntity entry exists for resourceName and PU, update it. If not
+            // found, create a new entry
+            Query iaequery = em.createQuery(
+                    "Select i from IntegrityAuditEntity i where i.resourceName=:rn and i.persistenceUnit=:pu");
+            iaequery.setParameter("rn", this.resourceName);
+            iaequery.setParameter("pu", this.persistenceUnit);
+
+            @SuppressWarnings("rawtypes")
+            List iaeList = iaequery.getResultList();
+            IntegrityAuditEntity iae;
+
+            // If it already exists, we just want to update the properties and lastUpdated date
+            if (!iaeList.isEmpty()) {
+                // ignores multiple results
+                iae = (IntegrityAuditEntity) iaeList.get(0);
+                // refresh the object from DB in case cached data was returned
+                em.refresh(iae);
+                logger.info("Resource: " + this.resourceName + " with PersistenceUnit: " + this.persistenceUnit
+                        + " exists and entry be updated");
+            } else {
+                // If it does not exist, we also must add teh resourceName, persistenceUnit and
+                // designated values
+                logger.info("Adding resource " + resourceName + " with PersistenceUnit: " + this.persistenceUnit
+                        + " to IntegrityAuditEntity table");
+                iae = new IntegrityAuditEntity();
+                iae.setResourceName(this.resourceName);
+                iae.setPersistenceUnit(this.persistenceUnit);
+                iae.setDesignated(false);
+            }
+            // update/set properties in entry
+            iae.setSite(this.siteName);
+            iae.setNodeType(this.nodeType);
+            iae.setJdbcDriver(this.dbDriver);
+            iae.setJdbcPassword(properties.getProperty(IntegrityAuditProperties.DB_PWD).trim());
+            iae.setJdbcUrl(altDbUrl == null ? this.dbUrl : altDbUrl);
+            iae.setJdbcUser(dbUser);
+
+            em.persist(iae);
+            // flush to the DB
+            em.flush();
+
+            // commit transaction
+            et.commit();
+            em.close();
+        } catch (Exception e) {
+            String msg = "DbDAO: " + "register() " + "encountered a problem in execution: ";
+            logger.error(msg + e);
+            throw new DbDaoTransactionException(e);
+        }
+
+    }
+
+    public void setDesignated(boolean designated) throws DbDaoTransactionException {
+        setDesignated(this.resourceName, this.persistenceUnit, designated);
+    }
+
+    /**
+     * Set designated.
+     * 
+     * @param resourceName the resource name
+     * @param persistenceUnit the persistence unit
+     * @param desig true if is designated
+     * @throws DbDaoTransactionException if an error occurs
+     */
+    public void setDesignated(String resourceName, String persistenceUnit, boolean desig)
+            throws DbDaoTransactionException {
+        logger.debug("setDesignated: enter, resourceName: " + resourceName + ", persistenceUnit: " + persistenceUnit
+                + ", designated: " + desig);
+        try {
+
+            EntityManager em = emf.createEntityManager();
+
+            // Start a transaction
+            EntityTransaction et = em.getTransaction();
+
+            et.begin();
+
+            // if IntegrityAuditEntity entry exists for resourceName and PU, update it. If not
+            // found, create a new entry
+            Query iaequery = em.createQuery(
+                    "Select i from IntegrityAuditEntity i where i.resourceName=:rn and i.persistenceUnit=:pu");
+            iaequery.setParameter("rn", resourceName);
+            iaequery.setParameter("pu", persistenceUnit);
+
+            @SuppressWarnings("rawtypes")
+            List iaeList = iaequery.getResultList();
+            IntegrityAuditEntity iae;
+
+            if (!iaeList.isEmpty()) {
+                // ignores multiple results
+                iae = (IntegrityAuditEntity) iaeList.get(0);
+                // refresh the object from DB in case cached data was returned
+                em.refresh(iae);
+                logger.info("Resource: " + resourceName + " with PersistenceUnit: " + persistenceUnit
+                        + " exists and designated be updated");
+                iae.setDesignated(desig);
+
+                em.persist(iae);
+                // flush to the DB
+                em.flush();
+            } else {
+                // If it does not exist, log an error
+                logger.error("Attempting to setDesignated(" + desig + ") on an entry that does not exist:"
+                        + " resource " + resourceName + " with PersistenceUnit: " + persistenceUnit);
+            }
+
+            // close the transaction
+            et.commit();
+            // close the EntityManager
+            em.close();
+        } catch (Exception e) {
+            String msg = "DbDAO: " + "setDesignated() " + "ecountered a problem in execution: ";
+            logger.error(msg + e);
+            throw new DbDaoTransactionException(e);
+        }
+
+    }
+
+    /**
+     * Set last updated.
+     * 
+     * @throws DbDaoTransactionException if an error occurs
+     */
+    public void setLastUpdated() throws DbDaoTransactionException {
+        logger.debug("setLastUpdated: enter, resourceName: " + this.resourceName + ", persistenceUnit: "
+                + this.persistenceUnit);
+        try {
+            EntityManager em = emf.createEntityManager();
+
+            // Start a transaction
+            EntityTransaction et = em.getTransaction();
+
+            et.begin();
+
+            // if IntegrityAuditEntity entry exists for resourceName and PU, update it. If not
+            // found, create a new entry
+            Query iaequery = em.createQuery(
+                    "Select i from IntegrityAuditEntity i where i.resourceName=:rn and i.persistenceUnit=:pu");
+            iaequery.setParameter("rn", this.resourceName);
+            iaequery.setParameter("pu", this.persistenceUnit);
+
+            @SuppressWarnings("rawtypes")
+            List iaeList = iaequery.getResultList();
+            IntegrityAuditEntity iae;
+
+            if (!iaeList.isEmpty()) {
+                // ignores multiple results
+                iae = (IntegrityAuditEntity) iaeList.get(0);
+                // refresh the object from DB in case cached data was returned
+                em.refresh(iae);
+                logger.info("Resource: " + this.resourceName + " with PersistenceUnit: " + this.persistenceUnit
+                        + " exists and lastUpdated be updated");
+                iae.setLastUpdated(new Date());
+
+                em.persist(iae);
+                // flush to the DB
+                em.flush();
+            } else {
+                // If it does not exist, log an error
+                logger.error("Attempting to setLastUpdated" + " on an entry that does not exist:" + " resource "
+                        + this.resourceName + " with PersistenceUnit: " + this.persistenceUnit);
+            }
+
+            // close the transaction
+            et.commit();
+            // close the EntityManager
+            em.close();
+        } catch (Exception e) {
+            String msg = "DbDAO: " + "setLastUpdated() " + "ecountered a problem in execution: ";
+            logger.error(msg + e);
+            throw new DbDaoTransactionException(e);
+        }
+
+    }
+
+    /**
+     * Normally this method should only be used in a JUnit test environment. Manually deletes all
+     * PDP records in droolspdpentity table.
+     */
+    public int deleteAllIntegrityAuditEntities() throws DbDaoTransactionException {
+
+        try {
+
+            if (!IntegrityAudit.isUnitTesting()) {
+                String msg = "DbDAO: " + "deleteAllIntegrityAuditEntities() "
+                        + "should only be invoked during JUnit testing";
+                logger.error(msg);
+                throw new DbDaoTransactionException(msg);
+            }
+
+            EntityManager em = emf.createEntityManager();
+            // Start a transaction
+            EntityTransaction et = em.getTransaction();
+
+            et.begin();
+
+            // if IntegrityAuditEntity entry exists for resourceName and PU, update it. If not
+            // found, create a new entry
+            Query iaequery = em.createQuery("Delete from IntegrityAuditEntity");
+
+            int returnCode = iaequery.executeUpdate();
+
+            // commit transaction
+            et.commit();
+            em.close();
+
+            logger.info("deleteAllIntegrityAuditEntities: returnCode=" + returnCode);
+
+            return returnCode;
+
+        } catch (Exception e) {
+            String msg = "DbDAO: " + "deleteAllIntegrityAuditEntities() " + "encountered a problem in execution: ";
+            logger.error(msg + e);
+            throw new DbDaoTransactionException(e);
+        }
+
+    }
+
+    /**
+     * Changes designation to specified resourceName
+     * 
+     * <p>static lock object in conjunction with synchronized keyword ensures that designation
+     * changes are done serially within a resource. I.e. static lock ensures that multiple
+     * instantiations of DbDAO don't interleave changeDesignated() invocations and potentially
+     * produce simultaneous designations.
+     * 
+     * <p>Optimistic locking (the default, versus pessimistic) is sufficient to avoid simultaneous
+     * designations from interleaved changeDesignated() invocations from different resources
+     * (entities), because it prevents "dirty" and "non-repeatable" reads.
+     * 
+     * <p>See http://www.objectdb.com/api/java/jpa/LockModeType
+     * 
+     * <p>and
+     * 
+     * <p>http://stackoverflow.com/questions/2120248/how-to-synchronize-a-static-
+     * variable-among-threads-running-different-instances-o
+     */
+    public void changeDesignated(String resourceName, String persistenceUnit, String nodeType)
+            throws DbDaoTransactionException {
+
+        if (logger.isDebugEnabled()) {
+            logger.debug("changeDesignated: Entering, resourceName=" + resourceName + ", persistenceUnit="
+                    + persistenceUnit + ", nodeType=" + nodeType);
+        }
+
+        long startTime = System.currentTimeMillis();
+
+        synchronized (lock) {
+
+            EntityManager em = null;
+            try {
+
+                em = emf.createEntityManager();
+                em.getTransaction().begin();
+
+                /*
+                 * Define query
+                 */
+                Query query = em.createQuery(
+                        "Select i from IntegrityAuditEntity i where i.persistenceUnit=:pu and i.nodeType=:nt");
+                query.setParameter("pu", persistenceUnit);
+                query.setParameter("nt", nodeType);
+
+                /*
+                 * Execute query using pessimistic write lock. This ensures that if anyone else is
+                 * currently reading the records we'll throw a LockTimeoutException.
+                 */
+                @SuppressWarnings("unchecked")
+                List<IntegrityAuditEntity> integrityAuditEntityList = query.getResultList();
+                for (Object o : integrityAuditEntityList) {
+                    if (o instanceof IntegrityAuditEntity) {
+                        IntegrityAuditEntity integrityAuditEntity = (IntegrityAuditEntity) o;
+                        if (integrityAuditEntity.getResourceName().equals(resourceName)) {
+                            if (logger.isDebugEnabled()) {
+                                logger.debug("changeDesignated: Designating resourceName="
+                                        + integrityAuditEntity.getResourceName());
+                            }
+                            integrityAuditEntity.setDesignated(true);
+                        } else {
+                            if (logger.isDebugEnabled()) {
+                                logger.debug("changeDesignated: Removing designation from resourceName="
+                                        + integrityAuditEntity.getResourceName());
+                            }
+                            integrityAuditEntity.setDesignated(false);
+                        }
+                    }
+                }
+
+                if (logger.isDebugEnabled()) {
+                    logger.debug("changeDesignated: Committing designation to resourceName=" + resourceName);
+                }
+                em.getTransaction().commit();
+
+                /*
+                 * If we get a LockTimeoutException, no harm done really. We'll probably be
+                 * successful on the next attempt. The odds of another DbDAO instance on this entity
+                 * or another entity attempting a simultaneous IntegrityAuditEntity table
+                 * read/update are pretty slim (we're only in this method for two or three
+                 * milliseconds)
+                 */
+            } catch (LockTimeoutException e) {
+                if (em != null) {
+                    em.getTransaction().rollback();
+
+                    String msg = "DbDAO: " + "changeDesignated() " + "caught LockTimeoutException, message="
+                            + e.getMessage();
+                    logger.error(msg + e);
+                    throw new DbDaoTransactionException(msg, e);
+                } else {
+                    String msg = "DbDAO: " + "changeDesignated() " + "caught LockTimeoutException, message="
+                            + e.getMessage() + ". Error rolling back transaction.";
+                    logger.error(msg + e);
+                    throw new DbDaoTransactionException(msg, e);
+                }
+            } catch (Exception e) {
+                if (em != null) {
+                    em.getTransaction().rollback();
+
+                    String msg = "DbDAO: " + "changeDesignated() " + "caught Exception, message=" + e.getMessage();
+                    logger.error(msg + e);
+                    throw new DbDaoTransactionException(msg, e);
+                } else {
+                    String msg = "DbDAO: " + "changeDesignated() " + "caught LockTimeoutException, message="
+                            + e.getMessage() + ". Error rolling back transaction.";
+                    logger.error(msg + e);
+                    throw new DbDaoTransactionException(msg, e);
+                }
+            }
+
+        } // end synchronized block
+
+        if (logger.isDebugEnabled()) {
+            logger.debug("changeDesignated: Exiting; time expended=" + (System.currentTimeMillis() - startTime) + "ms");
+        }
+
+    }
 
 
 }
index 7271627..dc1c6f1 100644 (file)
 package org.onap.policy.common.ia;
 
 public class DbDaoTransactionException extends IntegrityAuditException {
-       private static final long serialVersionUID = 1L;
-       public DbDaoTransactionException() {
-               super();
-       }
-       public DbDaoTransactionException(String message) {
-               super(message);
-       }
+    private static final long serialVersionUID = 1L;
 
-       public DbDaoTransactionException(Throwable cause) {
-               super(cause);
-       }
-       public DbDaoTransactionException(String message, Throwable cause) {
-               super(message, cause);
-       }
+    public DbDaoTransactionException() {
+        super();
+    }
+
+    public DbDaoTransactionException(String message) {
+        super(message);
+    }
+
+    public DbDaoTransactionException(Throwable cause) {
+        super(cause);
+    }
+
+    public DbDaoTransactionException(String message, Throwable cause) {
+        super(message, cause);
+    }
 }
index cab0861..9abdbe5 100644 (file)
@@ -26,275 +26,277 @@ import java.util.concurrent.CountDownLatch;
 
 import org.onap.policy.common.ia.IntegrityAuditProperties.NodeTypeEnum;
 import org.onap.policy.common.logging.flexlogger.FlexLogger;
-import org.onap.policy.common.logging.flexlogger.Logger; 
+import org.onap.policy.common.logging.flexlogger.Logger;
 
 /**
- * class IntegrityAudit
- * Audits all persisted entities for all resource clusters for all sites and logs any anomalies.
+ * class IntegrityAudit Audits all persisted entities for all resource clusters for all sites and
+ * logs any anomalies.
  */
 public class IntegrityAudit {
-       
-       private static final Logger logger = FlexLogger.getLogger(IntegrityAudit.class);
-
-       private static boolean isUnitTesting;
-       private boolean isThreadInitialized = false; 
-       
-       AuditThread auditThread = null;
-               
-       private String persistenceUnit;
-       private Properties properties;
-       private String resourceName;
-       
-       
-       /*
-        * This is the audit period in milliseconds. For example, if it had a value of 3600000, the audit
-        * can only run once per hour.  If it has a value of 6000, it can run once per minute.
-        * 
-        * Values: 
-        *    integrityAuditPeriodMillis < 0 (negative number) indicates the audit is off
-        *    integrityAuditPeriodMillis == 0 indicates the audit is to run continuously
-        *    integrityAuditPeriodMillis > 0 indicates the audit is to run at most once during the indicated period
-        * 
-        */
-       private int integrityAuditPeriodMillis;
-       
-       /**
-        * IntegrityAudit constructor
-        * @param resourceName
-        * @param persistenceUnit
-        * @param properties
-        * @throws IntegrityAuditException
-        */
-       public IntegrityAudit(String resourceName, String persistenceUnit, Properties properties) throws IntegrityAuditException {
-               
-               logger.info("Constructor: Entering and checking for nulls");
-               StringBuilder parmList = new StringBuilder();
-               if (parmsAreBad(resourceName, persistenceUnit, properties, parmList)) {
-                       logger.error("Constructor: Parms contain nulls; cannot run audit for resourceName="
-                                       + resourceName + ", persistenceUnit=" + persistenceUnit
-                                       + ", bad parameters: " + parmList);
-                       throw new IntegrityAuditException(
-                                       "Constructor: Parms contain nulls; cannot run audit for resourceName="
-                                                       + resourceName + ", persistenceUnit="
-                                                       + persistenceUnit
-                                                       + ", bad parameters: " + parmList);
-               }
-               
-               this.persistenceUnit = persistenceUnit;
-               this.properties = properties;
-               this.resourceName = resourceName;
-               
-               if(properties.getProperty(IntegrityAuditProperties.AUDIT_PERIOD_SECONDS) != null){ //It is allowed to be null
-                       this.integrityAuditPeriodMillis= 1000 * Integer.parseInt(properties.getProperty(IntegrityAuditProperties.AUDIT_PERIOD_SECONDS).trim());
-               } else if(properties.getProperty(IntegrityAuditProperties.AUDIT_PERIOD_MILLISECONDS) != null){ //It is allowed to be null
-                               this.integrityAuditPeriodMillis= Integer.parseInt(properties.getProperty(IntegrityAuditProperties.AUDIT_PERIOD_MILLISECONDS).trim());
-               } else{
-                       //If it is null, set it to the default value
-                       this.integrityAuditPeriodMillis = 1000 * IntegrityAuditProperties.DEFAULT_AUDIT_PERIOD_SECONDS;
-               }
-               logger.info("Constructor: Exiting");
-               
-       }
-       
-       /**
-        * Used during JUnit testing by AuditPeriodTest.java
-        */
-       public int getIntegrityAuditPeriodSeconds() {
-               return (integrityAuditPeriodMillis / 1000);
-       }
-
-       /**
-        * Determine if the nodeType conforms to the required node types
-        */
-       public static boolean isNodeTypeEnum(String nt) {
-               for (NodeTypeEnum n : NodeTypeEnum.values()) {
-                       if (n.toString().equals(nt)) {
-                               return true;
-                       }
-               }
-               return false;
-       }
-       
-
-       /**
-        * Makes sure we don't try to run the audit with bad parameters.
-        */
-       public static boolean parmsAreBad(String resourceName, String persistenceUnit,
-                       Properties properties, StringBuilder badparams) {
-
-               boolean parmsAreBad = false;
-               
-               if(resourceName == null || resourceName.isEmpty()){
-                       badparams.append("resourceName ");
-                       parmsAreBad = true;
-               }
-               
-               if(persistenceUnit == null || persistenceUnit.isEmpty()){
-                       badparams.append("persistenceUnit ");
-                       parmsAreBad = true;
-               }
-               
-               if(properties == null || properties.isEmpty()){
-                       badparams.append("properties ");
-                       parmsAreBad = true;
-               }
-               else{
-                       String dbDriver = properties.getProperty(IntegrityAuditProperties.DB_DRIVER);
-                       if(dbDriver == null || dbDriver.isEmpty()){
-                               badparams.append("dbDriver ");
-                               parmsAreBad = true;
-                       }
-       
-                       String dbUrl = properties.getProperty(IntegrityAuditProperties.DB_URL);
-                       if(dbUrl == null || dbUrl.isEmpty()){
-                               badparams.append("dbUrl ");
-                               parmsAreBad = true;
-                       }
-                       
-                       String dbUser = properties.getProperty(IntegrityAuditProperties.DB_USER);
-                       if(dbUser == null || dbUser.isEmpty()){
-                               badparams.append("dbUser ");
-                               parmsAreBad = true;
-                       }
-                       
-                       String dbPwd = properties.getProperty(IntegrityAuditProperties.DB_PWD);
-                       if(dbPwd == null){ //may be empty
-                               badparams.append("dbPwd ");
-                               parmsAreBad = true;
-                       }
-                       
-                       String siteName = properties.getProperty(IntegrityAuditProperties.SITE_NAME);
-                       if(siteName == null || siteName.isEmpty()){
-                               badparams.append("siteName ");
-                               parmsAreBad = true;
-                       }
-                       
-                       String nodeType = properties.getProperty(IntegrityAuditProperties.NODE_TYPE);
-                       if(nodeType == null || nodeType.isEmpty()){
-                               badparams.append("nodeType ");
-                               parmsAreBad = true;
-                       } else {
-                               nodeType = nodeType.trim();
-                               if (!isNodeTypeEnum(nodeType)) {
-                                       String nodetypes = "nodeType must be one of[";
-                                       for (NodeTypeEnum n : NodeTypeEnum.values()) {
-                                               nodetypes = nodetypes.concat(n.toString() + " ");
-                                       }
-                                       badparams.append(nodetypes + "] ");
-                                       parmsAreBad = true;
-                               }
-                       }
-                       if(properties.getProperty(IntegrityAuditProperties.AUDIT_PERIOD_SECONDS) != null){ //It is allowed to be null
-                               try{
-                                       Integer.parseInt(properties.getProperty(IntegrityAuditProperties.AUDIT_PERIOD_SECONDS).trim());
-                               }catch(NumberFormatException nfe){
-                                       badparams.append(", auditPeriodSeconds=" 
-                                                       + properties.getProperty(IntegrityAuditProperties.AUDIT_PERIOD_SECONDS).trim());
-                                       parmsAreBad = true;
-                               }
-                       }
-                       else if(properties.getProperty(IntegrityAuditProperties.AUDIT_PERIOD_MILLISECONDS) != null){ //It is allowed to be null
-                               try{
-                                       Integer.parseInt(properties.getProperty(IntegrityAuditProperties.AUDIT_PERIOD_MILLISECONDS).trim());
-                               }catch(NumberFormatException nfe){
-                                       badparams.append(", auditPeriodMilliSeconds=" 
-                                                       + properties.getProperty(IntegrityAuditProperties.AUDIT_PERIOD_MILLISECONDS).trim());
-                                       parmsAreBad = true;
-                               }
-                       }
-               } // End else
-               logger.debug("parmsAreBad: exit:" 
-                               + "\nresourceName: " + resourceName
-                               + "\npersistenceUnit: " + persistenceUnit
-                               + "\nproperties: " + properties);
-               
-               return parmsAreBad;
-       }       
-       /**
-        * Starts the audit thread
-        * @throws IntegrityAuditException
-        */
-       public void startAuditThread() throws IntegrityAuditException {
-               startAuditThread(null);
-       }
-       /**
-        * Starts the audit thread
-        * @param queue 
-        * @return {@code true} if the thread was started, {@code false} otherwise
-        * @throws IntegrityAuditException
-        */
-       protected boolean startAuditThread(BlockingQueue<CountDownLatch> queue) throws IntegrityAuditException {
-
-               logger.info("startAuditThread: Entering");
-               
-               boolean success = false;
-               
-               if (integrityAuditPeriodMillis >= 0) {
-                       this.auditThread = new AuditThread(this.resourceName,
-                                       this.persistenceUnit, this.properties,
-                                       integrityAuditPeriodMillis, this, queue);
-                       logger.info("startAuditThread: Audit started and will run every "
-                                       + integrityAuditPeriodMillis/1000 + " seconds");
-                       this.auditThread.start();
-                       success = true;
-               } else {
-                       logger.info("startAuditThread: Suppressing integrity audit, integrityAuditPeriodSeconds="
-                                       + integrityAuditPeriodMillis/1000);
-               }
-
-               logger.info("startAuditThread: Exiting");
-               
-               return success;
-       }
-       /**
-        * Stops the audit thread
-        */
-       public void stopAuditThread() {
-
-               logger.info("stopAuditThread: Entering");
-               
-               if (this.auditThread != null) {
-                       this.auditThread.interrupt();
-               } else {
-                       logger.info("stopAuditThread: auditThread never instantiated; no need to interrupt");
-               }
-               
-               logger.info("stopAuditThread: Exiting");
-       }
-
-       public boolean isThreadInitialized() {
-               return isThreadInitialized;
-       }
-
-       public void setThreadInitialized(boolean isThreadInitialized) {
-               logger.info("setThreadInitialized: Setting isThreadInitialized=" + isThreadInitialized);
-               this.isThreadInitialized = isThreadInitialized;
-       }
-
-       public static boolean isUnitTesting() {
-               return isUnitTesting;
-       }
-
-       public static void setUnitTesting(boolean isUnitTesting) {
-               IntegrityAudit.isUnitTesting = isUnitTesting;
-       }
-
-       /**
-        * Waits a bit for the AuditThread to complete. Used by JUnit tests.
-        * 
-        * @param twaitms
-        *            wait time, in milliseconds
-        * @return {@code true} if the thread stopped within the given time,
-        *         {@code false} otherwise
-        * @throws InterruptedException
-        */
-       protected boolean joinAuditThread(long twaitms) throws InterruptedException {
-               if(this.auditThread == null) {
-                       return true;
-                       
-               } else {
-                       this.auditThread.join(twaitms);
-                       return ! this.auditThread.isAlive();
-               }
-       }
+
+    private static final Logger logger = FlexLogger.getLogger(IntegrityAudit.class);
+
+    private static boolean isUnitTesting;
+    private boolean isThreadInitialized = false;
+
+    AuditThread auditThread = null;
+
+    private String persistenceUnit;
+    private Properties properties;
+    private String resourceName;
+
+
+    /*
+     * This is the audit period in milliseconds. For example, if it had a value of 3600000, the
+     * audit can only run once per hour. If it has a value of 6000, it can run once per minute.
+     * 
+     * Values: integrityAuditPeriodMillis < 0 (negative number) indicates the audit is off
+     * integrityAuditPeriodMillis == 0 indicates the audit is to run continuously
+     * integrityAuditPeriodMillis > 0 indicates the audit is to run at most once during the
+     * indicated period
+     * 
+     */
+    private int integrityAuditPeriodMillis;
+
+    /**
+     * IntegrityAudit constructor.
+     * 
+     * @param resourceName the resource name
+     * @param persistenceUnit the persistence unit
+     * @param properties the properties
+     * @throws IntegrityAuditException if an error occurs
+     */
+    public IntegrityAudit(String resourceName, String persistenceUnit, Properties properties)
+            throws IntegrityAuditException {
+
+        logger.info("Constructor: Entering and checking for nulls");
+        StringBuilder parmList = new StringBuilder();
+        if (parmsAreBad(resourceName, persistenceUnit, properties, parmList)) {
+            logger.error("Constructor: Parms contain nulls; cannot run audit for resourceName=" + resourceName
+                    + ", persistenceUnit=" + persistenceUnit + ", bad parameters: " + parmList);
+            throw new IntegrityAuditException("Constructor: Parms contain nulls; cannot run audit for resourceName="
+                    + resourceName + ", persistenceUnit=" + persistenceUnit + ", bad parameters: " + parmList);
+        }
+
+        this.persistenceUnit = persistenceUnit;
+        this.properties = properties;
+        this.resourceName = resourceName;
+
+        // IntegrityAuditProperties.AUDIT_PERIOD_SECONDS and
+        // IntegrityAuditProperties.AUDIT_PERIOD_MILLISECONDS are allowed to be null
+        if (properties.getProperty(IntegrityAuditProperties.AUDIT_PERIOD_SECONDS) != null) {
+            this.integrityAuditPeriodMillis = 1000
+                    * Integer.parseInt(properties.getProperty(IntegrityAuditProperties.AUDIT_PERIOD_SECONDS).trim());
+        } else if (properties.getProperty(IntegrityAuditProperties.AUDIT_PERIOD_MILLISECONDS) != null) {
+            this.integrityAuditPeriodMillis =
+                    Integer.parseInt(properties.getProperty(IntegrityAuditProperties.AUDIT_PERIOD_MILLISECONDS).trim());
+        } else {
+            // If it is null, set it to the default value
+            this.integrityAuditPeriodMillis = 1000 * IntegrityAuditProperties.DEFAULT_AUDIT_PERIOD_SECONDS;
+        }
+        logger.info("Constructor: Exiting");
+
+    }
+
+    /**
+     * Used during JUnit testing by AuditPeriodTest.java
+     */
+    public int getIntegrityAuditPeriodSeconds() {
+        return (integrityAuditPeriodMillis / 1000);
+    }
+
+    /**
+     * Determine if the nodeType conforms to the required node types.
+     */
+    public static boolean isNodeTypeEnum(String nt) {
+        for (NodeTypeEnum n : NodeTypeEnum.values()) {
+            if (n.toString().equals(nt)) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+
+    /**
+     * Makes sure we don't try to run the audit with bad parameters.
+     */
+    public static boolean parmsAreBad(String resourceName, String persistenceUnit, Properties properties,
+            StringBuilder badparams) {
+
+        boolean parmsAreBad = false;
+
+        if (resourceName == null || resourceName.isEmpty()) {
+            badparams.append("resourceName ");
+            parmsAreBad = true;
+        }
+
+        if (persistenceUnit == null || persistenceUnit.isEmpty()) {
+            badparams.append("persistenceUnit ");
+            parmsAreBad = true;
+        }
+
+        if (properties == null || properties.isEmpty()) {
+            badparams.append("properties ");
+            parmsAreBad = true;
+        } else {
+            String dbDriver = properties.getProperty(IntegrityAuditProperties.DB_DRIVER);
+            if (dbDriver == null || dbDriver.isEmpty()) {
+                badparams.append("dbDriver ");
+                parmsAreBad = true;
+            }
+
+            String dbUrl = properties.getProperty(IntegrityAuditProperties.DB_URL);
+            if (dbUrl == null || dbUrl.isEmpty()) {
+                badparams.append("dbUrl ");
+                parmsAreBad = true;
+            }
+
+            String dbUser = properties.getProperty(IntegrityAuditProperties.DB_USER);
+            if (dbUser == null || dbUser.isEmpty()) {
+                badparams.append("dbUser ");
+                parmsAreBad = true;
+            }
+
+            String dbPwd = properties.getProperty(IntegrityAuditProperties.DB_PWD);
+            if (dbPwd == null) { // may be empty
+                badparams.append("dbPwd ");
+                parmsAreBad = true;
+            }
+
+            String siteName = properties.getProperty(IntegrityAuditProperties.SITE_NAME);
+            if (siteName == null || siteName.isEmpty()) {
+                badparams.append("siteName ");
+                parmsAreBad = true;
+            }
+
+            String nodeType = properties.getProperty(IntegrityAuditProperties.NODE_TYPE);
+            if (nodeType == null || nodeType.isEmpty()) {
+                badparams.append("nodeType ");
+                parmsAreBad = true;
+            } else {
+                nodeType = nodeType.trim();
+                if (!isNodeTypeEnum(nodeType)) {
+                    String nodetypes = "nodeType must be one of[";
+                    for (NodeTypeEnum n : NodeTypeEnum.values()) {
+                        nodetypes = nodetypes.concat(n.toString() + " ");
+                    }
+                    badparams.append(nodetypes + "] ");
+                    parmsAreBad = true;
+                }
+            }
+            // IntegrityAuditProperties.AUDIT_PERIOD_SECONDS and
+            // IntegrityAuditProperties.AUDIT_PERIOD_MILLISECONDS are allowed to be null
+            if (properties.getProperty(IntegrityAuditProperties.AUDIT_PERIOD_SECONDS) != null) {
+                try {
+                    Integer.parseInt(properties.getProperty(IntegrityAuditProperties.AUDIT_PERIOD_SECONDS).trim());
+                } catch (NumberFormatException nfe) {
+                    badparams.append(", auditPeriodSeconds="
+                            + properties.getProperty(IntegrityAuditProperties.AUDIT_PERIOD_SECONDS).trim());
+                    parmsAreBad = true;
+                }
+            } else if (properties.getProperty(IntegrityAuditProperties.AUDIT_PERIOD_MILLISECONDS) != null) {
+                try {
+                    Integer.parseInt(properties.getProperty(IntegrityAuditProperties.AUDIT_PERIOD_MILLISECONDS).trim());
+                } catch (NumberFormatException nfe) {
+                    badparams.append(", auditPeriodMilliSeconds="
+                            + properties.getProperty(IntegrityAuditProperties.AUDIT_PERIOD_MILLISECONDS).trim());
+                    parmsAreBad = true;
+                }
+            }
+        } // End else
+        logger.debug("parmsAreBad: exit:" + "\nresourceName: " + resourceName + "\npersistenceUnit: " + persistenceUnit
+                + "\nproperties: " + properties);
+
+        return parmsAreBad;
+    }
+
+    /**
+     * Starts the audit thread.
+     * 
+     * @throws IntegrityAuditException if an error occurs
+     */
+    public void startAuditThread() throws IntegrityAuditException {
+        startAuditThread(null);
+    }
+
+    /**
+     * Starts the audit thread.
+     * 
+     * @param queue the queue
+     * @return {@code true} if the thread was started, {@code false} otherwise
+     * @throws IntegrityAuditException if an error occurs
+     */
+    protected boolean startAuditThread(BlockingQueue<CountDownLatch> queue) throws IntegrityAuditException {
+
+        logger.info("startAuditThread: Entering");
+
+        boolean success = false;
+
+        if (integrityAuditPeriodMillis >= 0) {
+            this.auditThread = new AuditThread(this.resourceName, this.persistenceUnit, this.properties,
+                    integrityAuditPeriodMillis, this, queue);
+            logger.info("startAuditThread: Audit started and will run every " + integrityAuditPeriodMillis / 1000
+                    + " seconds");
+            this.auditThread.start();
+            success = true;
+        } else {
+            logger.info("startAuditThread: Suppressing integrity audit, integrityAuditPeriodSeconds="
+                    + integrityAuditPeriodMillis / 1000);
+        }
+
+        logger.info("startAuditThread: Exiting");
+
+        return success;
+    }
+
+    /**
+     * Stops the audit thread.
+     */
+    public void stopAuditThread() {
+
+        logger.info("stopAuditThread: Entering");
+
+        if (this.auditThread != null) {
+            this.auditThread.interrupt();
+        } else {
+            logger.info("stopAuditThread: auditThread never instantiated; no need to interrupt");
+        }
+
+        logger.info("stopAuditThread: Exiting");
+    }
+
+    public boolean isThreadInitialized() {
+        return isThreadInitialized;
+    }
+
+    public void setThreadInitialized(boolean isThreadInitialized) {
+        logger.info("setThreadInitialized: Setting isThreadInitialized=" + isThreadInitialized);
+        this.isThreadInitialized = isThreadInitialized;
+    }
+
+    public static boolean isUnitTesting() {
+        return isUnitTesting;
+    }
+
+    public static void setUnitTesting(boolean isUnitTesting) {
+        IntegrityAudit.isUnitTesting = isUnitTesting;
+    }
+
+    /**
+     * Waits a bit for the AuditThread to complete. Used by JUnit tests.
+     * 
+     * @param twaitms wait time, in milliseconds
+     * @return {@code true} if the thread stopped within the given time, {@code false} otherwise
+     * @throws InterruptedException if the thread is interrupted
+     */
+    protected boolean joinAuditThread(long twaitms) throws InterruptedException {
+        if (this.auditThread == null) {
+            return true;
+
+        } else {
+            this.auditThread.join(twaitms);
+            return !this.auditThread.isAlive();
+        }
+    }
 }
index a62c837..81e8b90 100644 (file)
@@ -2,7 +2,7 @@
  * ============LICENSE_START=======================================================
  * Integrity Audit
  * ================================================================================
- * 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.
 
 package org.onap.policy.common.ia;
 
-public class IntegrityAuditException extends Exception{
-       private static final long serialVersionUID = 1L;
-       public IntegrityAuditException() {
-               super();
-       }
-       public IntegrityAuditException(String message) {
-               super(message);
-       }
+public class IntegrityAuditException extends Exception {
+    private static final long serialVersionUID = 1L;
 
-       public IntegrityAuditException(Throwable cause) {
-               super(cause);
-       }
-       public IntegrityAuditException(String message, Throwable cause) {
-               super(message, cause);
-       }
+    public IntegrityAuditException() {
+        super();
+    }
+
+    public IntegrityAuditException(String message) {
+        super(message);
+    }
+
+    public IntegrityAuditException(Throwable cause) {
+        super(cause);
+    }
+
+    public IntegrityAuditException(String message, Throwable cause) {
+        super(message, cause);
+    }
 }
index b8db3ac..2708c09 100644 (file)
@@ -22,34 +22,26 @@ package org.onap.policy.common.ia;
 
 public class IntegrityAuditProperties {
 
-       public static final int DEFAULT_AUDIT_PERIOD_SECONDS = -1; // Audit does not run
-       
-       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 AUDIT_PERIOD_SECONDS = "integrity_audit_period_seconds";
-       public static final String AUDIT_PERIOD_MILLISECONDS = "integrity_audit_period_milliseconds";
-       
-       
-       public static final String SITE_NAME = "site_name";
-       public static final String NODE_TYPE = "node_type";
-       
-       public enum NodeTypeEnum {
-               pdp_xacml,
-               pdp_drools,
-               pap,
-               pap_admin,
-               logparser,
-               brms_gateway,
-               astra_gateway,
-               elk_server,
-               pypdp
-
-       }
-       
-       private IntegrityAuditProperties() {
-               
-       }
-       
+    public static final int DEFAULT_AUDIT_PERIOD_SECONDS = -1; // Audit does not run
+
+    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 AUDIT_PERIOD_SECONDS = "integrity_audit_period_seconds";
+    public static final String AUDIT_PERIOD_MILLISECONDS = "integrity_audit_period_milliseconds";
+
+
+    public static final String SITE_NAME = "site_name";
+    public static final String NODE_TYPE = "node_type";
+
+    public enum NodeTypeEnum {
+        pdp_xacml, pdp_drools, pap, pap_admin, logparser, brms_gateway, astra_gateway, elk_server, pypdp
+
+    }
+
+    private IntegrityAuditProperties() {
+
+    }
+
 }
index 766268b..d3c92fa 100644 (file)
 package org.onap.policy.common.ia;
 
 public class IntegrityAuditPropertiesException extends IntegrityAuditException {
-       private static final long serialVersionUID = 1L;
-       public IntegrityAuditPropertiesException() {
-               super();
-       }
-       public IntegrityAuditPropertiesException(String message) {
-               super(message);
-       }
+    private static final long serialVersionUID = 1L;
 
-       public IntegrityAuditPropertiesException(Throwable cause) {
-               super(cause);
-       }
-       public IntegrityAuditPropertiesException(String message, Throwable cause) {
-               super(message, cause);
-       }
+    public IntegrityAuditPropertiesException() {
+        super();
+    }
+
+    public IntegrityAuditPropertiesException(String message) {
+        super(message);
+    }
+
+    public IntegrityAuditPropertiesException(Throwable cause) {
+        super(cause);
+    }
+
+    public IntegrityAuditPropertiesException(String message, Throwable cause) {
+        super(message, cause);
+    }
 }
index da69f2d..23b90ef 100644 (file)
@@ -42,184 +42,185 @@ import javax.persistence.TemporalType;
  */
 
 @Entity
-@Table(name="IntegrityAuditEntity")
-@NamedQueries({
-       @NamedQuery(name=" IntegrityAuditEntity.findAll", query="SELECT e FROM IntegrityAuditEntity e "),
-       @NamedQuery(name="IntegrityAuditEntity.deleteAll", query="DELETE FROM IntegrityAuditEntity WHERE 1=1")
-})
+@Table(name = "IntegrityAuditEntity")
+@NamedQueries({@NamedQuery(name = " IntegrityAuditEntity.findAll", query = "SELECT e FROM IntegrityAuditEntity e "),
+        @NamedQuery(name = "IntegrityAuditEntity.deleteAll", query = "DELETE FROM IntegrityAuditEntity WHERE 1=1")})
 
 public class IntegrityAuditEntity implements Serializable {
-       private static final long serialVersionUID = 1L;
-
-       private static boolean isUnitTesting;
-       
-       @Id
-       @GeneratedValue(strategy = GenerationType.AUTO)
-       @Column(name="id")
-       private long id;
-       
-       @Column(name="persistenceUnit", nullable=false)
-       private String persistenceUnit;
-       
-       @Column(name="site", nullable=true)
-       private String site;
-       
-       @Column(name="nodeType", nullable=true)
-       private String nodeType;
-       
-       @Column(name="resourceName", nullable=false, unique=true)
-       private String resourceName;
-       
-       @Column(name="designated", nullable=true)
-       private boolean designated = false;
-
-       @Column(name="jdbcDriver", nullable=false)
-       private String jdbcDriver;
-       
-       @Column(name="jdbcUrl", nullable=false)
-       private String jdbcUrl;
-       
-       @Column(name="jdbcUser", nullable=false)
-       private String jdbcUser;
-       
-       @Column(name="jdbcPassword", nullable=false)
-       private String jdbcPassword;
-       
-       @Temporal(TemporalType.TIMESTAMP)
-       @Column(name="createdDate", updatable=true)
-       private Date createdDate;
-       
-       @Temporal(TemporalType.TIMESTAMP)
-       @Column(name="lastUpdated")
-       private Date lastUpdated;
-
-       
-       public IntegrityAuditEntity() {
-               // Empty constructor
-       }
-
-       @PrePersist
-       public void     prePersist() {
-               Date date = new Date();
-               this.createdDate = date;
-               this.lastUpdated = date;
-       }
-       
-       @PreUpdate
-       public void preUpdate() {
-               this.lastUpdated = new Date();
-       }
-
-       public long getId() {
-               return id;
-       }
-
-       public String getPersistenceUnit() {
-               return persistenceUnit;
-       }
-
-       public void setPersistenceUnit(String persistenceUnit) {
-               this.persistenceUnit = persistenceUnit;
-       }
-
-       public String getSite() {
-               return site;
-       }
-
-       public void setSite(String site) {
-               this.site = site;
-       }
-
-       public String getNodeType() {
-               return nodeType;
-       }
-
-       public void setNodeType(String nodeType) {
-               this.nodeType = nodeType;
-       }
-
-       public String getResourceName() {
-               return resourceName;
-       }
-
-       public void setResourceName(String resourceName) {
-               this.resourceName = resourceName;
-       }
-
-       public boolean isDesignated() {
-               return designated;
-       }
-
-       public void setDesignated(boolean designated) {
-               this.designated = designated;
-       }
-
-       public String getJdbcDriver() {
-               return jdbcDriver;
-       }
-
-       public void setJdbcDriver(String jdbcDriver) {
-               this.jdbcDriver = jdbcDriver;
-       }
-
-       public String getJdbcUrl() {
-               return jdbcUrl;
-       }
-
-       public void setJdbcUrl(String jdbcUrl) {
-               this.jdbcUrl = jdbcUrl;
-       }
-
-       public String getJdbcUser() {
-               return jdbcUser;
-       }
-
-       public void setJdbcUser(String jdbcUser) {
-               this.jdbcUser = jdbcUser;
-       }
-
-       public String getJdbcPassword() {
-               return jdbcPassword;
-       }
-
-       public void setJdbcPassword(String jdbcPassword) {
-               this.jdbcPassword = jdbcPassword;
-       }
-
-       public Date getLastUpdated() {
-               return lastUpdated;
-       }
-
-       public void setLastUpdated(Date lastUpdated) {
-               this.lastUpdated = lastUpdated;
-       }
-
-       public Date getCreatedDate() {
-               return createdDate;
-       }
-       
-       public void setCreatedDate(Date created) {
-               this.createdDate = created;
-       }
-
-       public static boolean isUnitTesting() {
-               return isUnitTesting;
-       }
-
-       public static void setUnitTesting(boolean isUnitTesting) {
-               IntegrityAuditEntity.isUnitTesting = isUnitTesting;
-       }
-
-       private void writeObject(ObjectOutputStream out) throws IOException {
-               if(isUnitTesting()) {
-                       /*
-                        * Note: other fields may be added here, as long as the
-                        * created-date and last-updated date are not included.
-                        */
-                       out.writeObject(jdbcUrl);
-                       
-               } else {
-                       out.defaultWriteObject();
-               }
-       }
+    private static final long serialVersionUID = 1L;
+
+    private static boolean isUnitTesting;
+
+    @Id
+    @GeneratedValue(strategy = GenerationType.AUTO)
+    @Column(name = "id")
+    private long id;
+
+    @Column(name = "persistenceUnit", nullable = false)
+    private String persistenceUnit;
+
+    @Column(name = "site", nullable = true)
+    private String site;
+
+    @Column(name = "nodeType", nullable = true)
+    private String nodeType;
+
+    @Column(name = "resourceName", nullable = false, unique = true)
+    private String resourceName;
+
+    @Column(name = "designated", nullable = true)
+    private boolean designated = false;
+
+    @Column(name = "jdbcDriver", nullable = false)
+    private String jdbcDriver;
+
+    @Column(name = "jdbcUrl", nullable = false)
+    private String jdbcUrl;
+
+    @Column(name = "jdbcUser", nullable = false)
+    private String jdbcUser;
+
+    @Column(name = "jdbcPassword", nullable = false)
+    private String jdbcPassword;
+
+    @Temporal(TemporalType.TIMESTAMP)
+    @Column(name = "createdDate", updatable = true)
+    private Date createdDate;
+
+    @Temporal(TemporalType.TIMESTAMP)
+    @Column(name = "lastUpdated")
+    private Date lastUpdated;
+
+
+    public IntegrityAuditEntity() {
+        // Empty constructor
+    }
+
+    /**
+     * Pre persist.
+     */
+    @PrePersist
+    public void prePersist() {
+        Date date = new Date();
+        this.createdDate = date;
+        this.lastUpdated = date;
+    }
+
+    @PreUpdate
+    public void preUpdate() {
+        this.lastUpdated = new Date();
+    }
+
+    public long getId() {
+        return id;
+    }
+
+    public String getPersistenceUnit() {
+        return persistenceUnit;
+    }
+
+    public void setPersistenceUnit(String persistenceUnit) {
+        this.persistenceUnit = persistenceUnit;
+    }
+
+    public String getSite() {
+        return site;
+    }
+
+    public void setSite(String site) {
+        this.site = site;
+    }
+
+    public String getNodeType() {
+        return nodeType;
+    }
+
+    public void setNodeType(String nodeType) {
+        this.nodeType = nodeType;
+    }
+
+    public String getResourceName() {
+        return resourceName;
+    }
+
+    public void setResourceName(String resourceName) {
+        this.resourceName = resourceName;
+    }
+
+    public boolean isDesignated() {
+        return designated;
+    }
+
+    public void setDesignated(boolean designated) {
+        this.designated = designated;
+    }
+
+    public String getJdbcDriver() {
+        return jdbcDriver;
+    }
+
+    public void setJdbcDriver(String jdbcDriver) {
+        this.jdbcDriver = jdbcDriver;
+    }
+
+    public String getJdbcUrl() {
+        return jdbcUrl;
+    }
+
+    public void setJdbcUrl(String jdbcUrl) {
+        this.jdbcUrl = jdbcUrl;
+    }
+
+    public String getJdbcUser() {
+        return jdbcUser;
+    }
+
+    public void setJdbcUser(String jdbcUser) {
+        this.jdbcUser = jdbcUser;
+    }
+
+    public String getJdbcPassword() {
+        return jdbcPassword;
+    }
+
+    public void setJdbcPassword(String jdbcPassword) {
+        this.jdbcPassword = jdbcPassword;
+    }
+
+    public Date getLastUpdated() {
+        return lastUpdated;
+    }
+
+    public void setLastUpdated(Date lastUpdated) {
+        this.lastUpdated = lastUpdated;
+    }
+
+    public Date getCreatedDate() {
+        return createdDate;
+    }
+
+    public void setCreatedDate(Date created) {
+        this.createdDate = created;
+    }
+
+    public static boolean isUnitTesting() {
+        return isUnitTesting;
+    }
+
+    public static void setUnitTesting(boolean isUnitTesting) {
+        IntegrityAuditEntity.isUnitTesting = isUnitTesting;
+    }
+
+    private void writeObject(ObjectOutputStream out) throws IOException {
+        if (isUnitTesting()) {
+            /*
+             * Note: other fields may be added here, as long as the created-date and last-updated
+             * date are not included.
+             */
+            out.writeObject(jdbcUrl);
+
+        } else {
+            out.defaultWriteObject();
+        }
+    }
 }
index b627977..232468d 100644 (file)
@@ -44,217 +44,222 @@ import org.onap.policy.common.utils.test.log.logback.ExtractAppender;
  */
 public class AuditPeriodTest extends IntegrityAuditTestBase {
 
-       private static Logger logger = FlexLogger.getLogger(AuditPeriodTest.class);
+    private static Logger logger = FlexLogger.getLogger(AuditPeriodTest.class);
 
-       @BeforeClass
-       public static void setUpBeforeClass() throws Exception {
-               IntegrityAuditTestBase.setUpBeforeClass(DEFAULT_DB_URL_PREFIX + AuditPeriodTest.class.getSimpleName());
-       }
+    @BeforeClass
+    public static void setUpBeforeClass() throws Exception {
+        IntegrityAuditTestBase.setUpBeforeClass(DEFAULT_DB_URL_PREFIX + AuditPeriodTest.class.getSimpleName());
+    }
 
-       @AfterClass
-       public static void tearDownAfterClass() {
-               IntegrityAuditTestBase.tearDownAfterClass();
-       }
+    @AfterClass
+    public static void tearDownAfterClass() {
+        IntegrityAuditTestBase.tearDownAfterClass();
+    }
 
-       @Before
-       public void setUp() {
-               logger.info("setUp: Entering");
+    /**
+     * Set up for test case.
+     */
+    @Override
+    @Before
+    public void setUp() {
+        logger.info("setUp: Entering");
 
-               super.setUp();
+        super.setUp();
 
-               logger.info("setUp: Exiting");
+        logger.info("setUp: Exiting");
 
-       }
+    }
 
-       @After
-       public void tearDown() {
-               logger.info("tearDown: Entering");
+    /**
+     * Tear down after test cases.
+     */
+    @Override
+    @After
+    public void tearDown() {
+        logger.info("tearDown: Entering");
 
-               super.tearDown();
+        super.tearDown();
 
-               logger.info("tearDown: Exiting");
-       }
+        logger.info("tearDown: Exiting");
+    }
 
-       /*
-        * Verifies (via log parsing) that when a negative audit period is
-        * specified, the audit is suppressed.
-        */
-       @Test
-       public void testNegativeAuditPeriod() throws Exception {
+    /*
+     * Verifies (via log parsing) that when a negative audit period is specified, the audit is
+     * suppressed.
+     */
+    @Test
+    public void testNegativeAuditPeriod() throws Exception {
 
-               logger.info("testNegativeAuditPeriod: Entering");
+        logger.info("testNegativeAuditPeriod: Entering");
 
-               properties.put(IntegrityAuditProperties.AUDIT_PERIOD_SECONDS, "-1");
+        properties.put(IntegrityAuditProperties.AUDIT_PERIOD_SECONDS, "-1");
 
-               ExtractAppender logA = watch(debugLogger, "Suppressing integrity audit, integrityAuditPeriodSeconds=([^,]*)");
+        ExtractAppender logA = watch(debugLogger, "Suppressing integrity audit, integrityAuditPeriodSeconds=([^,]*)");
 
-               MyIntegrityAudit integrityAudit = makeAuditor("pdp1", A_SEQ_PU);
+        MyIntegrityAudit integrityAudit = makeAuditor("pdp1", A_SEQ_PU);
 
-               /*
-                * Sleep long enough to allow
-                
-                * 1) audit to immediately terminate.
-                */
-               waitThread(integrityAudit);
+        /*
+         * Sleep long enough to allow
+         * 
+         * 1) audit to immediately terminate.
+         */
+        waitThread(integrityAudit);
 
-               verifyItemsInLog(logA, "-1");
+        verifyItemsInLog(logA, "-1");
 
-               logger.info("testNegativeAuditPeriod: Exiting");
-
-       }
-
-       /*
-        * Verifies (via log parsing) that when an audit period of zero is
-        * specified, the audit runs continuously, generating a number of sleep/wake
-        * sequences in a short period of time (e.g. 100ms).
-        */
-       @Test
-       public void testZeroAuditPeriod() throws Exception {
-
-               logger.info("testZeroAuditPeriod: Entering");
-
-               properties.put(IntegrityAuditProperties.AUDIT_PERIOD_SECONDS, "0");
-
-               ExtractAppender logA = watch(debugLogger, "[Aa]waking from (0ms) sleep");
-
-               MyIntegrityAudit integrityAudit = makeAuditor("pdp1", A_SEQ_PU);
-
-               /*
-                * Wait for
-                * 
-                * 1) audit to generate a bunch of sleep wake sequences.
-                */
-               String[] awakings = new String[10];
-               for (int x = 0; x < awakings.length; ++x) {
-                       awakings[x] = "0ms";
-                       runAudit(integrityAudit);
-               }
-
-               // run a couple more audits
-               runAudit(integrityAudit);
-               runAudit(integrityAudit);
-
-               /*
-                * We should get at least 10 sleep/wake sequences.
-                */
-
-               verifyItemsInLog(logA, awakings);
-
-               logger.info("testZeroAuditPeriod: Exiting");
-
-       }
-
-       /**
-        * Verifies that when different audit periods are specified, there is an
-        * appropriate interval between the audits.
-        */
-       @Test
-       public void testLongAuditPeriod() throws Exception {
-
-               logger.info("testLongAuditPeriod: Entering");
-
-               testAuditPeriod(100);
-               testAuditPeriod(200);
-
-               logger.info("testLongAuditPeriod: Exiting");
-       }
-
-       /**
-        * Verifies that audits actually take as long as expected, even with
-        * multiple auditors running simultaneously.
-        * 
-        * @param periodms
-        *            audit period, in milliseconds
-        * @throws Exception
-        * @throws InterruptedException
-        */
-       private void testAuditPeriod(long periodms) throws Exception, InterruptedException {
-
-               properties.put(IntegrityAuditProperties.AUDIT_PERIOD_MILLISECONDS, String.valueOf(periodms));
-
-               /*
-                * Start several auditors.
-                */
-               MyIntegrityAudit[] ia = new MyIntegrityAudit[3];
-               for (int x = 0; x < ia.length; ++x) {
-                       ia[x] = makeAuditor("pdp" + x, A_SEQ_PU);
-               }
-
-               /*
-                * Run an audit on all of them.
-                */
-               runAudit(ia);
-
-               /*
-                * Now run again and ensure it waited long enough between runs.
-                */
-               long tmin = minAuditTime(ia);
-               assertTrue(tmin >= periodms + AUDIT_SIMULATION_MS);
-
-               /*
-                * Now run again and ensure it waited long enough between runs.
-                */
-               tmin = minAuditTime(ia);
-               assertTrue(tmin >= periodms + AUDIT_SIMULATION_MS);
-       }
-
-       /**
-        * Runs simultaneous audits on several auditors.
-        * 
-        * @param auditors
-        * @return the minimum time, in milliseconds, elapsed for any given auditor
-        * @throws InterruptedException
-        */
-       private long minAuditTime(MyIntegrityAudit... auditors) throws InterruptedException {
-               List<Thread> threads = new ArrayList<>(auditors.length);
-               AtomicLong tfirst = new AtomicLong(Long.MAX_VALUE);
-               long tbeg = System.currentTimeMillis();
-
-               // create the threads
-               for (MyIntegrityAudit p : auditors) {
-                       Thread t = new Thread() {
-
-                               @Override
-                               public void run() {
-                                       try {
-                                               runAudit(p);
-                                               setMinTime(tfirst);
-
-                                       } catch (InterruptedException e) {
-                                               ;
-                                       }
-                               }
-                       };
-
-                       t.setDaemon(true);
-                       threads.add(t);
-               }
-
-               // start the threads
-               for (Thread t : threads) {
-                       t.start();
-               }
-
-               // wait for them to complete
-               for (Thread t : threads) {
-                       t.join();
-               }
-
-               return (tfirst.get() - tbeg);
-       }
-
-       /**
-        * Sets a value to the minimum between the current value and the current
-        * time.
-        * 
-        * @param tmin
-        *            current minimum value/value to be set
-        */
-       private static void setMinTime(AtomicLong tmin) {
-               long tcur = System.currentTimeMillis();
-               long t;
-               while ((t = tmin.get()) > tcur) {
-                       tmin.compareAndSet(t, tcur);
-               }
-       }
+        logger.info("testNegativeAuditPeriod: Exiting");
+
+    }
+
+    /*
+     * Verifies (via log parsing) that when an audit period of zero is specified, the audit runs
+     * continuously, generating a number of sleep/wake sequences in a short period of time (e.g.
+     * 100ms).
+     */
+    @Test
+    public void testZeroAuditPeriod() throws Exception {
+
+        logger.info("testZeroAuditPeriod: Entering");
+
+        properties.put(IntegrityAuditProperties.AUDIT_PERIOD_SECONDS, "0");
+
+        final ExtractAppender logA = watch(debugLogger, "[Aa]waking from (0ms) sleep");
+
+        MyIntegrityAudit integrityAudit = makeAuditor("pdp1", A_SEQ_PU);
+
+        /*
+         * Wait for
+         * 
+         * 1) audit to generate a bunch of sleep wake sequences.
+         */
+        String[] awakings = new String[10];
+        for (int x = 0; x < awakings.length; ++x) {
+            awakings[x] = "0ms";
+            runAudit(integrityAudit);
+        }
+
+        // run a couple more audits
+        runAudit(integrityAudit);
+        runAudit(integrityAudit);
+
+        /*
+         * We should get at least 10 sleep/wake sequences.
+         */
+
+        verifyItemsInLog(logA, awakings);
+
+        logger.info("testZeroAuditPeriod: Exiting");
+
+    }
+
+    /**
+     * Verifies that when different audit periods are specified, there is an appropriate interval
+     * between the audits.
+     */
+    @Test
+    public void testLongAuditPeriod() throws Exception {
+
+        logger.info("testLongAuditPeriod: Entering");
+
+        testAuditPeriod(100);
+        testAuditPeriod(200);
+
+        logger.info("testLongAuditPeriod: Exiting");
+    }
+
+    /**
+     * Verifies that audits actually take as long as expected, even with multiple auditors running
+     * simultaneously.
+     * 
+     * @param periodms audit period, in milliseconds
+     * @throws Exception if an error occurs
+     * @throws InterruptedException if the thread is interrupted
+     */
+    private void testAuditPeriod(long periodms) throws Exception, InterruptedException {
+
+        properties.put(IntegrityAuditProperties.AUDIT_PERIOD_MILLISECONDS, String.valueOf(periodms));
+
+        /*
+         * Start several auditors.
+         */
+        MyIntegrityAudit[] ia = new MyIntegrityAudit[3];
+        for (int x = 0; x < ia.length; ++x) {
+            ia[x] = makeAuditor("pdp" + x, A_SEQ_PU);
+        }
+
+        /*
+         * Run an audit on all of them.
+         */
+        runAudit(ia);
+
+        /*
+         * Now run again and ensure it waited long enough between runs.
+         */
+        long tmin = minAuditTime(ia);
+        assertTrue(tmin >= periodms + AUDIT_SIMULATION_MS);
+
+        /*
+         * Now run again and ensure it waited long enough between runs.
+         */
+        tmin = minAuditTime(ia);
+        assertTrue(tmin >= periodms + AUDIT_SIMULATION_MS);
+    }
+
+    /**
+     * Runs simultaneous audits on several auditors.
+     * 
+     * @param auditors the auditors
+     * @return the minimum time, in milliseconds, elapsed for any given auditor
+     * @throws InterruptedException if the thread is interrupted
+     */
+    private long minAuditTime(MyIntegrityAudit... auditors) throws InterruptedException {
+        List<Thread> threads = new ArrayList<>(auditors.length);
+        AtomicLong tfirst = new AtomicLong(Long.MAX_VALUE);
+        final long tbeg = System.currentTimeMillis();
+
+        // create the threads
+        for (MyIntegrityAudit p : auditors) {
+            Thread auditThread = new Thread() {
+
+                @Override
+                public void run() {
+                    try {
+                        runAudit(p);
+                        setMinTime(tfirst);
+
+                    } catch (InterruptedException e) {
+                        ;
+                    }
+                }
+            };
+
+            auditThread.setDaemon(true);
+            threads.add(auditThread);
+        }
+
+        // start the threads
+        for (Thread t : threads) {
+            t.start();
+        }
+
+        // wait for them to complete
+        for (Thread t : threads) {
+            t.join();
+        }
+
+        return (tfirst.get() - tbeg);
+    }
+
+    /**
+     * Sets a value to the minimum between the current value and the current time.
+     * 
+     * @param tmin current minimum value/value to be set
+     */
+    private static void setMinTime(AtomicLong tmin) {
+        long tcur = System.currentTimeMillis();
+        long time;
+        while ((time = tmin.get()) > tcur) {
+            tmin.compareAndSet(time, tcur);
+        }
+    }
 }
index 3a48b20..6335482 100644 (file)
@@ -50,505 +50,507 @@ import org.onap.policy.common.logging.flexlogger.Logger;
  */
 public class DbAuditCompareEntriesTest extends IntegrityAuditTestBase {
 
-       private static Logger logger = FlexLogger.getLogger(DbAuditCompareEntriesTest.class);
-
-       private DbDAO dbDAO;
-       private static String resourceName = "pdp1";
-
-       @BeforeClass
-       public static void setUpBeforeClass() throws Exception {
-               IntegrityAuditTestBase
-                               .setUpBeforeClass(DEFAULT_DB_URL_PREFIX + DbAuditCompareEntriesTest.class.getSimpleName());
-       }
-
-       @AfterClass
-       public static void tearDownAfterClass() {
-               IntegrityAuditTestBase.tearDownAfterClass();
-       }
-
-       @Before
-       public void setUp() {
-
-               logger.info("setUp: Entering");
-
-               super.setUp();
-
-               truncateTables(makeProperties());
-
-               logger.info("setUp: Exiting");
-       }
-
-       /*
-        * Clean up DB after each test.
-        */
-       @After
-       public void tearDown() {
-               logger.info("tearDown: Entering");
-               
-               dbDAO.destroy();
-
-               super.tearDown();
-
-               logger.info("tearDown: Exiting");
-       }
-
-       /*
-        * Tests that a comparison between hashsets is successful if the entries
-        * match
-        */
-       // @Ignore
-       @Test
-       public void testSuccessfulComparison() throws Exception {
-               logger.info("testSuccessfulComparison: Entering");
-
-               dbDAO = new DbDAO(resourceName, A_SEQ_PU, makeProperties());
-               DbAudit dbAudit = new DbAudit(dbDAO);
-
-               String className = null;
-               // There is only one entry IntegrityAuditEntity, but we will check
-               // anyway
-               Set<String> classNameSet = dbDAO.getPersistenceClassNames();
-               for (String c : classNameSet) {
-                       if (c.equals("org.onap.policy.common.ia.jpa.IntegrityAuditEntity")) {
-                               className = c;
-                       }
-               }
-               String resourceName1 = resourceName;
-               String resourceName2 = resourceName;
-
-               IntegrityAuditEntity entry1 = new IntegrityAuditEntity();
-               IntegrityAuditEntity entry2 = new IntegrityAuditEntity();
-               Date date = new Date();
-
-               /*
-                * Two entries with the same field values
-                */
-               entry1.setDesignated(false);
-               entry1.setJdbcDriver(dbDriver);
-               entry1.setJdbcPassword(dbPwd);
-               entry1.setJdbcUrl(dbUrl);
-               entry1.setJdbcUser(dbUser);
-               entry1.setLastUpdated(date);
-               entry1.setNodeType(nodeType);
-               entry1.setPersistenceUnit(A_SEQ_PU);
-               entry1.setResourceName(resourceName1);
-               entry1.setSite(siteName);
-
-               entry2.setDesignated(false);
-               entry2.setJdbcDriver(dbDriver);
-               entry2.setJdbcPassword(dbPwd);
-               entry2.setJdbcUrl(dbUrl);
-               entry2.setJdbcUser(dbUser);
-               entry2.setLastUpdated(date);
-               entry2.setNodeType(nodeType);
-               entry2.setPersistenceUnit(A_SEQ_PU);
-               entry2.setResourceName(resourceName2);
-               entry2.setSite(siteName);
-
-               dbAudit.writeAuditDebugLog(className, resourceName1, resourceName2, entry1, entry2);
-
-               HashMap<Object, Object> myEntries = new HashMap<Object, Object>();
-               HashMap<Object, Object> theirEntries = new HashMap<Object, Object>();
-
-               myEntries.put("pdp1", entry1);
-               theirEntries.put("pdp1", entry2);
-
-               Set<Object> result = dbAudit.compareEntries(myEntries, theirEntries);
-
-               /*
-                * Assert that there are no mismatches returned
-                */
-               assertTrue(result.isEmpty());
-
-               logger.info("testSuccessfulComparison: Exit");
-       }
-
-       /*
-        * Tests that an error is detected if an entry in one hashset doesn't match
-        * the other
-        */
-       // @Ignore
-       @Test
-       public void testComparisonError() throws Exception {
-               logger.info("testComparisonError: Entering");
-
-               dbDAO = new DbDAO(resourceName, A_SEQ_PU, makeProperties());
-               DbAudit dbAudit = new DbAudit(dbDAO);
-
-               String resourceName1 = resourceName;
-               String resourceName2 = resourceName;
-
-               IntegrityAuditEntity entry1 = new IntegrityAuditEntity();
-               IntegrityAuditEntity entry2 = new IntegrityAuditEntity();
-               Date date = new Date();
-
-               /*
-                * Create two entries with different designated values
-                */
-               entry1.setDesignated(false);
-               entry1.setJdbcDriver(dbDriver);
-               entry1.setJdbcPassword(dbPwd);
-               entry1.setJdbcUrl(dbUrl);
-               entry1.setJdbcUser(dbUser);
-               entry1.setLastUpdated(date);
-               entry1.setNodeType(nodeType);
-               entry1.setPersistenceUnit(A_SEQ_PU);
-               entry1.setResourceName(resourceName1);
-               entry1.setSite(siteName);
-
-               entry2.setDesignated(true);
-               entry2.setJdbcDriver(dbDriver);
-               entry2.setJdbcPassword(dbPwd);
-               entry2.setJdbcUrl(dbUrl);
-               entry2.setJdbcUser(dbUser);
-               entry2.setLastUpdated(date);
-               entry2.setNodeType(nodeType);
-               entry2.setPersistenceUnit(A_SEQ_PU);
-               entry2.setResourceName(resourceName2);
-               entry2.setSite(siteName);
-
-               HashMap<Object, Object> myEntries = new HashMap<Object, Object>();
-               HashMap<Object, Object> theirEntries = new HashMap<Object, Object>();
-
-               myEntries.put("pdp1", entry1);
-               theirEntries.put("pdp1", entry2);
-
-               Set<Object> result = dbAudit.compareEntries(myEntries, theirEntries);
-
-               /*
-                * Assert that there was one mismatch
-                */
-               assertEquals(1, result.size());
-
-               logger.info("testComparisonError: Exit");
-       }
-
-       /*
-        * Tests that a mismatch/miss entry is detected if there are missing entries
-        * in one or both of the hashsets
-        */
-       // @Ignore
-       @Test
-       public void testCompareMissingEntries() throws Exception {
-               logger.info("testCompareMissingEntries: Entering");
-
-               dbDAO = new DbDAO(resourceName, A_SEQ_PU, makeProperties());
-               DbAudit dbAudit = new DbAudit(dbDAO);
-
-               String resourceName1 = resourceName;
-               String resourceName2 = resourceName;
-
-               IntegrityAuditEntity entry1 = new IntegrityAuditEntity();
-               IntegrityAuditEntity entry2 = new IntegrityAuditEntity();
-               IntegrityAuditEntity entry3 = new IntegrityAuditEntity();
-               IntegrityAuditEntity entry4 = new IntegrityAuditEntity();
-
-               Date date = new Date();
-
-               /*
-                * 4 entries, one mismatch, two miss entries
-                */
-               entry1.setDesignated(false);
-               entry1.setJdbcDriver(dbDriver);
-               entry1.setJdbcPassword(dbPwd);
-               entry1.setJdbcUrl(dbUrl);
-               entry1.setJdbcUser(dbUser);
-               entry1.setLastUpdated(date);
-               entry1.setNodeType(nodeType);
-               entry1.setPersistenceUnit(A_SEQ_PU);
-               entry1.setResourceName(resourceName1);
-               entry1.setSite(siteName);
-
-               entry2.setDesignated(true);
-               entry2.setJdbcDriver(dbDriver);
-               entry2.setJdbcPassword(dbPwd);
-               entry2.setJdbcUrl(dbUrl);
-               entry2.setJdbcUser(dbUser);
-               entry2.setLastUpdated(date);
-               entry2.setNodeType(nodeType);
-               entry2.setPersistenceUnit(A_SEQ_PU);
-               entry2.setResourceName(resourceName2);
-               entry2.setSite(siteName);
-
-               entry3.setDesignated(false);
-               entry3.setJdbcDriver(dbDriver);
-               entry3.setJdbcPassword(dbPwd);
-               entry3.setJdbcUrl(dbUrl);
-               entry3.setJdbcUser(dbUser);
-               entry3.setLastUpdated(date);
-               entry3.setNodeType(nodeType);
-               entry3.setPersistenceUnit(A_SEQ_PU);
-               entry3.setResourceName(resourceName2);
-               entry3.setSite("SiteB");
-
-               entry4.setDesignated(false);
-               entry4.setJdbcDriver(dbDriver);
-               entry4.setJdbcPassword(dbPwd);
-               entry4.setJdbcUrl(dbUrl);
-               entry4.setJdbcUser(dbUser);
-               entry4.setLastUpdated(date);
-               entry4.setNodeType(nodeType);
-               entry4.setPersistenceUnit(A_SEQ_PU);
-               entry4.setResourceName(resourceName2);
-               entry4.setSite("SiteB");
-
-               HashMap<Object, Object> myEntries = new HashMap<Object, Object>();
-               HashMap<Object, Object> theirEntries = new HashMap<Object, Object>();
-
-               myEntries.put("0", entry1);
-               myEntries.put("1", entry3);
-               theirEntries.put("0", entry2);
-               theirEntries.put("2", entry4);
-
-               Set<Object> mismatchResult = dbAudit.compareEntries(myEntries, theirEntries);
-
-               /*
-                * Assert 3 mismatches/missing entries were found
-                */
-               assertEquals(3, mismatchResult.size());
-
-               logger.info("testCompareMissingEntries: Exit");
-       }
-
-       /*
-        * Tests that comparison algorithm works for each entity in the hashsets
-        */
-       // @Ignore
-       @Test
-       public void testCompareAllHashEntities() throws Exception {
-               logger.info("testCompareAllHashEntities: Entering");
-
-               dbDAO = new DbDAO(resourceName, A_SEQ_PU, makeProperties());
-               DbAudit dbAudit = new DbAudit(dbDAO);
-
-               Set<String> classNameSet = dbDAO.getPersistenceClassNames();
-               Set<Object> mismatchResult = new HashSet<Object>();
-               for (String c : classNameSet) {
-                       if (c.equals("org.onap.policy.common.ia.jpa.IntegrityAuditEntity")) {
-                               String resourceName1 = resourceName;
-                               String resourceName2 = resourceName;
-
-                               IntegrityAuditEntity entry1 = new IntegrityAuditEntity();
-                               IntegrityAuditEntity entry2 = new IntegrityAuditEntity();
-                               Date date = new Date();
-
-                               /*
-                                * Two entries with the same field values
-                                */
-                               entry1.setDesignated(false);
-                               entry1.setJdbcDriver(dbDriver);
-                               entry1.setJdbcPassword(dbPwd);
-                               entry1.setJdbcUrl(dbUrl);
-                               entry1.setJdbcUser(dbUser);
-                               entry1.setLastUpdated(date);
-                               entry1.setNodeType(nodeType);
-                               entry1.setPersistenceUnit(A_SEQ_PU);
-                               entry1.setResourceName(resourceName1);
-                               entry1.setSite(siteName);
-
-                               entry2.setDesignated(false);
-                               entry2.setJdbcDriver(dbDriver);
-                               entry2.setJdbcPassword(dbPwd);
-                               entry2.setJdbcUrl(dbUrl);
-                               entry2.setJdbcUser(dbUser);
-                               entry2.setLastUpdated(date);
-                               entry2.setNodeType(nodeType);
-                               entry2.setPersistenceUnit(A_SEQ_PU);
-                               entry2.setResourceName(resourceName2);
-                               entry2.setSite(siteName);
-
-                               HashMap<Object, Object> myEntries = new HashMap<Object, Object>();
-                               HashMap<Object, Object> theirEntries = new HashMap<Object, Object>();
-
-                               myEntries.put("pdp1", entry1);
-                               theirEntries.put("pdp1", entry2);
-
-                               mismatchResult = dbAudit.compareEntries(myEntries, theirEntries);
-
-                               /*
-                                * Assert there was no mismatches
-                                */
-                               assertTrue(mismatchResult.isEmpty());
-                       } else if (c.equals("org.onap.policy.common.ia.jpa.IaTestEntity")) {
-                               IaTestEntity iate = new IaTestEntity();
-                               IaTestEntity iate2 = new IaTestEntity();
-                               IaTestEntity iate3 = new IaTestEntity();
-                               IaTestEntity iate4 = new IaTestEntity();
-
-                               Date date = new Date();
-
-                               /*
-                                * Four entries, 2 mismatches
-                                */
-                               iate.setCreatedBy("Ford");
-                               iate.setModifiedBy("Ford");
-                               iate.setModifiedDate(date);
-
-                               iate2.setCreatedBy("Ford");
-                               iate2.setModifiedBy("Zaphod");
-                               iate2.setModifiedDate(date);
-
-                               iate3.setCreatedBy("Zaphod");
-                               iate3.setModifiedBy("Ford");
-                               iate3.setModifiedDate(date);
-
-                               iate4.setCreatedBy("Ford");
-                               iate4.setModifiedBy("Ford");
-                               iate4.setModifiedDate(date);
-
-                               HashMap<Object, Object> myEntries = new HashMap<Object, Object>();
-                               HashMap<Object, Object> theirEntries = new HashMap<Object, Object>();
-
-                               myEntries.put("0", iate);
-                               myEntries.put("1", iate2);
-                               theirEntries.put("0", iate3);
-                               theirEntries.put("1", iate4);
-
-                               mismatchResult = dbAudit.compareEntries(myEntries, theirEntries);
-
-                               /*
-                                * Assert that there is 2 mismatches
-                                */
-                               assertEquals(2, mismatchResult.size());
-                       }
-               }
-
-               logger.info("testCompareAllHashEntities: Exit");
-       }
-
-       /*
-        * Tests that comparison algorithm works for each entity in the database
-        */
-       @Ignore
-       @Test
-       public void testCompareAllDbEntities() throws Exception {
-               logger.info("testCompareAllDbEntities: Entering");
-
-               logger.info("Setting up DB");
-
-               IntegrityAudit.setUnitTesting(true);
-
-               Properties properties = makeProperties();
-
-               Properties properties2 = makeProperties();
-               properties2.put(IntegrityAuditProperties.DB_URL,
-                               "jdbc:h2:mem:" + DbAuditCompareEntriesTest.class.getSimpleName() + "2");
-
-               // Clean up the two DBs
-               truncateTables(properties);
-               truncateTables(properties2);
-
-               // Add entries into DB1
-               dbDAO = new DbDAO(resourceName, A_SEQ_PU, properties);
-               new DbDAO("pdp2", A_SEQ_PU, properties).destroy();
-               DbAudit dbAudit = new DbAudit(dbDAO);
-
-               // Add entries into DB2
-               DbDAO dbDAO3 = new DbDAO(resourceName, A_SEQ_PU, properties2);
-               new DbDAO("pdp2", A_SEQ_PU, properties2).destroy();
-
-               // Pull all entries and compare
-               Set<String> classNameSet = dbDAO.getPersistenceClassNames();
-               Map<Object, Object> myEntries;
-               Map<Object, Object> theirEntries;
-               Set<Object> mismatchResult = new HashSet<Object>();
-               String className;
-               for (String c : classNameSet) {
-                       className = c;
-                       logger.info("classNameSet entry = " + c);
-                       myEntries = dbDAO.getAllEntries(A_SEQ_PU, properties, className);
-                       theirEntries = dbDAO3.getAllEntries(A_SEQ_PU, properties2, className);
-                       mismatchResult = dbAudit.compareEntries(myEntries, theirEntries);
-                       if (className.contains("IntegrityAuditEntity")) {
-                               break;
-                       }
-               }
-               
-               dbDAO3.destroy();
-
-               // Assert that there is 2 mismatches between IntegrityAuditEntity tables
-               assertEquals(2, mismatchResult.size());
-
-               logger.info("testCompareAllDbEntities: Exit");
-       }
-
-       /**
-        * @param properties
-        */
-       private void truncateTables(Properties properties) {
-               truncateTable(properties, A_SEQ_PU, "IntegrityAuditEntity");
-               truncateTable(properties, A_SEQ_PU, "IaTestEntity");
-       }
-
-       /*
-        * Tests that differences in embedded classes are still caught
-        */
-       // @Ignore
-       @Test
-       public void testEmbeddedClass() throws Exception {
-               logger.info("testEmbeddedClasses: Entering");
-
-               dbDAO = new DbDAO(resourceName, A_SEQ_PU, properties);
-               DbAudit dbAudit = new DbAudit(dbDAO);
-
-               String className = null;
-               // There is only one entry IntegrityAuditEntity, but we will check
-               // anyway
-               Set<String> classNameSet = dbDAO.getPersistenceClassNames();
-               for (String c : classNameSet) {
-                       if (c.equals("org.onap.policy.common.ia.jpa.IaTestEntity")) {
-                               className = c;
-                       }
-               }
-
-               IaTestEntity iate = new IaTestEntity();
-               IaTestEntity iate2 = new IaTestEntity();
-
-               Date date = new Date();
-
-               PersonSample person = new PersonSample("Ford", "Prefect", 21);
-               PersonSample person2 = new PersonSample("Zaphod", "Beeblebrox", 25);
-
-               /*
-                * Silly tests to bump coverage stats, not sure why they are counting
-                * PersonSample to begin with. Will have to look into that at some
-                * point.
-                */
-               assertNotEquals(person.getAge(), person2.getAge());
-               assertNotEquals(person.getFirstName(), person2.getFirstName());
-               assertNotEquals(person.getLasttName(), person2.getLasttName());
-               PersonSample personTest = new PersonSample(null, null, 0);
-               personTest.setAge(person.getAge());
-               personTest.setFirstName(person.getFirstName());
-               personTest.setLastName(person.getLasttName());
-               /*
-                * Two entries, 1 mismatch
-                */
-               iate.setCreatedBy("Ford");
-               iate.setModifiedBy("Zaphod");
-               iate.setModifiedDate(date);
-               iate.setPersonTest(person);
-
-               iate2.setCreatedBy("Ford");
-               iate2.setModifiedBy("Zaphod");
-               iate2.setModifiedDate(date);
-               iate2.setPersonTest(person2);
-
-               dbAudit.writeAuditDebugLog(className, "resource1", "resource2", iate, iate2);
-
-               HashMap<Object, Object> myEntries = new HashMap<Object, Object>();
-               HashMap<Object, Object> theirEntries = new HashMap<Object, Object>();
-
-               myEntries.put("0", iate);
-               theirEntries.put("0", iate2);
-
-               Set<Object> result = dbAudit.compareEntries(myEntries, theirEntries);
-
-               /*
-                * Assert that there are no mismatches returned
-                */
-               assertTrue(!result.isEmpty());
-
-               logger.info("testEmbeddedClasses: Exit");
-       }
+    private static Logger logger = FlexLogger.getLogger(DbAuditCompareEntriesTest.class);
+
+    private DbDAO dbDao;
+    private static String resourceName = "pdp1";
+
+    @BeforeClass
+    public static void setUpBeforeClass() throws Exception {
+        IntegrityAuditTestBase
+                .setUpBeforeClass(DEFAULT_DB_URL_PREFIX + DbAuditCompareEntriesTest.class.getSimpleName());
+    }
+
+    @AfterClass
+    public static void tearDownAfterClass() {
+        IntegrityAuditTestBase.tearDownAfterClass();
+    }
+
+    /**
+     * Set up for test cases.
+     */
+    @Override
+    @Before
+    public void setUp() {
+
+        logger.info("setUp: Entering");
+
+        super.setUp();
+
+        truncateTables(makeProperties());
+
+        logger.info("setUp: Exiting");
+    }
+
+    /**
+     * Clean up DB after each test.
+     */
+    @Override
+    @After
+    public void tearDown() {
+        logger.info("tearDown: Entering");
+
+        dbDao.destroy();
+
+        super.tearDown();
+
+        logger.info("tearDown: Exiting");
+    }
+
+    /*
+     * Tests that a comparison between hashsets is successful if the entries match
+     */
+    // @Ignore
+    @Test
+    public void testSuccessfulComparison() throws Exception {
+        logger.info("testSuccessfulComparison: Entering");
+
+        dbDao = new DbDAO(resourceName, A_SEQ_PU, makeProperties());
+        final DbAudit dbAudit = new DbAudit(dbDao);
+
+        String className = null;
+        // There is only one entry IntegrityAuditEntity, but we will check
+        // anyway
+        Set<String> classNameSet = dbDao.getPersistenceClassNames();
+        for (String c : classNameSet) {
+            if (c.equals("org.onap.policy.common.ia.jpa.IntegrityAuditEntity")) {
+                className = c;
+            }
+        }
+        final String resourceName1 = resourceName;
+        final String resourceName2 = resourceName;
+
+        final IntegrityAuditEntity entry1 = new IntegrityAuditEntity();
+        final IntegrityAuditEntity entry2 = new IntegrityAuditEntity();
+        Date date = new Date();
+
+        /*
+         * Two entries with the same field values
+         */
+        entry1.setDesignated(false);
+        entry1.setJdbcDriver(dbDriver);
+        entry1.setJdbcPassword(dbPwd);
+        entry1.setJdbcUrl(dbUrl);
+        entry1.setJdbcUser(dbUser);
+        entry1.setLastUpdated(date);
+        entry1.setNodeType(nodeType);
+        entry1.setPersistenceUnit(A_SEQ_PU);
+        entry1.setResourceName(resourceName1);
+        entry1.setSite(siteName);
+
+        entry2.setDesignated(false);
+        entry2.setJdbcDriver(dbDriver);
+        entry2.setJdbcPassword(dbPwd);
+        entry2.setJdbcUrl(dbUrl);
+        entry2.setJdbcUser(dbUser);
+        entry2.setLastUpdated(date);
+        entry2.setNodeType(nodeType);
+        entry2.setPersistenceUnit(A_SEQ_PU);
+        entry2.setResourceName(resourceName2);
+        entry2.setSite(siteName);
+
+        dbAudit.writeAuditDebugLog(className, resourceName1, resourceName2, entry1, entry2);
+
+        HashMap<Object, Object> myEntries = new HashMap<Object, Object>();
+        HashMap<Object, Object> theirEntries = new HashMap<Object, Object>();
+
+        myEntries.put("pdp1", entry1);
+        theirEntries.put("pdp1", entry2);
+
+        Set<Object> result = dbAudit.compareEntries(myEntries, theirEntries);
+
+        /*
+         * Assert that there are no mismatches returned
+         */
+        assertTrue(result.isEmpty());
+
+        logger.info("testSuccessfulComparison: Exit");
+    }
+
+    /*
+     * Tests that an error is detected if an entry in one hashset doesn't match the other
+     */
+    // @Ignore
+    @Test
+    public void testComparisonError() throws Exception {
+        logger.info("testComparisonError: Entering");
+
+        dbDao = new DbDAO(resourceName, A_SEQ_PU, makeProperties());
+        final DbAudit dbAudit = new DbAudit(dbDao);
+
+        final String resourceName1 = resourceName;
+        final String resourceName2 = resourceName;
+
+        final IntegrityAuditEntity entry1 = new IntegrityAuditEntity();
+        final IntegrityAuditEntity entry2 = new IntegrityAuditEntity();
+        Date date = new Date();
+
+        /*
+         * Create two entries with different designated values
+         */
+        entry1.setDesignated(false);
+        entry1.setJdbcDriver(dbDriver);
+        entry1.setJdbcPassword(dbPwd);
+        entry1.setJdbcUrl(dbUrl);
+        entry1.setJdbcUser(dbUser);
+        entry1.setLastUpdated(date);
+        entry1.setNodeType(nodeType);
+        entry1.setPersistenceUnit(A_SEQ_PU);
+        entry1.setResourceName(resourceName1);
+        entry1.setSite(siteName);
+
+        entry2.setDesignated(true);
+        entry2.setJdbcDriver(dbDriver);
+        entry2.setJdbcPassword(dbPwd);
+        entry2.setJdbcUrl(dbUrl);
+        entry2.setJdbcUser(dbUser);
+        entry2.setLastUpdated(date);
+        entry2.setNodeType(nodeType);
+        entry2.setPersistenceUnit(A_SEQ_PU);
+        entry2.setResourceName(resourceName2);
+        entry2.setSite(siteName);
+
+        HashMap<Object, Object> myEntries = new HashMap<Object, Object>();
+        HashMap<Object, Object> theirEntries = new HashMap<Object, Object>();
+
+        myEntries.put("pdp1", entry1);
+        theirEntries.put("pdp1", entry2);
+
+        Set<Object> result = dbAudit.compareEntries(myEntries, theirEntries);
+
+        /*
+         * Assert that there was one mismatch
+         */
+        assertEquals(1, result.size());
+
+        logger.info("testComparisonError: Exit");
+    }
+
+    /*
+     * Tests that a mismatch/miss entry is detected if there are missing entries in one or both of
+     * the hashsets
+     */
+    // @Ignore
+    @Test
+    public void testCompareMissingEntries() throws Exception {
+        logger.info("testCompareMissingEntries: Entering");
+
+        dbDao = new DbDAO(resourceName, A_SEQ_PU, makeProperties());
+        final DbAudit dbAudit = new DbAudit(dbDao);
+
+        final String resourceName1 = resourceName;
+        final String resourceName2 = resourceName;
+
+        final IntegrityAuditEntity entry1 = new IntegrityAuditEntity();
+        final IntegrityAuditEntity entry2 = new IntegrityAuditEntity();
+        final IntegrityAuditEntity entry3 = new IntegrityAuditEntity();
+        final IntegrityAuditEntity entry4 = new IntegrityAuditEntity();
+
+        Date date = new Date();
+
+        /*
+         * 4 entries, one mismatch, two miss entries
+         */
+        entry1.setDesignated(false);
+        entry1.setJdbcDriver(dbDriver);
+        entry1.setJdbcPassword(dbPwd);
+        entry1.setJdbcUrl(dbUrl);
+        entry1.setJdbcUser(dbUser);
+        entry1.setLastUpdated(date);
+        entry1.setNodeType(nodeType);
+        entry1.setPersistenceUnit(A_SEQ_PU);
+        entry1.setResourceName(resourceName1);
+        entry1.setSite(siteName);
+
+        entry2.setDesignated(true);
+        entry2.setJdbcDriver(dbDriver);
+        entry2.setJdbcPassword(dbPwd);
+        entry2.setJdbcUrl(dbUrl);
+        entry2.setJdbcUser(dbUser);
+        entry2.setLastUpdated(date);
+        entry2.setNodeType(nodeType);
+        entry2.setPersistenceUnit(A_SEQ_PU);
+        entry2.setResourceName(resourceName2);
+        entry2.setSite(siteName);
+
+        entry3.setDesignated(false);
+        entry3.setJdbcDriver(dbDriver);
+        entry3.setJdbcPassword(dbPwd);
+        entry3.setJdbcUrl(dbUrl);
+        entry3.setJdbcUser(dbUser);
+        entry3.setLastUpdated(date);
+        entry3.setNodeType(nodeType);
+        entry3.setPersistenceUnit(A_SEQ_PU);
+        entry3.setResourceName(resourceName2);
+        entry3.setSite("SiteB");
+
+        entry4.setDesignated(false);
+        entry4.setJdbcDriver(dbDriver);
+        entry4.setJdbcPassword(dbPwd);
+        entry4.setJdbcUrl(dbUrl);
+        entry4.setJdbcUser(dbUser);
+        entry4.setLastUpdated(date);
+        entry4.setNodeType(nodeType);
+        entry4.setPersistenceUnit(A_SEQ_PU);
+        entry4.setResourceName(resourceName2);
+        entry4.setSite("SiteB");
+
+        HashMap<Object, Object> myEntries = new HashMap<Object, Object>();
+        HashMap<Object, Object> theirEntries = new HashMap<Object, Object>();
+
+        myEntries.put("0", entry1);
+        myEntries.put("1", entry3);
+        theirEntries.put("0", entry2);
+        theirEntries.put("2", entry4);
+
+        Set<Object> mismatchResult = dbAudit.compareEntries(myEntries, theirEntries);
+
+        /*
+         * Assert 3 mismatches/missing entries were found
+         */
+        assertEquals(3, mismatchResult.size());
+
+        logger.info("testCompareMissingEntries: Exit");
+    }
+
+    /*
+     * Tests that comparison algorithm works for each entity in the hashsets
+     */
+    // @Ignore
+    @Test
+    public void testCompareAllHashEntities() throws Exception {
+        logger.info("testCompareAllHashEntities: Entering");
+
+        dbDao = new DbDAO(resourceName, A_SEQ_PU, makeProperties());
+        DbAudit dbAudit = new DbAudit(dbDao);
+
+        Set<String> classNameSet = dbDao.getPersistenceClassNames();
+        Set<Object> mismatchResult = new HashSet<Object>();
+        for (String className : classNameSet) {
+            if (className.equals("org.onap.policy.common.ia.jpa.IntegrityAuditEntity")) {
+                final String resourceName1 = resourceName;
+                final String resourceName2 = resourceName;
+
+                final IntegrityAuditEntity entry1 = new IntegrityAuditEntity();
+                final IntegrityAuditEntity entry2 = new IntegrityAuditEntity();
+                Date date = new Date();
+
+                /*
+                 * Two entries with the same field values
+                 */
+                entry1.setDesignated(false);
+                entry1.setJdbcDriver(dbDriver);
+                entry1.setJdbcPassword(dbPwd);
+                entry1.setJdbcUrl(dbUrl);
+                entry1.setJdbcUser(dbUser);
+                entry1.setLastUpdated(date);
+                entry1.setNodeType(nodeType);
+                entry1.setPersistenceUnit(A_SEQ_PU);
+                entry1.setResourceName(resourceName1);
+                entry1.setSite(siteName);
+
+                entry2.setDesignated(false);
+                entry2.setJdbcDriver(dbDriver);
+                entry2.setJdbcPassword(dbPwd);
+                entry2.setJdbcUrl(dbUrl);
+                entry2.setJdbcUser(dbUser);
+                entry2.setLastUpdated(date);
+                entry2.setNodeType(nodeType);
+                entry2.setPersistenceUnit(A_SEQ_PU);
+                entry2.setResourceName(resourceName2);
+                entry2.setSite(siteName);
+
+                HashMap<Object, Object> myEntries = new HashMap<Object, Object>();
+                HashMap<Object, Object> theirEntries = new HashMap<Object, Object>();
+
+                myEntries.put("pdp1", entry1);
+                theirEntries.put("pdp1", entry2);
+
+                mismatchResult = dbAudit.compareEntries(myEntries, theirEntries);
+
+                /*
+                 * Assert there was no mismatches
+                 */
+                assertTrue(mismatchResult.isEmpty());
+            } else if (className.equals("org.onap.policy.common.ia.jpa.IaTestEntity")) {
+                final IaTestEntity iate = new IaTestEntity();
+                final IaTestEntity iate2 = new IaTestEntity();
+                final IaTestEntity iate3 = new IaTestEntity();
+                final IaTestEntity iate4 = new IaTestEntity();
+
+                Date date = new Date();
+
+                /*
+                 * Four entries, 2 mismatches
+                 */
+                iate.setCreatedBy("Ford");
+                iate.setModifiedBy("Ford");
+                iate.setModifiedDate(date);
+
+                iate2.setCreatedBy("Ford");
+                iate2.setModifiedBy("Zaphod");
+                iate2.setModifiedDate(date);
+
+                iate3.setCreatedBy("Zaphod");
+                iate3.setModifiedBy("Ford");
+                iate3.setModifiedDate(date);
+
+                iate4.setCreatedBy("Ford");
+                iate4.setModifiedBy("Ford");
+                iate4.setModifiedDate(date);
+
+                HashMap<Object, Object> myEntries = new HashMap<Object, Object>();
+                HashMap<Object, Object> theirEntries = new HashMap<Object, Object>();
+
+                myEntries.put("0", iate);
+                myEntries.put("1", iate2);
+                theirEntries.put("0", iate3);
+                theirEntries.put("1", iate4);
+
+                mismatchResult = dbAudit.compareEntries(myEntries, theirEntries);
+
+                /*
+                 * Assert that there is 2 mismatches
+                 */
+                assertEquals(2, mismatchResult.size());
+            }
+        }
+
+        logger.info("testCompareAllHashEntities: Exit");
+    }
+
+    /*
+     * Tests that comparison algorithm works for each entity in the database
+     */
+    @Ignore
+    @Test
+    public void testCompareAllDbEntities() throws Exception {
+        logger.info("testCompareAllDbEntities: Entering");
+
+        logger.info("Setting up DB");
+
+        IntegrityAudit.setUnitTesting(true);
+
+        Properties properties = makeProperties();
+
+        Properties properties2 = makeProperties();
+        properties2.put(IntegrityAuditProperties.DB_URL,
+                "jdbc:h2:mem:" + DbAuditCompareEntriesTest.class.getSimpleName() + "2");
+
+        // Clean up the two DBs
+        truncateTables(properties);
+        truncateTables(properties2);
+
+        // Add entries into DB1
+        dbDao = new DbDAO(resourceName, A_SEQ_PU, properties);
+        new DbDAO("pdp2", A_SEQ_PU, properties).destroy();
+        DbAudit dbAudit = new DbAudit(dbDao);
+
+        // Add entries into DB2
+        DbDAO dbDao3 = new DbDAO(resourceName, A_SEQ_PU, properties2);
+        new DbDAO("pdp2", A_SEQ_PU, properties2).destroy();
+
+        // Pull all entries and compare
+        Set<String> classNameSet = dbDao.getPersistenceClassNames();
+        Map<Object, Object> myEntries;
+        Map<Object, Object> theirEntries;
+        Set<Object> mismatchResult = new HashSet<Object>();
+        for (String className : classNameSet) {
+            logger.info("classNameSet entry = " + className);
+            myEntries = dbDao.getAllEntries(A_SEQ_PU, properties, className);
+            theirEntries = dbDao3.getAllEntries(A_SEQ_PU, properties2, className);
+            mismatchResult = dbAudit.compareEntries(myEntries, theirEntries);
+            if (className.contains("IntegrityAuditEntity")) {
+                break;
+            }
+        }
+
+        dbDao3.destroy();
+
+        // Assert that there is 2 mismatches between IntegrityAuditEntity tables
+        assertEquals(2, mismatchResult.size());
+
+        logger.info("testCompareAllDbEntities: Exit");
+    }
+
+    /**
+     * Truncate the tables.
+     * 
+     * @param properties the properties
+     */
+    private void truncateTables(Properties properties) {
+        truncateTable(properties, A_SEQ_PU, "IntegrityAuditEntity");
+        truncateTable(properties, A_SEQ_PU, "IaTestEntity");
+    }
+
+    /*
+     * Tests that differences in embedded classes are still caught
+     */
+    // @Ignore
+    @Test
+    public void testEmbeddedClass() throws Exception {
+        logger.info("testEmbeddedClasses: Entering");
+
+        dbDao = new DbDAO(resourceName, A_SEQ_PU, properties);
+        final DbAudit dbAudit = new DbAudit(dbDao);
+
+        String className = null;
+        // There is only one entry IntegrityAuditEntity, but we will check
+        // anyway
+        Set<String> classNameSet = dbDao.getPersistenceClassNames();
+        for (String classNameInClassNameSet : classNameSet) {
+            if (classNameInClassNameSet.equals("org.onap.policy.common.ia.jpa.IaTestEntity")) {
+                className = classNameInClassNameSet;
+            }
+        }
+
+        final IaTestEntity iate = new IaTestEntity();
+        final IaTestEntity iate2 = new IaTestEntity();
+
+        final Date date = new Date();
+
+        PersonSample person = new PersonSample("Ford", "Prefect", 21);
+        PersonSample person2 = new PersonSample("Zaphod", "Beeblebrox", 25);
+
+        /*
+         * Silly tests to bump coverage stats, not sure why they are counting PersonSample to begin
+         * with. Will have to look into that at some point.
+         */
+        assertNotEquals(person.getAge(), person2.getAge());
+        assertNotEquals(person.getFirstName(), person2.getFirstName());
+        assertNotEquals(person.getLasttName(), person2.getLasttName());
+        PersonSample personTest = new PersonSample(null, null, 0);
+        personTest.setAge(person.getAge());
+        personTest.setFirstName(person.getFirstName());
+        personTest.setLastName(person.getLasttName());
+        /*
+         * Two entries, 1 mismatch
+         */
+        iate.setCreatedBy("Ford");
+        iate.setModifiedBy("Zaphod");
+        iate.setModifiedDate(date);
+        iate.setPersonTest(person);
+
+        iate2.setCreatedBy("Ford");
+        iate2.setModifiedBy("Zaphod");
+        iate2.setModifiedDate(date);
+        iate2.setPersonTest(person2);
+
+        dbAudit.writeAuditDebugLog(className, "resource1", "resource2", iate, iate2);
+
+        HashMap<Object, Object> myEntries = new HashMap<Object, Object>();
+        HashMap<Object, Object> theirEntries = new HashMap<Object, Object>();
+
+        myEntries.put("0", iate);
+        theirEntries.put("0", iate2);
+
+        Set<Object> result = dbAudit.compareEntries(myEntries, theirEntries);
+
+        /*
+         * Assert that there are no mismatches returned
+         */
+        assertTrue(!result.isEmpty());
+
+        logger.info("testEmbeddedClasses: Exit");
+    }
 }
index ad4041f..cfbf90c 100644 (file)
@@ -53,230 +53,236 @@ import org.onap.policy.common.utils.test.log.logback.ExtractAppender;
  */
 public class DbAuditTest extends IntegrityAuditTestBase {
 
-       private static Logger logger = FlexLogger.getLogger(DbAuditTest.class);
+    private static Logger logger = FlexLogger.getLogger(DbAuditTest.class);
+
+    private static final String resourceName = "pdp1";
+
+    private EntityManagerFactory emf2;
+    private EntityManager em2;
+    private DbDAO dbDao;
+
+    @BeforeClass
+    public static void setUpBeforeClass() throws Exception {
+        IntegrityAuditTestBase.setUpBeforeClass(DEFAULT_DB_URL_PREFIX + DbAuditTest.class.getSimpleName());
+        IntegrityAuditEntity.setUnitTesting(true);
+    }
+
+    @AfterClass
+    public static void tearDownAfterClass() {
+        IntegrityAuditTestBase.tearDownAfterClass();
+        IntegrityAuditEntity.setUnitTesting(false);
+    }
+
+    /**
+     * Set up for test cases.
+     */
+    @Override
+    @Before
+    public void setUp() {
+        logger.info("setUp: Entering");
+
+        super.setUp();
+
+        dbDao = null;
+        emf2 = null;
+        em2 = null;
+
+        logger.info("setUp: Exiting");
+    }
+
+    /**
+     * Tear down after test cases.
+     */
+    @Override
+    @After
+    public void tearDown() {
+        logger.info("tearDown: Entering");
+
+        if (dbDao != null) {
+            dbDao.destroy();
+        }
+
+        if (em2 != null) {
+            em2.close();
+        }
+
+        if (emf2 != null) {
+            emf2.close();
+        }
+
+        super.tearDown();
 
-       private static final String resourceName = "pdp1";
+        logger.info("tearDown: Exiting");
+    }
+
+    private void createDb(Properties properties) {
+        if (emf2 != null) {
+            throw new IllegalStateException("DB2 has already been created");
+        }
+
+        // open the DB and ensure it stays open until the test completes
+        emf2 = Persistence.createEntityManagerFactory(A_SEQ_PU, properties);
+        em2 = emf2.createEntityManager();
+
+        truncateTable(properties, A_SEQ_PU, "IntegrityAuditEntity");
+    }
+
+    /*
+     * Tests printing an error to the log in the event where there are no entities saved in the
+     * database
+     */
+    @Test
+    public void noEntitiesTest() throws Exception {
+        Properties properties = makeProperties();
+
+        logger.info("noEntitiesTest: Entering");
+
+        dbDao = new DbDAO(resourceName, A_SEQ_PU, properties);
+        dbDao.deleteAllIntegrityAuditEntities();
+        try {
+            DbAudit dbAudit = new DbAudit(dbDao);
+            dbAudit.dbAudit(resourceName, A_SEQ_PU, nodeType);
+            fail("found unexpected entities");
+
+        } catch (DbAuditException e) {
+            // Ignore expected exception
+        }
+
+        logger.info("noEntitiesTest: Exit");
+    }
+
+    /*
+     * Tests the detection of only one entry in the database
+     */
+    @Test
+    public void oneEntityTest() throws Exception {
+        Properties properties = makeProperties();
+
+        logger.info("oneEntityTest: Entering");
+
+        final ExtractAppender log = watch(debugLogger, "DbAudit: Found only (one) IntegrityAuditEntity entry:");
+
+        // Add one entry in the database
+        dbDao = new DbDAO(resourceName, A_SEQ_PU, properties);
+        DbAudit dbAudit = new DbAudit(dbDao);
+        dbAudit.dbAudit(resourceName, A_SEQ_PU, nodeType);
+
+        List<IntegrityAuditEntity> iaeList = dbDao.getIntegrityAuditEntities(A_SEQ_PU, nodeType);
+        logger.info("List size: " + iaeList.size());
+
+        verifyItemsInLog(log, "one");
+
+        logger.info("oneEntityTest: Exit");
+    }
+
+    /*
+     * Tests reporting mismatches and missing entries using the error log
+     */
+    @Test
+    public void mismatchTest() throws Exception {
+        logger.info("mismatchTest: Entering");
+
+        // use new URLs so we get a completely new DB
+        String dbUrl = DbAuditTest.dbUrl + "_mismatchTest";
+        String dbUrl2 = dbUrl + "2";
+
+        Properties properties = makeProperties();
+        properties.put(IntegrityAuditProperties.DB_URL, dbUrl);
+
+        // Properties for DB2
+        Properties properties2 = makeProperties();
+        properties2.put(IntegrityAuditProperties.DB_URL, dbUrl2);
+
+        /*
+         * We must drop and re-create DB1 so that it's sequence generator is in step with the
+         * sequence generator for DB2.
+         */
+        recreateDb1(properties);
+
+        // create/open DB2
+        createDb(properties2);
 
-       private EntityManagerFactory emf2;
-       private EntityManager em2;
-       private DbDAO dbDAO;
+        final ExtractAppender dbglog = watch(debugLogger, "Mismatched entries [(]keys[)]:(.*)");
+        final ExtractAppender errlog = watch(errorLogger, "DB Audit: ([0-9])");
+
+        /*
+         * Create entries in DB1 & DB2 for the resource of interest
+         */
+        dbDao = new DbDAO(resourceName, A_SEQ_PU, properties);
 
-       @BeforeClass
-       public static void setUpBeforeClass() throws Exception {
-               IntegrityAuditTestBase.setUpBeforeClass(DEFAULT_DB_URL_PREFIX + DbAuditTest.class.getSimpleName());
-               IntegrityAuditEntity.setUnitTesting(true);
-       }
+        new DbDAO(resourceName, A_SEQ_PU, properties2).destroy();
+
+        /*
+         * Entries in DB1, pointing to DB2, except for pdp3
+         */
+        new DbDAO("pdp2", A_SEQ_PU, properties, dbUrl2).destroy();
+        new DbDAO("pdp1", A_SEQ_PU, properties, dbUrl2).destroy();
+        new DbDAO("pdp3", A_SEQ_PU, properties).destroy(); // mismatched URL
+        new DbDAO("pdp4", A_SEQ_PU, properties, dbUrl2).destroy();
+
+        /*
+         * Identical entries in DB2, all pointing to DB2, including pdp3, but leaving out pdp4
+         */
+        new DbDAO("pdp2", A_SEQ_PU, properties2).destroy();
+        new DbDAO("pdp1", A_SEQ_PU, properties2).destroy();
+        new DbDAO("pdp3", A_SEQ_PU, properties2).destroy();
+
+        /*
+         * Run the DB Audit, once it finds a mismatch and sleeps, update DB1 to have the same entry
+         * as DB2 it can be confirmed that the mismatch is resolved
+         */
+        DbAudit dbAudit = new DbAudit(dbDao);
+        dbAudit.dbAudit(resourceName, A_SEQ_PU, nodeType);
 
-       @AfterClass
-       public static void tearDownAfterClass() {
-               IntegrityAuditTestBase.tearDownAfterClass();
-               IntegrityAuditEntity.setUnitTesting(false);
-       }
+        // update pdp3 entry in DB1 to point to DB2
+        new DbDAO("pdp3", A_SEQ_PU, properties, dbUrl2).destroy();
+
+        /*
+         * Run the audit again and correct the mismatch, the result should be one entry in the
+         * mismatchKeySet because of the missing entry from the beginning of the test
+         */
+        dbAudit.dbAudit(resourceName, A_SEQ_PU, nodeType);
 
-       @Before
-       public void setUp() {
-               logger.info("setUp: Entering");
+        assertFalse(dbglog.getExtracted().isEmpty());
+
+        String mismatchIndex = dbglog.getExtracted().get(dbglog.getExtracted().size() - 1);
+        int mismatchEntries = mismatchIndex.trim().split(",").length;
+        logger.info("mismatchTest: mismatchIndex found: '" + mismatchIndex + "'" + " mismatachEntries = "
+                + mismatchEntries);
 
-               super.setUp();
+        // Assert there is only one entry index
+        assertEquals(1, mismatchEntries);
+
+        // Now check the entry in the error.log
+        assertFalse(errlog.getExtracted().isEmpty());
 
-               dbDAO = null;
-               emf2 = null;
-               em2 = null;
+        String mismatchNum = errlog.getExtracted().get(errlog.getExtracted().size() - 1);
 
-               logger.info("setUp: Exiting");
-       }
+        logger.info("mismatchTest: mismatchNum found: '" + mismatchNum + "'");
 
-       @After
-       public void tearDown() {
-               logger.info("tearDown: Entering");
+        // Assert that there are a total of 3 mismatches - 1 between each
+        // comparison node.
+        assertEquals("3", mismatchNum);
+
+        logger.info("mismatchTest: Exit");
+    }
 
-               if (dbDAO != null) {
-                       dbDAO.destroy();
-               }
-
-               if (em2 != null) {
-                       em2.close();
-               }
-
-               if (emf2 != null) {
-                       emf2.close();
-               }
-
-               super.tearDown();
-
-               logger.info("tearDown: Exiting");
-       }
-
-       private void createDb(Properties properties) {
-               if (emf2 != null) {
-                       throw new IllegalStateException("DB2 has already been created");
-               }
-
-               // open the DB and ensure it stays open until the test completes
-               emf2 = Persistence.createEntityManagerFactory(A_SEQ_PU, properties);
-               em2 = emf2.createEntityManager();
-
-               truncateTable(properties, A_SEQ_PU, "IntegrityAuditEntity");
-       }
-
-       /*
-        * Tests printing an error to the log in the event where there are no
-        * entities saved in the database
-        */
-       @Test
-       public void noEntitiesTest() throws Exception {
-               Properties properties = makeProperties();
-
-               logger.info("noEntitiesTest: Entering");
-
-               dbDAO = new DbDAO(resourceName, A_SEQ_PU, properties);
-               dbDAO.deleteAllIntegrityAuditEntities();
-               try {
-                       DbAudit dbAudit = new DbAudit(dbDAO);
-                       dbAudit.dbAudit(resourceName, A_SEQ_PU, nodeType);
-                       fail("found unexpected entities");
-
-               } catch (DbAuditException e) {
-
-               }
-
-               logger.info("noEntitiesTest: Exit");
-       }
-
-       /*
-        * Tests the detection of only one entry in the database
-        */
-       @Test
-       public void oneEntityTest() throws Exception {
-               Properties properties = makeProperties();
-
-               logger.info("oneEntityTest: Entering");
-
-               ExtractAppender log = watch(debugLogger, "DbAudit: Found only (one) IntegrityAuditEntity entry:");
-
-               // Add one entry in the database
-               dbDAO = new DbDAO(resourceName, A_SEQ_PU, properties);
-               DbAudit dbAudit = new DbAudit(dbDAO);
-               dbAudit.dbAudit(resourceName, A_SEQ_PU, nodeType);
-
-               List<IntegrityAuditEntity> iaeList = dbDAO.getIntegrityAuditEntities(A_SEQ_PU, nodeType);
-               logger.info("List size: " + iaeList.size());
-
-               verifyItemsInLog(log, "one");
-
-               logger.info("oneEntityTest: Exit");
-       }
-
-       /*
-        * Tests reporting mismatches and missing entries using the error log
-        */
-       @Test
-       public void mismatchTest() throws Exception {
-               logger.info("mismatchTest: Entering");
-               
-               // use new URLs so we get a completely new DB
-               String dbUrl = DbAuditTest.dbUrl + "_mismatchTest";
-               String dbUrl2 = dbUrl + "2";
-
-               Properties properties = makeProperties();
-               properties.put(IntegrityAuditProperties.DB_URL, dbUrl);
-
-               // Properties for DB2
-               Properties properties2 = makeProperties();
-               properties2.put(IntegrityAuditProperties.DB_URL, dbUrl2);
-
-               /*
-                * We must drop and re-create DB1 so that it's sequence generator is in
-                * step with the sequence generator for DB2.
-                */             
-               recreateDb1(properties);
-
-               // create/open DB2
-               createDb(properties2);
-
-               ExtractAppender dbglog = watch(debugLogger, "Mismatched entries [(]keys[)]:(.*)");
-               ExtractAppender errlog = watch(errorLogger, "DB Audit: ([0-9])");
-
-               /*
-                * Create entries in DB1 & DB2 for the resource of interest
-                */
-               dbDAO = new DbDAO(resourceName, A_SEQ_PU, properties);
-
-               new DbDAO(resourceName, A_SEQ_PU, properties2).destroy();
-
-               /*
-                * Entries in DB1, pointing to DB2, except for pdp3
-                */
-               new DbDAO("pdp2", A_SEQ_PU, properties, dbUrl2).destroy();
-               new DbDAO("pdp1", A_SEQ_PU, properties, dbUrl2).destroy();
-               new DbDAO("pdp3", A_SEQ_PU, properties).destroy(); // mismatched URL
-               new DbDAO("pdp4", A_SEQ_PU, properties, dbUrl2).destroy();
-
-               /*
-                * Identical entries in DB2, all pointing to DB2, including pdp3, but
-                * leaving out pdp4
-                */
-               new DbDAO("pdp2", A_SEQ_PU, properties2).destroy();
-               new DbDAO("pdp1", A_SEQ_PU, properties2).destroy();
-               new DbDAO("pdp3", A_SEQ_PU, properties2).destroy();
-
-               /*
-                * Run the DB Audit, once it finds a mismatch and sleeps, update DB1 to
-                * have the same entry as DB2 it can be confirmed that the mismatch is
-                * resolved
-                */
-               DbAudit dbAudit = new DbAudit(dbDAO);
-               dbAudit.dbAudit(resourceName, A_SEQ_PU, nodeType);
-
-               // update pdp3 entry in DB1 to point to DB2
-               new DbDAO("pdp3", A_SEQ_PU, properties, dbUrl2).destroy();
-
-               /*
-                * Run the audit again and correct the mismatch, the result should be
-                * one entry in the mismatchKeySet because of the missing entry from the
-                * beginning of the test
-                */
-               dbAudit.dbAudit(resourceName, A_SEQ_PU, nodeType);
-
-               assertFalse(dbglog.getExtracted().isEmpty());
-
-               String mismatchIndex = dbglog.getExtracted().get(dbglog.getExtracted().size() - 1);
-               int mismatchEntries = mismatchIndex.trim().split(",").length;
-               logger.info("mismatchTest: mismatchIndex found: '" + mismatchIndex + "'" + " mismatachEntries = "
-                               + mismatchEntries);
-
-               // Assert there is only one entry index
-               assertEquals(1, mismatchEntries);
-
-               // Now check the entry in the error.log
-               assertFalse(errlog.getExtracted().isEmpty());
-
-               String mismatchNum = errlog.getExtracted().get(errlog.getExtracted().size() - 1);
-
-               logger.info("mismatchTest: mismatchNum found: '" + mismatchNum + "'");
-
-               // Assert that there are a total of 3 mismatches - 1 between each
-               // comparison node.
-               assertEquals("3", mismatchNum);
-
-               logger.info("mismatchTest: Exit");
-       }
-
-       /**
-        * Re-creates DB1, using the specified properties.
-        * @param properties
-        */
-       private void recreateDb1(Properties properties) {
-               em.close();
-               emf.close();
-               
-               createDb(properties);
-               
-               em = em2;
-               emf = emf2;
-               
-               em2 = null;
-               emf2 = null;
-       }
+    /**
+     * Re-creates DB1, using the specified properties.
+     * 
+     * @param properties the properties
+     */
+    private void recreateDb1(Properties properties) {
+        em.close();
+        emf.close();
+
+        createDb(properties);
+
+        em = em2;
+        emf = emf2;
+
+        em2 = null;
+        emf2 = null;
+    }
 
 }
index c4cba28..01e2f2b 100644 (file)
@@ -30,6 +30,7 @@ import static org.junit.Assert.assertTrue;
  * where they have write privileges and can execute time-sensitive
  * tasks.
  */
+
 import java.util.Date;
 import java.util.HashSet;
 import java.util.List;
@@ -58,393 +59,399 @@ import org.onap.policy.common.utils.jpa.EntityTransCloser;
  * tasks.
  */
 public class DbDAOTest extends IntegrityAuditTestBase {
-       private static String resourceName = "pdp0";
-
-       private DbDAO d;
-
-       @BeforeClass
-       public static void setUpBeforeClass() throws Exception {
-               IntegrityAuditTestBase.setUpBeforeClass(DEFAULT_DB_URL_PREFIX + DbDAOTest.class.getSimpleName());
-       }
-
-       @AfterClass
-       public static void tearDownAfterClass() {
-               IntegrityAuditTestBase.tearDownAfterClass();
-       }
-
-       @Before
-       public void setUp() {
-               super.setUp();
-               d = null;
-       }
-
-       @After
-       public void tearDown() {
-               if(d != null) {
-                       d.destroy();
-               }
-               
-               super.tearDown();
-       }
-
-       /* Tests registering a new IntegrityAuditEntity object in the DB */
-       @Test
-       public void testNewRegistration() throws Exception {
-               Properties properties = makeProperties();
-
-               try(EntityTransCloser et = new EntityTransCloser(em.getTransaction())) {
-                       d = new DbDAO(resourceName, A_SEQ_PU, properties);
-
-                       // Find the proper entry in the database
-                       Query iaequery = em
-                                       .createQuery("Select i from IntegrityAuditEntity i where i.resourceName=:rn and i.persistenceUnit=:pu");
-                       iaequery.setParameter("rn", DbDAOTest.resourceName);
-                       iaequery.setParameter("pu", DbDAOTest.A_SEQ_PU);
-
-                       @SuppressWarnings("rawtypes")
-                       List iaeList = iaequery.getResultList();
-
-                       // Assert that the IntegrityAuditEntity object was found
-                       assertNotNull(iaeList);
-
-                       // flush to the DB
-                       em.flush();
-                       et.commit();
-               }
-       }
-
-       /*
-        * Tests updating an IntegrityAuditEntity if it has already been registered
-        */
-       @Test
-       public void testUpdateRegistration() throws Exception {
-               Properties properties = makeProperties();
-
-               d = new DbDAO(resourceName, A_SEQ_PU, properties);
-
-               // Change site_name in properties to test that an update was made to
-               // an existing entry in the table
-               properties.put(IntegrityAuditProperties.SITE_NAME, "SiteB");
-               d = new DbDAO(resourceName, A_SEQ_PU, properties);
-
-               try(EntityTransCloser et = new EntityTransCloser(em.getTransaction())) {
-                       // Find the proper entry in the database
-                       Query iaequery = em
-                                       .createQuery("Select i from IntegrityAuditEntity i where i.resourceName=:rn and i.persistenceUnit=:pu");
-                       iaequery.setParameter("rn", DbDAOTest.resourceName);
-                       iaequery.setParameter("pu", DbDAOTest.A_SEQ_PU);
-
-                       @SuppressWarnings("rawtypes")
-                       List iaeList = iaequery.getResultList();
-                       IntegrityAuditEntity iae = null;
-                       if (!iaeList.isEmpty()) {
-                               // ignores multiple results
-                               iae = (IntegrityAuditEntity) iaeList.get(0);
-
-                               em.refresh(iae);
-                               em.persist(iae);
-
-                               // flush to the DB
-                               em.flush();
-
-                               // commit transaction
-                               et.commit();
-
-                               // Assert that the site_name for the existing entry was updated
-                               assertEquals("SiteB", iae.getSite());
-                       }
-               }
-       }
-
-       /* Tests obtaining all Integrity Audit Entities from a table */
-       @Test
-       public void testGetIntegrityAuditEntities() throws Exception {
-               Properties properties = makeProperties();
-
-               // Add some entries to the DB
-               d = new DbDAO(resourceName, A_SEQ_PU, properties);
-               new DbDAO("pdp1", A_SEQ_PU, properties).destroy();
-               properties.put(IntegrityAuditProperties.NODE_TYPE, "pdp_drools");
-               new DbDAO("pdp2", A_SEQ_PU, properties).destroy();
-
-               List<IntegrityAuditEntity> entities;
-               // Obtain entries based on persistenceUnit and nodeType
-               entities = d.getIntegrityAuditEntities(A_SEQ_PU, "pdp_xacml");
-               assertEquals(2, entities.size());
-       }
-
-       /* Tests retrieving a DbDAO instance's IntegrityAuditEntity */
-       @Test
-       public void testGetMyIntegrityAuditEntity() throws Exception {
-               Properties properties = makeProperties();
-
-               d = new DbDAO(resourceName, A_SEQ_PU, properties);
-               IntegrityAuditEntity iae = d.getMyIntegrityAuditEntity();
-               // assertEquals("integrityAuditPU", iae.getPersistenceUnit());
-               assertEquals(A_SEQ_PU, iae.getPersistenceUnit());
-       }
-
-       /* Tests obtaining an IntegrityAuditEntity by ID */
-       @Test
-       public void testGetIntegrityAuditEntity() throws Exception {
-               Properties properties = makeProperties();
-
-               // Obtain an entry from the database based on ID
-               d = new DbDAO(resourceName, A_SEQ_PU, properties);
-
-               // Find the proper database entry
-               Query iaequery = em
-                               .createQuery("Select i from IntegrityAuditEntity i where i.resourceName=:rn and i.persistenceUnit=:pu");
-               iaequery.setParameter("rn", DbDAOTest.resourceName);
-               iaequery.setParameter("pu", DbDAOTest.A_SEQ_PU);
-
-               @SuppressWarnings("rawtypes")
-               List iaeList = iaequery.getResultList();
-               IntegrityAuditEntity iae = null;
-               if (!iaeList.isEmpty()) {
-                       // ignores multiple results
-                       iae = (IntegrityAuditEntity) iaeList.get(0);
-
-                       // refresh the object from DB in case cached data was returned
-                       em.refresh(iae);
-
-                       // Obtain ID for an IntegrityAuditEntity
-                       PersistenceUnitUtil util = emf.getPersistenceUnitUtil();
-                       Object iaeId = util.getIdentifier(iae);
-
-                       // Obtain the same IntegrityAuditEntity based on ID
-                       IntegrityAuditEntity iaeDuplicate = d.getIntegrityAuditEntity((long) iaeId);
-                       Object duplicateId = util.getIdentifier(iaeDuplicate);
-
-                       // Assert that the proper entry was retrieved based on ID
-                       assertEquals((long) iaeId, (long) duplicateId);
-               }
-       }
-
-       /* Tests setting an IntegrityAuditEntity as the designated node */
-       @Test
-       public void testSetDesignated() throws Exception {
-               Properties properties = makeProperties();
-
-               try(EntityTransCloser et = new EntityTransCloser(em.getTransaction())) {
-                       // Create an entry and set it's designated field to true
-                       d = new DbDAO(resourceName, A_SEQ_PU, properties);
-                       d.setDesignated(resourceName, A_SEQ_PU, true);
-
-                       // Find the proper entry in the database
-                       Query iaequery = em
-                                       .createQuery("Select i from IntegrityAuditEntity i where i.resourceName=:rn and i.persistenceUnit=:pu");
-                       iaequery.setParameter("rn", resourceName);
-                       iaequery.setParameter("pu", A_SEQ_PU);
-
-                       @SuppressWarnings("rawtypes")
-                       List iaeList = iaequery.getResultList();
-                       IntegrityAuditEntity iae = null;
-
-                       if (!iaeList.isEmpty()) {
-                               // ignores multiple results
-                               iae = (IntegrityAuditEntity) iaeList.get(0);
-                               em.refresh(iae);
-
-                               // Check if the node is designated
-                               boolean result = iae.isDesignated();
-
-                               // Assert that it is designated
-                               assertTrue(result);
-                       }
-
-                       // flush to the DB
-                       em.flush();
-
-                       // close the transaction
-                       et.commit();
-               }
-       }
-
-       /* Tests that the lastUpdated column in the database is updated properly */
-       @Test
-       public void testSetLastUpdated() throws Exception {
-               Properties properties = makeProperties();
-
-               try(EntityTransCloser et = new EntityTransCloser(em.getTransaction())) {
-                       // Create an entry
-                       d = new DbDAO(resourceName, A_SEQ_PU, properties);
-
-                       // Find the proper entry in the database
-                       Query iaequery = em
-                                       .createQuery("Select i from IntegrityAuditEntity i where i.resourceName=:rn and i.persistenceUnit=:pu");
-                       iaequery.setParameter("rn", resourceName);
-                       iaequery.setParameter("pu", A_SEQ_PU);
-
-                       @SuppressWarnings("rawtypes")
-                       List iaeList = iaequery.getResultList();
-                       IntegrityAuditEntity iae = null;
-
-                       if (!iaeList.isEmpty()) {
-                               // ignores multiple results
-                               iae = (IntegrityAuditEntity) iaeList.get(0);
-                               // refresh the object from DB in case cached data was returned
-                               em.refresh(iae);
-
-                               // Obtain old update value and set new update value
-                               Date oldDate = iae.getLastUpdated();
-
-                               // ensure dates are different by sleeping for a bit
-                               Thread.sleep(1);
-
-                               iae.setSite("SiteB");
-                               iae.setLastUpdated(new Date());
-                               Date newDate = iae.getLastUpdated();
-
-                               em.persist(iae);
-                               // flush to the DB
-                               em.flush();
-                               // close the transaction
-                               et.commit();
-
-                               // Assert that the old and new update times are different
-                               assertNotEquals(oldDate, newDate);
-                       }
-               }
-       }
-
-       /* Tests that all the entries from a class can be retrieved */
-       @Test
-       public void testGetAllMyEntriesString() throws Exception {
-               Properties properties = makeProperties();
-
-               // create entries for the IntegrityAuditEntity table
-               d = new DbDAO(resourceName, A_SEQ_PU, properties);
-               new DbDAO("pdp1", A_SEQ_PU, properties).destroy();
-               new DbDAO("pdp2", A_SEQ_PU, properties).destroy();
-
-               // Obtain a hash with the persisted objects
-               Map<Object, Object> entries = d.getAllMyEntries("org.onap.policy.common.ia.jpa.IntegrityAuditEntity");
-
-               // Assert there were 3 entries for that class
-               assertEquals(3, entries.size());
-       }
-
-       /*
-        * Tests retrieving all entities in a Persistence Unit using the class name
-        * and a hashset of IDs
-        */
-       @Test
-       public void testGetAllMyEntriesStringHashSet() throws Exception {
-               Properties properties = makeProperties();
-
-               // create entries for the IntegrityAuditEntity table
-               d = new DbDAO(resourceName, A_SEQ_PU, properties);
-               new DbDAO("pdp1", A_SEQ_PU, properties).destroy();
-               new DbDAO("pdp2", A_SEQ_PU, properties).destroy();
-
-               // Obtain all entity keys
-               CriteriaBuilder cb = em.getCriteriaBuilder();
-               CriteriaQuery<Object> cq = cb.createQuery();
-               Root<?> rootEntry = cq.from(Class.forName("org.onap.policy.common.ia.jpa.IntegrityAuditEntity"));
-               CriteriaQuery<Object> all = cq.select(rootEntry);
-               TypedQuery<Object> allQuery = em.createQuery(all);
-               List<Object> objectList = allQuery.getResultList();
-               HashSet<Object> resultSet = new HashSet<Object>();
-               PersistenceUnitUtil util = emf.getPersistenceUnitUtil();
-               for (Object o : objectList) {
-                       Object key = util.getIdentifier(o);
-                       resultSet.add(key);
-               }
-
-               // Obtain a hash with the persisted objects
-               Map<Object, Object> entries = d.getAllMyEntries("org.onap.policy.common.ia.jpa.IntegrityAuditEntity",
-                               resultSet);
-
-               // Assert there were 3 entries for that class
-               assertEquals(3, entries.size());
-       }
-
-       /*
-        * Tests retrieving all entities in a Persistence Unit using the persistence
-        * unit, properties, and class name
-        */
-       @Test
-       public void testGetAllEntriesStringPropertiesString() throws Exception {
-               Properties properties = makeProperties();
-
-               // create entries for the IntegrityAuditEntity table
-               d = new DbDAO(resourceName, A_SEQ_PU, properties);
-               new DbDAO("pdp1", A_SEQ_PU, properties).destroy();
-               new DbDAO("pdp2", A_SEQ_PU, properties).destroy();
-
-               // Obtain a hash with the persisted objects
-               Map<Object, Object> entries = d.getAllEntries("integrityAuditPU", properties,
-                               "org.onap.policy.common.ia.jpa.IntegrityAuditEntity");
-
-               // Assert there were 3 entries for that class
-               assertEquals(3, entries.size());
-       }
-
-       /*
-        * Tests retrieving all entities in a Persistence Unit using the persistence
-        * unit, properties, class name, and a hashset of IDs
-        */
-       @Test
-       public void testGetAllEntriesStringPropertiesStringHashSet() throws Exception {
-               Properties properties = makeProperties();
-
-               // create entries for the IntegrityAuditEntity table
-               d = new DbDAO(resourceName, A_SEQ_PU, properties);
-               new DbDAO("pdp1", A_SEQ_PU, properties).destroy();
-               new DbDAO("pdp2", A_SEQ_PU, properties).destroy();
-
-               // Obtain all entity keys
-               CriteriaBuilder cb = em.getCriteriaBuilder();
-               CriteriaQuery<Object> cq = cb.createQuery();
-               Root<?> rootEntry = cq.from(Class.forName("org.onap.policy.common.ia.jpa.IntegrityAuditEntity"));
-               CriteriaQuery<Object> all = cq.select(rootEntry);
-               TypedQuery<Object> allQuery = em.createQuery(all);
-               List<Object> objectList = allQuery.getResultList();
-               HashSet<Object> resultSet = new HashSet<Object>();
-               PersistenceUnitUtil util = emf.getPersistenceUnitUtil();
-               for (Object o : objectList) {
-                       Object key = util.getIdentifier(o);
-                       resultSet.add(key);
-               }
-
-               // Obtain a hash with the persisted objects
-               Map<Object, Object> entries = d.getAllEntries("integrityAuditPU", properties,
-                               "org.onap.policy.common.ia.jpa.IntegrityAuditEntity", resultSet);
-
-               // Assert there were 3 entries for that class
-               assertEquals(3, entries.size());
-       }
-
-       /*
-        * Tests getting all the entries from a class based on persistenceUnit,
-        * properties, and className
-        */
-       @Test
-       public void testGetAllEntries() throws Exception {
-               Properties properties = makeProperties();
-
-               // create entries for the IntegrityAuditEntity table
-               d = new DbDAO(resourceName, A_SEQ_PU, properties);
-               new DbDAO("pdp1", A_SEQ_PU, properties).destroy();
-               new DbDAO("pdp2", A_SEQ_PU, properties).destroy();
-
-               // Obtain a hash with the persisted objects
-               Map<Object, Object> entries = d.getAllEntries(A_SEQ_PU, properties,
-                               "org.onap.policy.common.ia.jpa.IntegrityAuditEntity");
-
-               // Assert there were 3 entries for that class
-               assertEquals(3, entries.size());
-       }
-
-       /* Tests obtaining all class names of persisted classes */
-       public void testGetPersistenceClassNames() throws Exception {
-               Properties properties = makeProperties();
-
-               d = new DbDAO(resourceName, A_SEQ_PU, properties);
-
-               // Retrieve persistence class names
-               Set<String> result = d.getPersistenceClassNames();
-               assertEquals(1, result.size());
-       }
+    private static String resourceName = "pdp0";
+
+    private DbDAO dbDao;
+
+    @BeforeClass
+    public static void setUpBeforeClass() throws Exception {
+        IntegrityAuditTestBase.setUpBeforeClass(DEFAULT_DB_URL_PREFIX + DbDAOTest.class.getSimpleName());
+    }
+
+    @AfterClass
+    public static void tearDownAfterClass() {
+        IntegrityAuditTestBase.tearDownAfterClass();
+    }
+
+    @Override
+    @Before
+    public void setUp() {
+        super.setUp();
+        dbDao = null;
+    }
+
+    /**
+     * Tear down after test cases.
+     */
+    @Override
+    @After
+    public void tearDown() {
+        if (dbDao != null) {
+            dbDao.destroy();
+        }
+
+        super.tearDown();
+    }
+
+    /* Tests registering a new IntegrityAuditEntity object in the DB */
+    @Test
+    public void testNewRegistration() throws Exception {
+        Properties properties = makeProperties();
+
+        try (EntityTransCloser et = new EntityTransCloser(em.getTransaction())) {
+            dbDao = new DbDAO(resourceName, A_SEQ_PU, properties);
+
+            // Find the proper entry in the database
+            Query iaequery = em.createQuery(
+                    "Select i from IntegrityAuditEntity i where i.resourceName=:rn and i.persistenceUnit=:pu");
+            iaequery.setParameter("rn", DbDAOTest.resourceName);
+            iaequery.setParameter("pu", DbDAOTest.A_SEQ_PU);
+
+            @SuppressWarnings("rawtypes")
+            List iaeList = iaequery.getResultList();
+
+            // Assert that the IntegrityAuditEntity object was found
+            assertNotNull(iaeList);
+
+            // flush to the DB
+            em.flush();
+            et.commit();
+        }
+    }
+
+    /*
+     * Tests updating an IntegrityAuditEntity if it has already been registered
+     */
+    @Test
+    public void testUpdateRegistration() throws Exception {
+        Properties properties = makeProperties();
+
+        dbDao = new DbDAO(resourceName, A_SEQ_PU, properties);
+
+        // Change site_name in properties to test that an update was made to
+        // an existing entry in the table
+        properties.put(IntegrityAuditProperties.SITE_NAME, "SiteB");
+        dbDao = new DbDAO(resourceName, A_SEQ_PU, properties);
+
+        try (EntityTransCloser et = new EntityTransCloser(em.getTransaction())) {
+            // Find the proper entry in the database
+            Query iaequery = em.createQuery(
+                    "Select i from IntegrityAuditEntity i where i.resourceName=:rn and i.persistenceUnit=:pu");
+            iaequery.setParameter("rn", DbDAOTest.resourceName);
+            iaequery.setParameter("pu", DbDAOTest.A_SEQ_PU);
+
+            @SuppressWarnings("rawtypes")
+            List iaeList = iaequery.getResultList();
+            IntegrityAuditEntity iae = null;
+            if (!iaeList.isEmpty()) {
+                // ignores multiple results
+                iae = (IntegrityAuditEntity) iaeList.get(0);
+
+                em.refresh(iae);
+                em.persist(iae);
+
+                // flush to the DB
+                em.flush();
+
+                // commit transaction
+                et.commit();
+
+                // Assert that the site_name for the existing entry was updated
+                assertEquals("SiteB", iae.getSite());
+            }
+        }
+    }
+
+    /* Tests obtaining all Integrity Audit Entities from a table */
+    @Test
+    public void testGetIntegrityAuditEntities() throws Exception {
+        Properties properties = makeProperties();
+
+        // Add some entries to the DB
+        dbDao = new DbDAO(resourceName, A_SEQ_PU, properties);
+        new DbDAO("pdp1", A_SEQ_PU, properties).destroy();
+        properties.put(IntegrityAuditProperties.NODE_TYPE, "pdp_drools");
+        new DbDAO("pdp2", A_SEQ_PU, properties).destroy();
+
+        List<IntegrityAuditEntity> entities;
+        // Obtain entries based on persistenceUnit and nodeType
+        entities = dbDao.getIntegrityAuditEntities(A_SEQ_PU, "pdp_xacml");
+        assertEquals(2, entities.size());
+    }
+
+    /* Tests retrieving a DbDAO instance's IntegrityAuditEntity */
+    @Test
+    public void testGetMyIntegrityAuditEntity() throws Exception {
+        Properties properties = makeProperties();
+
+        dbDao = new DbDAO(resourceName, A_SEQ_PU, properties);
+        IntegrityAuditEntity iae = dbDao.getMyIntegrityAuditEntity();
+        // assertEquals("integrityAuditPU", iae.getPersistenceUnit());
+        assertEquals(A_SEQ_PU, iae.getPersistenceUnit());
+    }
+
+    /* Tests obtaining an IntegrityAuditEntity by ID */
+    @Test
+    public void testGetIntegrityAuditEntity() throws Exception {
+        Properties properties = makeProperties();
+
+        // Obtain an entry from the database based on ID
+        dbDao = new DbDAO(resourceName, A_SEQ_PU, properties);
+
+        // Find the proper database entry
+        Query iaequery = em
+                .createQuery("Select i from IntegrityAuditEntity i where i.resourceName=:rn and i.persistenceUnit=:pu");
+        iaequery.setParameter("rn", DbDAOTest.resourceName);
+        iaequery.setParameter("pu", DbDAOTest.A_SEQ_PU);
+
+        @SuppressWarnings("rawtypes")
+        List iaeList = iaequery.getResultList();
+        IntegrityAuditEntity iae = null;
+        if (!iaeList.isEmpty()) {
+            // ignores multiple results
+            iae = (IntegrityAuditEntity) iaeList.get(0);
+
+            // refresh the object from DB in case cached data was returned
+            em.refresh(iae);
+
+            // Obtain ID for an IntegrityAuditEntity
+            PersistenceUnitUtil util = emf.getPersistenceUnitUtil();
+            Object iaeId = util.getIdentifier(iae);
+
+            // Obtain the same IntegrityAuditEntity based on ID
+            IntegrityAuditEntity iaeDuplicate = dbDao.getIntegrityAuditEntity((long) iaeId);
+            Object duplicateId = util.getIdentifier(iaeDuplicate);
+
+            // Assert that the proper entry was retrieved based on ID
+            assertEquals((long) iaeId, (long) duplicateId);
+        }
+    }
+
+    /* Tests setting an IntegrityAuditEntity as the designated node */
+    @Test
+    public void testSetDesignated() throws Exception {
+        Properties properties = makeProperties();
+
+        try (EntityTransCloser et = new EntityTransCloser(em.getTransaction())) {
+            // Create an entry and set it's designated field to true
+            dbDao = new DbDAO(resourceName, A_SEQ_PU, properties);
+            dbDao.setDesignated(resourceName, A_SEQ_PU, true);
+
+            // Find the proper entry in the database
+            Query iaequery = em.createQuery(
+                    "Select i from IntegrityAuditEntity i where i.resourceName=:rn and i.persistenceUnit=:pu");
+            iaequery.setParameter("rn", resourceName);
+            iaequery.setParameter("pu", A_SEQ_PU);
+
+            @SuppressWarnings("rawtypes")
+            List iaeList = iaequery.getResultList();
+            IntegrityAuditEntity iae = null;
+
+            if (!iaeList.isEmpty()) {
+                // ignores multiple results
+                iae = (IntegrityAuditEntity) iaeList.get(0);
+                em.refresh(iae);
+
+                // Check if the node is designated
+                boolean result = iae.isDesignated();
+
+                // Assert that it is designated
+                assertTrue(result);
+            }
+
+            // flush to the DB
+            em.flush();
+
+            // close the transaction
+            et.commit();
+        }
+    }
+
+    /* Tests that the lastUpdated column in the database is updated properly */
+    @Test
+    public void testSetLastUpdated() throws Exception {
+        Properties properties = makeProperties();
+
+        try (EntityTransCloser et = new EntityTransCloser(em.getTransaction())) {
+            // Create an entry
+            dbDao = new DbDAO(resourceName, A_SEQ_PU, properties);
+
+            // Find the proper entry in the database
+            Query iaequery = em.createQuery(
+                    "Select i from IntegrityAuditEntity i where i.resourceName=:rn and i.persistenceUnit=:pu");
+            iaequery.setParameter("rn", resourceName);
+            iaequery.setParameter("pu", A_SEQ_PU);
+
+            @SuppressWarnings("rawtypes")
+            List iaeList = iaequery.getResultList();
+            IntegrityAuditEntity iae = null;
+
+            if (!iaeList.isEmpty()) {
+                // ignores multiple results
+                iae = (IntegrityAuditEntity) iaeList.get(0);
+                // refresh the object from DB in case cached data was returned
+                em.refresh(iae);
+
+                // Obtain old update value and set new update value
+                final Date oldDate = iae.getLastUpdated();
+
+                // ensure dates are different by sleeping for a bit
+                Thread.sleep(1);
+
+                iae.setSite("SiteB");
+                iae.setLastUpdated(new Date());
+                final Date newDate = iae.getLastUpdated();
+
+                em.persist(iae);
+                // flush to the DB
+                em.flush();
+                // close the transaction
+                et.commit();
+
+                // Assert that the old and new update times are different
+                assertNotEquals(oldDate, newDate);
+            }
+        }
+    }
+
+    /* Tests that all the entries from a class can be retrieved */
+    @Test
+    public void testGetAllMyEntriesString() throws Exception {
+        Properties properties = makeProperties();
+
+        // create entries for the IntegrityAuditEntity table
+        dbDao = new DbDAO(resourceName, A_SEQ_PU, properties);
+        new DbDAO("pdp1", A_SEQ_PU, properties).destroy();
+        new DbDAO("pdp2", A_SEQ_PU, properties).destroy();
+
+        // Obtain a hash with the persisted objects
+        Map<Object, Object> entries = dbDao.getAllMyEntries("org.onap.policy.common.ia.jpa.IntegrityAuditEntity");
+
+        // Assert there were 3 entries for that class
+        assertEquals(3, entries.size());
+    }
+
+    /*
+     * Tests retrieving all entities in a Persistence Unit using the class name and a hashset of IDs
+     */
+    @Test
+    public void testGetAllMyEntriesStringHashSet() throws Exception {
+        Properties properties = makeProperties();
+
+        // create entries for the IntegrityAuditEntity table
+        dbDao = new DbDAO(resourceName, A_SEQ_PU, properties);
+        new DbDAO("pdp1", A_SEQ_PU, properties).destroy();
+        new DbDAO("pdp2", A_SEQ_PU, properties).destroy();
+
+        // Obtain all entity keys
+        CriteriaBuilder cb = em.getCriteriaBuilder();
+        CriteriaQuery<Object> cq = cb.createQuery();
+        Root<?> rootEntry = cq.from(Class.forName("org.onap.policy.common.ia.jpa.IntegrityAuditEntity"));
+        CriteriaQuery<Object> all = cq.select(rootEntry);
+        TypedQuery<Object> allQuery = em.createQuery(all);
+        List<Object> objectList = allQuery.getResultList();
+        HashSet<Object> resultSet = new HashSet<Object>();
+        PersistenceUnitUtil util = emf.getPersistenceUnitUtil();
+        for (Object o : objectList) {
+            Object key = util.getIdentifier(o);
+            resultSet.add(key);
+        }
+
+        // Obtain a hash with the persisted objects
+        Map<Object, Object> entries =
+                dbDao.getAllMyEntries("org.onap.policy.common.ia.jpa.IntegrityAuditEntity", resultSet);
+
+        // Assert there were 3 entries for that class
+        assertEquals(3, entries.size());
+    }
+
+    /*
+     * Tests retrieving all entities in a Persistence Unit using the persistence unit, properties,
+     * and class name
+     */
+    @Test
+    public void testGetAllEntriesStringPropertiesString() throws Exception {
+        Properties properties = makeProperties();
+
+        // create entries for the IntegrityAuditEntity table
+        dbDao = new DbDAO(resourceName, A_SEQ_PU, properties);
+        new DbDAO("pdp1", A_SEQ_PU, properties).destroy();
+        new DbDAO("pdp2", A_SEQ_PU, properties).destroy();
+
+        // Obtain a hash with the persisted objects
+        Map<Object, Object> entries = dbDao.getAllEntries("integrityAuditPU", properties,
+                "org.onap.policy.common.ia.jpa.IntegrityAuditEntity");
+
+        // Assert there were 3 entries for that class
+        assertEquals(3, entries.size());
+    }
+
+    /*
+     * Tests retrieving all entities in a Persistence Unit using the persistence unit, properties,
+     * class name, and a hashset of IDs
+     */
+    @Test
+    public void testGetAllEntriesStringPropertiesStringHashSet() throws Exception {
+        Properties properties = makeProperties();
+
+        // create entries for the IntegrityAuditEntity table
+        dbDao = new DbDAO(resourceName, A_SEQ_PU, properties);
+        new DbDAO("pdp1", A_SEQ_PU, properties).destroy();
+        new DbDAO("pdp2", A_SEQ_PU, properties).destroy();
+
+        // Obtain all entity keys
+        CriteriaBuilder cb = em.getCriteriaBuilder();
+        CriteriaQuery<Object> cq = cb.createQuery();
+        Root<?> rootEntry = cq.from(Class.forName("org.onap.policy.common.ia.jpa.IntegrityAuditEntity"));
+        CriteriaQuery<Object> all = cq.select(rootEntry);
+        TypedQuery<Object> allQuery = em.createQuery(all);
+        List<Object> objectList = allQuery.getResultList();
+        HashSet<Object> resultSet = new HashSet<Object>();
+        PersistenceUnitUtil util = emf.getPersistenceUnitUtil();
+        for (Object o : objectList) {
+            Object key = util.getIdentifier(o);
+            resultSet.add(key);
+        }
+
+        // Obtain a hash with the persisted objects
+        Map<Object, Object> entries = dbDao.getAllEntries("integrityAuditPU", properties,
+                "org.onap.policy.common.ia.jpa.IntegrityAuditEntity", resultSet);
+
+        // Assert there were 3 entries for that class
+        assertEquals(3, entries.size());
+    }
+
+    /*
+     * Tests getting all the entries from a class based on persistenceUnit, properties, and
+     * className
+     */
+    @Test
+    public void testGetAllEntries() throws Exception {
+        Properties properties = makeProperties();
+
+        // create entries for the IntegrityAuditEntity table
+        dbDao = new DbDAO(resourceName, A_SEQ_PU, properties);
+        new DbDAO("pdp1", A_SEQ_PU, properties).destroy();
+        new DbDAO("pdp2", A_SEQ_PU, properties).destroy();
+
+        // Obtain a hash with the persisted objects
+        Map<Object, Object> entries =
+                dbDao.getAllEntries(A_SEQ_PU, properties, "org.onap.policy.common.ia.jpa.IntegrityAuditEntity");
+
+        // Assert there were 3 entries for that class
+        assertEquals(3, entries.size());
+    }
+
+    /**
+     * Tests obtaining all class names of persisted classes.
+     */
+    public void testGetPersistenceClassNames() throws Exception {
+        Properties properties = makeProperties();
+
+        dbDao = new DbDAO(resourceName, A_SEQ_PU, properties);
+
+        // Retrieve persistence class names
+        Set<String> result = dbDao.getPersistenceClassNames();
+        assertEquals(1, result.size());
+    }
 }
index b02b0c7..3c8ce52 100644 (file)
@@ -23,10 +23,6 @@ package org.onap.policy.common.ia;
 import static org.junit.Assert.assertEquals;
 
 import org.junit.Test;
-import org.onap.policy.common.ia.DbAuditException;
-import org.onap.policy.common.ia.DbDaoTransactionException;
-import org.onap.policy.common.ia.IntegrityAuditException;
-import org.onap.policy.common.ia.IntegrityAuditPropertiesException;
 import org.onap.policy.common.utils.test.ExceptionsTester;
 
 /**
@@ -34,23 +30,23 @@ import org.onap.policy.common.utils.test.ExceptionsTester;
  */
 public class ExceptionsTest extends ExceptionsTester {
 
-       @Test
-       public void testDbAuditException() throws Exception {
-               assertEquals(4, test(DbAuditException.class));
-       }
-
-       @Test
-       public void testDbDaoTransactionException() throws Exception {
-               assertEquals(4, test(DbDaoTransactionException.class));
-       }
-
-       @Test
-       public void testIntegrityAuditException() throws Exception {
-               assertEquals(4, test(IntegrityAuditException.class));
-       }
-
-       @Test
-       public void testIntegrityAuditPropertiesException() throws Exception {
-               assertEquals(4, test(IntegrityAuditPropertiesException.class));
-       }
+    @Test
+    public void testDbAuditException() throws Exception {
+        assertEquals(4, test(DbAuditException.class));
+    }
+
+    @Test
+    public void testDbDaoTransactionException() throws Exception {
+        assertEquals(4, test(DbDaoTransactionException.class));
+    }
+
+    @Test
+    public void testIntegrityAuditException() throws Exception {
+        assertEquals(4, test(IntegrityAuditException.class));
+    }
+
+    @Test
+    public void testIntegrityAuditPropertiesException() throws Exception {
+        assertEquals(4, test(IntegrityAuditPropertiesException.class));
+    }
 }
index 1861787..69f37da 100644 (file)
@@ -30,590 +30,573 @@ import org.onap.policy.common.logging.flexlogger.Logger;
 import org.onap.policy.common.utils.test.log.logback.ExtractAppender;
 
 /**
- * All JUnits are designed to run in the local development environment where
- * they have write privileges and can execute time-sensitive tasks.
- * <p/>
- * Many of the test verification steps are performed by scanning for items
- * written to the log file. Rather than actually scan the log file, an
- * {@link ExtractAppender} is used to monitor events that are logged and extract
- * relevant items. In order to attach the appender to the debug log, it assumes
- * that the debug log is a <i>logback</i> Logger configured per EELF.
- * <p/>
- * These tests use a temporary, in-memory DB, which is dropped once the tests
- * complete.
+ * All JUnits are designed to run in the local development environment where they have write
+ * privileges and can execute time-sensitive tasks.
+ * 
+ * <p>Many of the test verification steps are performed by scanning for items written to the log
+ * file. Rather than actually scan the log file, an {@link ExtractAppender} is used to monitor
+ * events that are logged and extract relevant items. In order to attach the appender to the debug
+ * log, it assumes that the debug log is a <i>logback</i> Logger configured per EELF.
+ * 
+ * <p>These tests use a temporary, in-memory DB, which is dropped once the tests complete.
  */
 public class IntegrityAuditDesignationTest extends IntegrityAuditTestBase {
 
-       private static Logger logger = FlexLogger.getLogger(IntegrityAuditDesignationTest.class);
-
-       /**
-        * Matches specified PDPs in the debug log. A regular expression matching
-        * the desired PDPs should be appended, followed by a right parenthesis. For
-        * example:
-        * 
-        * <pre>
-        * <code>new ExtractAppender(START_AUDIT_RE_PREFIX + "pdp[124])")
-        * </code>
-        * </pre>
-        */
-       private static final String START_AUDIT_RE_PREFIX = "Starting audit simulation for resourceName=(";
-
-       @BeforeClass
-       public static void setUpBeforeClass() throws Exception {
-               IntegrityAuditTestBase
-                               .setUpBeforeClass(DEFAULT_DB_URL_PREFIX + IntegrityAuditDesignationTest.class.getSimpleName());
-       }
-
-       @AfterClass
-       public static void tearDownAfterClass() {
-               IntegrityAuditTestBase.tearDownAfterClass();
-       }
-
-       @Before
-       public void setUp() {
-               logger.info("setUp: Entering");
-
-               super.setUp();
-
-               logger.info("setUp: Exiting");
-       }
-
-       @After
-       public void tearDown() {
-               logger.info("tearDown: Entering");
-
-               super.tearDown();
-
-               logger.info("tearDown: Exiting");
-
-       }
-
-       /*
-        * Tests designation logic when only one functioning resource is in play.
-        * Designation should stay with single resource.
-        * 
-        * Note: console.log must be examined to ascertain whether or not this test
-        * was successful.
-        */
-       @Test
-       public void testOneResource() throws Exception {
-
-               logger.info("testOneResource: Entering");
-
-               ExtractAppender logA = watch(debugLogger, START_AUDIT_RE);
-
-               MyIntegrityAudit integrityAudit = makeAuditor("pdp1", A_SEQ_PU);
-
-               /*
-                * Wait for
-                * 
-                * 1) pdp1 to run audit
-                * 
-                * 2) Logic to detect that no other node is available for designation
-                * 
-                * 3) pdp1 to run audit again
-                */
-               runAudit(integrityAudit);
-               waitStaleAndRun(integrityAudit);
-
-               logger.info("testOneResource: Stopping audit thread");
-               integrityAudit.stopAuditThread();
-
-               verifyItemsInLog(logA, "pdp1");
-
-               /*
-                * Test fix for ONAPD2TD-783: Audit fails to run when application is
-                * restarted.
-                */
-               integrityAudit.startAuditThread();
-
-               /*
-                * Sleep long enough to allow
-                * 
-                * 1) pdp1 to run audit
-                * 
-                * 2) Logic to detect that no other node is available for designation
-                * 
-                * 3) pdp1 to run audit again
-                */
-               runAudit(integrityAudit);
-               waitStaleAndRun(integrityAudit);
-
-               verifyItemsInLog(logA, "pdp1");
-
-               logger.info("testOneResource: Exiting");
-
-       }
-
-       /*
-        * Tests designation logic when two functioning resources are in play.
-        * Designation should alternate between resources.
-        * 
-        * Note: console.log must be examined to ascertain whether or not this test
-        * was successful. A quick way of examining the log is to search for the
-        * string "audit simulation":
-        * 
-        * As you can see from the "dbAuditSimulate" method, when it executes, it
-        * logs the "Starting audit simulation..." message and when it finishes, it
-        * logs the "Finished audit simulation..." message. By looking for these
-        * messages, you can verify that the audits are run by the proper resource.
-        * For example, when testFourResourcesOneDead is run, you should see a
-        * Starting.../Finished... sequence for "pdp1", followed by a
-        * Starting.../Finished... sequence for pdp2, followed by a
-        * Starting.../Finished... sequence for pdp4 (pdp3 is skipped as it's
-        * dead/hung), followed by a Starting.../Finished... sequence for "pdp1",
-        * etc.
-        */
-       @Test
-       public void testTwoResources() throws Exception {
-
-               logger.info("testTwoResources: Entering");
-
-               ExtractAppender logA = watch(debugLogger, START_AUDIT_RE);
-
-               /*
-                * Start audit for pdp1.
-                */
-               MyIntegrityAudit integrityAudit = makeAuditor("pdp1", A_SEQ_PU);
-
-               /*
-                * Start audit for pdp2.
-                */
-               MyIntegrityAudit integrityAudit2 = makeAuditor("pdp2", A_SEQ_PU);
-
-               /*
-                * Sleep long enough to allow
-                * 
-                * 1) pdp1 to run audit
-                * 
-                * 2) Logic to detect that pdp1 is stale and designate pdp2
-                * 
-                * 3) pdp2 to run audit
-                * 
-                * 4) Logic to detect that pdp2 is stale and designate pdp1
-                * 
-                * 5) pdp1 to run audit
-                */
-               runAudit(integrityAudit);
-               waitStaleAndRun(integrityAudit2);
-               waitStaleAndRun(integrityAudit);
-
-               verifyItemsInLog(logA, "pdp1", "pdp2", "pdp1");
-
-               logger.info("testTwoResources: Exiting");
-
-       }
-
-       /*
-        * Tests designation logic when two functioning resources are in play, each
-        * with different PUs. Audits for persistenceUnit and PU_B should run
-        * simultaneously. Designation should not alternate.
-        * 
-        * Note: console.log must be examined to ascertain whether or not this test
-        * was successful.
-        */
-       @Test
-       public void testTwoResourcesDifferentPus() throws Exception {
-
-               logger.info("testTwoResourcesDifferentPus: Entering");
-
-               ExtractAppender logA = watch(debugLogger, START_AUDIT_RE_PREFIX + "pdp1)");
-               ExtractAppender logB = watch(debugLogger, START_AUDIT_RE_PREFIX + "pdp2)");
-
-               /*
-                * Start audit for pdp1.
-                */
-               MyIntegrityAudit integrityAudit = makeAuditor("pdp1", A_SEQ_PU);
-
-               /*
-                * Start audit for pdp2.
-                */
-               MyIntegrityAudit integrityAudit2 = makeAuditor("pdp2", B_SEQ_PU);
-
-               /*
-                * Sleep long enough to allow
-                * 
-                * 1) pdp1 and pdp2 to run audit simultaneously
-                * 
-                * 2) Logic to detect that no other node is available for designation
-                * for either pdp1 or pdp2
-                * 
-                * 3) pdp1 and pdp2 to again run audit simultaneously
-                */
-               runAudit(integrityAudit, integrityAudit2);
-               waitStaleAndRun(integrityAudit, integrityAudit2);
-
-               verifyItemsInLog(logA, "pdp1", "pdp1");
-               verifyItemsInLog(logB, "pdp2", "pdp2");
-
-               logger.info("testTwoResourcesDifferentPus: Exiting");
-
-       }
-
-       /*
-        * Tests designation logic when two resources are in play but one of them is
-        * dead/hung. Designation should move to second resource but then get
-        * restored back to original resource when it's discovered that second
-        * resource is dead.
-        * 
-        * Note: console.log must be examined to ascertain whether or not this test
-        * was successful.
-        */
-       @Test
-       public void testTwoResourcesOneDead() throws Exception {
-
-               logger.info("testTwoResourcesOneDead: Entering");
-
-               ExtractAppender logA = watch(debugLogger, START_AUDIT_RE);
-
-               /*
-                * Start audit for pdp1.
-                */
-               MyIntegrityAudit integrityAudit = makeAuditor("pdp1", A_SEQ_PU);
-
-               /*
-                * Populate DB for pdp2, which will simulate it having registered but
-                * then having died.
-                */
-               new DbDAO("pdp2", A_SEQ_PU, makeProperties()).destroy();
-
-               /*
-                * Sleep long enough to allow
-                * 
-                * 1) pdp1 to run audit
-                * 
-                * 2) Logic to detect that other node, pdp2, is not available for
-                * designation
-                * 
-                * 3) pdp1 to run audit again
-                */
-               runAudit(integrityAudit);
-               waitStaleAndRun(integrityAudit);
-
-               verifyItemsInLog(logA, "pdp1", "pdp1");
-
-               logger.info("testTwoResourcesOneDead: Exiting");
-
-       }
-
-       /*
-        * Tests designation logic when three functioning resources are in play.
-        * Designation should round robin among resources.
-        * 
-        * Note: console.log must be examined to ascertain whether or not this test
-        * was successful.
-        */
-       @Test
-       public void testThreeResources() throws Exception {
-
-               logger.info("testThreeResources: Entering");
-
-               ExtractAppender logA = watch(debugLogger, START_AUDIT_RE);
-
-               /*
-                * Start audit for pdp1.
-                */
-               MyIntegrityAudit integrityAudit = makeAuditor("pdp1", A_SEQ_PU);
-
-               /*
-                * Start audit for pdp2.
-                */
-               MyIntegrityAudit integrityAudit2 = makeAuditor("pdp2", A_SEQ_PU);
-
-               /*
-                * Start audit for pdp3.
-                */
-               MyIntegrityAudit integrityAudit3 = makeAuditor("pdp3", A_SEQ_PU);
-
-               /*
-                * Sleep long enough to allow
-                * 
-                * 1) pdp1 to run audit
-                * 
-                * 2) Logic to detect that pdp1 is stale and designate pdp2
-                * 
-                * 3) pdp2 to run audit
-                * 
-                * 4) Logic to detect that pdp2 is stale and designate pdp3
-                * 
-                * 5) pdp3 to run audit
-                * 
-                * 6) Logic to detect that pdp3 is stale and designate pdp1
-                * 
-                * 7) pdp1 to run audit
-                */
-               runAudit(integrityAudit);
-               waitStaleAndRun(integrityAudit2);
-               waitStaleAndRun(integrityAudit3);
-               waitStaleAndRun(integrityAudit);
-
-               verifyItemsInLog(logA, "pdp1", "pdp2", "pdp3", "pdp1");
-
-               logger.info("testThreeResources: Exiting");
-
-       }
-
-       /*
-        * Tests designation logic when four functioning resources are in play, two
-        * with one PU, two with another. Audits for persistenceUnit and PU_B should
-        * run simultaneously. Designation should alternate between resources for
-        * each of the two persistence units.
-        * 
-        * Note: console.log must be examined to ascertain whether or not this test
-        * was successful.
-        */
-       @Test
-       public void testFourResourcesDifferentPus() throws Exception {
-
-               logger.info("testFourResourcesDifferentPus: Entering");
-
-               ExtractAppender logA = watch(debugLogger, START_AUDIT_RE_PREFIX + "pdp1|pdp3)");
-               ExtractAppender logB = watch(debugLogger, START_AUDIT_RE_PREFIX + "pdp2|pdp4)");
-
-               /*
-                * Start audit for "pdp1", testPU.
-                */
-               MyIntegrityAudit integrityAudit = makeAuditor("pdp1", A_SEQ_PU);
-
-               /*
-                * Start audit for pdp2, integrityAuditPU.
-                */
-               MyIntegrityAudit integrityAudit2 = makeAuditor("pdp2", B_SEQ_PU);
-
-               /*
-                * Start audit for pdp3, testPU.
-                */
-               MyIntegrityAudit integrityAudit3 = makeAuditor("pdp3", A_SEQ_PU);
-
-               /*
-                * Start audit for pdp4, integrityAuditPU.
-                */
-               MyIntegrityAudit integrityAudit4 = makeAuditor("pdp4", B_SEQ_PU);
-
-               /*
-                * Sleep long enough to allow
-                * 
-                * 1) pdp1 and pdp2 to run audit simultaneously
-                * 
-                * 2) Logic to detect that pdp1 and pdp2 are stale and designate pdp3
-                * (one's counterpart) and pdp4 (two's counterpart)
-                * 
-                * 3) pdp3 and pdp4 to run audit simultaneously
-                * 
-                * 4) Logic to detect that pdp3 and pdp4 are stale and designate pdp1
-                * (three's counterpart) and pdp2 (four's counterpart)
-                * 
-                * 5) pdp1 and pdp2 to run audit simultaneously
-                */
-               runAudit(integrityAudit, integrityAudit2);
-               waitStaleAndRun(integrityAudit3, integrityAudit4);
-               waitStaleAndRun(integrityAudit, integrityAudit2);
-
-               /*
-                * These sequences may be intermingled, so we extract and compare one
-                * sequence at a time.
-                */
-
-               // only care about pdp1 & pdp3 in this sequence
-               verifyItemsInLog(logA, "pdp1", "pdp3", "pdp1");
-
-               // only care about pdp2 & pdp4 in this sequence
-               verifyItemsInLog(logB, "pdp2", "pdp4", "pdp2");
-
-               logger.info("testFourResourcesDifferentPus: Exiting");
-
-       }
-
-       /*
-        * Tests designation logic when four resources are in play but one is not
-        * functioning. Designation should round robin among functioning resources
-        * only.
-        * 
-        * Note: console.log must be examined to ascertain whether or not this test
-        * was successful.
-        */
-       @Test
-       public void testFourResourcesOneDead() throws Exception {
-
-               logger.info("testFourResourcesOneDead: Entering");
-
-               ExtractAppender logA = watch(debugLogger, START_AUDIT_RE);
-
-               /*
-                * Start audit for pdp1.
-                */
-               MyIntegrityAudit integrityAudit = makeAuditor("pdp1", A_SEQ_PU);
-
-               /*
-                * Start audit for pdp2.
-                */
-               MyIntegrityAudit integrityAudit2 = makeAuditor("pdp2", A_SEQ_PU);
-
-               /*
-                * Populate DB for pdp3, which will simulate it having registered but
-                * then having died.
-                */
-               new DbDAO("pdp3", A_SEQ_PU, makeProperties()).destroy();
-
-               /*
-                * Start audit for pdp4.
-                */
-               MyIntegrityAudit integrityAudit4 = makeAuditor("pdp4", A_SEQ_PU);
-
-               /*
-                * Sleep long enough to allow
-                * 
-                * 1) pdp1 to run audit
-                * 
-                * 2) Logic to detect that pdp1 is stale and designate pdp2
-                * 
-                * 3) pdp2 to run audit
-                * 
-                * 4) Logic to detect that pdp2 is stale and designate pdp4
-                * 
-                * 5) pdp4 to run audit
-                * 
-                * 6) Logic to detect that pdp4 is stale and designate pdp1
-                * 
-                * 7) pdp1 to run audit
-                * 
-                * 8) Logic to detect that pdp1 is stale and designate pdp2
-                * 
-                * 7) pdp2 to run audit
-                */
-               runAudit(integrityAudit);
-               waitStaleAndRun(integrityAudit2);
-               waitStaleAndRun(integrityAudit4);
-               waitStaleAndRun(integrityAudit);
-               waitStaleAndRun(integrityAudit2);
-               waitStaleAndRun(integrityAudit4);
-
-               verifyItemsInLog(logA, "pdp1", "pdp2", "pdp4", "pdp1", "pdp2", "pdp4");
-
-               logger.info("testFourResourcesOneDead: Exiting");
-
-       }
-
-       /*
-        * Tests designation logic when four resources are in play but only one is
-        * functioning. Designation should remain with sole functioning resource.
-        * 
-        * Note: console.log must be examined to ascertain whether or not this test
-        * was successful.
-        */
-       @Test
-       public void testFourResourcesThreeDead() throws Exception {
-
-               logger.info("testFourResourcesThreeDead: Entering");
-
-               ExtractAppender logA = watch(debugLogger, START_AUDIT_RE);
-
-               /*
-                * Populate DB for "pdp1", which will simulate it having registered but
-                * then having died.
-                */
-               new DbDAO("pdp1", A_SEQ_PU, makeProperties()).destroy();
-
-               /*
-                * Populate DB for pdp2, which will simulate it having registered but
-                * then having died.
-                */
-               new DbDAO("pdp2", A_SEQ_PU, makeProperties()).destroy();
-
-               /*
-                * Start audit for pdp3.
-                */
-               MyIntegrityAudit integrityAudit3 = makeAuditor("pdp3", A_SEQ_PU);
-
-               /*
-                * Populate DB for pdp4, which will simulate it having registered but
-                * then having died.
-                */
-               new DbDAO("pdp4", A_SEQ_PU, makeProperties()).destroy();
-
-               /*
-                * Sleep long enough to allow
-                * 
-                * 1) pdp3 to discover that all other designation candidates are stale
-                * 
-                * 1) pdp3 to run audit
-                * 
-                * 2) Logic to detect that no other nodes are available for designation
-                * 
-                * 3) pdp3 to run audit again
-                */
-               runAudit(integrityAudit3);
-               waitStaleAndRun(integrityAudit3);
-
-               verifyItemsInLog(logA, "pdp3", "pdp3");
-
-               logger.info("testFourResourcesThreeDead: Exiting");
-
-       }
-
-       /*
-        * Tests designation logic when the designated node dies and is no longer
-        * current
-        * 
-        * Note: console.log must be examined to ascertain whether or not this test
-        * was successful.
-        */
-       @Test
-       public void testDesignatedNodeDead() throws Exception {
-               logger.info("testDesignatedNodeDead: Entering");
-
-               ExtractAppender logA = watch(debugLogger, START_AUDIT_RE);
-
-               /*
-                * Instantiate audit object for pdp1.
-                */
-               MyIntegrityAudit integrityAudit = makeAuditor("pdp1", A_SEQ_PU);
-
-               /*
-                * Start audit for pdp2.
-                */
-               MyIntegrityAudit integrityAudit2 = makeAuditor("pdp2", A_SEQ_PU);
-
-               /*
-                * Instantiate audit object for pdp3.
-                */
-               MyIntegrityAudit integrityAudit3 = makeAuditor("pdp3", A_SEQ_PU);
-
-               // Start audit on pdp1
-               logger.info("testDesignatedNodeDead: Start audit on pdp1");
-               runAudit(integrityAudit);
-
-               // Start the auditing threads on other nodes.
-               logger.info("testDesignatedNodeDead: Start audit on pdp2");
-               runAudit(integrityAudit2);
-
-               // Kill audit on pdp1
-               logger.info("testDesignatedNodeDead: Kill audit on pdp1");
-               integrityAudit.stopAuditThread();
-
-               // Wait long enough for pdp1 to get stale and pdp2 to take over
-               waitStaleAndRun(integrityAudit2);
-
-               // Start audit thread on pdp1 again.
-               logger.info("testDesignatedNodeDead: Start audit thread on pdp1 again.");
-               integrityAudit.startAuditThread();
-
-               // Wait long enough for pdp2 to complete its audit and get stale, at
-               // which point pdp3 should take over
-               logger.info(
-                               "testDesignatedNodeDead: Wait long enough for pdp2 to complete its audit and get stale, at which point pdp3 should take over");
-               waitStaleAndRun(integrityAudit3);
-
-               // Kill audit on pdp3
-               logger.info("testDesignatedNodeDead: Killing audit on pdp3");
-               integrityAudit3.stopAuditThread();
-
-               // Wait long enough for pdp3 to get stale and pdp1 to take over
-               logger.info("testDesignatedNodeDead: Wait long enough for pdp3 to get stale and pdp1 to take over");
-               waitStaleAndRun(integrityAudit);
-
-               verifyItemsInLog(logA, "pdp1", "pdp2", "pdp3", "pdp1");
-
-               logger.info("testDesignatedNodeDead: Exiting");
-       }
+    private static Logger logger = FlexLogger.getLogger(IntegrityAuditDesignationTest.class);
+
+    /**
+     * Matches specified PDPs in the debug log. A regular expression matching the desired PDPs
+     * should be appended, followed by a right parenthesis. For example:
+     * 
+     * <pre>
+     * <code>new ExtractAppender(START_AUDIT_RE_PREFIX + "pdp[124])")
+     * </code>
+     * </pre>
+     */
+    private static final String START_AUDIT_RE_PREFIX = "Starting audit simulation for resourceName=(";
+
+    @BeforeClass
+    public static void setUpBeforeClass() throws Exception {
+        IntegrityAuditTestBase
+                .setUpBeforeClass(DEFAULT_DB_URL_PREFIX + IntegrityAuditDesignationTest.class.getSimpleName());
+    }
+
+    @AfterClass
+    public static void tearDownAfterClass() {
+        IntegrityAuditTestBase.tearDownAfterClass();
+    }
+
+    /**
+     * Set up before test cases.
+     */
+    @Override
+    @Before
+    public void setUp() {
+        logger.info("setUp: Entering");
+
+        super.setUp();
+
+        logger.info("setUp: Exiting");
+    }
+
+    /**
+     * Tear down after test cases.
+     */
+    @Override
+    @After
+    public void tearDown() {
+        logger.info("tearDown: Entering");
+
+        super.tearDown();
+
+        logger.info("tearDown: Exiting");
+
+    }
+
+    /*
+     * Tests designation logic when only one functioning resource is in play. Designation should
+     * stay with single resource.
+     * 
+     * Note: console.log must be examined to ascertain whether or not this test was successful.
+     */
+    @Test
+    public void testOneResource() throws Exception {
+
+        logger.info("testOneResource: Entering");
+
+        final ExtractAppender logA = watch(debugLogger, START_AUDIT_RE);
+
+        MyIntegrityAudit integrityAudit = makeAuditor("pdp1", A_SEQ_PU);
+
+        /*
+         * Wait for
+         * 
+         * 1) pdp1 to run audit
+         * 
+         * 2) Logic to detect that no other node is available for designation
+         * 
+         * 3) pdp1 to run audit again
+         */
+        runAudit(integrityAudit);
+        waitStaleAndRun(integrityAudit);
+
+        logger.info("testOneResource: Stopping audit thread");
+        integrityAudit.stopAuditThread();
+
+        verifyItemsInLog(logA, "pdp1");
+
+        /*
+         * Test fix for ONAPD2TD-783: Audit fails to run when application is restarted.
+         */
+        integrityAudit.startAuditThread();
+
+        /*
+         * Sleep long enough to allow
+         * 
+         * 1) pdp1 to run audit
+         * 
+         * 2) Logic to detect that no other node is available for designation
+         * 
+         * 3) pdp1 to run audit again
+         */
+        runAudit(integrityAudit);
+        waitStaleAndRun(integrityAudit);
+
+        verifyItemsInLog(logA, "pdp1");
+
+        logger.info("testOneResource: Exiting");
+
+    }
+
+    /*
+     * Tests designation logic when two functioning resources are in play. Designation should
+     * alternate between resources.
+     * 
+     * Note: console.log must be examined to ascertain whether or not this test was successful. A
+     * quick way of examining the log is to search for the string "audit simulation":
+     * 
+     * As you can see from the "dbAuditSimulate" method, when it executes, it logs the
+     * "Starting audit simulation..." message and when it finishes, it logs the
+     * "Finished audit simulation..." message. By looking for these messages, you can verify that
+     * the audits are run by the proper resource. For example, when testFourResourcesOneDead is run,
+     * you should see a Starting.../Finished... sequence for "pdp1", followed by a
+     * Starting.../Finished... sequence for pdp2, followed by a Starting.../Finished... sequence for
+     * pdp4 (pdp3 is skipped as it's dead/hung), followed by a Starting.../Finished... sequence for
+     * "pdp1", etc.
+     */
+    @Test
+    public void testTwoResources() throws Exception {
+
+        logger.info("testTwoResources: Entering");
+
+        final ExtractAppender logA = watch(debugLogger, START_AUDIT_RE);
+
+        /*
+         * Start audit for pdp1.
+         */
+        MyIntegrityAudit integrityAudit = makeAuditor("pdp1", A_SEQ_PU);
+
+        /*
+         * Start audit for pdp2.
+         */
+        MyIntegrityAudit integrityAudit2 = makeAuditor("pdp2", A_SEQ_PU);
+
+        /*
+         * Sleep long enough to allow
+         * 
+         * 1) pdp1 to run audit
+         * 
+         * 2) Logic to detect that pdp1 is stale and designate pdp2
+         * 
+         * 3) pdp2 to run audit
+         * 
+         * 4) Logic to detect that pdp2 is stale and designate pdp1
+         * 
+         * 5) pdp1 to run audit
+         */
+        runAudit(integrityAudit);
+        waitStaleAndRun(integrityAudit2);
+        waitStaleAndRun(integrityAudit);
+
+        verifyItemsInLog(logA, "pdp1", "pdp2", "pdp1");
+
+        logger.info("testTwoResources: Exiting");
+
+    }
+
+    /*
+     * Tests designation logic when two functioning resources are in play, each with different PUs.
+     * Audits for persistenceUnit and PU_B should run simultaneously. Designation should not
+     * alternate.
+     * 
+     * Note: console.log must be examined to ascertain whether or not this test was successful.
+     */
+    @Test
+    public void testTwoResourcesDifferentPus() throws Exception {
+
+        logger.info("testTwoResourcesDifferentPus: Entering");
+
+        final ExtractAppender logA = watch(debugLogger, START_AUDIT_RE_PREFIX + "pdp1)");
+        final ExtractAppender logB = watch(debugLogger, START_AUDIT_RE_PREFIX + "pdp2)");
+
+        /*
+         * Start audit for pdp1.
+         */
+        MyIntegrityAudit integrityAudit = makeAuditor("pdp1", A_SEQ_PU);
+
+        /*
+         * Start audit for pdp2.
+         */
+        MyIntegrityAudit integrityAudit2 = makeAuditor("pdp2", B_SEQ_PU);
+
+        /*
+         * Sleep long enough to allow
+         * 
+         * 1) pdp1 and pdp2 to run audit simultaneously
+         * 
+         * 2) Logic to detect that no other node is available for designation for either pdp1 or
+         * pdp2
+         * 
+         * 3) pdp1 and pdp2 to again run audit simultaneously
+         */
+        runAudit(integrityAudit, integrityAudit2);
+        waitStaleAndRun(integrityAudit, integrityAudit2);
+
+        verifyItemsInLog(logA, "pdp1", "pdp1");
+        verifyItemsInLog(logB, "pdp2", "pdp2");
+
+        logger.info("testTwoResourcesDifferentPus: Exiting");
+
+    }
+
+    /*
+     * Tests designation logic when two resources are in play but one of them is dead/hung.
+     * Designation should move to second resource but then get restored back to original resource
+     * when it's discovered that second resource is dead.
+     * 
+     * Note: console.log must be examined to ascertain whether or not this test was successful.
+     */
+    @Test
+    public void testTwoResourcesOneDead() throws Exception {
+
+        logger.info("testTwoResourcesOneDead: Entering");
+
+        final ExtractAppender logA = watch(debugLogger, START_AUDIT_RE);
+
+        /*
+         * Start audit for pdp1.
+         */
+        MyIntegrityAudit integrityAudit = makeAuditor("pdp1", A_SEQ_PU);
+
+        /*
+         * Populate DB for pdp2, which will simulate it having registered but then having died.
+         */
+        new DbDAO("pdp2", A_SEQ_PU, makeProperties()).destroy();
+
+        /*
+         * Sleep long enough to allow
+         * 
+         * 1) pdp1 to run audit
+         * 
+         * 2) Logic to detect that other node, pdp2, is not available for designation
+         * 
+         * 3) pdp1 to run audit again
+         */
+        runAudit(integrityAudit);
+        waitStaleAndRun(integrityAudit);
+
+        verifyItemsInLog(logA, "pdp1", "pdp1");
+
+        logger.info("testTwoResourcesOneDead: Exiting");
+
+    }
+
+    /*
+     * Tests designation logic when three functioning resources are in play. Designation should
+     * round robin among resources.
+     * 
+     * Note: console.log must be examined to ascertain whether or not this test was successful.
+     */
+    @Test
+    public void testThreeResources() throws Exception {
+
+        logger.info("testThreeResources: Entering");
+
+        final ExtractAppender logA = watch(debugLogger, START_AUDIT_RE);
+
+        /*
+         * Start audit for pdp1.
+         */
+        MyIntegrityAudit integrityAudit = makeAuditor("pdp1", A_SEQ_PU);
+
+        /*
+         * Start audit for pdp2.
+         */
+        MyIntegrityAudit integrityAudit2 = makeAuditor("pdp2", A_SEQ_PU);
+
+        /*
+         * Start audit for pdp3.
+         */
+        MyIntegrityAudit integrityAudit3 = makeAuditor("pdp3", A_SEQ_PU);
+
+        /*
+         * Sleep long enough to allow
+         * 
+         * 1) pdp1 to run audit
+         * 
+         * 2) Logic to detect that pdp1 is stale and designate pdp2
+         * 
+         * 3) pdp2 to run audit
+         * 
+         * 4) Logic to detect that pdp2 is stale and designate pdp3
+         * 
+         * 5) pdp3 to run audit
+         * 
+         * 6) Logic to detect that pdp3 is stale and designate pdp1
+         * 
+         * 7) pdp1 to run audit
+         */
+        runAudit(integrityAudit);
+        waitStaleAndRun(integrityAudit2);
+        waitStaleAndRun(integrityAudit3);
+        waitStaleAndRun(integrityAudit);
+
+        verifyItemsInLog(logA, "pdp1", "pdp2", "pdp3", "pdp1");
+
+        logger.info("testThreeResources: Exiting");
+
+    }
+
+    /*
+     * Tests designation logic when four functioning resources are in play, two with one PU, two
+     * with another. Audits for persistenceUnit and PU_B should run simultaneously. Designation
+     * should alternate between resources for each of the two persistence units.
+     * 
+     * Note: console.log must be examined to ascertain whether or not this test was successful.
+     */
+    @Test
+    public void testFourResourcesDifferentPus() throws Exception {
+
+        logger.info("testFourResourcesDifferentPus: Entering");
+
+        final ExtractAppender logA = watch(debugLogger, START_AUDIT_RE_PREFIX + "pdp1|pdp3)");
+        final ExtractAppender logB = watch(debugLogger, START_AUDIT_RE_PREFIX + "pdp2|pdp4)");
+
+        /*
+         * Start audit for "pdp1", testPU.
+         */
+        MyIntegrityAudit integrityAudit = makeAuditor("pdp1", A_SEQ_PU);
+
+        /*
+         * Start audit for pdp2, integrityAuditPU.
+         */
+        MyIntegrityAudit integrityAudit2 = makeAuditor("pdp2", B_SEQ_PU);
+
+        /*
+         * Start audit for pdp3, testPU.
+         */
+        MyIntegrityAudit integrityAudit3 = makeAuditor("pdp3", A_SEQ_PU);
+
+        /*
+         * Start audit for pdp4, integrityAuditPU.
+         */
+        MyIntegrityAudit integrityAudit4 = makeAuditor("pdp4", B_SEQ_PU);
+
+        /*
+         * Sleep long enough to allow
+         * 
+         * 1) pdp1 and pdp2 to run audit simultaneously
+         * 
+         * 2) Logic to detect that pdp1 and pdp2 are stale and designate pdp3 (one's counterpart)
+         * and pdp4 (two's counterpart)
+         * 
+         * 3) pdp3 and pdp4 to run audit simultaneously
+         * 
+         * 4) Logic to detect that pdp3 and pdp4 are stale and designate pdp1 (three's counterpart)
+         * and pdp2 (four's counterpart)
+         * 
+         * 5) pdp1 and pdp2 to run audit simultaneously
+         */
+        runAudit(integrityAudit, integrityAudit2);
+        waitStaleAndRun(integrityAudit3, integrityAudit4);
+        waitStaleAndRun(integrityAudit, integrityAudit2);
+
+        /*
+         * These sequences may be intermingled, so we extract and compare one sequence at a time.
+         */
+
+        // only care about pdp1 & pdp3 in this sequence
+        verifyItemsInLog(logA, "pdp1", "pdp3", "pdp1");
+
+        // only care about pdp2 & pdp4 in this sequence
+        verifyItemsInLog(logB, "pdp2", "pdp4", "pdp2");
+
+        logger.info("testFourResourcesDifferentPus: Exiting");
+
+    }
+
+    /*
+     * Tests designation logic when four resources are in play but one is not functioning.
+     * Designation should round robin among functioning resources only.
+     * 
+     * Note: console.log must be examined to ascertain whether or not this test was successful.
+     */
+    @Test
+    public void testFourResourcesOneDead() throws Exception {
+
+        logger.info("testFourResourcesOneDead: Entering");
+
+        final ExtractAppender logA = watch(debugLogger, START_AUDIT_RE);
+
+        /*
+         * Start audit for pdp1.
+         */
+        MyIntegrityAudit integrityAudit = makeAuditor("pdp1", A_SEQ_PU);
+
+        /*
+         * Start audit for pdp2.
+         */
+        MyIntegrityAudit integrityAudit2 = makeAuditor("pdp2", A_SEQ_PU);
+
+        /*
+         * Populate DB for pdp3, which will simulate it having registered but then having died.
+         */
+        new DbDAO("pdp3", A_SEQ_PU, makeProperties()).destroy();
+
+        /*
+         * Start audit for pdp4.
+         */
+        MyIntegrityAudit integrityAudit4 = makeAuditor("pdp4", A_SEQ_PU);
+
+        /*
+         * Sleep long enough to allow
+         * 
+         * 1) pdp1 to run audit
+         * 
+         * 2) Logic to detect that pdp1 is stale and designate pdp2
+         * 
+         * 3) pdp2 to run audit
+         * 
+         * 4) Logic to detect that pdp2 is stale and designate pdp4
+         * 
+         * 5) pdp4 to run audit
+         * 
+         * 6) Logic to detect that pdp4 is stale and designate pdp1
+         * 
+         * 7) pdp1 to run audit
+         * 
+         * 8) Logic to detect that pdp1 is stale and designate pdp2
+         * 
+         * 7) pdp2 to run audit
+         */
+        runAudit(integrityAudit);
+        waitStaleAndRun(integrityAudit2);
+        waitStaleAndRun(integrityAudit4);
+        waitStaleAndRun(integrityAudit);
+        waitStaleAndRun(integrityAudit2);
+        waitStaleAndRun(integrityAudit4);
+
+        verifyItemsInLog(logA, "pdp1", "pdp2", "pdp4", "pdp1", "pdp2", "pdp4");
+
+        logger.info("testFourResourcesOneDead: Exiting");
+
+    }
+
+    /*
+     * Tests designation logic when four resources are in play but only one is functioning.
+     * Designation should remain with sole functioning resource.
+     * 
+     * Note: console.log must be examined to ascertain whether or not this test was successful.
+     */
+    @Test
+    public void testFourResourcesThreeDead() throws Exception {
+
+        logger.info("testFourResourcesThreeDead: Entering");
+
+        final ExtractAppender logA = watch(debugLogger, START_AUDIT_RE);
+
+        /*
+         * Populate DB for "pdp1", which will simulate it having registered but then having died.
+         */
+        new DbDAO("pdp1", A_SEQ_PU, makeProperties()).destroy();
+
+        /*
+         * Populate DB for pdp2, which will simulate it having registered but then having died.
+         */
+        new DbDAO("pdp2", A_SEQ_PU, makeProperties()).destroy();
+
+        /*
+         * Start audit for pdp3.
+         */
+        MyIntegrityAudit integrityAudit3 = makeAuditor("pdp3", A_SEQ_PU);
+
+        /*
+         * Populate DB for pdp4, which will simulate it having registered but then having died.
+         */
+        new DbDAO("pdp4", A_SEQ_PU, makeProperties()).destroy();
+
+        /*
+         * Sleep long enough to allow
+         * 
+         * 1) pdp3 to discover that all other designation candidates are stale
+         * 
+         * 1) pdp3 to run audit
+         * 
+         * 2) Logic to detect that no other nodes are available for designation
+         * 
+         * 3) pdp3 to run audit again
+         */
+        runAudit(integrityAudit3);
+        waitStaleAndRun(integrityAudit3);
+
+        verifyItemsInLog(logA, "pdp3", "pdp3");
+
+        logger.info("testFourResourcesThreeDead: Exiting");
+
+    }
+
+    /*
+     * Tests designation logic when the designated node dies and is no longer current
+     * 
+     * Note: console.log must be examined to ascertain whether or not this test was successful.
+     */
+    @Test
+    public void testDesignatedNodeDead() throws Exception {
+        logger.info("testDesignatedNodeDead: Entering");
+
+        final ExtractAppender logA = watch(debugLogger, START_AUDIT_RE);
+
+        /*
+         * Instantiate audit object for pdp1.
+         */
+        final MyIntegrityAudit integrityAudit = makeAuditor("pdp1", A_SEQ_PU);
+
+        /*
+         * Start audit for pdp2.
+         */
+        final MyIntegrityAudit integrityAudit2 = makeAuditor("pdp2", A_SEQ_PU);
+
+        /*
+         * Instantiate audit object for pdp3.
+         */
+        final MyIntegrityAudit integrityAudit3 = makeAuditor("pdp3", A_SEQ_PU);
+
+        // Start audit on pdp1
+        logger.info("testDesignatedNodeDead: Start audit on pdp1");
+        runAudit(integrityAudit);
+
+        // Start the auditing threads on other nodes.
+        logger.info("testDesignatedNodeDead: Start audit on pdp2");
+        runAudit(integrityAudit2);
+
+        // Kill audit on pdp1
+        logger.info("testDesignatedNodeDead: Kill audit on pdp1");
+        integrityAudit.stopAuditThread();
+
+        // Wait long enough for pdp1 to get stale and pdp2 to take over
+        waitStaleAndRun(integrityAudit2);
+
+        // Start audit thread on pdp1 again.
+        logger.info("testDesignatedNodeDead: Start audit thread on pdp1 again.");
+        integrityAudit.startAuditThread();
+
+        // Wait long enough for pdp2 to complete its audit and get stale, at
+        // which point pdp3 should take over
+        logger.info(
+                "testDesignatedNodeDead: Wait long enough for pdp2 to complete its audit and get stale, at which point"
+                        + " pdp3 should take over");
+        waitStaleAndRun(integrityAudit3);
+
+        // Kill audit on pdp3
+        logger.info("testDesignatedNodeDead: Killing audit on pdp3");
+        integrityAudit3.stopAuditThread();
+
+        // Wait long enough for pdp3 to get stale and pdp1 to take over
+        logger.info("testDesignatedNodeDead: Wait long enough for pdp3 to get stale and pdp1 to take over");
+        waitStaleAndRun(integrityAudit);
+
+        verifyItemsInLog(logA, "pdp1", "pdp2", "pdp3", "pdp1");
+
+        logger.info("testDesignatedNodeDead: Exiting");
+    }
 }
index 344ac34..5adbb56 100644 (file)
 
 package org.onap.policy.common.ia;
 
-import static org.junit.Assert.*;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
 
 import java.util.Properties;
 
 import org.junit.Test;
-import org.onap.policy.common.ia.IntegrityAudit;
-import org.onap.policy.common.ia.IntegrityAuditProperties;
 
 public class IntegrityAuditTest {
 
-       @Test
-       /**
-        * Test if we can access the updated bad params outside of the parmsAreBad method
-        */
-       public void parmsAreBadTest() {
-               // Try with 2 null params
-               StringBuilder badParams = new StringBuilder();
-               IntegrityAudit.parmsAreBad(null, "something", null, badParams);
-               
-               assertFalse("".equals(badParams.toString()));
-               assertTrue(badParams.toString().contains("resourceName"));
-               assertTrue(badParams.toString().contains("properties"));
-               
-               // Try with 1 null params
-               badParams = new StringBuilder();
-               Properties props = new Properties();
-               props.put(IntegrityAuditProperties.DB_DRIVER, "test_db_driver");
-               IntegrityAudit.parmsAreBad(null, "something", props, badParams);
-               
-               assertFalse("".equals(badParams.toString()));
-               assertTrue(badParams.toString().contains("resourceName"));
-               assertFalse(badParams.toString().contains("properties"));
-               
-               // Try with 0 null params
-               badParams = new StringBuilder();
-               IntegrityAudit.parmsAreBad("someting", "something", props, badParams);
-               assertFalse("".equals(badParams.toString()));
-               assertFalse(badParams.toString().contains("resourceName"));
-               assertFalse(badParams.toString().contains("properties"));
-               
-               // Try with invalid node type
-               props.put(IntegrityAuditProperties.NODE_TYPE, "bogus");
-               badParams = new StringBuilder();
-               IntegrityAudit.parmsAreBad("someting", "something", props, badParams);
-               assertFalse("".equals(badParams.toString()));
-               assertTrue(badParams.toString().contains("nodeType"));
+    @Test
+    /**
+     * Test if we can access the updated bad params outside of the parmsAreBad method.
+     */
+    public void parmsAreBadTest() {
+        // Try with 2 null params
+        StringBuilder badParams = new StringBuilder();
+        IntegrityAudit.parmsAreBad(null, "something", null, badParams);
 
-       }
+        assertFalse("".equals(badParams.toString()));
+        assertTrue(badParams.toString().contains("resourceName"));
+        assertTrue(badParams.toString().contains("properties"));
+
+        // Try with 1 null params
+        badParams = new StringBuilder();
+        Properties props = new Properties();
+        props.put(IntegrityAuditProperties.DB_DRIVER, "test_db_driver");
+        IntegrityAudit.parmsAreBad(null, "something", props, badParams);
+
+        assertFalse("".equals(badParams.toString()));
+        assertTrue(badParams.toString().contains("resourceName"));
+        assertFalse(badParams.toString().contains("properties"));
+
+        // Try with 0 null params
+        badParams = new StringBuilder();
+        IntegrityAudit.parmsAreBad("someting", "something", props, badParams);
+        assertFalse("".equals(badParams.toString()));
+        assertFalse(badParams.toString().contains("resourceName"));
+        assertFalse(badParams.toString().contains("properties"));
+
+        // Try with invalid node type
+        props.put(IntegrityAuditProperties.NODE_TYPE, "bogus");
+        badParams = new StringBuilder();
+        IntegrityAudit.parmsAreBad("someting", "something", props, badParams);
+        assertFalse("".equals(badParams.toString()));
+        assertTrue(badParams.toString().contains("nodeType"));
+
+    }
 
 }
index e30c563..afbcc45 100644 (file)
@@ -23,6 +23,9 @@ package org.onap.policy.common.ia;
 import static org.junit.Assert.assertTrue;
 import static org.junit.Assert.fail;
 
+import ch.qos.logback.classic.Level;
+import ch.qos.logback.classic.Logger;
+
 import java.io.FileOutputStream;
 import java.io.IOException;
 import java.util.ArrayList;
@@ -47,587 +50,560 @@ import org.onap.policy.common.utils.jpa.EntityTransCloser;
 import org.onap.policy.common.utils.test.log.logback.ExtractAppender;
 import org.slf4j.LoggerFactory;
 
-import ch.qos.logback.classic.Level;
-import ch.qos.logback.classic.Logger;
-
 /**
- * All JUnits are designed to run in the local development environment where
- * they have write privileges and can execute time-sensitive tasks.
- * <p/>
- * Many of the test verification steps are performed by scanning for items
- * written to the log file. Rather than actually scan the log file, an
- * {@link ExtractAppender} is used to monitor events that are logged and extract
- * relevant items. In order to attach the appender to the debug log, it assumes
- * that the debug log is a <i>logback</i> Logger configured per EELF.
- * <p/>
- * These tests use a temporary, in-memory DB, which is dropped once the tests
- * complete.
+ * All JUnits are designed to run in the local development environment where they have write
+ * privileges and can execute time-sensitive tasks.
+ * 
+ * <p>Many of the test verification steps are performed by scanning for items written to the log
+ * file. Rather than actually scan the log file, an {@link ExtractAppender} is used to monitor
+ * events that are logged and extract relevant items. In order to attach the appender to the debug
+ * log, it assumes that the debug log is a <i>logback</i> Logger configured per EELF.
+ * 
+ * <p>These tests use a temporary, in-memory DB, which is dropped once the tests complete.
  */
 public class IntegrityAuditTestBase {
 
-       /**
-        * Root of the debug logger, as defined in the logback-test.xml.
-        */
-       protected static final Logger debugLogger = (Logger) LoggerFactory.getLogger("com.att.eelf.debug");
-
-       /**
-        * Root of the error logger, as defined in the logback-test.xml.
-        */
-       protected static final Logger errorLogger = (Logger) LoggerFactory.getLogger("com.att.eelf.error");
-
-       /**
-        * Directory containing the log files.
-        */
-       private static final String LOG_DIR = "testingLogs/common-modules/integrity-audit";
-
-       /**
-        * Max time, in milliseconds, to wait for a latch to be triggered.
-        */
-       protected static final long WAIT_MS = 5000l;
-
-       /**
-        * Milliseconds that auditor should sleep between audit steps.
-        */
-       protected static final long SLEEP_INTERVAL_MS = 2l;
-
-       /**
-        * Milliseconds that auditor should sleep when an audit completes.
-        */
-       protected static final long COMPLETION_INTERVAL_MS = 5l;
-
-       /**
-        * Milliseconds that an entire audit-simulation cycles takes.
-        */
-       protected static final long AUDIT_SIMULATION_MS = SLEEP_INTERVAL_MS * AuditThread.AUDIT_SIMULATION_ITERATIONS;
-
-       /**
-        * Milliseconds that it takes for an auditor's last update to become stale.
-        * Includes a 1ms fudge factor.
-        */
-       protected static final long STALE_MS = 1 + 2 * Math.max(COMPLETION_INTERVAL_MS, AUDIT_SIMULATION_MS);
-
-       /**
-        * Milliseconds that the db-audit should wait between makings updates.
-        */
-       private static final long DB_AUDIT_UPDATE_MS = 10l;
-
-       /**
-        * Milliseconds that the db-audit should sleep between cycles.
-        */
-       private static final long DB_AUDIT_SLEEP_MS = 3l;
-
-       public static final String DEFAULT_DB_URL_PREFIX = "jdbc:h2:mem:";
-
-       protected static final String dbDriver = "org.h2.Driver";
-       protected static final String dbUser = "testu";
-       protected static final String dbPwd = "testp";
-       protected static final String siteName = "SiteA";
-       protected static final String nodeType = "pdp_xacml";
-
-       // will be defined by the test *Classes*
-       protected static String dbUrl;
-
-       /**
-        * Persistence unit for PDP sequence A.
-        */
-       protected static final String A_SEQ_PU = "testPU";
-
-       /**
-        * Persistence unit for PDP sequence B.
-        */
-       protected static final String B_SEQ_PU = "integrityAuditPU";
-
-       /**
-        * Matches the start of an audit for arbitrary PDPs in the debug log.
-        */
-       protected static final String START_AUDIT_RE = "Starting audit simulation for resourceName=([^,]*)";
-
-       /**
-        * Properties to be used in all tests.
-        */
-       protected static Properties properties;
-
-       /**
-        * Entity manager factory pointing to the in-memory DB for A_SEQ_PU.
-        */
-       protected static EntityManagerFactory emf;
-
-       /**
-        * Entity manager factory pointing to the in-memory DB associated with emf.
-        */
-       protected static EntityManager em;
-
-       /**
-        * Saved debug logger level, to be restored once all tests complete.
-        */
-       private static Level savedDebugLevel;
-
-       /**
-        * Saved error logger level, to be restored once all tests complete.
-        */
-       private static Level savedErrorLevel;
-
-       /**
-        * Saved audit sleep interval, to be restored once all tests complete.
-        */
-       private static long savedSleepIntervalMs;
-
-       /**
-        * Saved audit completion interval, to be restored once all tests complete.
-        */
-       private static long savedCompletionIntervalMs;
-
-       /**
-        * Saved db audit update time, to be restored once all tests complete.
-        */
-       private static long savedDbAuditUpdateMs;
-
-       /**
-        * Saved db audit sleep time, to be restored once all tests complete.
-        */
-       private static long savedDbAuditSleepMs;
-
-       /**
-        * List of auditors whose threads must be stopped when a given test case
-        * ends.
-        */
-       private List<MyIntegrityAudit> auditors;
-
-       /**
-        * List of appenders that must be removed from loggers when a given test
-        * case ends.
-        */
-       private List<LogApp> appenders;
-
-       /**
-        * Saves current configuration information and then sets new values.
-        * 
-        * @param dbDriver
-        *            the name of the DB Driver class
-        * @param dbUrl
-        *            the URL to the DB
-        * @throws IOException
-        * @throws Exception
-        */
-       protected static void setUpBeforeClass(String dbUrl) throws IOException {
-
-               // truncate the logs
-               new FileOutputStream(LOG_DIR + "/audit.log").close();
-               new FileOutputStream(LOG_DIR + "/debug.log").close();
-               new FileOutputStream(LOG_DIR + "/error.log").close();
-               new FileOutputStream(LOG_DIR + "/metrics.log").close();
-
-               IntegrityAuditTestBase.dbUrl = dbUrl;
-
-               // save data that we have to restore at the end of the test
-               savedDebugLevel = debugLogger.getLevel();
-               savedErrorLevel = errorLogger.getLevel();
-               savedSleepIntervalMs = AuditThread.getAuditThreadSleepIntervalMillis();
-               savedCompletionIntervalMs = AuditThread.getAuditCompletionIntervalMillis();
-               savedDbAuditUpdateMs = DbAudit.getDbAuditUpdateMillis();
-               savedDbAuditSleepMs = DbAudit.getDbAuditSleepMillis();
-
-               AuditThread.setAuditThreadSleepIntervalMillis(SLEEP_INTERVAL_MS);
-               AuditThread.setAuditCompletionIntervalMillis(COMPLETION_INTERVAL_MS);
-
-               DbAudit.setDbAuditUpdateMillis(DB_AUDIT_UPDATE_MS);
-               DbAudit.setDbAuditSleepMillis(DB_AUDIT_SLEEP_MS);
-
-               IntegrityAudit.setUnitTesting(true);
-
-               properties = new Properties();
-               properties.put(IntegrityAuditProperties.DB_DRIVER, dbDriver);
-               properties.put(IntegrityAuditProperties.DB_URL, dbUrl);
-               properties.put(IntegrityAuditProperties.DB_USER, dbUser);
-               properties.put(IntegrityAuditProperties.DB_PWD, dbPwd);
-               properties.put(IntegrityAuditProperties.SITE_NAME, siteName);
-               properties.put(IntegrityAuditProperties.NODE_TYPE, nodeType);
-
-               emf = Persistence.createEntityManagerFactory(A_SEQ_PU, makeProperties());
-
-               // keep this open so the in-memory DB stays around until all tests are
-               // done
-               em = emf.createEntityManager();
-
-               debugLogger.setLevel(Level.DEBUG);
-               errorLogger.setLevel(Level.ERROR);
-       }
-
-       /**
-        * Restores the configuration to what it was before the test.
-        */
-       protected static void tearDownAfterClass() {
-               AuditThread.setAuditThreadSleepIntervalMillis(savedSleepIntervalMs);
-               AuditThread.setAuditCompletionIntervalMillis(savedCompletionIntervalMs);
-
-               DbAudit.setDbAuditUpdateMillis(savedDbAuditUpdateMs);
-               DbAudit.setDbAuditSleepMillis(savedDbAuditSleepMs);
-
-               IntegrityAudit.setUnitTesting(false);
-
-               debugLogger.setLevel(savedDebugLevel);
-               errorLogger.setLevel(savedErrorLevel);
-
-               // this should result in the in-memory DB being deleted
-               em.close();
-               emf.close();
-       }
-
-       /**
-        * Sets up for a test, which includes deleting all records from the
-        * IntegrityAuditEntity table.
-        */
-       protected void setUp() {
-               auditors = new LinkedList<>();
-               appenders = new LinkedList<>();
-
-               properties.put(IntegrityAuditProperties.AUDIT_PERIOD_MILLISECONDS, String.valueOf(SLEEP_INTERVAL_MS));
-
-               // Clean up the DB
-               try (EntityTransCloser etc = new EntityTransCloser(em.getTransaction())) {
-                       EntityTransaction et = etc.getTransation();
-
-                       em.createQuery("Delete from IntegrityAuditEntity").executeUpdate();
-
-                       // commit transaction
-                       et.commit();
-               }
-       }
-
-       /**
-        * Cleans up after a test, removing any ExtractAppenders from the logger and
-        * stopping any AuditThreads.
-        */
-       protected void tearDown() {
-               for (LogApp p : appenders) {
-                       p.detach();
-               }
-
-               for (MyIntegrityAudit p : auditors) {
-                       p.stopAuditThread();
-               }
-       }
-
-       /**
-        * 
-        * @param properties
-        * @param persistenceUnit
-        * @param tableName
-        */
-       public void truncateTable(Properties properties, String persistenceUnit, String tableName) {
-
-               try (EntityMgrFactoryCloser emfc = new EntityMgrFactoryCloser(
-                               Persistence.createEntityManagerFactory(persistenceUnit, properties));
-                               EntityMgrCloser emc = new EntityMgrCloser(emfc.getFactory().createEntityManager());
-                               EntityTransCloser etc = new EntityTransCloser(emc.getManager().getTransaction())) {
-
-                       EntityManager em = emc.getManager();
-                       EntityTransaction et = etc.getTransation();
-
-                       // Clean up the DB
-                       em.createQuery("Delete from " + tableName).executeUpdate();
-
-                       // commit transaction
-                       et.commit();
-               }
-       }
-
-       /**
-        * Verifies that items appear within the log, in order. A given item may
-        * appear more than once. In addition, the log may contain extra items;
-        * those are ignored.
-        * 
-        * @param textre
-        *            regular expression used to extract an item from a line in the
-        *            log. The first "capture" group of the regular expression is
-        *            assumed to contain the extracted item
-        * @param items
-        *            items that should be matched by the items extracted from the
-        *            log, in order
-        * @throws IOException
-        * @throws AssertionError
-        *             if the desired items were not all found
-        */
-       protected void verifyItemsInLog(ExtractAppender app, String... items) throws IOException {
-
-               Iterator<String> it = new ArrayList<>(Arrays.asList(items)).iterator();
-               if (!it.hasNext()) {
-                       return;
-               }
-
-               String expected = it.next();
-               String last = null;
-
-               for (String rName : app.getExtracted()) {
-                       if (rName.equals(expected)) {
-                               if (!it.hasNext()) {
-                                       // matched all of the items
-                                       return;
-                               }
-
-                               last = expected;
-                               expected = it.next();
-
-                       } else if (!rName.equals(last)) {
-                               List<String> remaining = getRemaining(expected, it);
-                               fail("missing items " + remaining + ", but was: " + rName);
-                       }
-               }
-
-               List<String> remaining = getRemaining(expected, it);
-               assertTrue("missing items " + remaining, remaining.isEmpty());
-       }
-
-       /**
-        * Gets the remaining items from an iterator
-        * 
-        * @param current
-        *            the current item, to be included within the list
-        * @param it
-        *            iterator from which to get the remaining items
-        * @return a list of the remaining items
-        */
-       private LinkedList<String> getRemaining(String current, Iterator<String> it) {
-               LinkedList<String> remaining = new LinkedList<>();
-               remaining.add(current);
-
-               while (it.hasNext()) {
-                       remaining.add(it.next());
-               }
-               return remaining;
-       }
-
-       /**
-        * Waits for a thread to stop. If the thread doesn't complete in the
-        * allotted time, then it interrupts it and waits again.
-        * 
-        * @param auditor
-        *            the thread for which to wait
-        * @return {@code true} if the thread stopped, {@code false} otherwise
-        */
-       public boolean waitThread(MyIntegrityAudit auditor) {
-               if (auditor != null) {
-                       try {
-                               auditor.interrupt();
-
-                               if (!auditor.joinAuditThread(WAIT_MS)) {
-                                       System.out.println("failed to stop audit thread");
-                                       return false;
-                               }
-
-                       } catch (InterruptedException e) {
-                               Thread.currentThread().interrupt();
-                       }
-               }
-
-               return true;
-       }
-
-       /**
-        * Makes a new auditor.
-        * 
-        * @param resourceName2
-        * @param persistenceUnit2
-        * @return a new auditor
-        * @throws Exception
-        */
-       protected MyIntegrityAudit makeAuditor(String resourceName2, String persistenceUnit2) throws Exception {
-               return new MyIntegrityAudit(resourceName2, persistenceUnit2, makeProperties());
-       }
-
-       /**
-        * Watches for patterns in a logger by attaching a ExtractAppender to it.
-        * 
-        * @param logger
-        *            the logger to watch
-        * @param regex
-        *            regular expression used to extract relevant text
-        * @return a new appender
-        */
-       protected ExtractAppender watch(Logger logger, String regex) {
-               ExtractAppender app = new ExtractAppender(regex);
-               appenders.add(new LogApp(logger, app));
-
-               return app;
-       }
-
-       /**
-        * Makes a new Property set that's a clone of {@link #properties}.
-        * 
-        * @return a new Property set containing all of a copy of all of the
-        *         {@link #properties}
-        */
-       protected static Properties makeProperties() {
-               Properties props = new Properties();
-               props.putAll(properties);
-               return props;
-       }
-
-       /**
-        * Waits for data to become stale and then runs an audit on several auditors
-        * in parallel.
-        * 
-        * @param auditors
-        * @throws InterruptedException
-        */
-       protected void waitStaleAndRun(MyIntegrityAudit... auditors) throws InterruptedException {
-               waitStale();
-               runAudit(auditors);
-       }
-
-       /**
-        * Runs an audit on several auditors in parallel.
-        * 
-        * @param auditors
-        * @throws InterruptedException
-        */
-       protected void runAudit(MyIntegrityAudit... auditors) throws InterruptedException {
-
-               // start an audit cycle on each auditor
-               List<CountDownLatch> latches = new ArrayList<>(auditors.length);
-               for (MyIntegrityAudit p : auditors) {
-                       latches.add(p.startAudit());
-               }
-
-               // wait for each auditor to complete its cycle
-               for (CountDownLatch latch : latches) {
-                       waitLatch(latch);
-               }
-       }
-
-       /**
-        * Waits for a latch to reach zero.
-        * 
-        * @param latch
-        * @throws InterruptedException
-        * @throws AssertionError
-        *             if the latch did not reach zero in the allotted time
-        */
-       protected void waitLatch(CountDownLatch latch) throws InterruptedException {
-               assertTrue(latch.await(WAIT_MS, TimeUnit.SECONDS));
-       }
-
-       /**
-        * Sleep a bit so that the currently designated pdp becomes stale.
-        * 
-        * @throws InterruptedException
-        */
-       protected void waitStale() throws InterruptedException {
-               Thread.sleep(STALE_MS);
-       }
-
-       /**
-        * Tracks which appender has been added to a logger.
-        */
-       private static class LogApp {
-               private final Logger logger;
-               private final ExtractAppender appender;
-
-               public LogApp(Logger logger, ExtractAppender appender) {
-                       this.logger = logger;
-                       this.appender = appender;
-
-                       logger.addAppender(appender);
-
-                       appender.start();
-               }
-
-               public void detach() {
-                       logger.detachAppender(appender);
-               }
-       }
-
-       /**
-        * Manages audits by inserting latches into a queue for the AuditThread to
-        * count.
-        */
-       protected class MyIntegrityAudit extends IntegrityAudit {
-
-               /**
-                * Queue from which the AuditThread will take latches.
-                */
-               private BlockingQueue<CountDownLatch> queue = null;
-
-               /**
-                * Constructs an auditor and starts the AuditThread.
-                * 
-                * @param resourceName
-                * @param persistenceUnit
-                * @param properties
-                * @throws Exception
-                */
-               public MyIntegrityAudit(String resourceName, String persistenceUnit, Properties properties) throws Exception {
-                       super(resourceName, persistenceUnit, properties);
-
-                       auditors.add(this);
-
-                       startAuditThread();
-               }
-
-               /**
-                * Interrupts the AuditThread.
-                */
-               public void interrupt() {
-                       super.stopAuditThread();
-               }
-
-               /**
-                * Triggers an audit by adding a latch to the queue.
-                * 
-                * @return the latch that was added
-                * @throws InterruptedException
-                */
-               public CountDownLatch startAudit() throws InterruptedException {
-                       CountDownLatch latch = new CountDownLatch(1);
-                       queue.add(latch);
-
-                       return latch;
-               }
-
-               /**
-                * Starts a new AuditThread. Creates a new latch queue and associates it
-                * with the thread.
-                */
-               @Override
-               public final void startAuditThread() throws IntegrityAuditException {
-                       if (queue != null) {
-                               // queue up a bogus latch, in case a thread is still running
-                               queue.add(new CountDownLatch(1) {
-                                       @Override
-                                       public void countDown() {
-                                               throw new RuntimeException("auditor has multiple threads");
-                                       }
-                               });
-                       }
-
-                       queue = new LinkedBlockingQueue<>();
-
-                       if (super.startAuditThread(queue)) {
-                               // wait for the thread to start
-                               CountDownLatch latch = new CountDownLatch(1);
-                               queue.add(latch);
-                               
-                               try {
-                                       waitLatch(latch);
-                                       
-                               } catch (InterruptedException e) {
-                                       Thread.currentThread().interrupt();
-                                       throw new IntegrityAuditException(e);
-                               }
-                       }
-               }
-
-               /**
-                * Stops the AuditThread and waits for it to stop.
-                * 
-                * @throws AssertionError
-                *             if the thread is still running
-                */
-               @Override
-               public void stopAuditThread() {
-                       super.stopAuditThread();
-
-                       assertTrue(waitThread(this));
-               }
-       }
+    /**
+     * Root of the debug logger, as defined in the logback-test.xml.
+     */
+    protected static final Logger debugLogger = (Logger) LoggerFactory.getLogger("com.att.eelf.debug");
+
+    /**
+     * Root of the error logger, as defined in the logback-test.xml.
+     */
+    protected static final Logger errorLogger = (Logger) LoggerFactory.getLogger("com.att.eelf.error");
+
+    /**
+     * Directory containing the log files.
+     */
+    private static final String LOG_DIR = "testingLogs/common-modules/integrity-audit";
+
+    /**
+     * Max time, in milliseconds, to wait for a latch to be triggered.
+     */
+    protected static final long WAIT_MS = 5000L;
+
+    /**
+     * Milliseconds that auditor should sleep between audit steps.
+     */
+    protected static final long SLEEP_INTERVAL_MS = 2L;
+
+    /**
+     * Milliseconds that auditor should sleep when an audit completes.
+     */
+    protected static final long COMPLETION_INTERVAL_MS = 5L;
+
+    /**
+     * Milliseconds that an entire audit-simulation cycles takes.
+     */
+    protected static final long AUDIT_SIMULATION_MS = SLEEP_INTERVAL_MS * AuditThread.AUDIT_SIMULATION_ITERATIONS;
+
+    /**
+     * Milliseconds that it takes for an auditor's last update to become stale. Includes a 1ms fudge
+     * factor.
+     */
+    protected static final long STALE_MS = 1 + 2 * Math.max(COMPLETION_INTERVAL_MS, AUDIT_SIMULATION_MS);
+
+    /**
+     * Milliseconds that the db-audit should wait between makings updates.
+     */
+    private static final long DB_AUDIT_UPDATE_MS = 10L;
+
+    /**
+     * Milliseconds that the db-audit should sleep between cycles.
+     */
+    private static final long DB_AUDIT_SLEEP_MS = 3L;
+
+    public static final String DEFAULT_DB_URL_PREFIX = "jdbc:h2:mem:";
+
+    protected static final String dbDriver = "org.h2.Driver";
+    protected static final String dbUser = "testu";
+    protected static final String dbPwd = "testp";
+    protected static final String siteName = "SiteA";
+    protected static final String nodeType = "pdp_xacml";
+
+    // will be defined by the test *Classes*
+    protected static String dbUrl;
+
+    /**
+     * Persistence unit for PDP sequence A.
+     */
+    protected static final String A_SEQ_PU = "testPU";
+
+    /**
+     * Persistence unit for PDP sequence B.
+     */
+    protected static final String B_SEQ_PU = "integrityAuditPU";
+
+    /**
+     * Matches the start of an audit for arbitrary PDPs in the debug log.
+     */
+    protected static final String START_AUDIT_RE = "Starting audit simulation for resourceName=([^,]*)";
+
+    /**
+     * Properties to be used in all tests.
+     */
+    protected static Properties properties;
+
+    /**
+     * Entity manager factory pointing to the in-memory DB for A_SEQ_PU.
+     */
+    protected static EntityManagerFactory emf;
+
+    /**
+     * Entity manager factory pointing to the in-memory DB associated with emf.
+     */
+    protected static EntityManager em;
+
+    /**
+     * Saved debug logger level, to be restored once all tests complete.
+     */
+    private static Level savedDebugLevel;
+
+    /**
+     * Saved error logger level, to be restored once all tests complete.
+     */
+    private static Level savedErrorLevel;
+
+    /**
+     * Saved audit sleep interval, to be restored once all tests complete.
+     */
+    private static long savedSleepIntervalMs;
+
+    /**
+     * Saved audit completion interval, to be restored once all tests complete.
+     */
+    private static long savedCompletionIntervalMs;
+
+    /**
+     * Saved db audit update time, to be restored once all tests complete.
+     */
+    private static long savedDbAuditUpdateMs;
+
+    /**
+     * Saved db audit sleep time, to be restored once all tests complete.
+     */
+    private static long savedDbAuditSleepMs;
+
+    /**
+     * List of auditors whose threads must be stopped when a given test case ends.
+     */
+    private List<MyIntegrityAudit> auditors;
+
+    /**
+     * List of appenders that must be removed from loggers when a given test case ends.
+     */
+    private List<LogApp> appenders;
+
+    /**
+     * Saves current configuration information and then sets new values.
+     * 
+     * @param dbDriver the name of the DB Driver class
+     * @param dbUrl the URL to the DB
+     * @throws IOException if an IO error occurs
+     */
+    protected static void setUpBeforeClass(String dbUrl) throws IOException {
+
+        // truncate the logs
+        new FileOutputStream(LOG_DIR + "/audit.log").close();
+        new FileOutputStream(LOG_DIR + "/debug.log").close();
+        new FileOutputStream(LOG_DIR + "/error.log").close();
+        new FileOutputStream(LOG_DIR + "/metrics.log").close();
+
+        IntegrityAuditTestBase.dbUrl = dbUrl;
+
+        // save data that we have to restore at the end of the test
+        savedDebugLevel = debugLogger.getLevel();
+        savedErrorLevel = errorLogger.getLevel();
+        savedSleepIntervalMs = AuditThread.getAuditThreadSleepIntervalMillis();
+        savedCompletionIntervalMs = AuditThread.getAuditCompletionIntervalMillis();
+        savedDbAuditUpdateMs = DbAudit.getDbAuditUpdateMillis();
+        savedDbAuditSleepMs = DbAudit.getDbAuditSleepMillis();
+
+        AuditThread.setAuditThreadSleepIntervalMillis(SLEEP_INTERVAL_MS);
+        AuditThread.setAuditCompletionIntervalMillis(COMPLETION_INTERVAL_MS);
+
+        DbAudit.setDbAuditUpdateMillis(DB_AUDIT_UPDATE_MS);
+        DbAudit.setDbAuditSleepMillis(DB_AUDIT_SLEEP_MS);
+
+        IntegrityAudit.setUnitTesting(true);
+
+        properties = new Properties();
+        properties.put(IntegrityAuditProperties.DB_DRIVER, dbDriver);
+        properties.put(IntegrityAuditProperties.DB_URL, dbUrl);
+        properties.put(IntegrityAuditProperties.DB_USER, dbUser);
+        properties.put(IntegrityAuditProperties.DB_PWD, dbPwd);
+        properties.put(IntegrityAuditProperties.SITE_NAME, siteName);
+        properties.put(IntegrityAuditProperties.NODE_TYPE, nodeType);
+
+        emf = Persistence.createEntityManagerFactory(A_SEQ_PU, makeProperties());
+
+        // keep this open so the in-memory DB stays around until all tests are
+        // done
+        em = emf.createEntityManager();
+
+        debugLogger.setLevel(Level.DEBUG);
+        errorLogger.setLevel(Level.ERROR);
+    }
+
+    /**
+     * Restores the configuration to what it was before the test.
+     */
+    protected static void tearDownAfterClass() {
+        AuditThread.setAuditThreadSleepIntervalMillis(savedSleepIntervalMs);
+        AuditThread.setAuditCompletionIntervalMillis(savedCompletionIntervalMs);
+
+        DbAudit.setDbAuditUpdateMillis(savedDbAuditUpdateMs);
+        DbAudit.setDbAuditSleepMillis(savedDbAuditSleepMs);
+
+        IntegrityAudit.setUnitTesting(false);
+
+        debugLogger.setLevel(savedDebugLevel);
+        errorLogger.setLevel(savedErrorLevel);
+
+        // this should result in the in-memory DB being deleted
+        em.close();
+        emf.close();
+    }
+
+    /**
+     * Sets up for a test, which includes deleting all records from the IntegrityAuditEntity table.
+     */
+    protected void setUp() {
+        auditors = new LinkedList<>();
+        appenders = new LinkedList<>();
+
+        properties.put(IntegrityAuditProperties.AUDIT_PERIOD_MILLISECONDS, String.valueOf(SLEEP_INTERVAL_MS));
+
+        // Clean up the DB
+        try (EntityTransCloser etc = new EntityTransCloser(em.getTransaction())) {
+            EntityTransaction et = etc.getTransation();
+
+            em.createQuery("Delete from IntegrityAuditEntity").executeUpdate();
+
+            // commit transaction
+            et.commit();
+        }
+    }
+
+    /**
+     * Cleans up after a test, removing any ExtractAppenders from the logger and stopping any
+     * AuditThreads.
+     */
+    protected void tearDown() {
+        for (LogApp p : appenders) {
+            p.detach();
+        }
+
+        for (MyIntegrityAudit p : auditors) {
+            p.stopAuditThread();
+        }
+    }
+
+    /**
+     * Truncate the table.
+     * 
+     * @param properties the properties
+     * @param persistenceUnit the persistence unit
+     * @param tableName the name of the table
+     */
+    public void truncateTable(Properties properties, String persistenceUnit, String tableName) {
+
+        try (EntityMgrFactoryCloser emfc =
+                new EntityMgrFactoryCloser(Persistence.createEntityManagerFactory(persistenceUnit, properties));
+                EntityMgrCloser emc = new EntityMgrCloser(emfc.getFactory().createEntityManager());
+                EntityTransCloser etc = new EntityTransCloser(emc.getManager().getTransaction())) {
+
+            EntityManager em = emc.getManager();
+            EntityTransaction et = etc.getTransation();
+
+            // Clean up the DB
+            em.createQuery("Delete from " + tableName).executeUpdate();
+
+            // commit transaction
+            et.commit();
+        }
+    }
+
+    /**
+     * Verifies that items appear within the log, in order. A given item may appear more than once.
+     * In addition, the log may contain extra items; those are ignored.
+     * 
+     * @param textre regular expression used to extract an item from a line in the log. The first
+     *        "capture" group of the regular expression is assumed to contain the extracted item
+     * @param items items that should be matched by the items extracted from the log, in order
+     * @throws IOException if an IO error occurs
+     * @throws AssertionError if the desired items were not all found
+     */
+    protected void verifyItemsInLog(ExtractAppender app, String... items) throws IOException {
+
+        Iterator<String> it = new ArrayList<>(Arrays.asList(items)).iterator();
+        if (!it.hasNext()) {
+            return;
+        }
+
+        String expected = it.next();
+        String last = null;
+
+        for (String extractedText : app.getExtracted()) {
+            if (extractedText.equals(expected)) {
+                if (!it.hasNext()) {
+                    // matched all of the items
+                    return;
+                }
+
+                last = expected;
+                expected = it.next();
+
+            } else if (!extractedText.equals(last)) {
+                List<String> remaining = getRemaining(expected, it);
+                fail("missing items " + remaining + ", but was: " + extractedText);
+            }
+        }
+
+        List<String> remaining = getRemaining(expected, it);
+        assertTrue("missing items " + remaining, remaining.isEmpty());
+    }
+
+    /**
+     * Gets the remaining items from an iterator.
+     * 
+     * @param current the current item, to be included within the list
+     * @param it iterator from which to get the remaining items
+     * @return a list of the remaining items
+     */
+    private LinkedList<String> getRemaining(String current, Iterator<String> it) {
+        LinkedList<String> remaining = new LinkedList<>();
+        remaining.add(current);
+
+        while (it.hasNext()) {
+            remaining.add(it.next());
+        }
+        return remaining;
+    }
+
+    /**
+     * Waits for a thread to stop. If the thread doesn't complete in the allotted time, then it
+     * interrupts it and waits again.
+     * 
+     * @param auditor the thread for which to wait
+     * @return {@code true} if the thread stopped, {@code false} otherwise
+     */
+    public boolean waitThread(MyIntegrityAudit auditor) {
+        if (auditor != null) {
+            try {
+                auditor.interrupt();
+
+                if (!auditor.joinAuditThread(WAIT_MS)) {
+                    System.out.println("failed to stop audit thread");
+                    return false;
+                }
+
+            } catch (InterruptedException e) {
+                Thread.currentThread().interrupt();
+            }
+        }
+
+        return true;
+    }
+
+    /**
+     * Makes a new auditor.
+     * 
+     * @param resourceName2 the name of the resource
+     * @param persistenceUnit2 the persistence unit
+     * @return a new auditor
+     * @throws Exception if an error occurs
+     */
+    protected MyIntegrityAudit makeAuditor(String resourceName2, String persistenceUnit2) throws Exception {
+        return new MyIntegrityAudit(resourceName2, persistenceUnit2, makeProperties());
+    }
+
+    /**
+     * Watches for patterns in a logger by attaching a ExtractAppender to it.
+     * 
+     * @param logger the logger to watch
+     * @param regex regular expression used to extract relevant text
+     * @return a new appender
+     */
+    protected ExtractAppender watch(Logger logger, String regex) {
+        ExtractAppender app = new ExtractAppender(regex);
+        appenders.add(new LogApp(logger, app));
+
+        return app;
+    }
+
+    /**
+     * Makes a new Property set that's a clone of {@link #properties}.
+     * 
+     * @return a new Property set containing all of a copy of all of the {@link #properties}
+     */
+    protected static Properties makeProperties() {
+        Properties props = new Properties();
+        props.putAll(properties);
+        return props;
+    }
+
+    /**
+     * Waits for data to become stale and then runs an audit on several auditors in parallel.
+     * 
+     * @param auditors the auditors
+     * @throws InterruptedException if a thread is interrupted
+     */
+    protected void waitStaleAndRun(MyIntegrityAudit... auditors) throws InterruptedException {
+        waitStale();
+        runAudit(auditors);
+    }
+
+    /**
+     * Runs an audit on several auditors in parallel.
+     * 
+     * @param auditors the auditors
+     * @throws InterruptedException if a thread is interrupted
+     */
+    protected void runAudit(MyIntegrityAudit... auditors) throws InterruptedException {
+
+        // start an audit cycle on each auditor
+        List<CountDownLatch> latches = new ArrayList<>(auditors.length);
+        for (MyIntegrityAudit p : auditors) {
+            latches.add(p.startAudit());
+        }
+
+        // wait for each auditor to complete its cycle
+        for (CountDownLatch latch : latches) {
+            waitLatch(latch);
+        }
+    }
+
+    /**
+     * Waits for a latch to reach zero.
+     * 
+     * @param latch the latch to wait for
+     * @throws InterruptedException if the thread is interrupted
+     * @throws AssertionError if the latch did not reach zero in the allotted time
+     */
+    protected void waitLatch(CountDownLatch latch) throws InterruptedException {
+        assertTrue(latch.await(WAIT_MS, TimeUnit.SECONDS));
+    }
+
+    /**
+     * Sleep a bit so that the currently designated pdp becomes stale.
+     * 
+     * @throws InterruptedException if the thread is interrupted
+     */
+    protected void waitStale() throws InterruptedException {
+        Thread.sleep(STALE_MS);
+    }
+
+    /**
+     * Tracks which appender has been added to a logger.
+     */
+    private static class LogApp {
+        private final Logger logger;
+        private final ExtractAppender appender;
+
+        public LogApp(Logger logger, ExtractAppender appender) {
+            this.logger = logger;
+            this.appender = appender;
+
+            logger.addAppender(appender);
+
+            appender.start();
+        }
+
+        public void detach() {
+            logger.detachAppender(appender);
+        }
+    }
+
+    /**
+     * Manages audits by inserting latches into a queue for the AuditThread to count.
+     */
+    protected class MyIntegrityAudit extends IntegrityAudit {
+
+        /**
+         * Queue from which the AuditThread will take latches.
+         */
+        private BlockingQueue<CountDownLatch> queue = null;
+
+        /**
+         * Constructs an auditor and starts the AuditThread.
+         * 
+         * @param resourceName the resource name
+         * @param persistenceUnit the persistence unit
+         * @param properties the properties
+         * @throws Exception if an error occurs
+         */
+        public MyIntegrityAudit(String resourceName, String persistenceUnit, Properties properties) throws Exception {
+            super(resourceName, persistenceUnit, properties);
+
+            auditors.add(this);
+
+            startAuditThread();
+        }
+
+        /**
+         * Interrupts the AuditThread.
+         */
+        public void interrupt() {
+            super.stopAuditThread();
+        }
+
+        /**
+         * Triggers an audit by adding a latch to the queue.
+         * 
+         * @return the latch that was added
+         * @throws InterruptedException if the thread is interrupted
+         */
+        public CountDownLatch startAudit() throws InterruptedException {
+            CountDownLatch latch = new CountDownLatch(1);
+            queue.add(latch);
+
+            return latch;
+        }
+
+        /**
+         * Starts a new AuditThread. Creates a new latch queue and associates it with the thread.
+         */
+        @Override
+        public final void startAuditThread() throws IntegrityAuditException {
+            if (queue != null) {
+                // queue up a bogus latch, in case a thread is still running
+                queue.add(new CountDownLatch(1) {
+                    @Override
+                    public void countDown() {
+                        throw new RuntimeException("auditor has multiple threads");
+                    }
+                });
+            }
+
+            queue = new LinkedBlockingQueue<>();
+
+            if (super.startAuditThread(queue)) {
+                // wait for the thread to start
+                CountDownLatch latch = new CountDownLatch(1);
+                queue.add(latch);
+
+                try {
+                    waitLatch(latch);
+
+                } catch (InterruptedException e) {
+                    Thread.currentThread().interrupt();
+                    throw new IntegrityAuditException(e);
+                }
+            }
+        }
+
+        /**
+         * Stops the AuditThread and waits for it to stop.
+         * 
+         * @throws AssertionError if the thread is still running
+         */
+        @Override
+        public void stopAuditThread() {
+            super.stopAuditThread();
+
+            assertTrue(waitThread(this));
+        }
+    }
 }
index 43277a7..36b9ef6 100644 (file)
@@ -37,119 +37,139 @@ import javax.persistence.Temporal;
 import javax.persistence.TemporalType;
 
 @Entity
-@Table(name="IaTestEntity")
-@NamedQueries({
-       @NamedQuery(name=" IaTestEntity.findAll", query="SELECT e FROM IaTestEntity e "),
-       @NamedQuery(name="IaTestEntity.deleteAll", query="DELETE FROM IaTestEntity WHERE 1=1")
-})
+@Table(name = "IaTestEntity")
+@NamedQueries({@NamedQuery(name = " IaTestEntity.findAll", query = "SELECT e FROM IaTestEntity e "),
+        @NamedQuery(name = "IaTestEntity.deleteAll", query = "DELETE FROM IaTestEntity WHERE 1=1")})
 
 public class IaTestEntity implements Serializable {
-       private static final long serialVersionUID = 1L;
-
-       @Id
-       @GeneratedValue(strategy = GenerationType.AUTO)
-       @Column(name="ImTestId")
-       private long imTestId;
-       
-       @Column(name="created_by", nullable=false, length=255)
-       private String createdBy = "guest";
-       
-       @Column(name="person", nullable=false, length=255)
-       private PersonSample person;
-
-       @Temporal(TemporalType.TIMESTAMP)
-       @Column(name="created_date", updatable=false)
-       private Date createdDate;
-
-       @Column(name="modified_by", nullable=false, length=255)
-       private String modifiedBy = "guest";
-
-       @Temporal(TemporalType.TIMESTAMP)
-       @Column(name="modified_date", nullable=false)
-       private Date modifiedDate;
-
-       public IaTestEntity() {
-       }
-
-       @PrePersist
-       public void     prePersist() {
-               Date date = new Date();
-               this.createdDate = date;
-               this.modifiedDate = date;
-       }
-
-       @PreUpdate
-       public void preUpdate() {
-               this.modifiedDate = new Date();
-       }
-       
-       /**
-        * @return the Id
-        */
-       public long getImTestId() {
-               return imTestId;
-       }
-       
-       /**
-        * @return the createdBy
-        */
-       public String getCreatedBy() {
-               return createdBy;
-       }
-
-       /**
-        * @param createdBy the createdBy to set
-        */
-       public void setCreatedBy(String createdBy) {
-               this.createdBy = createdBy;
-       }
-       
-       /**
-        * @return the modifiedBy
-        */
-       public String getModifiedBy() {
-               return modifiedBy;
-       }
-       
-       /**
-        * @param modifiedBy the modifiedBy to set
-        */
-       public void setModifiedBy(String modifiedBy) {
-               this.modifiedBy = modifiedBy;
-       }
-       
-       /**
-        * @return the modifiedDate
-        */
-       public Date getModifiedDate() {
-               return modifiedDate;
-       }
-
-       /**
-        * @param modifiedDate the modifiedDate to set
-        */
-       public void setModifiedDate(Date modifiedDate) {
-               this.modifiedDate = modifiedDate;
-       }
-
-       /**
-        * @return the createdDate
-        */
-       public Date getCreatedDate() {
-               return createdDate;
-       }
-       
-       /**
-        * @param the person to set
-        */
-       public void setPersonTest(PersonSample p) {
-               this.person = p;
-       }
-       
-       /**
-        * @return the person
-        */
-       public PersonSample getPersonTest() {
-               return person;
-       }
+    private static final long serialVersionUID = 1L;
+
+    @Id
+    @GeneratedValue(strategy = GenerationType.AUTO)
+    @Column(name = "ImTestId")
+    private long imTestId;
+
+    @Column(name = "created_by", nullable = false, length = 255)
+    private String createdBy = "guest";
+
+    @Column(name = "person", nullable = false, length = 255)
+    private PersonSample person;
+
+    @Temporal(TemporalType.TIMESTAMP)
+    @Column(name = "created_date", updatable = false)
+    private Date createdDate;
+
+    @Column(name = "modified_by", nullable = false, length = 255)
+    private String modifiedBy = "guest";
+
+    @Temporal(TemporalType.TIMESTAMP)
+    @Column(name = "modified_date", nullable = false)
+    private Date modifiedDate;
+
+    public IaTestEntity() {}
+
+    /**
+     * PrePersist call back method.
+     */
+    @PrePersist
+    public void prePersist() {
+        Date date = new Date();
+        this.createdDate = date;
+        this.modifiedDate = date;
+    }
+
+    @PreUpdate
+    public void preUpdate() {
+        this.modifiedDate = new Date();
+    }
+
+    /**
+     * The the Im test Id.
+     * 
+     * @return the Id
+     */
+    public long getImTestId() {
+        return imTestId;
+    }
+
+    /**
+     * Get the createdBy.
+     * 
+     * @return the createdBy
+     */
+    public String getCreatedBy() {
+        return createdBy;
+    }
+
+    /**
+     * Set the createdBy.
+     * 
+     * @param createdBy the createdBy to set
+     */
+    public void setCreatedBy(String createdBy) {
+        this.createdBy = createdBy;
+    }
+
+    /**
+     * Get the modifiedBy.
+     * 
+     * @return the modifiedBy
+     */
+    public String getModifiedBy() {
+        return modifiedBy;
+    }
+
+    /**
+     * Set the ModifiedBy.
+     * 
+     * @param modifiedBy the modifiedBy to set
+     */
+    public void setModifiedBy(String modifiedBy) {
+        this.modifiedBy = modifiedBy;
+    }
+
+    /**
+     * Get the ModifiedDate.
+     * 
+     * @return the modifiedDate
+     */
+    public Date getModifiedDate() {
+        return modifiedDate;
+    }
+
+    /**
+     * Set the ModifiedDate.
+     * 
+     * @param modifiedDate the modifiedDate to set
+     */
+    public void setModifiedDate(Date modifiedDate) {
+        this.modifiedDate = modifiedDate;
+    }
+
+    /**
+     * Get the CreatedDate.
+     * 
+     * @return the createdDate
+     */
+    public Date getCreatedDate() {
+        return createdDate;
+    }
+
+    /**
+     * Set the person.
+     * 
+     * @param person the person to set
+     */
+    public void setPersonTest(PersonSample person) {
+        this.person = person;
+    }
+
+    /**
+     * Get the person.
+     * 
+     * @return the person
+     */
+    public PersonSample getPersonTest() {
+        return person;
+    }
 }
index d7fcf33..47fa843 100644 (file)
@@ -23,42 +23,47 @@ package org.onap.policy.common.ia.jpa;
 import java.io.Serializable;
 
 public class PersonSample implements Serializable {
-       /**
-        * 
-        */
-       private static final long serialVersionUID = 1L;
-       private String firstName;
-       private String lastName;
-       private int age;
-       
-       public PersonSample(String first, String last, int age) {
-               this.firstName = first;
-               this.lastName = last;
-               this.age = age;
-       }
-       
-       public String getFirstName() {
-               return this.firstName;
-       }
-       
-       public void setFirstName(String name) {
-               this.firstName = name;
-       }
-       
-       public String getLasttName() {
-               return this.lastName;
-       }
-       
-       public void setLastName(String name) {
-               this.lastName = name;
-       }
-       
-       public int getAge() {
-               return this.age;
-       }
-       
-       public void setAge(int age) {
-               this.age = age;
-       }
-       
+
+    private static final long serialVersionUID = 1L;
+    private String firstName;
+    private String lastName;
+    private int age;
+
+    /**
+     * Create an instance.
+     * 
+     * @param first first name
+     * @param last last name
+     * @param age age
+     */
+    public PersonSample(String first, String last, int age) {
+        this.firstName = first;
+        this.lastName = last;
+        this.age = age;
+    }
+
+    public String getFirstName() {
+        return this.firstName;
+    }
+
+    public void setFirstName(String name) {
+        this.firstName = name;
+    }
+
+    public String getLasttName() {
+        return this.lastName;
+    }
+
+    public void setLastName(String name) {
+        this.lastName = name;
+    }
+
+    public int getAge() {
+        return this.age;
+    }
+
+    public void setAge(int age) {
+        this.age = age;
+    }
+
 }