aboutsummaryrefslogtreecommitdiffstats
path: root/server/sonar-db-dao
diff options
context:
space:
mode:
authorDuarte Meneses <duarte.meneses@sonarsource.com>2022-02-01 15:16:25 -0600
committersonartech <sonartech@sonarsource.com>2022-02-22 20:02:46 +0000
commit60c1a4038e041a342dda9810e6fd761d66b01bdb (patch)
tree0e76b4252e4d7d257cf4ddcb6f081996bb1e03ab /server/sonar-db-dao
parent9694d4113bf401b84e86e0223dbea8f5339388d8 (diff)
downloadsonarqube-60c1a4038e041a342dda9810e6fd761d66b01bdb.tar.gz
sonarqube-60c1a4038e041a342dda9810e6fd761d66b01bdb.zip
SONAR-15994 Migrate Sonarqube IOC framework from Pico to Spring
Diffstat (limited to 'server/sonar-db-dao')
-rw-r--r--server/sonar-db-dao/src/main/java/org/sonar/db/MyBatis.java3
-rw-r--r--server/sonar-db-dao/src/main/java/org/sonar/db/audit/NoOpAuditPersister.java2
-rw-r--r--server/sonar-db-dao/src/main/java/org/sonar/db/property/InternalPropertiesDao.java12
-rw-r--r--server/sonar-db-dao/src/test/java/org/sonar/db/DaoModuleTest.java6
-rw-r--r--server/sonar-db-dao/src/test/java/org/sonar/db/MyBatisTest.java6
-rw-r--r--server/sonar-db-dao/src/testFixtures/java/org/sonar/db/DbTester.java18
-rw-r--r--server/sonar-db-dao/src/testFixtures/java/org/sonar/db/FastSpringContainer.java104
-rw-r--r--server/sonar-db-dao/src/testFixtures/java/org/sonar/db/SQDatabase.java49
8 files changed, 145 insertions, 55 deletions
diff --git a/server/sonar-db-dao/src/main/java/org/sonar/db/MyBatis.java b/server/sonar-db-dao/src/main/java/org/sonar/db/MyBatis.java
index bf75d7a5965..d128c08158f 100644
--- a/server/sonar-db-dao/src/main/java/org/sonar/db/MyBatis.java
+++ b/server/sonar-db-dao/src/main/java/org/sonar/db/MyBatis.java
@@ -157,16 +157,19 @@ import org.sonar.db.user.UserTokenDto;
import org.sonar.db.user.UserTokenMapper;
import org.sonar.db.webhook.WebhookDeliveryMapper;
import org.sonar.db.webhook.WebhookMapper;
+import org.springframework.beans.factory.annotation.Autowired;
public class MyBatis implements Startable {
private final List<MyBatisConfExtension> confExtensions;
private final Database database;
private SqlSessionFactory sessionFactory;
+ @Autowired(required = false)
public MyBatis(Database database) {
this(database, null);
}
+ @Autowired(required = false)
public MyBatis(Database database, @Nullable MyBatisConfExtension[] confExtensions) {
this.confExtensions = confExtensions == null ? Collections.emptyList() : Arrays.asList(confExtensions);
this.database = database;
diff --git a/server/sonar-db-dao/src/main/java/org/sonar/db/audit/NoOpAuditPersister.java b/server/sonar-db-dao/src/main/java/org/sonar/db/audit/NoOpAuditPersister.java
index eb1d6a09169..2567bfbc8f0 100644
--- a/server/sonar-db-dao/src/main/java/org/sonar/db/audit/NoOpAuditPersister.java
+++ b/server/sonar-db-dao/src/main/java/org/sonar/db/audit/NoOpAuditPersister.java
@@ -19,6 +19,7 @@
*/
package org.sonar.db.audit;
+import javax.annotation.Priority;
import org.sonar.db.DbSession;
import org.sonar.db.audit.model.ComponentKeyNewValue;
import org.sonar.db.audit.model.ComponentNewValue;
@@ -38,6 +39,7 @@ import org.sonar.db.audit.model.UserPermissionNewValue;
import org.sonar.db.audit.model.UserTokenNewValue;
import org.sonar.db.audit.model.WebhookNewValue;
+@Priority(2)
public class NoOpAuditPersister implements AuditPersister {
@Override
public void addUserGroup(DbSession dbSession, UserGroupNewValue newValue) {
diff --git a/server/sonar-db-dao/src/main/java/org/sonar/db/property/InternalPropertiesDao.java b/server/sonar-db-dao/src/main/java/org/sonar/db/property/InternalPropertiesDao.java
index 235b832177a..132e5b08c93 100644
--- a/server/sonar-db-dao/src/main/java/org/sonar/db/property/InternalPropertiesDao.java
+++ b/server/sonar-db-dao/src/main/java/org/sonar/db/property/InternalPropertiesDao.java
@@ -57,11 +57,7 @@ public class InternalPropertiesDao implements Dao {
private static final Optional<String> OPTIONAL_OF_EMPTY_STRING = Optional.of("");
private final System2 system2;
- private AuditPersister auditPersister;
-
- public InternalPropertiesDao(System2 system2) {
- this.system2 = system2;
- }
+ private final AuditPersister auditPersister;
public InternalPropertiesDao(System2 system2, AuditPersister auditPersister) {
this.system2 = system2;
@@ -89,7 +85,7 @@ public class InternalPropertiesDao implements Dao {
mapper.insertAsText(key, value, now);
}
- if (auditPersister != null && auditPersister.isTrackedProperty(key)) {
+ if (auditPersister.isTrackedProperty(key)) {
if (deletedRows > 0) {
auditPersister.updateProperty(dbSession, new PropertyNewValue(key, value), false);
} else {
@@ -112,7 +108,7 @@ public class InternalPropertiesDao implements Dao {
int deletedRows = mapper.deleteByKey(key);
mapper.insertAsEmpty(key, system2.now());
- if (auditPersister != null && auditPersister.isTrackedProperty(key)) {
+ if (auditPersister.isTrackedProperty(key)) {
if (deletedRows > 0) {
auditPersister.updateProperty(dbSession, new PropertyNewValue(key, ""), false);
} else {
@@ -124,7 +120,7 @@ public class InternalPropertiesDao implements Dao {
public void delete(DbSession dbSession, String key) {
int deletedRows = getMapper(dbSession).deleteByKey(key);
- if (auditPersister != null && deletedRows > 0 && auditPersister.isTrackedProperty(key)) {
+ if (deletedRows > 0 && auditPersister.isTrackedProperty(key)) {
auditPersister.deleteProperty(dbSession, new PropertyNewValue(key), false);
}
}
diff --git a/server/sonar-db-dao/src/test/java/org/sonar/db/DaoModuleTest.java b/server/sonar-db-dao/src/test/java/org/sonar/db/DaoModuleTest.java
index b312959a5ce..96f261556af 100644
--- a/server/sonar-db-dao/src/test/java/org/sonar/db/DaoModuleTest.java
+++ b/server/sonar-db-dao/src/test/java/org/sonar/db/DaoModuleTest.java
@@ -20,15 +20,15 @@
package org.sonar.db;
import org.junit.Test;
-import org.sonar.core.platform.ComponentContainer;
+import org.sonar.core.platform.ListContainer;
import static org.assertj.core.api.Assertions.assertThat;
public class DaoModuleTest {
@Test
public void verify_count_of_added_components() {
- ComponentContainer container = new ComponentContainer();
+ ListContainer container = new ListContainer();
new DaoModule().configure(container);
- assertThat(container.size()).isGreaterThan(1);
+ assertThat(container.getAddedObjects()).hasSizeGreaterThan(1);
}
}
diff --git a/server/sonar-db-dao/src/test/java/org/sonar/db/MyBatisTest.java b/server/sonar-db-dao/src/test/java/org/sonar/db/MyBatisTest.java
index 63b11946b31..4414ef3309a 100644
--- a/server/sonar-db-dao/src/test/java/org/sonar/db/MyBatisTest.java
+++ b/server/sonar-db-dao/src/test/java/org/sonar/db/MyBatisTest.java
@@ -21,7 +21,6 @@ package org.sonar.db;
import org.apache.ibatis.session.Configuration;
import org.hamcrest.core.Is;
-import org.junit.After;
import org.junit.AfterClass;
import org.junit.BeforeClass;
import org.junit.Test;
@@ -46,11 +45,6 @@ public class MyBatisTest {
private MyBatis underTest = new MyBatis(database);
- @After
- public void tearDown() {
- underTest.stop();
- }
-
@Test
public void shouldConfigureMyBatis() {
underTest.start();
diff --git a/server/sonar-db-dao/src/testFixtures/java/org/sonar/db/DbTester.java b/server/sonar-db-dao/src/testFixtures/java/org/sonar/db/DbTester.java
index 9e3e83f17e8..d8d9e8bb483 100644
--- a/server/sonar-db-dao/src/testFixtures/java/org/sonar/db/DbTester.java
+++ b/server/sonar-db-dao/src/testFixtures/java/org/sonar/db/DbTester.java
@@ -28,7 +28,6 @@ import java.util.Map;
import java.util.stream.Stream;
import javax.annotation.Nullable;
import org.apache.commons.dbcp2.BasicDataSource;
-import org.picocontainer.containers.TransientPicoContainer;
import org.sonar.api.utils.System2;
import org.sonar.core.util.SequenceUuidFactory;
import org.sonar.core.util.UuidFactory;
@@ -145,15 +144,16 @@ public class DbTester extends AbstractDbTester<TestDbImpl> {
}
private void initDbClient() {
- TransientPicoContainer ioc = new TransientPicoContainer();
- ioc.addComponent(auditPersister);
- ioc.addComponent(db.getMyBatis());
- ioc.addComponent(system2);
- ioc.addComponent(uuidFactory);
- for (Class daoClass : DaoModule.classes()) {
- ioc.addComponent(daoClass);
+ FastSpringContainer ioc = new FastSpringContainer();
+ ioc.add(auditPersister);
+ ioc.add(db.getMyBatis());
+ ioc.add(system2);
+ ioc.add(uuidFactory);
+ for (Class<?> daoClass : DaoModule.classes()) {
+ ioc.add(daoClass);
}
- List<Dao> daos = ioc.getComponents(Dao.class);
+ ioc.start();
+ List<Dao> daos = ioc.getComponentsByType(Dao.class);
client = new DbClient(db.getDatabase(), db.getMyBatis(), new TestDBSessions(db.getMyBatis()), daos.toArray(new Dao[daos.size()]));
}
diff --git a/server/sonar-db-dao/src/testFixtures/java/org/sonar/db/FastSpringContainer.java b/server/sonar-db-dao/src/testFixtures/java/org/sonar/db/FastSpringContainer.java
new file mode 100644
index 00000000000..47b5cded6b8
--- /dev/null
+++ b/server/sonar-db-dao/src/testFixtures/java/org/sonar/db/FastSpringContainer.java
@@ -0,0 +1,104 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2022 SonarSource SA
+ * mailto:info 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.db;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Optional;
+import java.util.function.Supplier;
+import org.sonar.core.platform.Container;
+import org.sonar.core.platform.StartableBeanPostProcessor;
+import org.springframework.beans.factory.NoSuchBeanDefinitionException;
+import org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory;
+import org.springframework.context.support.GenericApplicationContext;
+
+/**
+ * A fast(er) Spring container. It doesn't support several things that are supported in
+ * {@link org.sonar.core.platform.SpringComponentContainer}, such as:
+ * <ul>
+ * <li>Adding extensions</li>
+ * <li>Use of annotations</li>
+ * <li>Adding duplicate components from different Classloaders</li>
+ * <li>Hierarchy of container</li>
+ * <li>Different initialization strategies</li>
+ * </ul>
+ */
+public class FastSpringContainer implements Container {
+ private final GenericApplicationContext context = new GenericApplicationContext();
+
+ public FastSpringContainer() {
+ ((AbstractAutowireCapableBeanFactory) context.getBeanFactory()).setParameterNameDiscoverer(null);
+ add(StartableBeanPostProcessor.class);
+ }
+
+ @Override
+ public Container add(Object... objects) {
+ for (Object o : objects) {
+ if (o instanceof Class) {
+ Class<?> clazz = (Class<?>) o;
+ context.registerBean(clazz.getName(), clazz);
+ } else {
+ registerInstance(o);
+ }
+ }
+ return this;
+ }
+
+ public void start() {
+ context.refresh();
+ }
+
+ private <T> void registerInstance(T instance) {
+ Supplier<T> supplier = () -> instance;
+ Class<T> clazz = (Class<T>) instance.getClass();
+ context.registerBean(clazz.getName(), clazz, supplier);
+ }
+
+ @Override
+ public <T> T getComponentByType(Class<T> type) {
+ try {
+ return context.getBean(type);
+ } catch (Exception t) {
+ throw new IllegalStateException("Unable to load component " + type, t);
+ }
+ }
+
+ @Override public <T> Optional<T> getOptionalComponentByType(Class<T> type) {
+ try {
+ return Optional.of(context.getBean(type));
+ } catch (NoSuchBeanDefinitionException t) {
+ return Optional.empty();
+ }
+ }
+
+ @Override
+ public <T> List<T> getComponentsByType(Class<T> type) {
+ try {
+ return new ArrayList<>(context.getBeansOfType(type).values());
+ } catch (Exception t) {
+ throw new IllegalStateException("Unable to load components " + type, t);
+ }
+ }
+
+ @Override
+ public Container getParent() {
+ return null;
+ }
+}
diff --git a/server/sonar-db-dao/src/testFixtures/java/org/sonar/db/SQDatabase.java b/server/sonar-db-dao/src/testFixtures/java/org/sonar/db/SQDatabase.java
index 169bf9763c2..dc515bfcd4f 100644
--- a/server/sonar-db-dao/src/testFixtures/java/org/sonar/db/SQDatabase.java
+++ b/server/sonar-db-dao/src/testFixtures/java/org/sonar/db/SQDatabase.java
@@ -35,7 +35,8 @@ import org.sonar.api.internal.SonarRuntimeImpl;
import org.sonar.api.utils.System2;
import org.sonar.api.utils.Version;
import org.sonar.api.utils.log.Loggers;
-import org.sonar.core.platform.ComponentContainer;
+import org.sonar.core.platform.Container;
+import org.sonar.core.platform.SpringComponentContainer;
import org.sonar.core.util.UuidFactoryFast;
import org.sonar.core.util.logs.Profiler;
import org.sonar.db.dialect.Dialect;
@@ -43,15 +44,12 @@ import org.sonar.process.logging.LogbackHelper;
import org.sonar.server.platform.db.migration.MigrationConfigurationModule;
import org.sonar.server.platform.db.migration.engine.MigrationContainer;
import org.sonar.server.platform.db.migration.engine.MigrationContainerImpl;
-import org.sonar.server.platform.db.migration.engine.MigrationContainerPopulator;
-import org.sonar.server.platform.db.migration.engine.MigrationContainerPopulatorImpl;
import org.sonar.server.platform.db.migration.history.MigrationHistoryTableImpl;
import org.sonar.server.platform.db.migration.step.MigrationStep;
import org.sonar.server.platform.db.migration.step.MigrationStepExecutionException;
import org.sonar.server.platform.db.migration.step.MigrationSteps;
import org.sonar.server.platform.db.migration.step.MigrationStepsExecutor;
import org.sonar.server.platform.db.migration.step.RegisteredMigrationStep;
-import org.sonar.server.platform.db.migration.version.DbVersion;
import static com.google.common.base.Preconditions.checkState;
@@ -101,29 +99,23 @@ public class SQDatabase extends DefaultDatabase {
}
}
- public static final class H2MigrationContainerPopulator extends MigrationContainerPopulatorImpl {
- public H2MigrationContainerPopulator(DbVersion... dbVersions) {
- super(H2StepExecutor.class, dbVersions);
- }
- }
-
public static final class H2StepExecutor implements MigrationStepsExecutor {
private static final String STEP_START_PATTERN = "{}...";
private static final String STEP_STOP_PATTERN = "{}: {}";
- private final ComponentContainer componentContainer;
+ private final Container container;
- public H2StepExecutor(ComponentContainer componentContainer) {
- this.componentContainer = componentContainer;
+ public H2StepExecutor(Container container) {
+ this.container = container;
}
@Override
public void execute(List<RegisteredMigrationStep> steps) {
- steps.forEach(step -> execute(step, componentContainer));
+ steps.forEach(step -> execute(step, container));
}
- private void execute(RegisteredMigrationStep step, ComponentContainer componentContainer) {
- MigrationStep migrationStep = componentContainer.getComponentByType(step.getStepClass());
+ private void execute(RegisteredMigrationStep step, Container container) {
+ MigrationStep migrationStep = container.getComponentByType(step.getStepClass());
checkState(migrationStep != null, "Can not find instance of " + step.getStepClass());
execute(step, migrationStep);
@@ -149,24 +141,23 @@ public class SQDatabase extends DefaultDatabase {
}
private void executeDbMigrations(NoopDatabase noopDatabase) {
- ComponentContainer parentContainer = new ComponentContainer();
- parentContainer.add(noopDatabase);
- parentContainer.add(H2MigrationContainerPopulator.class);
+ SpringComponentContainer container = new SpringComponentContainer();
+ container.add(noopDatabase);
MigrationConfigurationModule migrationConfigurationModule = new MigrationConfigurationModule();
- migrationConfigurationModule.configure(parentContainer);
+ migrationConfigurationModule.configure(container);
// dependencies required by DB migrations
- parentContainer.add(SonarRuntimeImpl.forSonarQube(Version.create(8, 0), SonarQubeSide.SERVER, SonarEdition.COMMUNITY));
- parentContainer.add(UuidFactoryFast.getInstance());
- parentContainer.add(System2.INSTANCE);
- parentContainer.add(MapSettings.class);
+ container.add(SonarRuntimeImpl.forSonarQube(Version.create(8, 0), SonarQubeSide.SERVER, SonarEdition.COMMUNITY));
+ container.add(UuidFactoryFast.getInstance());
+ container.add(System2.INSTANCE);
+ container.add(MapSettings.class);
- parentContainer.startComponents();
-
- MigrationContainer migrationContainer = new MigrationContainerImpl(parentContainer, parentContainer.getComponentByType(MigrationContainerPopulator.class));
+ container.startComponents();
+ MigrationContainer migrationContainer = new MigrationContainerImpl(container, H2StepExecutor.class);
MigrationSteps migrationSteps = migrationContainer.getComponentByType(MigrationSteps.class);
- migrationContainer.getComponentByType(MigrationStepsExecutor.class)
- .execute(migrationSteps.readAll());
+ MigrationStepsExecutor executor = migrationContainer.getComponentByType(MigrationStepsExecutor.class);
+
+ executor.execute(migrationSteps.readAll());
}
private void createMigrationHistoryTable(NoopDatabase noopDatabase) {