This is an automated email from the ASF dual-hosted git repository.

brusdev pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/activemq-artemis.git


The following commit(s) were added to refs/heads/main by this push:
     new 101c0d2  ARTEMIS-3679 Brokers shutdown after daylight saving fall back
101c0d2 is described below

commit 101c0d2cd0f4127592f1817c52ab595359bc9b85
Author: franz1981 <[email protected]>
AuthorDate: Thu Feb 10 17:10:30 2022 +0100

    ARTEMIS-3679 Brokers shutdown after daylight saving fall back
---
 .../jdbc/store/sql/PropertySQLProvider.java        |  5 ++
 .../artemis/jdbc/store/sql/SQLProvider.java        |  2 +
 .../src/main/resources/journal-sql.properties      | 23 ++++--
 .../core/server/impl/jdbc/JdbcLeaseLock.java       | 88 +++++++++++++++-------
 .../server/impl/jdbc/JdbcSharedStateManager.java   |  4 +-
 .../core/server/impl/jdbc/JdbcLeaseLockTest.java   | 39 +++++++++-
 .../artemis/tests/util/ActiveMQTestBase.java       | 10 +++
 7 files changed, 130 insertions(+), 41 deletions(-)

diff --git 
a/artemis-jdbc-store/src/main/java/org/apache/activemq/artemis/jdbc/store/sql/PropertySQLProvider.java
 
b/artemis-jdbc-store/src/main/java/org/apache/activemq/artemis/jdbc/store/sql/PropertySQLProvider.java
index d7399b6..0fb6d95 100644
--- 
a/artemis-jdbc-store/src/main/java/org/apache/activemq/artemis/jdbc/store/sql/PropertySQLProvider.java
+++ 
b/artemis-jdbc-store/src/main/java/org/apache/activemq/artemis/jdbc/store/sql/PropertySQLProvider.java
@@ -259,6 +259,11 @@ public class PropertySQLProvider implements SQLProvider {
    }
 
    @Override
+   public String currentTimestampTimeZoneId() {
+      return sql("current-timestamp-timezone-id");
+   }
+
+   @Override
    public String writeStateSQL() {
       return format(sql("write-state"), tableName, STATE_ROW_ID);
    }
diff --git 
a/artemis-jdbc-store/src/main/java/org/apache/activemq/artemis/jdbc/store/sql/SQLProvider.java
 
