diff options
author | Teryk Bellahsene <teryk.bellahsene@sonarsource.com> | 2015-02-05 16:47:06 +0100 |
---|---|---|
committer | Teryk Bellahsene <teryk.bellahsene@sonarsource.com> | 2015-02-10 18:03:03 +0100 |
commit | 398fd6721569580d553d7e296775cdb9fec48a10 (patch) | |
tree | b791252b47be9e3b459904448a306a5daaf8fe32 /sonar-core | |
parent | e50ceb6ff967aed44048295380deff968588479e (diff) | |
download | sonarqube-398fd6721569580d553d7e296775cdb9fec48a10.tar.gz sonarqube-398fd6721569580d553d7e296775cdb9fec48a10.zip |
SONAR-5183 timezones - semaphores migration
Diffstat (limited to 'sonar-core')
9 files changed, 87 insertions, 122 deletions
diff --git a/sonar-core/src/main/java/org/sonar/core/persistence/DatabaseVersion.java b/sonar-core/src/main/java/org/sonar/core/persistence/DatabaseVersion.java index 80de635be56..371f1e964fc 100644 --- a/sonar-core/src/main/java/org/sonar/core/persistence/DatabaseVersion.java +++ b/sonar-core/src/main/java/org/sonar/core/persistence/DatabaseVersion.java @@ -33,7 +33,7 @@ import java.util.List; */ public class DatabaseVersion implements BatchComponent, ServerComponent { - public static final int LAST_VERSION = 783; + public static final int LAST_VERSION = 786; /** * List of all the tables.n diff --git a/sonar-core/src/main/java/org/sonar/core/persistence/SemaphoreDao.java b/sonar-core/src/main/java/org/sonar/core/persistence/SemaphoreDao.java index 00fbcad5012..e50e39c3fa8 100644 --- a/sonar-core/src/main/java/org/sonar/core/persistence/SemaphoreDao.java +++ b/sonar-core/src/main/java/org/sonar/core/persistence/SemaphoreDao.java @@ -19,14 +19,15 @@ */ package org.sonar.core.persistence; -import com.google.common.base.Preconditions; import com.google.common.base.Strings; -import org.apache.commons.lang.time.DateUtils; import org.apache.ibatis.session.SqlSession; import org.sonar.api.utils.Semaphores; +import org.sonar.api.utils.System2; import javax.annotation.CheckForNull; -import java.util.Date; + +import static com.google.common.base.Preconditions.checkArgument; +import static org.sonar.api.utils.DateUtils.longToDate; /** * @since 3.4 @@ -35,80 +36,66 @@ public class SemaphoreDao { private static final String SEMAPHORE_NAME_MUST_NOT_BE_EMPTY = "Semaphore name must not be empty"; private final MyBatis mybatis; + private final System2 system; - public SemaphoreDao(MyBatis mybatis) { + public SemaphoreDao(MyBatis mybatis, System2 system) { this.mybatis = mybatis; + this.system = system; } public Semaphores.Semaphore acquire(String name, int maxAgeInSeconds) { - Preconditions.checkArgument(!Strings.isNullOrEmpty(name), SEMAPHORE_NAME_MUST_NOT_BE_EMPTY); - Preconditions.checkArgument(maxAgeInSeconds >= 0, "Semaphore max age must be positive: " + maxAgeInSeconds); + checkArgument(!Strings.isNullOrEmpty(name), SEMAPHORE_NAME_MUST_NOT_BE_EMPTY); + checkArgument(maxAgeInSeconds >= 0, "Semaphore max age must be positive: " + maxAgeInSeconds); - SqlSession session = mybatis.openSession(false); - try { - SemaphoreMapper mapper = session.getMapper(SemaphoreMapper.class); - Date dbNow = mapper.now(); - SemaphoreDto semaphore = tryToInsert(name, dbNow, session); + try (SqlSession session = mybatis.openSession(false)) { + SemaphoreDto semaphore = tryToInsert(name, system.now(), session); boolean isAcquired; if (semaphore == null) { semaphore = selectSemaphore(name, session); - isAcquired = acquireIfOutdated(name, maxAgeInSeconds, session, mapper); + isAcquired = acquireIfOutdated(name, maxAgeInSeconds, session); } else { isAcquired = true; } - return createLock(semaphore, session, isAcquired); - } finally { - MyBatis.closeQuietly(session); + return createLock(semaphore, isAcquired); } } public Semaphores.Semaphore acquire(String name) { - Preconditions.checkArgument(!Strings.isNullOrEmpty(name), SEMAPHORE_NAME_MUST_NOT_BE_EMPTY); + checkArgument(!Strings.isNullOrEmpty(name), SEMAPHORE_NAME_MUST_NOT_BE_EMPTY); - SqlSession session = mybatis.openSession(false); - try { - SemaphoreMapper mapper = session.getMapper(SemaphoreMapper.class); - Date now = mapper.now(); - SemaphoreDto semaphore = tryToInsert(name, now, session); + try (SqlSession session = mybatis.openSession(false)) { + SemaphoreDto semaphore = tryToInsert(name, system.now(), session); if (semaphore == null) { semaphore = selectSemaphore(name, session); - return createLock(semaphore, session, false); + return createLock(semaphore, false); } else { - return createLock(semaphore, session, true); + return createLock(semaphore, true); } - } finally { - MyBatis.closeQuietly(session); } } public void update(Semaphores.Semaphore semaphore) { - Preconditions.checkArgument(semaphore != null, "Semaphore must not be null"); + checkArgument(semaphore != null, "Semaphore must not be null"); - SqlSession session = mybatis.openSession(false); - try { - SemaphoreMapper mapper = session.getMapper(SemaphoreMapper.class); - mapper.update(semaphore.getName()); + try (SqlSession session = mybatis.openSession(false)) { + mapper(session).update(semaphore.getName(), system.now()); session.commit(); - } finally { - MyBatis.closeQuietly(session); } } public void release(String name) { - Preconditions.checkArgument(!Strings.isNullOrEmpty(name), SEMAPHORE_NAME_MUST_NOT_BE_EMPTY); - SqlSession session = mybatis.openSession(false); - try { - session.getMapper(SemaphoreMapper.class).release(name); + checkArgument(!Strings.isNullOrEmpty(name), SEMAPHORE_NAME_MUST_NOT_BE_EMPTY); + try (SqlSession session = mybatis.openSession(false)) { + mapper(session).release(name); session.commit(); - } finally { - MyBatis.closeQuietly(session); } } - private boolean acquireIfOutdated(String name, int maxAgeInSeconds, SqlSession session, SemaphoreMapper mapper) { - Date dbNow = mapper.now(); - Date updatedBefore = DateUtils.addSeconds(dbNow, -maxAgeInSeconds); - boolean ok = mapper.acquire(name, updatedBefore) == 1; + private boolean acquireIfOutdated(String name, int maxAgeInSeconds, SqlSession session) { + long now = system.now(); + long updatedBefore = now - (long) maxAgeInSeconds * 1000; + + boolean ok = mapper(session).acquire(name, updatedBefore, now) == 1; session.commit(); return ok; } @@ -118,50 +105,46 @@ public class SemaphoreDao { * the lock date) */ @CheckForNull - private SemaphoreDto tryToInsert(String name, Date lockedNow, SqlSession session) { + private SemaphoreDto tryToInsert(String name, long lockedNow, SqlSession session) { try { - SemaphoreMapper mapper = session.getMapper(SemaphoreMapper.class); + long now = system.now(); SemaphoreDto semaphore = new SemaphoreDto() - .setName(name) - .setLockedAt(lockedNow); - mapper.initialize(semaphore); + .setName(name) + .setCreatedAt(now) + .setUpdatedAt(now) + .setLockedAt(lockedNow); + mapper(session).initialize(semaphore); session.commit(); return semaphore; } catch (Exception e) { - // probably because of the semaphore already exists in db + // probably because the semaphore already exists in db session.rollback(); return null; } } - private Semaphores.Semaphore createLock(SemaphoreDto dto, SqlSession session, boolean acquired) { + private Semaphores.Semaphore createLock(SemaphoreDto dto, boolean acquired) { Semaphores.Semaphore semaphore = new Semaphores.Semaphore() - .setName(dto.getName()) - .setLocked(acquired) - .setLockedAt(dto.getLockedAt()) - .setCreatedAt(dto.getCreatedAt()) - .setUpdatedAt(dto.getUpdatedAt()); + .setName(dto.getName()) + .setLocked(acquired) + .setLockedAt(longToDate(dto.getLockedAt())) + .setCreatedAt(longToDate(dto.getCreatedAt())) + .setUpdatedAt(longToDate(dto.getUpdatedAt())); if (!acquired) { - semaphore.setDurationSinceLocked(getDurationSinceLocked(dto, session)); + semaphore.setDurationSinceLocked(lockedSince(dto)); } return semaphore; } - private long getDurationSinceLocked(SemaphoreDto semaphore, SqlSession session) { - long now = now(session).getTime(); - semaphore.getLockedAt(); - long lockedAt = semaphore.getLockedAt().getTime(); - return now - lockedAt; + private long lockedSince(SemaphoreDto semaphore) { + return system.now() - semaphore.getLockedAt(); } protected SemaphoreDto selectSemaphore(String name, SqlSession session) { - SemaphoreMapper mapper = session.getMapper(SemaphoreMapper.class); - return mapper.selectSemaphore(name); + return mapper(session).selectSemaphore(name); } - protected Date now(SqlSession session) { - SemaphoreMapper mapper = session.getMapper(SemaphoreMapper.class); - return mapper.now(); + private SemaphoreMapper mapper(SqlSession session) { + return session.getMapper(SemaphoreMapper.class); } - } diff --git a/sonar-core/src/main/java/org/sonar/core/persistence/SemaphoreDto.java b/sonar-core/src/main/java/org/sonar/core/persistence/SemaphoreDto.java index b556030aa0a..d28bb804ab6 100644 --- a/sonar-core/src/main/java/org/sonar/core/persistence/SemaphoreDto.java +++ b/sonar-core/src/main/java/org/sonar/core/persistence/SemaphoreDto.java @@ -22,8 +22,6 @@ package org.sonar.core.persistence; import org.apache.commons.codec.digest.DigestUtils; import org.apache.commons.lang.builder.ReflectionToStringBuilder; -import java.util.Date; - /** * @since 3.4 */ @@ -31,9 +29,9 @@ public class SemaphoreDto { private Long id; private String name; private String checksum; - private Date lockedAt; - private Date createdAt; - private Date updatedAt; + private Long lockedAt; + private Long createdAt; + private Long updatedAt; public String getName() { return name; @@ -45,11 +43,11 @@ public class SemaphoreDto { return this; } - public Date getLockedAt() { + public Long getLockedAt() { return lockedAt; } - public SemaphoreDto setLockedAt(Date d) { + public SemaphoreDto setLockedAt(Long d) { this.lockedAt = d; return this; } @@ -63,20 +61,20 @@ public class SemaphoreDto { return this; } - public Date getCreatedAt() { + public Long getCreatedAt() { return createdAt; } - public SemaphoreDto setCreatedAt(Date createdAt) { + public SemaphoreDto setCreatedAt(Long createdAt) { this.createdAt = createdAt; return this; } - public Date getUpdatedAt() { + public Long getUpdatedAt() { return updatedAt; } - public SemaphoreDto setUpdatedAt(Date updatedAt) { + public SemaphoreDto setUpdatedAt(Long updatedAt) { this.updatedAt = updatedAt; return this; } diff --git a/sonar-core/src/main/java/org/sonar/core/persistence/SemaphoreMapper.java b/sonar-core/src/main/java/org/sonar/core/persistence/SemaphoreMapper.java index 489243cd931..22773833bbc 100644 --- a/sonar-core/src/main/java/org/sonar/core/persistence/SemaphoreMapper.java +++ b/sonar-core/src/main/java/org/sonar/core/persistence/SemaphoreMapper.java @@ -21,19 +21,15 @@ package org.sonar.core.persistence; import org.apache.ibatis.annotations.Param; -import java.util.Date; - public interface SemaphoreMapper { int initialize(SemaphoreDto semaphore); - int acquire(@Param("name") String name, @Param("updatedBefore") Date updatedBefore); - - Date now(); + int acquire(@Param("name") String name, @Param("updatedBefore") Long updatedBefore, @Param("now") Long now); void release(String name); SemaphoreDto selectSemaphore(@Param("name") String name); - void update(String name); + void update(@Param("name") String name, @Param("now") Long now); } diff --git a/sonar-core/src/main/resources/org/sonar/core/persistence/SemaphoreMapper.xml b/sonar-core/src/main/resources/org/sonar/core/persistence/SemaphoreMapper.xml index bdd0d86a85d..4c42b26ea17 100644 --- a/sonar-core/src/main/resources/org/sonar/core/persistence/SemaphoreMapper.xml +++ b/sonar-core/src/main/resources/org/sonar/core/persistence/SemaphoreMapper.xml @@ -5,20 +5,12 @@ <insert id="initialize" parameterType="map" useGeneratedKeys="false" > INSERT INTO semaphores (name, checksum, created_at, updated_at, locked_at) - VALUES (#{name}, #{checksum}, current_timestamp, current_timestamp, #{lockedAt}) + VALUES (#{name}, #{checksum}, #{createdAt}, #{updatedAt}, #{lockedAt}) </insert> - <select id="now" resultType="Date" > - select current_timestamp - </select> - - <select id="now" databaseId="oracle" resultType="Date" > - select current_timestamp from dual - </select> - <update id="acquire" parameterType="map"> update semaphores - set updated_at = current_timestamp, locked_at = current_timestamp + set updated_at = #{now}, locked_at = #{now} where name=#{name} <if test="updatedBefore != null"> AND updated_at < #{updatedBefore} @@ -34,9 +26,9 @@ from semaphores s where s.name=#{name} </select> - <update id="update" parameterType="String" > + <update id="update" parameterType="map" > update semaphores - set updated_at = current_timestamp + set updated_at = #{now} where name=#{name} </update> diff --git a/sonar-core/src/main/resources/org/sonar/core/persistence/rows-h2.sql b/sonar-core/src/main/resources/org/sonar/core/persistence/rows-h2.sql index fd2663d75e5..60192f301df 100644 --- a/sonar-core/src/main/resources/org/sonar/core/persistence/rows-h2.sql +++ b/sonar-core/src/main/resources/org/sonar/core/persistence/rows-h2.sql @@ -311,6 +311,9 @@ INSERT INTO SCHEMA_MIGRATIONS(VERSION) VALUES ('780'); INSERT INTO SCHEMA_MIGRATIONS(VERSION) VALUES ('781'); INSERT INTO SCHEMA_MIGRATIONS(VERSION) VALUES ('782'); INSERT INTO SCHEMA_MIGRATIONS(VERSION) VALUES ('783'); +INSERT INTO SCHEMA_MIGRATIONS(VERSION) VALUES ('784'); +INSERT INTO SCHEMA_MIGRATIONS(VERSION) VALUES ('785'); +INSERT INTO SCHEMA_MIGRATIONS(VERSION) VALUES ('786'); INSERT INTO USERS(ID, LOGIN, NAME, EMAIL, CRYPTED_PASSWORD, SALT, CREATED_AT, UPDATED_AT, REMEMBER_TOKEN, REMEMBER_TOKEN_EXPIRES_AT) VALUES (1, 'admin', 'Administrator', '', 'a373a0e667abb2604c1fd571eb4ad47fe8cc0878', '48bc4b0d93179b5103fd3885ea9119498e9d161b', '1418215735482', '1418215735482', null, null); ALTER TABLE USERS ALTER COLUMN ID RESTART WITH 2; diff --git a/sonar-core/src/main/resources/org/sonar/core/persistence/schema-h2.ddl b/sonar-core/src/main/resources/org/sonar/core/persistence/schema-h2.ddl index fadf4581aa9..81d7d1d1779 100644 --- a/sonar-core/src/main/resources/org/sonar/core/persistence/schema-h2.ddl +++ b/sonar-core/src/main/resources/org/sonar/core/persistence/schema-h2.ddl @@ -403,9 +403,9 @@ CREATE TABLE "SEMAPHORES" ( "ID" INTEGER NOT NULL GENERATED BY DEFAULT AS IDENTITY (START WITH 1, INCREMENT BY 1), "NAME" VARCHAR(4000), "CHECKSUM" VARCHAR(200), - "CREATED_AT" TIMESTAMP, - "UPDATED_AT" TIMESTAMP, - "LOCKED_AT" TIMESTAMP + "CREATED_AT" BIGINT, + "UPDATED_AT" BIGINT, + "LOCKED_AT" BIGINT ); CREATE TABLE "MEASURE_FILTERS" ( diff --git a/sonar-core/src/test/java/org/sonar/core/persistence/SemaphoreDaoTest.java b/sonar-core/src/test/java/org/sonar/core/persistence/SemaphoreDaoTest.java index a2652f1aaa1..5710a80c2a7 100644 --- a/sonar-core/src/test/java/org/sonar/core/persistence/SemaphoreDaoTest.java +++ b/sonar-core/src/test/java/org/sonar/core/persistence/SemaphoreDaoTest.java @@ -19,15 +19,14 @@ */ package org.sonar.core.persistence; -import org.apache.commons.lang.time.DateUtils; import org.apache.ibatis.session.SqlSession; import org.junit.Before; import org.junit.Rule; import org.junit.Test; import org.junit.rules.ExpectedException; import org.sonar.api.utils.Semaphores; +import org.sonar.api.utils.System2; -import java.util.Date; import java.util.concurrent.CountDownLatch; import java.util.concurrent.CyclicBarrier; import java.util.concurrent.atomic.AtomicInteger; @@ -37,10 +36,12 @@ import static org.assertj.core.api.Assertions.assertThat; public class SemaphoreDaoTest extends AbstractDaoTestCase { private SemaphoreDao dao; + private System2 system; @Before public void before() { - dao = new SemaphoreDao(getMyBatis()); + system = System2.INSTANCE; + dao = new SemaphoreDao(getMyBatis(), system); } @Rule @@ -51,7 +52,7 @@ public class SemaphoreDaoTest extends AbstractDaoTestCase { thrown.expect(IllegalArgumentException.class); thrown.expectMessage("Semaphore name must not be empty"); - SemaphoreDao dao = new SemaphoreDao(getMyBatis()); + SemaphoreDao dao = new SemaphoreDao(getMyBatis(), system); dao.acquire(null, 5000); } @@ -60,7 +61,7 @@ public class SemaphoreDaoTest extends AbstractDaoTestCase { thrown.expect(IllegalArgumentException.class); thrown.expectMessage("Semaphore max age must be positive: -5000"); - SemaphoreDao dao = new SemaphoreDao(getMyBatis()); + SemaphoreDao dao = new SemaphoreDao(getMyBatis(), system); dao.acquire("foo", -5000); } @@ -69,7 +70,7 @@ public class SemaphoreDaoTest extends AbstractDaoTestCase { thrown.expect(IllegalArgumentException.class); thrown.expectMessage("Semaphore name must not be empty"); - SemaphoreDao dao = new SemaphoreDao(getMyBatis()); + SemaphoreDao dao = new SemaphoreDao(getMyBatis(), system); dao.release(null); } @@ -97,14 +98,14 @@ public class SemaphoreDaoTest extends AbstractDaoTestCase { assertThat(lock.getDurationSinceLocked()).isNull(); SemaphoreDto semaphore = selectSemaphore("foo"); - assertThat(semaphore.getCreatedAt().getTime()).isEqualTo(semaphore.getUpdatedAt().getTime()); + assertThat(semaphore.getCreatedAt()).isEqualTo(semaphore.getUpdatedAt()); Thread.sleep(1000); dao.update(lock); semaphore = selectSemaphore("foo"); - assertThat(semaphore.getCreatedAt().getTime()).isLessThan(semaphore.getUpdatedAt().getTime()); + assertThat(semaphore.getCreatedAt()).isLessThan(semaphore.getUpdatedAt()); dao.release("foo"); assertThat(selectSemaphore("foo")).isNull(); @@ -247,19 +248,11 @@ public class SemaphoreDaoTest extends AbstractDaoTestCase { } } - private boolean isRecent(Date date) { - Date future = DateUtils.addMinutes(now(), 1); - Date past = DateUtils.addDays(now(), -1); - return date.after(past) && date.before(future); - } - - private Date now() { - SqlSession session = getMyBatis().openSession(); - try { - return dao.now(session); - } finally { - MyBatis.closeQuietly(session); - } + private boolean isRecent(Long date) { + int oneMinuteInMs = 60 * 1000; + long future = system.now() + oneMinuteInMs; + long past = system.now() - oneMinuteInMs; + return date > past && date < future; } private static class Runner extends Thread { diff --git a/sonar-core/src/test/resources/org/sonar/core/persistence/SemaphoreDaoTest/old_semaphore.xml b/sonar-core/src/test/resources/org/sonar/core/persistence/SemaphoreDaoTest/old_semaphore.xml index 903ea7916c7..23a1d4ff67b 100644 --- a/sonar-core/src/test/resources/org/sonar/core/persistence/SemaphoreDaoTest/old_semaphore.xml +++ b/sonar-core/src/test/resources/org/sonar/core/persistence/SemaphoreDaoTest/old_semaphore.xml @@ -1,3 +1,3 @@ <dataset> - <semaphores id="1" name="foo" checksum="acbd18db4cc2f85cedef654fccc4a4d8" created_at="2010-01-25" updated_at="2010-01-25" locked_at="2010-01-25"/> -</dataset>
\ No newline at end of file + <semaphores id="1" name="foo" checksum="acbd18db4cc2f85cedef654fccc4a4d8" created_at="1264374000000" updated_at="1264374000000" locked_at="1264374000000"/> +</dataset> |