]> source.dussan.org Git - sonarqube.git/commitdiff
SONAR-7675 add InternalPropertiesImpl to Web and Ce containers
authorSébastien Lesaint <sebastien.lesaint@sonarsource.com>
Thu, 1 Sep 2016 15:20:29 +0000 (17:20 +0200)
committerSébastien Lesaint <sebastien.lesaint@sonarsource.com>
Mon, 5 Sep 2016 09:32:17 +0000 (11:32 +0200)
server/sonar-ce/src/main/java/org/sonar/ce/container/ComputeEngineContainerImpl.java
server/sonar-ce/src/test/java/org/sonar/ce/container/ComputeEngineContainerImplTest.java
server/sonar-server/src/main/java/org/sonar/server/platform/platformlevel/PlatformLevel4.java
server/sonar-server/src/main/java/org/sonar/server/property/InternalProperties.java [new file with mode: 0644]
server/sonar-server/src/main/java/org/sonar/server/property/InternalPropertiesImpl.java [new file with mode: 0644]
server/sonar-server/src/main/java/org/sonar/server/property/package-info.java [new file with mode: 0644]
server/sonar-server/src/test/java/org/sonar/server/property/InternalPropertiesImplTest.java [new file with mode: 0644]

index 27f5bec1cbb38c09e05377c98ba485d4c4ca3c2a..fff798be3cf45fcc0afeee7b52ec80dae6539e31 100644 (file)
@@ -115,6 +115,7 @@ import org.sonar.server.plugins.InstalledPluginReferentialFactory;
 import org.sonar.server.plugins.ServerExtensionInstaller;
 import org.sonar.server.plugins.privileged.PrivilegedPluginsBootstraper;
 import org.sonar.server.plugins.privileged.PrivilegedPluginsStopper;
+import org.sonar.server.property.InternalPropertiesImpl;
 import org.sonar.server.qualityprofile.BuiltInProfiles;
 import org.sonar.server.qualityprofile.QProfileComparison;
 import org.sonar.server.qualityprofile.QProfileLookup;
@@ -385,6 +386,7 @@ public class ComputeEngineContainerImpl implements ComputeEngineContainer {
       ProjectAnalysisTaskModule.class,
       CeTaskProcessorModule.class,
 
+      InternalPropertiesImpl.class,
       ProjectSettingsFactory.class,
     };
   }