b/artemis-jdbc-store/src/main/java/org/apache/activemq/artemis/jdbc/store/sql/SQLProvider.java
index 5f2f26f..17d03dc 100644
--- 
a/artemis-jdbc-store/src/main/java/org/apache/activemq/artemis/jdbc/store/sql/SQLProvider.java
+++ 
b/artemis-jdbc-store/src/main/java/org/apache/activemq/artemis/jdbc/store/sql/SQLProvider.java
@@ -92,6 +92,8 @@ public interface SQLProvider {
 
    String currentTimestampSQL();
 
+   String currentTimestampTimeZoneId();
+
    String writeStateSQL();
 
    String readStateSQL();
diff --git a/artemis-jdbc-store/src/main/resources/journal-sql.properties 
b/artemis-jdbc-store/src/main/resources/journal-sql.properties
index 4312379..5125554 100644
--- a/artemis-jdbc-store/src/main/resources/journal-sql.properties
+++ b/artemis-jdbc-store/src/main/resources/journal-sql.properties
@@ -37,12 +37,12 @@ delete-journal-record=DELETE FROM %s WHERE id = ?
 delete-journal-tx-record=DELETE FROM %s WHERE txId=?
 count-journal-record=SELECT COUNT(*) FROM %s
 
-create-node-manager-store-table=CREATE TABLE %s (ID INT NOT NULL, HOLDER_ID 
VARCHAR(128), HOLDER_EXPIRATION_TIME TIMESTAMP, NODE_ID CHAR(36),STATE CHAR(1), 
PRIMARY KEY(ID))
+create-node-manager-store-table=CREATE TABLE %s (ID INT NOT NULL, HOLDER_ID 
VARCHAR(128), HOLDER_EXPIRATION_TIME BIGINT, NODE_ID CHAR(36),STATE CHAR(1), 
PRIMARY KEY(ID))
 create-state=INSERT INTO %s (ID) VALUES (%s)
-try-acquire-lock=UPDATE %s SET HOLDER_ID = ?, HOLDER_EXPIRATION_TIME = ? WHERE 
(HOLDER_EXPIRATION_TIME IS NULL OR (HOLDER_EXPIRATION_TIME < CURRENT_TIMESTAMP 
AND ? > CURRENT_TIMESTAMP)) AND ID = %s
+try-acquire-lock=UPDATE %s SET HOLDER_ID = ?, HOLDER_EXPIRATION_TIME = ? WHERE 
(HOLDER_EXPIRATION_TIME IS NULL OR HOLDER_EXPIRATION_TIME < ?) AND ID = %s
 try-release-lock=UPDATE %s SET HOLDER_ID = NULL, HOLDER_EXPIRATION_TIME = NULL 
WHERE HOLDER_ID = ? AND ID = %s
-is-locked=SELECT HOLDER_ID, HOLDER_EXPIRATION_TIME, CURRENT_TIMESTAMP FROM %s 
WHERE ID = %s
-renew-lock=UPDATE %s SET HOLDER_EXPIRATION_TIME = ? WHERE HOLDER_ID = ? AND 
HOLDER_EXPIRATION_TIME IS NOT NULL AND ? >= HOLDER_EXPIRATION_TIME AND ? > 
CURRENT_TIMESTAMP AND ID = %s
+is-locked=SELECT HOLDER_ID, HOLDER_EXPIRATION_TIME FROM %s WHERE ID = %s
+renew-lock=UPDATE %s SET HOLDER_EXPIRATION_TIME = ? WHERE HOLDER_ID = ? AND 
HOLDER_EXPIRATION_TIME IS NOT NULL AND ? >= HOLDER_EXPIRATION_TIME AND ID = %s
 current-timestamp=SELECT CURRENT_TIMESTAMP FROM %s
 write-state=UPDATE %s SET STATE = ? WHERE ID = %s
 read-state=SELECT STATE FROM %s WHERE ID = %s
@@ -65,6 +65,8 @@ table-names-case.derby=upper
 # PostgreSQL SQL statements
 create-file-table.postgresql=CREATE TABLE %s (ID BIGSERIAL, FILENAME 
VARCHAR(255), EXTENSION VARCHAR(10), DATA OID, PRIMARY KEY(ID))
 create-journal-table.postgresql=CREATE TABLE %s(id BIGINT,recordType 
SMALLINT,compactCount SMALLINT,txId BIGINT,userRecordType SMALLINT,variableSize 
INTEGER,record BYTEA,txDataSize INTEGER,txData BYTEA,txCheckNoRecords 
INTEGER,seq BIGINT)
+current-timestamp.postgresql=SELECT NOW() AT TIME ZONE 'UTC'
+current-timestamp-timezone-id.postgresql=UTC
 
 # 1 GiB
 max-blob-size.postgresql=1073741824
@@ -75,6 +77,8 @@ create-file-table.mysql=CREATE TABLE %s(ID BIGINT NOT NULL 
AUTO_INCREMENT, FILEN
 append-to-file.mysql=SELECT DATA, ID FROM %s WHERE ID=? FOR UPDATE
 create-journal-table.mysql=CREATE TABLE %s(id BIGINT,recordType 
SMALLINT,compactCount SMALLINT,txId BIGINT,userRecordType SMALLINT,variableSize 
INTEGER,record LONGBLOB,txDataSize INTEGER,txData LONGBLOB,txCheckNoRecords 
INTEGER,seq BIGINT) ENGINE=InnoDB
 copy-file-record-by-id.mysql=UPDATE %1$s, (SELECT DATA AS FROM_DATA FROM %1$s 
WHERE id=?) SELECT_COPY SET DATA=FROM_DATA WHERE id=?
+current-timestamp.mysql=SELECT UTC_TIMESTAMP(6)
+current-timestamp-timezone-id.mysql=UTC
 # 4 GiB
 max-blob-size.mysql=4294967296
 table-names-case.mysql=lower
@@ -82,7 +86,9 @@ table-names-case.mysql=lower
 # Oracle SQL statements
 create-file-table.oracle=CREATE TABLE %s(ID NUMBER(19) GENERATED BY DEFAULT ON 
NULL AS IDENTITY, FILENAME VARCHAR(255), EXTENSION VARCHAR(10), DATA BLOB, 
PRIMARY KEY(ID))
 create-journal-table.oracle=CREATE TABLE %s(id NUMBER(19),recordType 
NUMBER(5),compactCount NUMBER(5),txId NUMBER(19),userRecordType 
NUMBER(5),variableSize NUMBER(10),record BLOB,txDataSize NUMBER(10),txData 
BLOB,txCheckNoRecords NUMBER(10),seq NUMBER(19))
-
+create-node-manager-store-table.oracle=CREATE TABLE %s (ID INT NOT NULL, 
HOLDER_ID VARCHAR(128), HOLDER_EXPIRATION_TIME NUMBER(19), NODE_ID 
CHAR(36),STATE CHAR(1), PRIMARY KEY(ID))
+current-timestamp.oracle=SELECT SYSTIMESTAMP AT TIME ZONE 'UTC' FROM DUAL
+current-timestamp-timezone-id.oracle=UTC
 # 4 GiB
 max-blob-size.oracle=4294967296
 table-names-case.oracle=upper
@@ -94,10 +100,13 @@ create-file-table.db2=CREATE TABLE %s (ID BIGINT GENERATED 
ALWAYS AS IDENTITY (S
 replace-file.db2=UPDATE %s SET DATA=? WHERE ID=?
 append-to-file.db2=UPDATE %s SET DATA = (DATA || ?) WHERE ID=?
 table-names-case.db2=upper
+current-timestamp.db2=SELECT CURRENT TIMESTAMP - CURRENT TIMEZONE FROM 
SYSIBM.SYSDUMMY1
+current-timestamp-timezone-id.db2=UTC
 
 # MSSQL SQL statements
 create-file-table.mssql=CREATE TABLE %s (ID BIGINT NOT NULL IDENTITY, FILENAME 
VARCHAR(255), EXTENSION VARCHAR(10), DATA VARBINARY(max), PRIMARY KEY(ID))
 create-journal-table.mssql=CREATE TABLE %s(id BIGINT,recordType 
SMALLINT,compactCount SMALLINT,txId BIGINT,userRecordType SMALLINT,variableSize 
INTEGER,record VARBINARY(max),txDataSize INTEGER,txData 
VARBINARY(max),txCheckNoRecords INTEGER,seq BIGINT NOT NULL, PRIMARY KEY(seq))
-create-node-manager-store-table.mssql=CREATE TABLE %s (ID INT NOT NULL, 
HOLDER_ID VARCHAR(128), HOLDER_EXPIRATION_TIME DATETIME, NODE_ID CHAR(36),STATE 
CHAR(1), PRIMARY KEY(ID))
-current-timestamp.mssql=SELECT CURRENT_TIMESTAMP
+create-node-manager-store-table.mssql=CREATE TABLE %s (ID INT NOT NULL, 
HOLDER_ID VARCHAR(128), HOLDER_EXPIRATION_TIME BIGINT, NODE_ID CHAR(36),STATE 
CHAR(1), PRIMARY KEY(ID))
+current-timestamp.mssql=SELECT SYSUTCDATETIME()
+current-timestamp-timezone-id.mssql=UTC
 max-blob-size.mssql=2147483647
\ No newline at end of file
diff --git 
a/artemis-server/src/main/java/org/apache/activemq/artemis/core/server/impl/jdbc/JdbcLeaseLock.java
 
b/artemis-server/src/main/java/org/apache/activemq/artemis/core/server/impl/jdbc/JdbcLeaseLock.java
index ba8c200..64800d0 100644
--- 
a/artemis-server/src/main/java/org/apache/activemq/artemis/core/server/impl/jdbc/JdbcLeaseLock.java
+++ 
b/artemis-server/src/main/java/org/apache/activemq/artemis/core/server/impl/jdbc/JdbcLeaseLock.java
@@ -21,8 +21,9 @@ import java.sql.Connection;
 import java.sql.PreparedStatement;
 import java.sql.ResultSet;
 import java.sql.SQLException;
-import java.sql.Timestamp;
+import java.util.Calendar;
 import java.util.Objects;
+import java.util.TimeZone;
 import java.util.concurrent.TimeUnit;
 import java.util.function.Predicate;
 
@@ -43,6 +44,7 @@ final class JdbcLeaseLock implements LeaseLock {
    private final String renewLock;
    private final String isLocked;
    private final String currentDateTime;
+   private final TimeZone currentDateTimeTimeZone;
    private final long expirationMillis;
    private final int queryTimeout;
    private boolean maybeAcquired;
@@ -60,6 +62,7 @@ final class JdbcLeaseLock implements LeaseLock {
                  String renewLock,
                  String isLocked,
                  String currentDateTime,
+                 String currentDateTimeTimeZoneId,
                  long expirationMIllis,
                  long queryTimeoutMillis,
                  String lockName) {
@@ -72,6 +75,7 @@ final class JdbcLeaseLock implements LeaseLock {
       this.renewLock = renewLock;
       this.isLocked = isLocked;
       this.currentDateTime = currentDateTime;
+      this.currentDateTimeTimeZone = currentDateTimeTimeZoneId == null ? null 
: TimeZone.getTimeZone(currentDateTimeTimeZoneId);
       this.expirationMillis = expirationMIllis;
       this.maybeAcquired = false;
       this.connectionProvider = connectionProvider;
@@ -86,7 +90,6 @@ final class JdbcLeaseLock implements LeaseLock {
          }
       }
       this.queryTimeout = expectedTimeout;
-
    }
 
    public String holderId() {
@@ -114,14 +117,14 @@ final class JdbcLeaseLock implements LeaseLock {
          final boolean autoCommit = connection.getAutoCommit();
          connection.setAutoCommit(false);
          try (PreparedStatement preparedStatement = 
connection.prepareStatement(this.isLocked)) {
+            final long currentTimestamp = dbCurrentTimeMillis(connection);
             final String lockStatus;
             try (ResultSet resultSet = preparedStatement.executeQuery()) {
                if (!resultSet.next()) {
                   lockStatus = null;
                } else {
                   final String currentHolderId = resultSet.getString(1);
-                  final Timestamp expirationTime = resultSet.getTimestamp(2);
-                  final Timestamp currentTimestamp = resultSet.getTimestamp(3);
+                  final long expirationTime = resultSet.getLong(2);
                   lockStatus = "holderId = " + currentHolderId + " 
expirationTime = " + expirationTime + " currentTimestamp = " + currentTimestamp;
                }
             }
@@ -138,8 +141,40 @@ final class JdbcLeaseLock implements LeaseLock {
       }
    }
 
+   public long dbCurrentTimeMillis() {
+      SQLException suppressed = null;
+      try (Connection connection = connectionProvider.getConnection()) {
+         
connection.setTransactionIsolation(Connection.TRANSACTION_READ_COMMITTED);
+         final boolean autoCommit = connection.getAutoCommit();
+         connection.setAutoCommit(false);
+         try {
+            return dbCurrentTimeMillis(connection);
+         } catch (SQLException e) {
+            suppressed = e;
+            connection.rollback();
+            suppressed = null;
+            throw new IllegalStateException(e);
+         } finally {
+            connection.setAutoCommit(autoCommit);
+         }
+      } catch (SQLException e) {
+         final RuntimeException stateEx = new IllegalStateException(e);
+         if (suppressed != null) {
+            stateEx.addSuppressed(suppressed);
+         }
+         throw stateEx;
+      }
+   }
+
    private long dbCurrentTimeMillis(Connection connection) throws SQLException 
{
-      try (PreparedStatement currentDateTime = 
connection.prepareStatement(this.currentDateTime)) {
+      return dbCurrentTimeMillis(connection, queryTimeout, currentDateTime, 
currentDateTimeTimeZone);
+   }
+
+   public static long dbCurrentTimeMillis(final Connection connection,
+                                          final int queryTimeout,
+                                          final String currentDateTimeSql,
+                                          final TimeZone 
currentDateTimeTimeZone) throws SQLException {
+      try (PreparedStatement currentDateTime = 
connection.prepareStatement(currentDateTimeSql)) {
          if (queryTimeout >= 0) {
             currentDateTime.setQueryTimeout(queryTimeout);
          }
@@ -147,14 +182,16 @@ final class JdbcLeaseLock implements LeaseLock {
          try (ResultSet resultSet = currentDateTime.executeQuery()) {
             resultSet.next();
             final long endTime = stripMilliseconds(System.currentTimeMillis());
-            final Timestamp currentTimestamp = resultSet.getTimestamp(1);
-            final long currentTime = currentTimestamp.getTime();
-            final long currentTimeMillis = stripMilliseconds(currentTime);
-            if (currentTimeMillis < startTime) {
-               LOGGER.warnf("[%s] %s query currentTimestamp = %s on database 
should happen AFTER %s on broker", lockName, holderId, currentTimestamp, new 
Timestamp(startTime));
+
+            final long currentTime = (currentDateTimeTimeZone == null ?
+               resultSet.getTimestamp(1) :
+               resultSet.getTimestamp(1, 
Calendar.getInstance(currentDateTimeTimeZone))).getTime();
+            final long currentTimeNoMillis = stripMilliseconds(currentTime);
+            if (currentTimeNoMillis < startTime) {
+               LOGGER.warnf("currentTimestamp = %d on database should happen 
AFTER %d on broker", currentTimeNoMillis, startTime);
             }
-            if (currentTimeMillis > endTime) {
-               LOGGER.warnf("[%s] %s query currentTimestamp = %s on database 
should happen BEFORE %s on broker", lockName, holderId, currentTimestamp, new 
Timestamp(endTime));
+            if (currentTimeNoMillis > endTime) {
+               LOGGER.warnf("currentTimestamp = %d on database should happen 
BEFORE %d on broker", currentTimeNoMillis, endTime);
             }
             return currentTime;
          }
@@ -170,15 +207,13 @@ final class JdbcLeaseLock implements LeaseLock {
          try (PreparedStatement preparedStatement = 
connection.prepareStatement(this.renewLock)) {
             final long now = dbCurrentTimeMillis(connection);
             final long localExpirationTime = now + expirationMillis;
-            final Timestamp expirationTime = new 
Timestamp(localExpirationTime);
             if (LOGGER.isDebugEnabled()) {
                LOGGER.debugf("[%s] %s is renewing lock with expirationTime = 
%s",
-                             lockName, holderId, expirationTime);
+                             lockName, holderId, localExpirationTime);
             }
-            preparedStatement.setTimestamp(1, expirationTime);
+            preparedStatement.setLong(1, localExpirationTime);
             preparedStatement.setString(2, holderId);
-            preparedStatement.setTimestamp(3, expirationTime);
-            preparedStatement.setTimestamp(4, expirationTime);
+            preparedStatement.setLong(3, localExpirationTime);
             final int updatedRows = preparedStatement.executeUpdate();
             final boolean renewed = updatedRows == 1;
             connection.commit();
@@ -218,11 +253,10 @@ final class JdbcLeaseLock implements LeaseLock {
             final long now = dbCurrentTimeMillis(connection);
             preparedStatement.setString(1, holderId);
             final long localExpirationTime = now + expirationMillis;
-            final Timestamp expirationTime = new 
Timestamp(localExpirationTime);
-            preparedStatement.setTimestamp(2, expirationTime);
-            preparedStatement.setTimestamp(3, expirationTime);
-            LOGGER.debugf("[%s] %s is trying to acquire lock with 
expirationTime %s",
-                          lockName, holderId, expirationTime);
+            preparedStatement.setLong(2, localExpirationTime);
+            preparedStatement.setLong(3, now);
+            LOGGER.debugf("[%s] %s is trying to acquire lock with 
expirationTime %l",
+                          lockName, holderId, localExpirationTime);
             final boolean acquired = preparedStatement.executeUpdate() == 1;
             connection.commit();
             if (acquired) {
@@ -263,6 +297,7 @@ final class JdbcLeaseLock implements LeaseLock {
          final boolean autoCommit = connection.getAutoCommit();
          connection.setAutoCommit(false);
          try (PreparedStatement preparedStatement = 
connection.prepareStatement(this.isLocked)) {
+            final long currentTimestampMillis = 
dbCurrentTimeMillis(connection);
             boolean result;
             try (ResultSet resultSet = preparedStatement.executeQuery()) {
                if (!resultSet.next()) {
@@ -270,12 +305,9 @@ final class JdbcLeaseLock implements LeaseLock {
                } else {
                   final String currentHolderId = resultSet.getString(1);
                   result = holderIdFilter.test(currentHolderId);
-                  final Timestamp expirationTime = resultSet.getTimestamp(2);
-                  final Timestamp currentTimestamp = resultSet.getTimestamp(3);
-                  final long currentTimestampMillis = 
currentTimestamp.getTime();
+                  final long lockExpirationTime = resultSet.getLong(2);
                   boolean zombie = false;
-                  if (expirationTime != null) {
-                     final long lockExpirationTime = expirationTime.getTime();
+                  if (lockExpirationTime > 0) {
                      final long expiredBy = currentTimestampMillis - 
lockExpirationTime;
                      if (expiredBy > 0) {
                         result = false;
@@ -285,7 +317,7 @@ final class JdbcLeaseLock implements LeaseLock {
                   if (LOGGER.isDebugEnabled()) {
                      LOGGER.debugf("[%s] %s has found %s with holderId = %s 
expirationTime = %s currentTimestamp = %s",
                                    lockName, holderId, zombie ? "zombie lock" 
: "lock",
-                                   currentHolderId, expirationTime, 
currentTimestamp);
+                                   currentHolderId, lockExpirationTime, 
currentTimestampMillis);
                   }
                }
             }
diff --git 
a/artemis-server/src/main/java/org/apache/activemq/artemis/core/server/impl/jdbc/JdbcSharedStateManager.java
 
b/artemis-server/src/main/java/org/apache/activemq/artemis/core/server/impl/jdbc/JdbcSharedStateManager.java
index df43c6b..00c4d1a 100644
--- 
a/artemis-server/src/main/java/org/apache/activemq/artemis/core/server/impl/jdbc/JdbcSharedStateManager.java
+++ 
b/artemis-server/src/main/java/org/apache/activemq/artemis/core/server/impl/jdbc/JdbcSharedStateManager.java
@@ -97,7 +97,7 @@ final class JdbcSharedStateManager extends AbstractJDBCDriver 
implements SharedS
       return new JdbcLeaseLock(holderId, connectionProvider, 
sqlProvider.tryAcquireLiveLockSQL(),
                                sqlProvider.tryReleaseLiveLockSQL(), 
sqlProvider.renewLiveLockSQL(),
                                sqlProvider.isLiveLockedSQL(), 
sqlProvider.currentTimestampSQL(),
-                               expirationMillis, queryTimeoutMillis, "LIVE");
+                               sqlProvider.currentTimestampTimeZoneId(), 
expirationMillis, queryTimeoutMillis, "LIVE");
    }
 
    static JdbcLeaseLock createBackupLock(String holderId,
@@ -108,7 +108,7 @@ final class JdbcSharedStateManager extends 
AbstractJDBCDriver implements SharedS
       return new JdbcLeaseLock(holderId, connectionProvider, 
sqlProvider.tryAcquireBackupLockSQL(),
                                sqlProvider.tryReleaseBackupLockSQL(), 
sqlProvider.renewBackupLockSQL(),
                                sqlProvider.isBackupLockedSQL(), 
sqlProvider.currentTimestampSQL(),
-                               expirationMillis, queryTimeoutMillis, "BACKUP");
+                               sqlProvider.currentTimestampTimeZoneId(), 
expirationMillis, queryTimeoutMillis, "BACKUP");
    }
 
    @Override
diff --git 
a/artemis-server/src/test/java/org/apache/activemq/artemis/core/server/impl/jdbc/JdbcLeaseLockTest.java
 
b/artemis-server/src/test/java/org/apache/activemq/artemis/core/server/impl/jdbc/JdbcLeaseLockTest.java
index 84e4dc6..a0d482c 100644
--- 
a/artemis-server/src/test/java/org/apache/activemq/artemis/core/server/impl/jdbc/JdbcLeaseLockTest.java
+++ 
b/artemis-server/src/test/java/org/apache/activemq/artemis/core/server/impl/jdbc/JdbcLeaseLockTest.java
@@ -38,8 +38,10 @@ import 
org.apache.activemq.artemis.tests.util.ActiveMQTestBase;
 import org.apache.activemq.artemis.utils.Wait;
 import org.apache.activemq.artemis.utils.actors.ArtemisExecutor;
 import org.apache.activemq.artemis.utils.actors.OrderedExecutorFactory;
+import org.hamcrest.MatcherAssert;
 import org.junit.After;
 import org.junit.Assert;
+import org.junit.Assume;
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
@@ -47,7 +49,9 @@ import org.junit.runners.Parameterized;
 import org.junit.runners.Parameterized.Parameter;
 
 import static org.hamcrest.Matchers.greaterThanOrEqualTo;
+import static org.hamcrest.Matchers.lessThan;
 import static org.hamcrest.core.Is.is;
+import static org.hamcrest.core.IsInstanceOf.instanceOf;
 
 @RunWith(Parameterized.class)
 public class JdbcLeaseLockTest extends ActiveMQTestBase {
@@ -85,6 +89,20 @@ public class JdbcLeaseLockTest extends ActiveMQTestBase {
       }
    }
 
+   private LeaseLock lock(long acquireMillis, long queryTimeoutMillis) {
+      try {
+         return JdbcSharedStateManager
+            .createLiveLock(
+               UUID.randomUUID().toString(),
+               jdbcSharedStateManager.getJdbcConnectionProvider(),
+               sqlProvider,
+               acquireMillis,
+               queryTimeoutMillis);
+      } catch (Exception e) {
+         throw new IllegalStateException(e);
+      }
+   }
+
    @Before
    public void createLockTable() throws Exception {
       dbConf = createDefaultDatabaseStorageConfiguration();
@@ -96,8 +114,8 @@ public class JdbcLeaseLockTest extends ActiveMQTestBase {
       if (withExistingTable) {
          TestJDBCDriver testDriver = TestJDBCDriver
             .usingDbConf(
-                dbConf,
-                sqlProvider);
+               dbConf,
+               sqlProvider);
          testDriver.start();
          testDriver.stop();
       }
@@ -292,7 +310,7 @@ public class JdbcLeaseLockTest extends ActiveMQTestBase {
       };
       final ScheduledLeaseLock scheduledLeaseLock = ScheduledLeaseLock
          .of(scheduledExecutorService, artemisExecutor,
-         "test", lock(), dbConf.getJdbcLockRenewPeriodMillis(), lockListener);
+             "test", lock(), dbConf.getJdbcLockRenewPeriodMillis(), 
lockListener);
 
       Assert.assertTrue(scheduledLeaseLock.lock().tryAcquire());
       scheduledLeaseLock.start();
@@ -328,13 +346,26 @@ public class JdbcLeaseLockTest extends ActiveMQTestBase {
       scheduledLeaseLock.lock().release();
       Assert.assertFalse(scheduledLeaseLock.lock().isHeldByCaller());
       TimeUnit.MILLISECONDS.sleep(3 * scheduledLeaseLock.renewPeriodMillis());
-      Assert.assertThat(lostLock.get(), is(greaterThanOrEqualTo(2L)));
+      MatcherAssert.assertThat(lostLock.get(), is(greaterThanOrEqualTo(2L)));
       scheduledLeaseLock.stop();
       executorService.shutdown();
       scheduledExecutorService.shutdown();
    }
 
    @Test
+   public void shouldJdbcAndSystemTimeToBeAligned() throws 
InterruptedException {
+      final LeaseLock lock = lock(TimeUnit.SECONDS.toMillis(10), 
TimeUnit.SECONDS.toMillis(10));
+      Assume.assumeThat(lock, instanceOf(JdbcLeaseLock.class));
+      final JdbcLeaseLock jdbcLock = JdbcLeaseLock.class.cast(lock);
+      final long utcSystemTime = System.currentTimeMillis();
+      TimeUnit.SECONDS.sleep(1);
+      final long utcJdbcTime = jdbcLock.dbCurrentTimeMillis();
+      final long millisDiffJdbcSystem = utcJdbcTime - utcSystemTime;
+      MatcherAssert.assertThat(millisDiffJdbcSystem, greaterThanOrEqualTo(0L));
+      MatcherAssert.assertThat(millisDiffJdbcSystem, 
lessThan(TimeUnit.SECONDS.toMillis(10)));
+   }
+
+   @Test
    public void shouldNotifyOnceLostLockIfStopped() throws Exception {
       final ExecutorService executorService = 
Executors.newSingleThreadExecutor();
       final ScheduledExecutorService scheduledExecutorService = 
Executors.newScheduledThreadPool(1);
diff --git 
a/artemis-server/src/test/java/org/apache/activemq/artemis/tests/util/ActiveMQTestBase.java
 
b/artemis-server/src/test/java/org/apache/activemq/artemis/tests/util/ActiveMQTestBase.java
index 7d6b04e..5237ee1 100644
--- 
a/artemis-server/src/test/java/org/apache/activemq/artemis/tests/util/ActiveMQTestBase.java
+++ 
b/artemis-server/src/test/java/org/apache/activemq/artemis/tests/util/ActiveMQTestBase.java
@@ -531,6 +531,8 @@ public abstract class ActiveMQTestBase extends Assert {
       dbStorageConfiguration.setMessageTableName("MESSAGE");
       dbStorageConfiguration.setLargeMessageTableName("LARGE_MESSAGE");
       dbStorageConfiguration.setPageStoreTableName("PAGE_STORE");
+      dbStorageConfiguration.setJdbcPassword(getJDBCPassword());
+      dbStorageConfiguration.setJdbcUser(getJDBCUser());
       dbStorageConfiguration.setJdbcDriverClassName(getJDBCClassName());
       
dbStorageConfiguration.setJdbcLockAcquisitionTimeoutMillis(getJdbcLockAcquisitionTimeoutMillis());
       
dbStorageConfiguration.setJdbcLockExpirationMillis(getJdbcLockExpirationMillis());
@@ -867,6 +869,14 @@ public abstract class ActiveMQTestBase extends Assert {
       return System.getProperty("jdbc.driver.class", 
"org.apache.derby.jdbc.EmbeddedDriver");
    }
 
+   protected String getJDBCUser() {
+      return System.getProperty("jdbc.user", null);
+   }
+
+   protected String getJDBCPassword() {
+      return System.getProperty("jdbc.password", null);
+   }
+
    protected final File getTestDirfile() {
       return new File(testDir);
    }

Reply via email to