aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPamela Dragosh <pdragosh@research.att.com>2018-03-21 12:10:13 +0000
committerGerrit Code Review <gerrit@onap.org>2018-03-21 12:10:13 +0000
commit93e0eba78843ec618db65f428eb64a393ba51493 (patch)
treeeb24cd5f34af22ac728ebd55c60c647d5cad1fad
parenta00f4db1250355b756bd69c98465fdda3a4503ca (diff)
parentb632bb134cf056640e7d5b3647875c41bfdc58da (diff)
Merge "Removed checkstyle warnings"
-rw-r--r--integrity-audit/src/main/java/org/onap/policy/common/ia/AuditThread.java1645
-rw-r--r--integrity-audit/src/main/java/org/onap/policy/common/ia/DbAudit.java967
-rw-r--r--integrity-audit/src/main/java/org/onap/policy/common/ia/DbAuditException.java29
-rw-r--r--integrity-audit/src/main/java/org/onap/policy/common/ia/DbDAO.java1408
-rw-r--r--integrity-audit/src/main/java/org/onap/policy/common/ia/DbDaoTransactionException.java29
-rw-r--r--integrity-audit/src/main/java/org/onap/policy/common/ia/IntegrityAudit.java536
-rw-r--r--integrity-audit/src/main/java/org/onap/policy/common/ia/IntegrityAuditException.java33
-rw-r--r--integrity-audit/src/main/java/org/onap/policy/common/ia/IntegrityAuditProperties.java52
-rw-r--r--integrity-audit/src/main/java/org/onap/policy/common/ia/IntegrityAuditPropertiesException.java29
-rw-r--r--integrity-audit/src/main/java/org/onap/policy/common/ia/jpa/IntegrityAuditEntity.java357
-rw-r--r--integrity-audit/src/test/java/org/onap/policy/common/ia/AuditPeriodTest.java397
-rw-r--r--integrity-audit/src/test/java/org/onap/policy/common/ia/DbAuditCompareEntriesTest.java1004
-rw-r--r--integrity-audit/src/test/java/org/onap/policy/common/ia/DbAuditTest.java436
-rw-r--r--integrity-audit/src/test/java/org/onap/policy/common/ia/DbDAOTest.java785
-rw-r--r--integrity-audit/src/test/java/org/onap/policy/common/ia/ExceptionsTest.java42
-rw-r--r--integrity-audit/src/test/java/org/onap/policy/common/ia/IntegrityAuditDesignationTest.java1149
-rw-r--r--integrity-audit/src/test/java/org/onap/policy/common/ia/IntegrityAuditTest.java79
-rw-r--r--integrity-audit/src/test/java/org/onap/policy/common/ia/IntegrityAuditTestBase.java1134
-rw-r--r--integrity-audit/src/test/java/org/onap/policy/common/ia/jpa/IaTestEntity.java246
-rw-r--r--integrity-audit/src/test/java/org/onap/policy/common/ia/jpa/PersonSample.java81
20 files changed, 5196 insertions, 5242 deletions
diff --git a/integrity-audit/src/main/java/org/onap/policy/common/ia/AuditThread.java b/integrity-audit/src/main/java/org/onap/policy/common/ia/AuditThread.java
index efa1b1d3..f1839b12 100644
--- a/integrity-audit/src/main/java/org/onap/policy/common/ia/AuditThread.java
+++ b/integrity-audit/src/main/java/org/onap/policy/common/ia/AuditThread.java
@@ -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;
+ }
}
diff --git a/integrity-audit/src/main/java/org/onap/policy/common/ia/DbAudit.java b/integrity-audit/src/main/java/org/onap/policy/common/ia/DbAudit.java
index 6fb619e4..4c4104f6 100644
--- a/integrity-audit/src/main/java/org/onap/policy/common/ia/DbAudit.java
+++ b/integrity-audit/src/main/java/org/onap/policy/common/ia/DbAudit.java
@@ -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;
+ }
}
diff --git a/integrity-audit/src/main/java/org/onap/policy/common/ia/DbAuditException.java b/integrity-audit/src/main/java/org/onap/policy/common/ia/DbAuditException.java
index dc629c65..a539f6bd 100644
--- a/integrity-audit/src/main/java/org/onap/policy/common/ia/DbAuditException.java
+++ b/integrity-audit/src/main/java/org/onap/policy/common/ia/DbAuditException.java
@@ -21,18 +21,21 @@
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);
+ }
}
diff --git a/integrity-audit/src/main/java/org/onap/policy/common/ia/DbDAO.java b/integrity-audit/src/main/java/org/onap/policy/common/ia/DbDAO.java
index 73beda78..864adacb 100644
--- a/integrity-audit/src/main/java/org/onap/policy/common/ia/DbDAO.java
+++ b/integrity-audit/src/main/java/org/onap/policy/common/ia/DbDAO.java
@@ -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");
+ }
+
+ }
}
diff --git a/integrity-audit/src/main/java/org/onap/policy/common/ia/DbDaoTransactionException.java b/integrity-audit/src/main/java/org/onap/policy/common/ia/DbDaoTransactionException.java
index 72716279..dc1c6f14 100644
--- a/integrity-audit/src/main/java/org/onap/policy/common/ia/DbDaoTransactionException.java
+++ b/integrity-audit/src/main/java/org/onap/policy/common/ia/DbDaoTransactionException.java
@@ -21,18 +21,21 @@
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);
+ }
}
diff --git a/integrity-audit/src/main/java/org/onap/policy/common/ia/IntegrityAudit.java b/integrity-audit/src/main/java/org/onap/policy/common/ia/IntegrityAudit.java
index cab08610..9abdbe52 100644
--- a/integrity-audit/src/main/java/org/onap/policy/common/ia/IntegrityAudit.java
+++ b/integrity-audit/src/main/java/org/onap/policy/common/ia/IntegrityAudit.java
@@ -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();
+ }
+ }
}
diff --git a/integrity-audit/src/main/java/org/onap/policy/common/ia/IntegrityAuditException.java b/integrity-audit/src/main/java/org/onap/policy/common/ia/IntegrityAuditException.java
index a62c837c..81e8b90c 100644
--- a/integrity-audit/src/main/java/org/onap/policy/common/ia/IntegrityAuditException.java
+++ b/integrity-audit/src/main/java/org/onap/policy/common/ia/IntegrityAuditException.java
@@ -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.
@@ -20,19 +20,22 @@
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);
+ }
}
diff --git a/integrity-audit/src/main/java/org/onap/policy/common/ia/IntegrityAuditProperties.java b/integrity-audit/src/main/java/org/onap/policy/common/ia/IntegrityAuditProperties.java
index b8db3ac2..2708c090 100644
--- a/integrity-audit/src/main/java/org/onap/policy/common/ia/IntegrityAuditProperties.java
+++ b/integrity-audit/src/main/java/org/onap/policy/common/ia/IntegrityAuditProperties.java
@@ -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() {
+
+ }
+
}
diff --git a/integrity-audit/src/main/java/org/onap/policy/common/ia/IntegrityAuditPropertiesException.java b/integrity-audit/src/main/java/org/onap/policy/common/ia/IntegrityAuditPropertiesException.java
index 766268bc..d3c92fa5 100644
--- a/integrity-audit/src/main/java/org/onap/policy/common/ia/IntegrityAuditPropertiesException.java
+++ b/integrity-audit/src/main/java/org/onap/policy/common/ia/IntegrityAuditPropertiesException.java
@@ -21,18 +21,21 @@
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);
+ }
}
diff --git a/integrity-audit/src/main/java/org/onap/policy/common/ia/jpa/IntegrityAuditEntity.java b/integrity-audit/src/main/java/org/onap/policy/common/ia/jpa/IntegrityAuditEntity.java
index da69f2de..23b90efc 100644
--- a/integrity-audit/src/main/java/org/onap/policy/common/ia/jpa/IntegrityAuditEntity.java
+++ b/integrity-audit/src/main/java/org/onap/policy/common/ia/jpa/IntegrityAuditEntity.java
@@ -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();
+ }
+ }
}
diff --git a/integrity-audit/src/test/java/org/onap/policy/common/ia/AuditPeriodTest.java b/integrity-audit/src/test/java/org/onap/policy/common/ia/AuditPeriodTest.java
index b627977b..232468d6 100644
--- a/integrity-audit/src/test/java/org/onap/policy/common/ia/AuditPeriodTest.java
+++ b/integrity-audit/src/test/java/org/onap/policy/common/ia/AuditPeriodTest.java
@@ -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);
+ }
+ }
}
diff --git a/integrity-audit/src/test/java/org/onap/policy/common/ia/DbAuditCompareEntriesTest.java b/integrity-audit/src/test/java/org/onap/policy/common/ia/DbAuditCompareEntriesTest.java
index 3a48b20c..6335482a 100644
--- a/integrity-audit/src/test/java/org/onap/policy/common/ia/DbAuditCompareEntriesTest.java
+++ b/integrity-audit/src/test/java/org/onap/policy/common/ia/DbAuditCompareEntriesTest.java
@@ -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");
+ }
}
diff --git a/integrity-audit/src/test/java/org/onap/policy/common/ia/DbAuditTest.java b/integrity-audit/src/test/java/org/onap/policy/common/ia/DbAuditTest.java
index ad4041f5..cfbf90cb 100644
--- a/integrity-audit/src/test/java/org/onap/policy/common/ia/DbAuditTest.java
+++ b/integrity-audit/src/test/java/org/onap/policy/common/ia/DbAuditTest.java
@@ -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;
+ }
}
diff --git a/integrity-audit/src/test/java/org/onap/policy/common/ia/DbDAOTest.java b/integrity-audit/src/test/java/org/onap/policy/common/ia/DbDAOTest.java
index c4cba280..01e2f2b0 100644
--- a/integrity-audit/src/test/java/org/onap/policy/common/ia/DbDAOTest.java
+++ b/integrity-audit/src/test/java/org/onap/policy/common/ia/DbDAOTest.java
@@ -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());
+ }
}
diff --git a/integrity-audit/src/test/java/org/onap/policy/common/ia/ExceptionsTest.java b/integrity-audit/src/test/java/org/onap/policy/common/ia/ExceptionsTest.java
index b02b0c7f..3c8ce528 100644
--- a/integrity-audit/src/test/java/org/onap/policy/common/ia/ExceptionsTest.java
+++ b/integrity-audit/src/test/java/org/onap/policy/common/ia/ExceptionsTest.java
@@ -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));
+ }
}
diff --git a/integrity-audit/src/test/java/org/onap/policy/common/ia/IntegrityAuditDesignationTest.java b/integrity-audit/src/test/java/org/onap/policy/common/ia/IntegrityAuditDesignationTest.java
index 1861787a..69f37da5 100644
--- a/integrity-audit/src/test/java/org/onap/policy/common/ia/IntegrityAuditDesignationTest.java
+++ b/integrity-audit/src/test/java/org/onap/policy/common/ia/IntegrityAuditDesignationTest.java
@@ -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");
+ }
}
diff --git a/integrity-audit/src/test/java/org/onap/policy/common/ia/IntegrityAuditTest.java b/integrity-audit/src/test/java/org/onap/policy/common/ia/IntegrityAuditTest.java
index 344ac34e..5adbb561 100644
--- a/integrity-audit/src/test/java/org/onap/policy/common/ia/IntegrityAuditTest.java
+++ b/integrity-audit/src/test/java/org/onap/policy/common/ia/IntegrityAuditTest.java
@@ -20,53 +20,52 @@
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"));
+
+ }
}
diff --git a/integrity-audit/src/test/java/org/onap/policy/common/ia/IntegrityAuditTestBase.java b/integrity-audit/src/test/java/org/onap/policy/common/ia/IntegrityAuditTestBase.java
index e30c5631..afbcc452 100644
--- a/integrity-audit/src/test/java/org/onap/policy/common/ia/IntegrityAuditTestBase.java
+++ b/integrity-audit/src/test/java/org/onap/policy/common/ia/IntegrityAuditTestBase.java
@@ -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));
+ }
+ }
}
diff --git a/integrity-audit/src/test/java/org/onap/policy/common/ia/jpa/IaTestEntity.java b/integrity-audit/src/test/java/org/onap/policy/common/ia/jpa/IaTestEntity.java
index 43277a71..36b9ef66 100644
--- a/integrity-audit/src/test/java/org/onap/policy/common/ia/jpa/IaTestEntity.java
+++ b/integrity-audit/src/test/java/org/onap/policy/common/ia/jpa/IaTestEntity.java
@@ -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;
+ }
}
diff --git a/integrity-audit/src/test/java/org/onap/policy/common/ia/jpa/PersonSample.java b/integrity-audit/src/test/java/org/onap/policy/common/ia/jpa/PersonSample.java
index d7fcf330..47fa843b 100644
--- a/integrity-audit/src/test/java/org/onap/policy/common/ia/jpa/PersonSample.java
+++ b/integrity-audit/src/test/java/org/onap/policy/common/ia/jpa/PersonSample.java
@@ -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;
+ }
+
}