From e871132b09476d7772fb8dbc597fb82248b89f6b Mon Sep 17 00:00:00 2001 From: Jim Hahn Date: Tue, 13 Feb 2018 14:16:47 -0500 Subject: Speed up integrity-audit tests Added additional DbDAO constructors to facilitate JUnit testing. Added DbDAO destroy() method to close the EntityManagerFactory. Pulled out common code into IntegrityAuditTestBase and subclassed the tests from there. Added hooks to IntegrityAudit so that the AuditThread timers could be set to smaller values so that all of the junit tests could be run in much less time. Added similar hooks to DbAudit. Modified integrity-audit tests to use new utility classes to auto-close JPA managers. Modified integrity-audit tests to use new utility class to scan logger items without the need to scan the actual log file. Added code to new test superclass to truncate the four ONAP logs. Modified hooks in IntegrityAuditEntity to adjust serialization so that dates are not serialized/de-serialized when used in junit tests. Deleted TestingUtils. Added a test for invalid nodeType property. Fixed issue wherein AuditThread doesn't stop when interrupted. Change-Id: I5101995b6b68655b2810777bc4d2ec80c7cbc363 Issue-ID: POLICY-582 Signed-off-by: Jim Hahn --- .../org/onap/policy/common/ia/AuditThread.java | 170 +++++++++++++++++++-- .../java/org/onap/policy/common/ia/DbAudit.java | 62 ++++++-- .../main/java/org/onap/policy/common/ia/DbDAO.java | 55 +++++-- .../org/onap/policy/common/ia/IntegrityAudit.java | 77 ++++++++-- .../policy/common/ia/IntegrityAuditProperties.java | 3 +- .../policy/common/ia/jpa/IntegrityAuditEntity.java | 23 ++- 6 files changed, 322 insertions(+), 68 deletions(-) (limited to 'integrity-audit/src/main/java/org/onap') 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 78ff4d3a..7af82132 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 @@ -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. @@ -25,6 +25,9 @@ import java.util.Comparator; import java.util.Date; import java.util.List; import java.util.Properties; +import java.util.concurrent.BlockingQueue; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.TimeUnit; import org.onap.policy.common.ia.jpa.IntegrityAuditEntity; import org.onap.policy.common.logging.eelf.MessageCodes; @@ -59,9 +62,15 @@ public class AuditThread extends Thread { /* * 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. + * we sleep integrityAuditPeriodMillis. May be modified by JUnit tests. */ - private static final long AUDIT_THREAD_SLEEP_INTERVAL = 5000; + 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. @@ -91,13 +100,25 @@ public class AuditThread extends Thread { /* * See IntegrityAudit class for usage. */ - private int integrityAuditPeriodMillis; + 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 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 @@ -110,11 +131,31 @@ public class AuditThread extends Thread { public AuditThread(String resourceName, String persistenceUnit, Properties properties, int integrityAuditPeriodSeconds, IntegrityAudit integrityAudit) throws Exception { + + 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 Exception + */ + public AuditThread(String resourceName, String persistenceUnit, + Properties properties, long integrityAuditMillis, IntegrityAudit integrityAudit, + BlockingQueue queue) + throws Exception { this.resourceName = resourceName; this.persistenceUnit = persistenceUnit; this.properties = properties; - this.integrityAuditPeriodMillis = integrityAuditPeriodSeconds * 1000; + this.integrityAuditPeriodMillis = integrityAuditMillis; this.integrityAudit = integrityAudit; + this.auditLatchQueue = queue; /* * The DbDAO Constructor registers this node in the IntegrityAuditEntity @@ -135,7 +176,16 @@ public class AuditThread extends Thread { logger.info("AuditThread.run: Entering"); - try { + 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. @@ -151,7 +201,6 @@ public class AuditThread extends Thread { while (true) { try{ - /* * It may have been awhile since we last cycled through this * loop, so refresh the list of IntegrityAuditEntities. @@ -249,6 +298,11 @@ public class AuditThread extends Thread { * 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=" @@ -268,25 +322,32 @@ public class AuditThread extends Thread { if (logger.isDebugEnabled()) { logger.debug("AuditThread.run: resourceName=" + this.resourceName + ": Sleeping " - + AuditThread.AUDIT_THREAD_SLEEP_INTERVAL + + AuditThread.auditThreadSleepIntervalMillis + "ms"); } - Thread.sleep(AuditThread.AUDIT_THREAD_SLEEP_INTERVAL); + Thread.sleep(AuditThread.auditThreadSleepIntervalMillis); if (logger.isDebugEnabled()) { logger.debug("AuditThread.run: resourceName=" + this.resourceName + ": Awaking from " - + AuditThread.AUDIT_THREAD_SLEEP_INTERVAL + + 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); - continue; } } @@ -296,10 +357,53 @@ public class AuditThread extends Thread { 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 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. */ @@ -617,7 +721,7 @@ public class AuditThread extends Thread { /** * Returns false if the lastUpdated time for the record in question is more - * than AUDIT_COMPLETION_INTERVAL seconds ago. During an audit, lastUpdated is updated every five + * 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 @@ -647,7 +751,7 @@ public class AuditThread extends Thread { lastUpdatedTime = lastUpdated.getTime(); } long timeDifference = currentTime.getTime() - lastUpdatedTime; - if (timeDifference > AUDIT_COMPLETION_INTERVAL) { + if (timeDifference > auditCompletionIntervalMillis) { stale = true; } @@ -678,7 +782,7 @@ public class AuditThread extends Thread { } /* - * If more than (AUDIT_COMPLETION_INTERVAL * 2) milliseconds have elapsed + * 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 @@ -707,7 +811,7 @@ public class AuditThread extends Thread { long lastUpdatedTime = lastUpdated.getTime(); timeDifference = currentTime.getTime() - lastUpdatedTime; - if (timeDifference > (AUDIT_COMPLETION_INTERVAL * 2)) { + if (timeDifference > (auditCompletionIntervalMillis * 2)) { if (logger.isDebugEnabled()) { logger.debug("resetAuditCompleted: Resetting auditCompleted for resourceName=" + this.resourceName); @@ -750,7 +854,7 @@ public class AuditThread extends Thread { + this.resourceName); } if (IntegrityAudit.isUnitTesting()) { - dbAudit.dbAuditSimulate(this.resourceName, this.persistenceUnit); + dbAudit.dbAuditSimulate(this.resourceName, this.persistenceUnit, AuditThread.AUDIT_SIMULATION_ITERATIONS, AuditThread.auditThreadSleepIntervalMillis); } else { dbAudit.dbAudit(this.resourceName, this.persistenceUnit, this.nodeType); @@ -762,4 +866,38 @@ public class AuditThread extends Thread { } + /** + * Adjusts the thread-sleep-interval to be used when an audit has + * not 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 + * not 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; + } + } 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 21bf5c8d..00b79917 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 @@ -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. @@ -53,6 +53,9 @@ 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) { @@ -212,7 +215,7 @@ public class DbAudit { } } //end for (IntegrityAuditEntity iae : iaeList) //Time check - if((System.currentTimeMillis() - startTime) >= 5000){ //5 seconds + if((System.currentTimeMillis() - startTime) >= dbAuditUpdateMillis){ //update the timestamp dbDAO.setLastUpdated(); //reset the startTime @@ -220,9 +223,9 @@ public class DbAudit { }else{ //sleep a couple seconds to break up the activity if (logger.isDebugEnabled()) { - logger.debug("dbAudit: Sleeping 2 seconds"); + logger.debug("dbAudit: Sleeping " + dbAuditSleepMillis + "ms"); } - Thread.sleep(2000); + Thread.sleep(dbAuditSleepMillis); if (logger.isDebugEnabled()) { logger.debug("dbAudit: Waking from sleep"); } @@ -315,7 +318,7 @@ public class DbAudit { } } //Time check - if((System.currentTimeMillis() - startTime) >= 5000){ //5 seconds + if((System.currentTimeMillis() - startTime) >= dbAuditUpdateMillis){ //update the timestamp dbDAO.setLastUpdated(); //reset the startTime @@ -323,9 +326,9 @@ public class DbAudit { }else{ //sleep a couple seconds to break up the activity if (logger.isDebugEnabled()) { - logger.debug("dbAudit: Second comparison; sleeping 2 seconds"); + logger.debug("dbAudit: Second comparison; sleeping " + dbAuditSleepMillis + "ms"); } - Thread.sleep(2000); + Thread.sleep(dbAuditSleepMillis); if (logger.isDebugEnabled()) { logger.debug("dbAudit: Second comparison; waking from sleep"); } @@ -347,22 +350,23 @@ public class DbAudit { /** * dbAuditSimulate simulates the DB audit * @param resourceName - * @param persistenceUnit + * @param persistenceUnit + * @param simulationIterations + * @param simulationIntervalMs * @param nodeType - * @throws InterruptedException - * @throws DbDaoTransactionException + * @throws DbAuditException */ - public void dbAuditSimulate(String resourceName, String persistenceUnit) 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 < AuditThread.AUDIT_SIMULATION_ITERATIONS; i++) { + for (int i = 0; i < simulationIterations; i++) { dbDAO.setLastUpdated(); logger.info("dbAuditSimulate: i=" + i + ", sleeping " - + AuditThread.AUDIT_SIMULATION_SLEEP_INTERVAL + "ms"); - Thread.sleep(AuditThread.AUDIT_SIMULATION_SLEEP_INTERVAL); + + simulationIntervalMs + "ms"); + Thread.sleep(simulationIntervalMs); } logger.info("dbAuditSimulate: Finished audit simulation for resourceName=" @@ -465,8 +469,36 @@ public class DbAudit { logger.info(msg); } + /** + * 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/DbDAO.java b/integrity-audit/src/main/java/org/onap/policy/common/ia/DbDAO.java index b30c7730..f34b24d5 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 @@ -69,26 +69,48 @@ public class DbDAO { */ private static final Object lock = new Object(); - /** * DbDAO Constructor - * @param resourceName - * @param persistenceUnit - * @param properties - * @throws Exception - */ + * + * @param resourceName + * @param persistenceUnit + * @param properties + * @throws Exception + */ public DbDAO(String resourceName, String persistenceUnit, Properties properties) throws Exception { + 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 Exception + */ + protected DbDAO(String resourceName, String persistenceUnit, Properties properties, String altDbUrl) + throws Exception { logger.debug("DbDAO contructor: enter"); - + validateProperties(resourceName, persistenceUnit, properties); - + emf = Persistence.createEntityManagerFactory(persistenceUnit, properties); - - register(); - + + 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 @@ -207,6 +229,7 @@ public class DbDAO { logger.error("getAllEntries encountered exception:", e); } em.close(); + theEmf.close(); logger.debug("getAllEntries: Returning resultMap, size=" + resultMap.size()); @@ -240,6 +263,7 @@ public class DbDAO { logger.error(msg, e); } em.close(); + theEmf.close(); logger.debug("getAllEntries: Exit, resultMap, size=" + resultMap.size()); return resultMap; } @@ -282,7 +306,7 @@ public class DbDAO { } } - + /** * getMyIntegrityAuditEntity() gets my IntegrityAuditEntity * @return @@ -382,8 +406,10 @@ public class DbDAO { /** * 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() throws DbDaoTransactionException { + private void register(String altDbUrl) throws DbDaoTransactionException { try{ EntityManager em = emf.createEntityManager(); @@ -421,10 +447,9 @@ public class DbDAO { //update/set properties in entry iae.setSite(this.siteName); iae.setNodeType(this.nodeType); - iae.setLastUpdated(new Date()); iae.setJdbcDriver(this.dbDriver); iae.setJdbcPassword(properties.getProperty(IntegrityAuditProperties.DB_PWD).trim()); - iae.setJdbcUrl(dbUrl); + iae.setJdbcUrl(altDbUrl == null ? this.dbUrl : altDbUrl); iae.setJdbcUser(dbUser); em.persist(iae); 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 4f7a15af..f1dbfec0 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 @@ -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. @@ -21,10 +21,11 @@ package org.onap.policy.common.ia; import java.util.Properties; - +import java.util.concurrent.BlockingQueue; +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.FlexLogger; import org.onap.policy.common.logging.flexlogger.Logger; /** @@ -46,16 +47,16 @@ public class IntegrityAudit { /* - * This is the audit period in seconds. For example, if it had a value of 3600, the audit - * can only run once per hour. If it has a value of 60, it can run once per minute. + * 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: - * integrityAuditPeriodSeconds < 0 (negative number) indicates the audit is off - * integrityAuditPeriodSecconds == 0 indicates the audit is to run continuously - * integrityAuditPeriodSeconds > 0 indicates the audit is to run at most once during the indicated period + * 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 integrityAuditPeriodSeconds; + private int integrityAuditPeriodMillis; /** * IntegrityAudit constructor @@ -84,10 +85,12 @@ public class IntegrityAudit { this.resourceName = resourceName; if(properties.getProperty(IntegrityAuditProperties.AUDIT_PERIOD_SECONDS) != null){ //It is allowed to be null - this.integrityAuditPeriodSeconds= Integer.parseInt(properties.getProperty(IntegrityAuditProperties.AUDIT_PERIOD_SECONDS).trim()); + 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.integrityAuditPeriodSeconds = IntegrityAuditProperties.DEFAULT_AUDIT_PERIOD_SECONDS; + this.integrityAuditPeriodMillis = 1000 * IntegrityAuditProperties.DEFAULT_AUDIT_PERIOD_SECONDS; } logger.info("Constructor: Exiting"); @@ -97,7 +100,7 @@ public class IntegrityAudit { * Used during JUnit testing by AuditPeriodTest.java */ public int getIntegrityAuditPeriodSeconds() { - return integrityAuditPeriodSeconds; + return (integrityAuditPeriodMillis / 1000); } /** @@ -190,6 +193,15 @@ public class IntegrityAudit { 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 @@ -203,22 +215,36 @@ public class IntegrityAudit { * @throws Exception */ public void startAuditThread() throws Exception { + startAuditThread(null); + } + /** + * Starts the audit thread + * @param queue + * @return {@code true} if the thread was started, {@code false} otherwise + * @throws Exception + */ + protected boolean startAuditThread(BlockingQueue queue) throws Exception { logger.info("startAuditThread: Entering"); - if (integrityAuditPeriodSeconds >= 0) { + boolean success = false; + + if (integrityAuditPeriodMillis >= 0) { this.auditThread = new AuditThread(this.resourceName, this.persistenceUnit, this.properties, - integrityAuditPeriodSeconds, this); + integrityAuditPeriodMillis, this, queue); logger.info("startAuditThread: Audit started and will run every " - + integrityAuditPeriodSeconds + " seconds"); + + integrityAuditPeriodMillis/1000 + " seconds"); this.auditThread.start(); + success = true; } else { logger.info("startAuditThread: Suppressing integrity audit, integrityAuditPeriodSeconds=" - + integrityAuditPeriodSeconds); + + integrityAuditPeriodMillis/1000); } logger.info("startAuditThread: Exiting"); + + return success; } /** * Stops the audit thread @@ -252,4 +278,23 @@ public class IntegrityAudit { 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(); + } + } } 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 49b26fcb..b8db3ac2 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 @@ -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. @@ -29,6 +29,7 @@ public class IntegrityAuditProperties { 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"; 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 fb8823f5..da69f2de 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 @@ -1,8 +1,8 @@ -/*- +/* * ============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,6 +20,8 @@ package org.onap.policy.common.ia.jpa; +import java.io.IOException; +import java.io.ObjectOutputStream; import java.io.Serializable; import java.util.Date; @@ -105,9 +107,7 @@ public class IntegrityAuditEntity implements Serializable { @PreUpdate public void preUpdate() { - if (!isUnitTesting()) { - this.lastUpdated = new Date(); - } + this.lastUpdated = new Date(); } public long getId() { @@ -209,4 +209,17 @@ public class IntegrityAuditEntity implements Serializable { 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(); + } + } } -- cgit 1.2.3-korg