import org.sonar.api.utils.Durations;
import org.sonar.api.utils.System2;
import org.sonar.api.utils.UriReader;
+import org.sonar.ce.db.CeDbClient;
+import org.sonar.ce.db.ReadOnlyPropertiesDao;
import org.sonar.ce.es.EsIndexerEnabler;
import org.sonar.ce.property.CePropertyDefinitions;
import org.sonar.ce.settings.ComputeEngineSettings;
import org.sonar.core.util.UuidFactoryImpl;
import org.sonar.db.DaoModule;
import org.sonar.db.DatabaseChecker;
-import org.sonar.db.DbClient;
import org.sonar.db.DefaultDatabase;
import org.sonar.db.permission.PermissionRepository;
import org.sonar.db.purge.PurgeProfiler;
CeUserSession.class,
// DB
- DbClient.class,
DaoModule.class,
+ // DbClient.class, replaced by CeDbClient to use ReadOnlyPropertiesDao instead of PropertiesDao
+ ReadOnlyPropertiesDao.class,
+ CeDbClient.class,
// MigrationStepModule.class, DB maintenance, responsibility of Web Server
// Elasticsearch
IssueIndex.class,
// Classes kept for backward compatibility of plugins/libs (like sonar-license) that are directly calling classes from the core
- org.sonar.core.properties.PropertiesDao.class
+ // org.sonar.core.properties.PropertiesDao.class, replaced by ReadOnlyPropertiesDao (declared above) which is a ReadOnly implementation
};
private static final Object[] LEVEL_2_COMPONENTS = new Object[] {
+ // add ReadOnlyPropertiesDao at level2 again so that it shadows PropertiesDao
+ ReadOnlyPropertiesDao.class,
DefaultServerUpgradeStatus.class,
// no DatabaseMigrator.class, responsibility of Web Server
--- /dev/null
+/*
+ * 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.ce.db;
+
+import java.util.Map;
+import org.sonar.db.Dao;
+import org.sonar.db.Database;
+import org.sonar.db.DbClient;
+import org.sonar.db.MyBatis;
+import org.sonar.db.property.PropertiesDao;
+
+public class CeDbClient extends DbClient {
+ private ReadOnlyPropertiesDao readOnlyPropertiesDao;
+
+ public CeDbClient(Database database, MyBatis myBatis, Dao... daos) {
+ super(database, myBatis, daos);
+ }
+
+ @Override
+ protected void doOnLoad(Map<Class, Dao> daoByClass) {
+ this.readOnlyPropertiesDao = getDao(daoByClass, ReadOnlyPropertiesDao.class);
+ }
+
+ @Override
+ public PropertiesDao propertiesDao() {
+ return this.readOnlyPropertiesDao;
+ }
+}
--- /dev/null
+/*
+ * 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.ce.db;
+
+import java.util.Map;
+import org.sonar.core.properties.PropertiesDao;
+import org.sonar.db.DbSession;
+import org.sonar.db.MyBatis;
+import org.sonar.db.property.PropertyDto;
+
+/**
+ * Compute Engine specific override of {@link PropertiesDao} and {@link org.sonar.db.property.PropertiesDao} which
+ * implements no write method (ie. insert/update/delete) because updating the Properties is the Web Server responsibility
+ * alone.
+ * <p>
+ * This ugly trick is required because licensed plugin bundle {@link com.sonarsource.license.api.internal.ServerLicenseVerifierImpl}
+ * which update license properties by calling {@link PropertiesDao} directly and this can not be disabled.
+ * </p>
+ */
+public class ReadOnlyPropertiesDao extends PropertiesDao {
+ public ReadOnlyPropertiesDao(MyBatis mybatis) {
+ super(mybatis);
+ }
+
+ @Override
+ public void insertProperty(DbSession session, PropertyDto property) {
+ // do nothing
+ }
+
+ @Override
+ public void insertProperty(PropertyDto property) {
+ // do nothing
+ }
+
+ @Override
+ public void deleteProjectProperty(String key, Long projectId) {
+ // do nothing
+ }
+
+ @Override
+ public void deleteProjectProperty(String key, Long projectId, DbSession session) {
+ // do nothing
+ }
+
+ @Override
+ public void deleteProjectProperties(String key, String value, DbSession session) {
+ // do nothing
+ }
+
+ @Override
+ public void deleteProjectProperties(String key, String value) {
+ // do nothing
+ }
+
+ @Override
+ public void deleteGlobalProperties() {
+ // do nothing
+ }
+
+ @Override
+ public void deleteGlobalProperty(String key, DbSession session) {
+ // do nothing
+ }
+
+ @Override
+ public void deleteGlobalProperty(String key) {
+ // do nothing
+ }
+
+ @Override
+ public void deleteAllProperties(String key) {
+ // do nothing
+ }
+
+ @Override
+ public void insertGlobalProperties(Map<String, String> properties) {
+ // do nothing
+ }
+
+ @Override
+ public void renamePropertyKey(String oldKey, String newKey) {
+ // do nothing
+ }
+
+ @Override
+ public void updateProperties(String key, String oldValue, String newValue) {
+ // do nothing
+ }
+
+ @Override
+ public void updateProperties(String key, String oldValue, String newValue, DbSession session) {
+ // do nothing
+ }
+
+ @Override
+ public void setProperty(org.sonar.core.properties.PropertyDto property) {
+ // do nothing
+ }
+
+}
--- /dev/null
+/*
+ * 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.ce.db;
+
+import javax.annotation.ParametersAreNonnullByDefault;
);
assertThat(picoContainer.getParent().getParent().getComponentAdapters()).hasSize(
CONTAINER_ITSELF
- + 10 // level 2
+ + 11 // level 2
);
assertThat(picoContainer.getParent().getParent().getParent().getComponentAdapters()).hasSize(
COMPONENTS_IN_LEVEL_1_AT_CONSTRUCTION
--- /dev/null
+/*
+ * 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.ce.db;
+
+import org.junit.Test;
+import org.sonar.db.Dao;
+import org.sonar.db.Database;
+import org.sonar.db.DbClient;
+import org.sonar.db.MyBatis;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.mockito.Mockito.mock;
+
+public class CeDbClientTest {
+ private Database database = mock(Database.class);
+ private MyBatis myBatis = mock(MyBatis.class);
+ private ReadOnlyPropertiesDao readOnlyPropertiesDao = new ReadOnlyPropertiesDao(myBatis);
+
+ private DbClient underTest = new CeDbClient(database, myBatis, (Dao) readOnlyPropertiesDao);
+
+ @Test
+ public void getPropertiesDao_returns_ReadOnlyPropertiesDao() {
+ assertThat(underTest.propertiesDao()).isSameAs(readOnlyPropertiesDao);
+ }
+}
--- /dev/null
+/*
+ * 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.ce.db;
+
+import org.junit.Test;
+import org.sonar.db.DbSession;
+import org.sonar.db.MyBatis;
+import org.sonar.db.property.PropertyDto;
+
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verifyNoMoreInteractions;
+
+public class ReadOnlyPropertiesDaoTest {
+ private MyBatis myBatis = mock(MyBatis.class);
+ private DbSession dbSession = mock(DbSession.class);
+ private PropertyDto propertyDto = mock(PropertyDto.class);
+ private org.sonar.core.properties.PropertyDto oldPropertyDto = mock(org.sonar.core.properties.PropertyDto.class);
+ private ReadOnlyPropertiesDao underTest = new ReadOnlyPropertiesDao(myBatis);
+
+ @Test
+ public void insertProperty() {
+ underTest.insertProperty(dbSession, propertyDto);
+
+ assertNoInteraction();
+ }
+
+ @Test
+ public void insertProperty1() {
+ underTest.insertProperty(propertyDto);
+
+ assertNoInteraction();
+ }
+
+ @Test
+ public void deleteProjectProperty() {
+ underTest.deleteProjectProperty(null, null);
+
+ assertNoInteraction();
+
+ }
+
+ @Test
+ public void deleteProjectProperty1() {
+ underTest.deleteProjectProperty(null, null, dbSession);
+
+ assertNoInteraction();
+
+ }
+
+ @Test
+ public void deleteProjectProperties() {
+ underTest.deleteProjectProperties(null, null);
+
+ assertNoInteraction();
+
+ }
+
+ @Test
+ public void deleteProjectProperties1() {
+ underTest.deleteProjectProperties(null, null, dbSession);
+
+ assertNoInteraction();
+
+ }
+
+ @Test
+ public void deleteGlobalProperties() {
+ underTest.deleteGlobalProperties();
+
+ assertNoInteraction();
+
+ }
+
+ @Test
+ public void deleteGlobalProperty() {
+ underTest.deleteGlobalProperty(null);
+
+ assertNoInteraction();
+
+ }
+
+ @Test
+ public void deleteGlobalProperty1() {
+ underTest.deleteGlobalProperty(null, dbSession);
+
+ assertNoInteraction();
+
+ }
+
+ @Test
+ public void deleteAllProperties() {
+ underTest.deleteAllProperties(null);
+
+ assertNoInteraction();
+
+ }
+
+ @Test
+ public void insertGlobalProperties() {
+ underTest.insertGlobalProperties(null);
+
+ assertNoInteraction();
+
+ }
+
+ @Test
+ public void renamePropertyKey() {
+ underTest.renamePropertyKey(null, null);
+
+ assertNoInteraction();
+
+ }
+
+ @Test
+ public void updateProperties() {
+ underTest.updateProperties(null, null, null);
+
+ assertNoInteraction();
+
+ }
+
+ @Test
+ public void updateProperties1() {
+ underTest.updateProperties(null, null, null, dbSession);
+
+ assertNoInteraction();
+
+ }
+
+ @Test
+ public void setProperty() {
+ underTest.setProperty(oldPropertyDto);
+
+ assertNoInteraction();
+
+ }
+
+ private void assertNoInteraction() {
+ verifyNoMoreInteractions(myBatis, dbSession, propertyDto);
+ }
+}