Skip to content

Commit

Permalink
SONAR-8445 run DB migration of SQ 6.3 with Java
Browse files Browse the repository at this point in the history
add Java toolkit to run DB migrations
port last 3 DB migrations (ie. from current SQ 6.3) to this Java toolkit and make it run after Ruby migration
  • Loading branch information
sns-seb committed Dec 14, 2016
1 parent ea8ca62 commit ff76653
Show file tree
Hide file tree
Showing 67 changed files with 2,572 additions and 122 deletions.
@@ -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.platform.db.migration;

import org.sonar.core.platform.Module;
import org.sonar.server.platform.db.migration.engine.MigrationContainerPopulatorImpl;
import org.sonar.server.platform.db.migration.engine.MigrationEngineImpl;
import org.sonar.server.platform.db.migration.history.MigrationHistoryImpl;
import org.sonar.server.platform.db.migration.step.MigrationStepRegistryImpl;
import org.sonar.server.platform.db.migration.step.MigrationStepsProvider;

/**
* Defines the components for the migration engine. This does not include the
* {@link org.sonar.server.platform.db.migration.version.DbVersion} classes which are bundled together in
* {@link org.sonar.server.platform.db.migration.version.DbVersionModule}.
*/
public class MigrationEngineModule extends Module {
@Override
protected void configureModule() {
add(
// migration steps
MigrationStepRegistryImpl.class,
new MigrationStepsProvider(),

// history
MigrationHistoryImpl.class,

// engine
MigrationContainerPopulatorImpl.class,
MigrationEngineImpl.class);
}
}
@@ -0,0 +1,42 @@
/*
* 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.platform.db.migration.engine;

import org.sonar.core.platform.ContainerPopulator;

/**
* A dedicated container used to run DB migrations where all components are lazily instantiated.
* <p>
* As a new container will be created for each run of DB migrations, components in this container can safely be
* stateful.
* </p>
* <p>
* Lazy instantiation is convenient to instantiate {@link org.sonar.server.platform.db.migration.step.MigrationStep}
* classes only they really are to be executed.
* </p>
*/
public interface MigrationContainer extends ContainerPopulator.Container {

/**
* Cleans up resources after migration has run.
* <strong>This method must never fail.</strong>
*/
void cleanup();
}
@@ -0,0 +1,70 @@
/*
* 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.platform.db.migration.engine;

import org.picocontainer.ComponentAdapter;
import org.picocontainer.ComponentMonitor;
import org.picocontainer.DefaultPicoContainer;
import org.picocontainer.MutablePicoContainer;
import org.picocontainer.behaviors.OptInCaching;
import org.picocontainer.lifecycle.ReflectionLifecycleStrategy;
import org.picocontainer.monitors.NullComponentMonitor;
import org.sonar.api.config.PropertyDefinitions;
import org.sonar.core.platform.ComponentContainer;

import static java.util.Objects.requireNonNull;

public class MigrationContainerImpl extends ComponentContainer implements MigrationContainer {

public MigrationContainerImpl(ComponentContainer parent, MigrationContainerPopulator populator) {
super(createContainer(requireNonNull(parent)), parent.getComponentByType(PropertyDefinitions.class));

populateContainer(requireNonNull(populator));
startComponents();
}

private void populateContainer(MigrationContainerPopulator populator) {
populator.populateContainer(this);
}

/**
* Creates a PicContainer which extends the specified ComponentContainer <strong>but is not referenced in return</strong>.
*/
private static MutablePicoContainer createContainer(ComponentContainer parent) {
ComponentMonitor componentMonitor = new NullComponentMonitor();
ReflectionLifecycleStrategy lifecycleStrategy = new ReflectionLifecycleStrategy(componentMonitor, "start", "stop", "close") {
@Override
public boolean isLazy(ComponentAdapter<?> adapter) {
return true;
}
};
return new DefaultPicoContainer(new OptInCaching(), lifecycleStrategy, parent.getPicoContainer(), componentMonitor);
}

@Override
public void cleanup() {
stopComponents(true);
}

@Override
public String toString() {
return "MigrationContainerImpl";
}
}
@@ -0,0 +1,25 @@
/*
* 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.platform.db.migration.engine;

import org.sonar.core.platform.ContainerPopulator;

public interface MigrationContainerPopulator extends ContainerPopulator<MigrationContainer> {
}
@@ -0,0 +1,45 @@
/*
* 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.platform.db.migration.engine;

import org.sonar.server.platform.db.migration.step.MigrationStep;
import org.sonar.server.platform.db.migration.step.MigrationSteps;
import org.sonar.server.platform.db.migration.step.MigrationStepsExecutorImpl;

/**
* Responsible for:
* <ul>
* <li>adding all the {@link MigrationStep} classes to the container after building it</li>
* <li>adding dependencies for them to the container if there aren't already available in parent container</li>
* <li>adding the {@link MigrationStepsExecutorImpl} to the container</li>
* </ul>
*/
public class MigrationContainerPopulatorImpl implements MigrationContainerPopulator {
@Override
public void populateContainer(MigrationContainer container) {
container.add(MigrationStepsExecutorImpl.class);
populateFromMigrationSteps(container);
}

private static void populateFromMigrationSteps(MigrationContainer container) {
MigrationSteps migrationSteps = container.getComponentByType(MigrationSteps.class);
migrationSteps.readAll().forEach(step -> container.add(step.getStepClass()));
}
}
@@ -0,0 +1,33 @@
/*
* 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.platform.db.migration.engine;

/**
* This class is responsible for:
* <ul>
* <li>creating a dedicate container to run the migrations, populating it and starting it</li>
* <li>resolving the migration starting point</li>
* <li>starting the db migration execution</li>
* <li>stop the container and dispose of it</li>
* </ul>
*/
public interface MigrationEngine {
void execute();
}
@@ -0,0 +1,57 @@
/*
* 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.platform.db.migration.engine;

import java.util.Optional;
import org.sonar.core.platform.ComponentContainer;
import org.sonar.server.platform.db.migration.history.MigrationHistory;
import org.sonar.server.platform.db.migration.step.MigrationSteps;
import org.sonar.server.platform.db.migration.step.MigrationStepsExecutor;

public class MigrationEngineImpl implements MigrationEngine {
private final MigrationHistory migrationHistory;
private final ComponentContainer serverContainer;
private final MigrationContainerPopulator populator;
private final MigrationSteps migrationSteps;

public MigrationEngineImpl(MigrationHistory migrationHistory, ComponentContainer serverContainer, MigrationContainerPopulator populator, MigrationSteps migrationSteps) {
this.migrationHistory = migrationHistory;
this.serverContainer = serverContainer;
this.populator = populator;
this.migrationSteps = migrationSteps;
}

@Override
public void execute() {
MigrationContainer migrationContainer = new MigrationContainerImpl(serverContainer, populator);

try {
MigrationStepsExecutor stepsExecutor = migrationContainer.getComponentByType(MigrationStepsExecutor.class);
Optional<Long> lastMigrationNumber = migrationHistory.getLastMigrationNumber();
if (lastMigrationNumber.isPresent()) {
stepsExecutor.execute(migrationSteps.readFrom(lastMigrationNumber.get() + 1));
} else {
stepsExecutor.execute(migrationSteps.readAll());
}
} finally {
migrationContainer.cleanup();
}
}
}
@@ -0,0 +1,24 @@
/*
* 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.platform.db.migration.engine;

import javax.annotation.ParametersAreNonnullByDefault;

0 comments on commit ff76653

Please sign in to comment.