/* * SonarQube * Copyright (C) 2009-2017 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.server.platform.db.migration.step; import java.util.stream.Stream; import org.sonar.api.utils.log.Logger; import org.sonar.api.utils.log.Loggers; import org.sonar.core.util.logs.Profiler; import org.sonar.server.platform.db.migration.engine.MigrationContainer; import org.sonar.server.platform.db.migration.history.MigrationHistory; import static com.google.common.base.Preconditions.checkState; public class MigrationStepsExecutorImpl implements MigrationStepsExecutor { private static final Logger LOGGER = Loggers.get("DbMigrations"); private static final String GLOBAL_START_MESSAGE = "Executing DB migrations..."; private static final String GLOBAL_END_MESSAGE = "Executed DB migrations: {}"; private static final String STEP_START_PATTERN = "{}..."; private static final String STEP_STOP_PATTERN = "{}: {}"; private final MigrationContainer migrationContainer; private final MigrationHistory migrationHistory; public MigrationStepsExecutorImpl(MigrationContainer migrationContainer, MigrationHistory migrationHistory) { this.migrationContainer = migrationContainer; this.migrationHistory = migrationHistory; } @Override public void execute(Stream<RegisteredMigrationStep> steps) { Profiler globalProfiler = Profiler.create(LOGGER); globalProfiler.startInfo(GLOBAL_START_MESSAGE); boolean allStepsExecuted = false; try { steps.forEachOrdered(this::execute); allStepsExecuted = true; } finally { if (allStepsExecuted) { globalProfiler.stopInfo(GLOBAL_END_MESSAGE, "success"); } else { globalProfiler.stopError(GLOBAL_END_MESSAGE, "failure"); } } } private void execute(RegisteredMigrationStep step) { MigrationStep migrationStep = migrationContainer.getComponentByType(step.getStepClass()); checkState(migrationStep != null, "Can not find instance of " + step.getStepClass()); execute(step, migrationStep); } private void execute(RegisteredMigrationStep step, MigrationStep migrationStep) { Profiler stepProfiler = Profiler.create(LOGGER); stepProfiler.startInfo(STEP_START_PATTERN, step); boolean done = false; try { migrationStep.execute(); migrationHistory.done(step); done = true; } catch (Exception e) { throw new MigrationStepExecutionException(step, e); } finally { if (done) { stepProfiler.stopInfo(STEP_STOP_PATTERN, step, "success"); } else { stepProfiler.stopError(STEP_STOP_PATTERN, step, "failure"); } } } }