]> source.dussan.org Git - sonarqube.git/commitdiff
SONAR-3306 Refactoring to use DatabaseSemaphore instead of SemaphoreDao
authorJulien Lancelot <julien.lancelot@gmail.com>
Tue, 4 Dec 2012 13:35:07 +0000 (14:35 +0100)
committerJulien Lancelot <julien.lancelot@gmail.com>
Tue, 4 Dec 2012 14:04:30 +0000 (15:04 +0100)
12 files changed:
plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/CorePlugin.java
plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/DatabaseSemaphoreImpl.java [deleted file]
plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/DatabaseSemaphoreImplTest.java [deleted file]
sonar-batch/src/main/java/org/sonar/batch/bootstrap/BatchModule.java
sonar-batch/src/main/java/org/sonar/batch/bootstrap/CheckSemaphore.java
sonar-batch/src/test/java/org/sonar/batch/bootstrap/CheckSemaphoreTest.java
sonar-core/src/main/java/org/sonar/core/persistence/DatabaseSemaphoreImpl.java [new file with mode: 0644]
sonar-core/src/main/java/org/sonar/core/persistence/Lock.java [deleted file]
sonar-core/src/main/java/org/sonar/core/persistence/SemaphoreDao.java
sonar-core/src/test/java/org/sonar/core/persistence/DatabaseSemaphoreImplTest.java [new file with mode: 0644]
sonar-core/src/test/java/org/sonar/core/persistence/SemaphoreDaoTest.java
sonar-plugin-api/src/main/java/org/sonar/api/utils/DatabaseSemaphore.java

