aboutsummaryrefslogtreecommitdiffstats
path: root/sonar-core
diff options
context:
space:
mode:
authorTeryk Bellahsene <teryk.bellahsene@sonarsource.com>2015-02-05 16:47:06 +0100
committerTeryk Bellahsene <teryk.bellahsene@sonarsource.com>2015-02-10 18:03:03 +0100
commit398fd6721569580d553d7e296775cdb9fec48a10 (patch)
treeb791252b47be9e3b459904448a306a5daaf8fe32 /sonar-core
parente50ceb6ff967aed44048295380deff968588479e (diff)
downloadsonarqube-398fd6721569580d553d7e296775cdb9fec48a10.tar.gz
sonarqube-398fd6721569580d553d7e296775cdb9fec48a10.zip
SONAR-5183 timezones - semaphores migration
Diffstat (limited to 'sonar-core')
-rw-r--r--sonar-core/src/main/java/org/sonar/core/persistence/DatabaseVersion.java2
-rw-r--r--sonar-core/src/main/java/org/sonar/core/persistence/SemaphoreDao.java115
-rw-r--r--sonar-core/src/main/java/org/sonar/core/persistence/SemaphoreDto.java20
-rw-r--r--sonar-core/src/main/java/org/sonar/core/persistence/SemaphoreMapper.java8
-rw-r--r--sonar-core/src/main/resources/org/sonar/core/persistence/SemaphoreMapper.xml16
-rw-r--r--sonar-core/src/main/resources/org/sonar/core/persistence/rows-h2.sql3
-rw-r--r--sonar-core/src/main/resources/org/sonar/core/persistence/schema-h2.ddl6
-rw-r--r--sonar-core/src/test/java/org/sonar/core/persistence/SemaphoreDaoTest.java35
-rw-r--r--sonar-core/src/test/resources/org/sonar/core/persistence/SemaphoreDaoTest/old_semaphore.xml4
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 &lt; #{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>