index b513dfa7ef650d56af19557ec2e8c8b84c3b8843..98e1ba5c1e99b691b9d637194afe508666e3a19f 100644 (file)
@@ -88,7 +88,7 @@ public class ComputeEngineContainerImplTest {
     assertThat(picoContainer.getComponentAdapters())
       .hasSize(
         CONTAINER_ITSELF
-          + 79 // level 4
+          + 80 // level 4
           + 4 // content of CeConfigurationModule
           + 3 // content of CeHttpModule
           + 5 // content of CeQueueModule
index 1e7b008bc60f6b75d0c06385e3778d75ff86752c..4ae90268689da5c965fdddc8a1f4c99e4f3bd255 100644 (file)
@@ -177,6 +177,7 @@ import org.sonar.server.plugins.ws.UninstallAction;
 import org.sonar.server.plugins.ws.UpdatesAction;
 import org.sonar.server.project.ws.ProjectsWsModule;
 import org.sonar.server.projectlink.ws.ProjectLinksModule;
+import org.sonar.server.property.InternalPropertiesImpl;
 import org.sonar.server.qualitygate.QualityGateModule;
 import org.sonar.server.qualityprofile.BuiltInProfiles;
 import org.sonar.server.qualityprofile.QProfileBackuper;
@@ -635,6 +636,7 @@ public class PlatformLevel4 extends PlatformLevel {
       CeModule.class,
       CeWsModule.class,
 
+      InternalPropertiesImpl.class,
       ProjectSettingsFactory.class,
 
       // UI
diff --git a/server/sonar-server/src/main/java/org/sonar/server/property/InternalProperties.java b/server/sonar-server/src/main/java/org/sonar/server/property/InternalProperties.java
new file mode 100644 (file)
index 0000000..f1d5a1b
--- /dev/null
@@ -0,0 +1,49 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2016 SonarSource SA
+ * mailto:contact AT sonarsource DOT com
+ *
+ * This program 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.
+ *
+ * This program 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 this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ */
+package org.sonar.server.property;
+
+import java.util.Optional;
+import javax.annotation.Nullable;
+
+/**
+ * Allows to read and write internal properties.
+ */
+public interface InternalProperties {
+
+  /**
+   * Read the value of the specified property.
+   *
+   * @return {@link Optional#empty()} if the property does not exist, an empty string if the property is empty,
+   *         otherwise the value of the property as a String.
+   *
+   * @throws IllegalArgumentException if {@code propertyKey} is {@code null} or empty
+   */
+  Optional<String> read(String propertyKey);
+
+  /**
+   * Write the value of the specified property.
+   * <p>
+   *   {@code null} and empty string are valid values which will persist the specified property as empty.
+   * </p>
+   *
+   * @throws IllegalArgumentException if {@code propertyKey} is {@code null} or empty
+   */
+  void write(String propertyKey, @Nullable String value);
+}
diff --git a/server/sonar-server/src/main/java/org/sonar/server/property/InternalPropertiesImpl.java b/server/sonar-server/src/main/java/org/sonar/server/property/InternalPropertiesImpl.java
new file mode 100644 (file)
index 0000000..f99002d
--- /dev/null
@@ -0,0 +1,65 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2016 SonarSource SA
+ * mailto:contact AT sonarsource DOT com
+ *
+ * This program 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.
+ *
+ * This program 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 this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ */
+package org.sonar.server.property;
+
+import java.util.Optional;
+import javax.annotation.Nullable;
+import org.sonar.db.DbClient;
+import org.sonar.db.DbSession;
+
+import static com.google.common.base.Preconditions.checkArgument;
+
+/**
+ * A cache-less implementation of {@link InternalProperties} reading and writing to DB table INTERNAL_PROPERTIES.
+ */
+public class InternalPropertiesImpl implements InternalProperties {
+  private final DbClient dbClient;
+
+  public InternalPropertiesImpl(DbClient dbClient) {
+    this.dbClient = dbClient;
+  }
+
+  @Override
+  public Optional<String> read(String propertyKey) {
+    checkPropertyKey(propertyKey);
+
+    try (DbSession dbSession = dbClient.openSession(false)) {
+      return dbClient.internalPropertiesDao().selectByKey(dbSession, propertyKey);
+    }
+  }
+
+  @Override
+  public void write(String propertyKey, @Nullable String value) {
+    checkPropertyKey(propertyKey);
+
+    try (DbSession dbSession = dbClient.openSession(false)) {
+      if (value == null || value.isEmpty()) {
+        dbClient.internalPropertiesDao().saveAsEmpty(dbSession, propertyKey);
+      } else {
+        dbClient.internalPropertiesDao().save(dbSession, propertyKey, value);
+      }
+    }
+  }
+
+  private static void checkPropertyKey(@Nullable String propertyKey) {
+    checkArgument(propertyKey != null && !propertyKey.isEmpty(), "property key can't be null nor empty");
+  }
+
+}
diff --git a/server/sonar-server/src/main/java/org/sonar/server/property/package-info.java b/server/sonar-server/src/main/java/org/sonar/server/property/package-info.java
new file mode 100644 (file)
index 0000000..730caad
--- /dev/null
@@ -0,0 +1,23 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2016 SonarSource SA
+ * mailto:contact AT sonarsource DOT com
+ *
+ * This program 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.
+ *
+ * This program 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 this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ */
+@ParametersAreNonnullByDefault
+package org.sonar.server.property;
+
+import javax.annotation.ParametersAreNonnullByDefault;
diff --git a/server/sonar-server/src/test/java/org/sonar/server/property/InternalPropertiesImplTest.java b/server/sonar-server/src/test/java/org/sonar/server/property/InternalPropertiesImplTest.java
new file mode 100644 (file)
index 0000000..20c371b
--- /dev/null
@@ -0,0 +1,117 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2016 SonarSource SA
+ * mailto:contact AT sonarsource DOT com
+ *
+ * This program 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.
+ *
+ * This program 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 this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ */
+package org.sonar.server.property;
+
+import java.util.Optional;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.ExpectedException;
+import org.sonar.db.DbClient;
+import org.sonar.db.DbSession;
+import org.sonar.db.property.InternalPropertiesDao;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+public class InternalPropertiesImplTest {
+  private static final String EMPTY_STRING = "";
+  public static final String SOME_VALUE = "a value";
+  public static final String SOME_KEY = "some key";
+
+  @Rule
+  public ExpectedException expectedException = ExpectedException.none();
+  
+  private DbClient dbClient = mock(DbClient.class);
+  private DbSession dbSession = mock(DbSession.class);
+  private InternalPropertiesDao internalPropertiesDao = mock(InternalPropertiesDao.class);
+  private InternalPropertiesImpl underTest = new InternalPropertiesImpl(dbClient);
+
+  @Before
+  public void setUp() throws Exception {
+    when(dbClient.openSession(false)).thenReturn(dbSession);
+    when(dbClient.internalPropertiesDao()).thenReturn(internalPropertiesDao);
+  }
+
+  @Test
+  public void reads_throws_IAE_if_key_is_null() {
+    expectKeyNullOrEmptyIAE();
+
+    underTest.read(null);
+  }
+
+  @Test
+  public void reads_throws_IAE_if_key_is_empty() {
+    expectKeyNullOrEmptyIAE();
+
+    underTest.read(EMPTY_STRING);
+  }
+
+  @Test
+  public void reads_returns_optional_from_DAO() {
+    Optional<String> value = Optional.of("bablabla");
+
+    when(internalPropertiesDao.selectByKey(dbSession, SOME_KEY)).thenReturn(value);
+
+    assertThat(underTest.read(SOME_KEY)).isSameAs(value);
+  }
+
+  @Test
+  public void write_throws_IAE_if_key_is_null() {
+    expectKeyNullOrEmptyIAE();
+
+    underTest.write(null, SOME_VALUE);
+  }
+
+  @Test
+  public void writes_throws_IAE_if_key_is_empty() {
+    expectKeyNullOrEmptyIAE();
+
+    underTest.write(EMPTY_STRING, SOME_VALUE);
+  }
+
+  @Test
+  public void write_calls_dao_saveAsEmpty_when_value_is_null() {
+    underTest.write(SOME_KEY, null);
+
+    verify(internalPropertiesDao).saveAsEmpty(dbSession, SOME_KEY);
+  }
+
+  @Test
+  public void write_calls_dao_saveAsEmpty_when_value_is_empty() {
+    underTest.write(SOME_KEY, EMPTY_STRING);
+
+    verify(internalPropertiesDao).saveAsEmpty(dbSession, SOME_KEY);
+  }
+
+  @Test
+  public void write_calls_dao_save_when_value_is_neither_null_nor_empty() {
+    underTest.write(SOME_KEY, SOME_VALUE);
+
+    verify(internalPropertiesDao).save(dbSession, SOME_KEY, SOME_VALUE);
+  }
+
+  private void expectKeyNullOrEmptyIAE() {
+    expectedException.expect(IllegalArgumentException.class);
+    expectedException.expectMessage("key can't be null nor empty");
+  }
+}