index 810a5aa06bf26c3dcd6653343b9a447be2b81302..1cbc4f387fcb1e4875daff8e1df587599f6e1ea4 100644 (file)
@@ -394,7 +394,6 @@ public final class CorePlugin extends SonarPlugin {
       DefaultResourceTypes.class,
       UserManagedMetrics.class,
       ProjectFileSystemLogger.class,
-      DatabaseSemaphoreImpl.class,
       Periods.class,
 
       // maven
diff --git a/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/DatabaseSemaphoreImpl.java b/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/DatabaseSemaphoreImpl.java
deleted file mode 100644 (file)
index 813a679..0000000
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * Sonar, open source software quality management tool.
- * Copyright (C) 2008-2012 SonarSource
- * mailto:contact AT sonarsource DOT com
- *
- * Sonar is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * Sonar is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with Sonar; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02
- */
-package org.sonar.plugins.core;
-
-import org.sonar.api.utils.DatabaseSemaphore;
-import org.sonar.core.persistence.SemaphoreDao;
-
-/**
- * @since 3.4
- */
-public class DatabaseSemaphoreImpl implements DatabaseSemaphore {
-
-  private SemaphoreDao dao;
-
-  public DatabaseSemaphoreImpl(SemaphoreDao dao) {
-    this.dao = dao;
-  }
-
-  public boolean acquire(String name, int maxDurationInSeconds) {
-    return dao.acquire(name, maxDurationInSeconds).isAcquired();
-  }
-
-  public void release(String name) {
-    dao.release(name);
-  }
-}
diff --git a/plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/DatabaseSemaphoreImplTest.java b/plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/DatabaseSemaphoreImplTest.java
deleted file mode 100644 (file)
index e4f9945..0000000
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- * Sonar, open source software quality management tool.
- * Copyright (C) 2008-2012 SonarSource
- * mailto:contact AT sonarsource DOT com
- *
- * Sonar is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * Sonar is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with Sonar; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02
- */
-package org.sonar.plugins.core;
-
-import org.junit.Test;
-import org.sonar.core.persistence.Lock;
-import org.sonar.core.persistence.SemaphoreDao;
-
-import static org.mockito.Matchers.anyInt;
-import static org.mockito.Matchers.anyString;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
-
-public class DatabaseSemaphoreImplTest {
-
-  @Test
-  public void should_be_a_bridge_over_dao() {
-    Lock lock = mock(Lock.class);
-    SemaphoreDao dao = mock(SemaphoreDao.class);
-    when(dao.acquire(anyString(), anyInt())).thenReturn(lock);
-
-    DatabaseSemaphoreImpl impl = new DatabaseSemaphoreImpl(dao);
-
-    impl.acquire("do-xxx", 50000);
-    verify(dao).acquire("do-xxx", 50000);
-
-    impl.release("do-xxx");
-    verify(dao).release("do-xxx");
-  }
-}
index 949030df4f68f96ba5b7273a1ab80a20699840c6..3067a161cdab9cced2dbe21815cc1451a6e32245 100644 (file)
@@ -48,6 +48,7 @@ import org.sonar.core.i18n.RuleI18nManager;
 import org.sonar.core.metric.CacheMetricFinder;
 import org.sonar.core.notification.DefaultNotificationManager;
 import org.sonar.core.persistence.DaoUtils;
+import org.sonar.core.persistence.DatabaseSemaphoreImpl;
 import org.sonar.core.persistence.DatabaseVersion;
 import org.sonar.core.persistence.MyBatis;
 import org.sonar.core.resource.DefaultResourcePermissions;
@@ -103,6 +104,7 @@ public class BatchModule extends Module {
     container.addSingleton(DefaultUserFinder.class);
     container.addSingleton(ResourceTypes.class);
     container.addSingleton(MetricProvider.class);
+    container.addSingleton(DatabaseSemaphoreImpl.class);
     container.addSingleton(CheckSemaphore.class);
   }
 
index 7ea91681fe301eda9d6bb1df2c33312ece976cdf..9bc4b65e6210c02621204435f09943f0043b8d2e 100644 (file)
@@ -24,21 +24,22 @@ import org.slf4j.LoggerFactory;
 import org.sonar.api.CoreProperties;
 import org.sonar.api.config.Settings;
 import org.sonar.api.resources.Project;
+import org.sonar.api.utils.DatabaseSemaphore;
 import org.sonar.api.utils.SonarException;
 import org.sonar.batch.ProjectTree;
-import org.sonar.core.persistence.Lock;
-import org.sonar.core.persistence.SemaphoreDao;
+
+import static org.sonar.api.utils.DatabaseSemaphore.Lock;
 
 public class CheckSemaphore {
 
   private static final Logger LOG = LoggerFactory.getLogger(CheckSemaphore.class);
 
-  private final SemaphoreDao semaphoreDao;
+  private final DatabaseSemaphore databaseSemaphore;
   private final ProjectTree projectTree;
   private final Settings settings;
 
-  public CheckSemaphore(SemaphoreDao semaphoreDao, ProjectTree projectTree, Settings settings) {
-    this.semaphoreDao = semaphoreDao;
+  public CheckSemaphore(DatabaseSemaphore databaseSemaphore, ProjectTree projectTree, Settings settings) {
+    this.databaseSemaphore = databaseSemaphore;
     this.projectTree = projectTree;
     this.settings = settings;
   }
@@ -72,15 +73,16 @@ public class CheckSemaphore {
   private Lock acquire() {
     LOG.debug("Acquire semaphore on project : {}, with key {}", getProject(), getSemaphoreKey());
     if (!isForceAnalyseActivated()) {
-      return semaphoreDao.acquire(getSemaphoreKey());
+      return databaseSemaphore.acquire(getSemaphoreKey());
     } else {
-      return semaphoreDao.acquire(getSemaphoreKey(), 0);
+      // In force mode, we acquire the lock regardless there's a existing lock or not
+      return databaseSemaphore.acquire(getSemaphoreKey(), 0);
     }
   }
 
   private void release() {
     LOG.debug("Release semaphore on project : {}, with key {}", getProject(), getSemaphoreKey());
-    semaphoreDao.release(getSemaphoreKey());
+    databaseSemaphore.release(getSemaphoreKey());
   }
 
   private String getSemaphoreKey() {
index d003336713e3f8ef232fed14e44af622ccacf5b5..e3d09868d9ac76dea148519006032240d389031f 100644 (file)
@@ -24,10 +24,9 @@ import org.junit.Test;
 import org.sonar.api.CoreProperties;
 import org.sonar.api.config.Settings;
 import org.sonar.api.resources.Project;
+import org.sonar.api.utils.DatabaseSemaphore;
 import org.sonar.api.utils.SonarException;
 import org.sonar.batch.ProjectTree;
-import org.sonar.core.persistence.Lock;
-import org.sonar.core.persistence.SemaphoreDao;
 
 import java.util.Date;
 
@@ -37,12 +36,13 @@ import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.never;
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
+import static org.sonar.api.utils.DatabaseSemaphore.Lock;
 
 public class CheckSemaphoreTest {
 
   private CheckSemaphore checkSemaphore;
 
-  private SemaphoreDao semaphoreDao;
+  private DatabaseSemaphore databaseSemaphore;
   private ProjectTree projectTree;
   private Settings settings;
 
@@ -53,9 +53,9 @@ public class CheckSemaphoreTest {
   public void setUp() {
     lock = mock(Lock.class);
 
-    semaphoreDao = mock(SemaphoreDao.class);
-    when(semaphoreDao.acquire(anyString())).thenReturn(lock);
-    when(semaphoreDao.acquire(anyString(), anyInt())).thenReturn(lock);
+    databaseSemaphore = mock(DatabaseSemaphore.class);
+    when(databaseSemaphore.acquire(anyString())).thenReturn(lock);
+    when(databaseSemaphore.acquire(anyString(), anyInt())).thenReturn(lock);
 
     projectTree = mock(ProjectTree.class);
     settings = new Settings();
@@ -65,7 +65,7 @@ public class CheckSemaphoreTest {
     project = new Project("key", "branch", "name");
     when(projectTree.getRootProject()).thenReturn(project);
 
-    checkSemaphore = new CheckSemaphore(semaphoreDao, projectTree, settings);
+    checkSemaphore = new CheckSemaphore(databaseSemaphore, projectTree, settings);
   }
 
   @Test
@@ -73,7 +73,7 @@ public class CheckSemaphoreTest {
     when(lock.isAcquired()).thenReturn(true);
     checkSemaphore.start();
 
-    verify(semaphoreDao).acquire(anyString());
+    verify(databaseSemaphore).acquire(anyString());
   }
 
   @Test
@@ -84,7 +84,7 @@ public class CheckSemaphoreTest {
     when(lock.isAcquired()).thenReturn(true);
     checkSemaphore.start();
 
-    verify(semaphoreDao).acquire("batch-key");
+    verify(databaseSemaphore).acquire("batch-key");
   }
 
   @Test
@@ -92,7 +92,7 @@ public class CheckSemaphoreTest {
     when(lock.isAcquired()).thenReturn(true);
     checkSemaphore.start();
 
-    verify(semaphoreDao).acquire("batch-key:branch");
+    verify(databaseSemaphore).acquire("batch-key:branch");
   }
 
   @Test
@@ -100,7 +100,7 @@ public class CheckSemaphoreTest {
     setForceMode(true);
     when(lock.isAcquired()).thenReturn(true);
     checkSemaphore.start();
-    verify(semaphoreDao).acquire(anyString(), anyInt());
+    verify(databaseSemaphore).acquire(anyString(), anyInt());
   }
 
   @Test(expected = SonarException.class)
@@ -108,7 +108,7 @@ public class CheckSemaphoreTest {
     when(lock.getLocketAt()).thenReturn(new Date());
     when(lock.isAcquired()).thenReturn(false);
     checkSemaphore.start();
-    verify(semaphoreDao, never()).acquire(anyString());
+    verify(databaseSemaphore, never()).acquire(anyString());
   }
 
   @Test
@@ -116,21 +116,21 @@ public class CheckSemaphoreTest {
     setDryRunMode(true);
     settings = new Settings().setProperty(CoreProperties.DRY_RUN, true);
     checkSemaphore.start();
-    verify(semaphoreDao, never()).acquire(anyString());
-    verify(semaphoreDao, never()).acquire(anyString(), anyInt());
+    verify(databaseSemaphore, never()).acquire(anyString());
+    verify(databaseSemaphore, never()).acquire(anyString(), anyInt());
   }
 
   @Test
   public void shouldReleaseSemaphore() {
     checkSemaphore.stop();
-    verify(semaphoreDao).release(anyString());
+    verify(databaseSemaphore).release(anyString());
   }
 
   @Test
   public void shouldNotReleaseSemaphoreInDryRunMode() {
     setDryRunMode(true);
     checkSemaphore.stop();
-    verify(semaphoreDao, never()).release(anyString());
+    verify(databaseSemaphore, never()).release(anyString());
   }
 
   private void setDryRunMode(boolean isInDryRunMode) {
diff --git a/sonar-core/src/main/java/org/sonar/core/persistence/DatabaseSemaphoreImpl.java b/sonar-core/src/main/java/org/sonar/core/persistence/DatabaseSemaphoreImpl.java
new file mode 100644 (file)
index 0000000..75a5bb7
--- /dev/null
@@ -0,0 +1,46 @@
+/*
+ * Sonar, open source software quality management tool.
+ * Copyright (C) 2008-2012 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * Sonar is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * Sonar is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with Sonar; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02
+ */
+package org.sonar.core.persistence;
+
+import org.sonar.api.utils.DatabaseSemaphore;
+
+/**
+ * @since 3.4
+ */
+public class DatabaseSemaphoreImpl implements DatabaseSemaphore {
+
+  private SemaphoreDao dao;
+
+  public DatabaseSemaphoreImpl(SemaphoreDao dao) {
+    this.dao = dao;
+  }
+
+  public Lock acquire(String name, int maxDurationInSeconds) {
+    return dao.acquire(name, maxDurationInSeconds);
+  }
+
+  public Lock acquire(String name) {
+    return dao.acquire(name);
+  }
+
+  public void release(String name) {
+    dao.release(name);
+  }
+}
diff --git a/sonar-core/src/main/java/org/sonar/core/persistence/Lock.java b/sonar-core/src/main/java/org/sonar/core/persistence/Lock.java
deleted file mode 100644 (file)
index 1e47fbc..0000000
+++ /dev/null
@@ -1,72 +0,0 @@
-/*
- * Sonar, open source software quality management tool.
- * Copyright (C) 2008-2012 SonarSource
- * mailto:contact AT sonarsource DOT com
- *
- * Sonar is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * Sonar is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with Sonar; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02
- */
-
-package org.sonar.core.persistence;
-
-import java.util.Date;
-
-/**
- * @since 3.4
- */
-public class Lock {
-
-  private String name;
-  private boolean acquired;
-  private Date locketAt;
-  private Date createdAt;
-  private Date updatedAt;
-  private Long durationSinceLocked;
-
-  public Lock(String name, boolean acquired, Date locketAt, Date createdAt, Date updatedAt) {
-    this.name = name;
-    this.acquired = acquired;
-    this.locketAt = locketAt;
-    this.createdAt = createdAt;
-    this.updatedAt = updatedAt;
-  }
-
-  public String getName() {
-    return name;
-  }
-
-  public Date getLocketAt() {
-    return locketAt;
-  }
-
-  public Date getCreatedAt() {
-    return createdAt;
-  }
-
-  public Date getUpdatedAt() {
-    return updatedAt;
-  }
-
-  public boolean isAcquired() {
-    return acquired;
-  }
-
-  public Long getDurationSinceLocked() {
-    return durationSinceLocked;
-  }
-
-  public void setDurationSinceLocked(Long durationSinceLocked) {
-    this.durationSinceLocked = durationSinceLocked;
-  }
-}
index 12100acf19ab9bd555ed0693eeda4187d93cd323..471315c2d40ac53fc3fda0979f878217efbe750b 100644 (file)
@@ -26,6 +26,8 @@ import org.apache.ibatis.session.SqlSession;
 
 import java.util.Date;
 
+import static org.sonar.api.utils.DatabaseSemaphore.Lock;
+
 /**
  * @since 3.4
  */
diff --git a/sonar-core/src/test/java/org/sonar/core/persistence/DatabaseSemaphoreImplTest.java b/sonar-core/src/test/java/org/sonar/core/persistence/DatabaseSemaphoreImplTest.java
new file mode 100644 (file)
index 0000000..73a7d61
--- /dev/null
@@ -0,0 +1,50 @@
+/*
+ * Sonar, open source software quality management tool.
+ * Copyright (C) 2008-2012 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * Sonar is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * Sonar is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with Sonar; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02
+ */
+package org.sonar.core.persistence;
+
+import org.junit.Test;
+
+import static org.mockito.Matchers.anyInt;
+import static org.mockito.Matchers.anyString;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+import static org.sonar.api.utils.DatabaseSemaphore.Lock;
+
+public class DatabaseSemaphoreImplTest {
+
+  @Test
+  public void should_be_a_bridge_over_dao() {
+    Lock lock = mock(Lock.class);
+    SemaphoreDao dao = mock(SemaphoreDao.class);
+    when(dao.acquire(anyString(), anyInt())).thenReturn(lock);
+
+    DatabaseSemaphoreImpl impl = new DatabaseSemaphoreImpl(dao);
+
+    impl.acquire("do-xxx", 50000);
+    verify(dao).acquire("do-xxx", 50000);
+
+    impl.acquire("do-xxx");
+    verify(dao).acquire("do-xxx");
+
+    impl.release("do-xxx");
+    verify(dao).release("do-xxx");
+  }
+}
index 75582e650b1aefab902b33ec487398c2901517d0..948afed4a59611a467762ab65bb082b7860783fe 100644 (file)
@@ -32,6 +32,7 @@ import java.util.concurrent.CyclicBarrier;
 import java.util.concurrent.atomic.AtomicInteger;
 
 import static org.fest.assertions.Assertions.assertThat;
+import static org.sonar.api.utils.DatabaseSemaphore.Lock;
 
 public class SemaphoreDaoTest extends AbstractDaoTestCase {
 
index f01a6e6f25fd9e69d26889ce14d9edf59db5bbe1..888647c79cdee715a0995946699eeaadb46f9fda 100644 (file)
@@ -22,6 +22,8 @@ package org.sonar.api.utils;
 import org.sonar.api.BatchComponent;
 import org.sonar.api.ServerComponent;
 
+import java.util.Date;
+
 /**
  * A semaphore shared among all the processes that can connect to the central database.
  *
@@ -29,8 +31,77 @@ import org.sonar.api.ServerComponent;
  */
 public interface DatabaseSemaphore extends BatchComponent, ServerComponent {
 
-  boolean acquire(String name, int maxDurationInSeconds);
+  /**
+   * Try to acquire a lock on a name, for a given duration.
+   * The lock will be acquired if there's no existing lock on this name or if a lock exists but the max duration is reached.
+   *
+   * @param name the key of the semaphore
+   * @param maxDurationInSeconds the max duration in seconds the semaphore will be acquired (a value of zero can be used to always acquire a lock)
+   * @return a lock containing information if the lock could be acquired or not, the duration since locked, etc.
+   */
+  Lock acquire(String name, int maxDurationInSeconds);
+
+  /**
+   * Try to acquire the lock on a name.
+   * The lock will be acquired only if there's no existing lock.
+   *
+   * @param name the key of the semaphore
+   * @return a lock containing information if the lock could be acquired or not, the duration since locked, etc.
+   */
+  Lock acquire(String name);
 
+  /**
+   * Release the lock on a semaphore by its name.
+   *
+   * @param name the key of the semaphore
+   */
   void release(String name);
 
+  static class Lock {
+
+    private String name;
+    private boolean acquired;
+    private Date locketAt;
+    private Date createdAt;
+    private Date updatedAt;
+    private Long durationSinceLocked;
+
+    public Lock(String name, boolean acquired, Date locketAt, Date createdAt, Date updatedAt) {
+      this.name = name;
+      this.acquired = acquired;
+      this.locketAt = locketAt;
+      this.createdAt = createdAt;
+      this.updatedAt = updatedAt;
+    }
+
+    public String getName() {
+      return name;
+    }
+
+    public Date getLocketAt() {
+      return locketAt;
+    }
+
+    public Date getCreatedAt() {
+      return createdAt;
+    }
+
+    public Date getUpdatedAt() {
+      return updatedAt;
+    }
+
+    public boolean isAcquired() {
+      return acquired;
+    }
+
+    public Long getDurationSinceLocked() {
+      return durationSinceLocked;
+    }
+
+    public void setDurationSinceLocked(Long durationSinceLocked) {
+      this.durationSinceLocked = durationSinceLocked;
+    }
+
+  }
+
 }