import org.sonar.api.config.Settings;
import org.sonar.core.component.ComponentDto;
import org.sonar.core.computation.db.AnalysisReportDto;
-import org.sonar.core.computation.dbcleaner.ProjectPurgeTask;
+import org.sonar.server.computation.dbcleaner.ProjectPurgeTask;
import org.sonar.core.persistence.DbSession;
import org.sonar.core.purge.PurgeConfiguration;
import org.sonar.server.issue.index.IssueIndex;
--- /dev/null
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2014 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube 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.
+ *
+ * SonarQube 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.computation.dbcleaner;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.sonar.api.CoreProperties;
+import org.sonar.api.ServerComponent;
+import org.sonar.api.config.Settings;
+import org.sonar.api.utils.TimeUtils;
+import org.sonar.server.computation.dbcleaner.period.DefaultPeriodCleaner;
+import org.sonar.core.persistence.DbSession;
+import org.sonar.core.purge.PurgeConfiguration;
+import org.sonar.core.purge.PurgeDao;
+import org.sonar.core.purge.PurgeProfiler;
+
+import java.util.List;
+
+public class ProjectPurgeTask implements ServerComponent {
+ private static final Logger LOG = LoggerFactory.getLogger(ProjectPurgeTask.class);
+ private final PurgeProfiler profiler;
+ private final PurgeDao purgeDao;
+ private final DefaultPeriodCleaner periodCleaner;
+
+ public ProjectPurgeTask(PurgeDao purgeDao, DefaultPeriodCleaner periodCleaner, PurgeProfiler profiler) {
+ this.purgeDao = purgeDao;
+ this.periodCleaner = periodCleaner;
+ this.profiler = profiler;
+ }
+
+ public ProjectPurgeTask purge(DbSession session, PurgeConfiguration configuration, Settings settings) {
+ long start = System.currentTimeMillis();
+ profiler.reset();
+ cleanHistoricalData(session, configuration.rootProjectId(), settings);
+ doPurge(session, configuration);
+ if (settings.getBoolean(CoreProperties.PROFILING_LOG_PROPERTY)) {
+ long duration = System.currentTimeMillis() - start;
+ LOG.info("\n -------- Profiling for purge: " + TimeUtils.formatDuration(duration) + " --------\n");
+ profiler.dump(duration, LOG);
+ LOG.info("\n -------- End of profiling for purge --------\n");
+ }
+ return this;
+ }
+
+ private void cleanHistoricalData(DbSession session, long resourceId, Settings settings) {
+ try {
+ periodCleaner.clean(session, resourceId, settings);
+ } catch (Exception e) {
+ // purge errors must no fail the batch
+ LOG.error("Fail to clean historical data [id=" + resourceId + "]", e);
+ }
+ }
+
+ private void doPurge(DbSession session, PurgeConfiguration configuration) {
+ try {
+ purgeDao.purge(session, configuration);
+ } catch (Exception e) {
+ // purge errors must no fail the report analysis
+ LOG.error("Fail to purge data [id=" + configuration.rootProjectId() + "]", e);
+ }
+ }
+
+ public List<String> findUuidsToDisable(DbSession session, Long projectId) {
+ return purgeDao.selectPurgeableFiles(session, projectId);
+ }
+}
import org.sonar.api.utils.UriReader;
import org.sonar.api.utils.internal.TempFolderCleaner;
import org.sonar.core.component.SnapshotPerspectives;
-import org.sonar.core.computation.dbcleaner.DefaultPurgeTask;
-import org.sonar.core.computation.dbcleaner.ProjectPurgeTask;
-import org.sonar.core.computation.dbcleaner.period.DefaultPeriodCleaner;
+import org.sonar.server.computation.dbcleaner.DefaultPurgeTask;
+import org.sonar.server.computation.dbcleaner.ProjectPurgeTask;
+import org.sonar.server.computation.dbcleaner.period.DefaultPeriodCleaner;
import org.sonar.core.config.CorePropertyDefinitions;
import org.sonar.core.config.Logback;
import org.sonar.core.i18n.DefaultI18n;
import org.sonar.core.component.SnapshotDto;
import org.sonar.core.computation.db.AnalysisReportDto;
import org.sonar.core.computation.db.AnalysisReportDto.Status;
-import org.sonar.core.computation.dbcleaner.DbCleanerConstants;
-import org.sonar.core.computation.dbcleaner.ProjectPurgeTask;
+import org.sonar.server.computation.dbcleaner.DbCleanerConstants;
+import org.sonar.server.computation.dbcleaner.ProjectPurgeTask;
import org.sonar.core.persistence.DbSession;
import org.sonar.core.persistence.MyBatis;
import org.sonar.core.properties.PropertyDto;
import org.sonar.api.config.Settings;
import org.sonar.core.component.ComponentDto;
import org.sonar.core.computation.db.AnalysisReportDto;
-import org.sonar.core.computation.dbcleaner.ProjectPurgeTask;
+import org.sonar.server.computation.dbcleaner.ProjectPurgeTask;
import org.sonar.core.persistence.DbSession;
import org.sonar.core.purge.PurgeConfiguration;
import org.sonar.server.issue.index.IssueIndex;
--- /dev/null
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2014 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube 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.
+ *
+ * SonarQube 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.computation.dbcleaner;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.slf4j.Logger;
+import org.sonar.api.CoreProperties;
+import org.sonar.api.config.Settings;
+import org.sonar.server.computation.dbcleaner.period.DefaultPeriodCleaner;
+import org.sonar.core.persistence.DbSession;
+import org.sonar.core.purge.PurgeConfiguration;
+import org.sonar.core.purge.PurgeDao;
+import org.sonar.core.purge.PurgeProfiler;
+
+import static org.mockito.Matchers.any;
+import static org.mockito.Matchers.anyLong;
+import static org.mockito.Mockito.*;
+
+public class ProjectPurgeTaskTest {
+
+ private ProjectPurgeTask sut;
+ private PurgeDao dao;
+ private PurgeProfiler profiler;
+ private DefaultPeriodCleaner periodCleaner;
+
+ @Before
+ public void before() throws Exception {
+ this.dao = mock(PurgeDao.class);
+ this.profiler = mock(PurgeProfiler.class);
+ this.periodCleaner = mock(DefaultPeriodCleaner.class);
+
+ this.sut = new ProjectPurgeTask(dao, periodCleaner, profiler);
+ }
+
+ @Test
+ public void no_profiling_when_property_is_false() throws Exception {
+ Settings settings = mock(Settings.class);
+ when(settings.getBoolean(CoreProperties.PROFILING_LOG_PROPERTY)).thenReturn(false);
+
+ sut.purge(mock(DbSession.class), mock(PurgeConfiguration.class), settings);
+
+ verify(profiler, never()).dump(anyLong(), any(Logger.class));
+ }
+
+ @Test
+ public void profiling_when_property_is_true() throws Exception {
+ Settings settings = mock(Settings.class);
+ when(settings.getBoolean(CoreProperties.PROFILING_LOG_PROPERTY)).thenReturn(true);
+
+ sut.purge(mock(DbSession.class), mock(PurgeConfiguration.class), settings);
+
+ verify(profiler, times(1)).dump(anyLong(), any(Logger.class));
+ }
+
+ @Test
+ public void if_dao_purge_fails_it_should_not_interrupt_program_execution() throws Exception {
+ doThrow(RuntimeException.class).when(dao).purge(any(DbSession.class), any(PurgeConfiguration.class));
+
+ sut.purge(mock(DbSession.class), mock(PurgeConfiguration.class), mock(Settings.class));
+
+ verify(dao, times(1)).purge(any(DbSession.class), any(PurgeConfiguration.class));
+ }
+
+ @Test
+ public void if_profiler_cleaning_fails_it_should_not_interrupt_program_execution() throws Exception {
+ doThrow(RuntimeException.class).when(periodCleaner).clean(any(DbSession.class), anyLong(), any(Settings.class));
+
+ sut.purge(mock(DbSession.class), mock(PurgeConfiguration.class), mock(Settings.class));
+
+ verify(periodCleaner, times(1)).clean(any(DbSession.class), anyLong(), any(Settings.class));
+ }
+}
import org.sonar.batch.maven.MavenProjectConverter;
import org.sonar.batch.scm.ScmConfiguration;
import org.sonar.batch.scm.ScmSensor;
-import org.sonar.core.computation.dbcleaner.DefaultPurgeTask;
-import org.sonar.core.computation.dbcleaner.period.DefaultPeriodCleaner;
+import org.sonar.server.computation.dbcleaner.DefaultPurgeTask;
+import org.sonar.server.computation.dbcleaner.period.DefaultPeriodCleaner;
import org.sonar.core.config.CorePropertyDefinitions;
import java.util.Collection;
+++ /dev/null
-/*
- * SonarQube, open source software quality management tool.
- * Copyright (C) 2008-2014 SonarSource
- * mailto:contact AT sonarsource DOT com
- *
- * SonarQube 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.
- *
- * SonarQube 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.core.computation.dbcleaner;
-
-import org.sonar.api.CoreProperties;
-import org.sonar.api.PropertyType;
-import org.sonar.api.config.PropertyDefinition;
-import org.sonar.api.resources.Qualifiers;
-
-import java.util.Arrays;
-import java.util.List;
-
-public final class DataCleanerProperties {
-
- private DataCleanerProperties() {
- }
-
- public static List<PropertyDefinition> all() {
- return Arrays.asList(
- PropertyDefinition.builder(DbCleanerConstants.PROPERTY_CLEAN_DIRECTORY)
- .defaultValue("true")
- .name("Clean directory/package history")
- .description("If set to true, no history is kept at directory/package level. Setting this to false can cause database bloat.")
- .type(PropertyType.BOOLEAN)
- .onQualifiers(Qualifiers.PROJECT)
- .category(CoreProperties.CATEGORY_GENERAL)
- .subCategory(CoreProperties.SUBCATEGORY_DATABASE_CLEANER)
- .index(1)
- .build(),
-
- PropertyDefinition.builder(DbCleanerConstants.DAYS_BEFORE_DELETING_CLOSED_ISSUES)
- .defaultValue("30")
- .name("Delete closed issues after")
- .description("Issues that have been closed for more than this number of days will be deleted.")
- .type(PropertyType.INTEGER)
- .onQualifiers(Qualifiers.PROJECT)
- .category(CoreProperties.CATEGORY_GENERAL)
- .subCategory(CoreProperties.SUBCATEGORY_DATABASE_CLEANER)
- .index(2)
- .build(),
-
- PropertyDefinition.builder(DbCleanerConstants.HOURS_BEFORE_KEEPING_ONLY_ONE_SNAPSHOT_BY_DAY)
- .defaultValue("24")
- .name("Keep only one snapshot a day after")
- .description("After this number of hours, if there are several snapshots during the same day, "
- + "the DbCleaner keeps the most recent one and fully deletes the other ones.")
- .type(PropertyType.INTEGER)
- .onQualifiers(Qualifiers.PROJECT)
- .category(CoreProperties.CATEGORY_GENERAL)
- .subCategory(CoreProperties.SUBCATEGORY_DATABASE_CLEANER)
- .index(3)
- .build(),
-
- PropertyDefinition.builder(DbCleanerConstants.WEEKS_BEFORE_KEEPING_ONLY_ONE_SNAPSHOT_BY_WEEK)
- .defaultValue("4")
- .name("Keep only one snapshot a week after")
- .description("After this number of weeks, if there are several snapshots during the same week, "
- + "the DbCleaner keeps the most recent one and fully deletes the other ones")
- .type(PropertyType.INTEGER)
- .onQualifiers(Qualifiers.PROJECT)
- .category(CoreProperties.CATEGORY_GENERAL)
- .subCategory(CoreProperties.SUBCATEGORY_DATABASE_CLEANER)
- .index(4)
- .build(),
-
- PropertyDefinition.builder(DbCleanerConstants.WEEKS_BEFORE_KEEPING_ONLY_ONE_SNAPSHOT_BY_MONTH)
- .defaultValue("52")
- .name("Keep only one snapshot a month after")
- .description("After this number of weeks, if there are several snapshots during the same month, "
- + "the DbCleaner keeps the most recent one and fully deletes the other ones.")
- .type(PropertyType.INTEGER)
- .onQualifiers(Qualifiers.PROJECT)
- .category(CoreProperties.CATEGORY_GENERAL)
- .subCategory(CoreProperties.SUBCATEGORY_DATABASE_CLEANER)
- .index(5)
- .build(),
-
- PropertyDefinition.builder(DbCleanerConstants.WEEKS_BEFORE_DELETING_ALL_SNAPSHOTS)
- .defaultValue("260")
- .name("Delete all snapshots after")
- .description("After this number of weeks, all snapshots are fully deleted.")
- .type(PropertyType.INTEGER)
- .onQualifiers(Qualifiers.PROJECT)
- .category(CoreProperties.CATEGORY_GENERAL)
- .subCategory(CoreProperties.SUBCATEGORY_DATABASE_CLEANER)
- .index(6)
- .build()
- );
- }
-}
+++ /dev/null
-/*
- * SonarQube, open source software quality management tool.
- * Copyright (C) 2008-2014 SonarSource
- * mailto:contact AT sonarsource DOT com
- *
- * SonarQube 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.
- *
- * SonarQube 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.core.computation.dbcleaner;
-
-public interface DbCleanerConstants {
-
- String PLUGIN_KEY = "dbcleaner";
- String PLUGIN_NAME = "DbCleaner";
- String PROPERTY_CLEAN_DIRECTORY = "sonar.dbcleaner.cleanDirectory";
-
- String HOURS_BEFORE_KEEPING_ONLY_ONE_SNAPSHOT_BY_DAY = "sonar.dbcleaner.hoursBeforeKeepingOnlyOneSnapshotByDay";
- String WEEKS_BEFORE_KEEPING_ONLY_ONE_SNAPSHOT_BY_WEEK = "sonar.dbcleaner.weeksBeforeKeepingOnlyOneSnapshotByWeek";
- String WEEKS_BEFORE_KEEPING_ONLY_ONE_SNAPSHOT_BY_MONTH = "sonar.dbcleaner.weeksBeforeKeepingOnlyOneSnapshotByMonth";
- String WEEKS_BEFORE_DELETING_ALL_SNAPSHOTS = "sonar.dbcleaner.weeksBeforeDeletingAllSnapshots";
- String DAYS_BEFORE_DELETING_CLOSED_ISSUES = "sonar.dbcleaner.daysBeforeDeletingClosedIssues";
-}
+++ /dev/null
-/*
- * SonarQube, open source software quality management tool.
- * Copyright (C) 2008-2014 SonarSource
- * mailto:contact AT sonarsource DOT com
- *
- * SonarQube 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.
- *
- * SonarQube 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.core.computation.dbcleaner;
-
-import com.google.common.annotations.VisibleForTesting;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.sonar.api.CoreProperties;
-import org.sonar.api.config.Settings;
-import org.sonar.api.resources.Qualifiers;
-import org.sonar.api.utils.TimeUtils;
-import org.sonar.core.computation.dbcleaner.period.DefaultPeriodCleaner;
-import org.sonar.core.purge.IdUuidPair;
-import org.sonar.core.purge.PurgeConfiguration;
-import org.sonar.core.purge.PurgeDao;
-import org.sonar.core.purge.PurgeProfiler;
-import org.sonar.core.resource.ResourceDao;
-import org.sonar.core.resource.ResourceDto;
-import org.sonar.plugins.dbcleaner.api.PurgeTask;
-
-import static org.sonar.core.purge.PurgeConfiguration.newDefaultPurgeConfiguration;
-
-/**
- * @since 2.14
- */
-public class DefaultPurgeTask implements PurgeTask {
- private static final Logger LOG = LoggerFactory.getLogger(DefaultPurgeTask.class);
- private final PurgeProfiler profiler;
- private final PurgeDao purgeDao;
- private final ResourceDao resourceDao;
- private final Settings settings;
- private final DefaultPeriodCleaner periodCleaner;
-
- public DefaultPurgeTask(PurgeDao purgeDao, ResourceDao resourceDao, Settings settings, DefaultPeriodCleaner periodCleaner, PurgeProfiler profiler) {
- this.purgeDao = purgeDao;
- this.resourceDao = resourceDao;
- this.settings = settings;
- this.periodCleaner = periodCleaner;
- this.profiler = profiler;
- }
-
- @Override
- public DefaultPurgeTask delete(long resourceId) {
- ResourceDto project = resourceDao.getResource(resourceId);
- purgeDao.deleteResourceTree(new IdUuidPair(project.getId(), project.getUuid()));
- return this;
- }
-
- @VisibleForTesting
- boolean isNotViewNorSubview(String resourceQualifier) {
- return !(Qualifiers.VIEW.equals(resourceQualifier) || Qualifiers.SUBVIEW.equals(resourceQualifier));
- }
-
- @Override
- public DefaultPurgeTask purge(long resourceId) {
- long start = System.currentTimeMillis();
- String resourceQualifier = resourceDao.getResource(resourceId).getQualifier();
- if (isNotViewNorSubview(resourceQualifier)) {
- profiler.reset();
- cleanHistoricalData(resourceId);
- doPurge(resourceId);
- if (settings.getBoolean(CoreProperties.PROFILING_LOG_PROPERTY)) {
- long duration = System.currentTimeMillis() - start;
- LOG.info("\n -------- Profiling for purge: " + TimeUtils.formatDuration(duration) + " --------\n");
- profiler.dump(duration, LOG);
- LOG.info("\n -------- End of profiling for purge --------\n");
- }
- }
- return this;
- }
-
- private void cleanHistoricalData(long resourceId) {
- try {
- periodCleaner.clean(resourceId);
- } catch (Exception e) {
- // purge errors must no fail the batch
- LOG.error("Fail to clean historical data [id=" + resourceId + "]", e);
- }
- }
-
- private void doPurge(long resourceId) {
- try {
- purgeDao.purge(newPurgeConfigurationOnResource(resourceId));
- } catch (Exception e) {
- // purge errors must no fail the report analysis
- LOG.error("Fail to purge data [id=" + resourceId + "]", e);
- }
- }
-
- public PurgeConfiguration newPurgeConfigurationOnResource(long resourceId) {
- return newDefaultPurgeConfiguration(settings, resourceId);
- }
-}
+++ /dev/null
-/*
- * SonarQube, open source software quality management tool.
- * Copyright (C) 2008-2014 SonarSource
- * mailto:contact AT sonarsource DOT com
- *
- * SonarQube 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.
- *
- * SonarQube 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.core.computation.dbcleaner;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.sonar.api.CoreProperties;
-import org.sonar.api.ServerComponent;
-import org.sonar.api.config.Settings;
-import org.sonar.api.utils.TimeUtils;
-import org.sonar.core.computation.dbcleaner.period.DefaultPeriodCleaner;
-import org.sonar.core.persistence.DbSession;
-import org.sonar.core.purge.PurgeConfiguration;
-import org.sonar.core.purge.PurgeDao;
-import org.sonar.core.purge.PurgeProfiler;
-
-import java.util.List;
-
-public class ProjectPurgeTask implements ServerComponent {
- private static final Logger LOG = LoggerFactory.getLogger(ProjectPurgeTask.class);
- private final PurgeProfiler profiler;
- private final PurgeDao purgeDao;
- private final DefaultPeriodCleaner periodCleaner;
-
- public ProjectPurgeTask(PurgeDao purgeDao, DefaultPeriodCleaner periodCleaner, PurgeProfiler profiler) {
- this.purgeDao = purgeDao;
- this.periodCleaner = periodCleaner;
- this.profiler = profiler;
- }
-
- public ProjectPurgeTask purge(DbSession session, PurgeConfiguration configuration, Settings settings) {
- long start = System.currentTimeMillis();
- profiler.reset();
- cleanHistoricalData(session, configuration.rootProjectId(), settings);
- doPurge(session, configuration);
- if (settings.getBoolean(CoreProperties.PROFILING_LOG_PROPERTY)) {
- long duration = System.currentTimeMillis() - start;
- LOG.info("\n -------- Profiling for purge: " + TimeUtils.formatDuration(duration) + " --------\n");
- profiler.dump(duration, LOG);
- LOG.info("\n -------- End of profiling for purge --------\n");
- }
- return this;
- }
-
- private void cleanHistoricalData(DbSession session, long resourceId, Settings settings) {
- try {
- periodCleaner.clean(session, resourceId, settings);
- } catch (Exception e) {
- // purge errors must no fail the batch
- LOG.error("Fail to clean historical data [id=" + resourceId + "]", e);
- }
- }
-
- private void doPurge(DbSession session, PurgeConfiguration configuration) {
- try {
- purgeDao.purge(session, configuration);
- } catch (Exception e) {
- // purge errors must no fail the report analysis
- LOG.error("Fail to purge data [id=" + configuration.rootProjectId() + "]", e);
- }
- }
-
- public List<String> findUuidsToDisable(DbSession session, Long projectId) {
- return purgeDao.selectPurgeableFiles(session, projectId);
- }
-}
+++ /dev/null
-/*
- * SonarQube, open source software quality management tool.
- * Copyright (C) 2008-2014 SonarSource
- * mailto:contact AT sonarsource DOT com
- *
- * SonarQube 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.
- *
- * SonarQube 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.core.computation.dbcleaner;
-
-import javax.annotation.ParametersAreNonnullByDefault;
+++ /dev/null
-/*
- * SonarQube, open source software quality management tool.
- * Copyright (C) 2008-2014 SonarSource
- * mailto:contact AT sonarsource DOT com
- *
- * SonarQube 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.
- *
- * SonarQube 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.core.computation.dbcleaner.period;
-
-import com.google.common.annotations.VisibleForTesting;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.sonar.api.ServerExtension;
-import org.sonar.api.config.Settings;
-import org.sonar.api.task.TaskExtension;
-import org.sonar.api.utils.DateUtils;
-import org.sonar.core.persistence.DbSession;
-import org.sonar.core.persistence.MyBatis;
-import org.sonar.core.purge.PurgeDao;
-import org.sonar.core.purge.PurgeSnapshotQuery;
-import org.sonar.core.purge.PurgeableSnapshotDto;
-
-import java.util.List;
-
-public class DefaultPeriodCleaner implements TaskExtension, ServerExtension {
-
- private static final Logger LOG = LoggerFactory.getLogger(DefaultPeriodCleaner.class);
- private PurgeDao purgeDao;
- private Settings settings;
- private MyBatis mybatis;
-
- public DefaultPeriodCleaner(PurgeDao purgeDao, Settings settings, MyBatis mybatis) {
- this.purgeDao = purgeDao;
- this.settings = settings;
- this.mybatis = mybatis;
- }
-
- public void clean(long projectId) {
- clean(projectId, settings);
- }
-
- public void clean(long projectId, Settings settings) {
- DbSession session = mybatis.openSession(true);
- try {
- doClean(projectId, new Filters(settings).all(), session);
- } finally {
- MyBatis.closeQuietly(session);
- }
- }
-
- public void clean(DbSession session, long projectId, Settings settings) {
- doClean(projectId, new Filters(settings).all(), session);
- }
-
- @VisibleForTesting
- void doClean(long projectId, List<Filter> filters, DbSession session) {
- List<PurgeableSnapshotDto> history = selectProjectSnapshots(projectId, session);
- for (Filter filter : filters) {
- filter.log();
- delete(filter.filter(history), session);
- }
- }
-
- private void delete(List<PurgeableSnapshotDto> snapshots, DbSession session) {
- for (PurgeableSnapshotDto snapshot : snapshots) {
- LOG.info("<- Delete snapshot: " + DateUtils.formatDateTime(snapshot.getDate()) + " [" + snapshot.getSnapshotId() + "]");
- purgeDao.deleteSnapshots(PurgeSnapshotQuery.create().setRootSnapshotId(snapshot.getSnapshotId()), session);
- purgeDao.deleteSnapshots(PurgeSnapshotQuery.create().setId(snapshot.getSnapshotId()), session);
- }
- }
-
- private List<PurgeableSnapshotDto> selectProjectSnapshots(long resourceId, DbSession session) {
- return purgeDao.selectPurgeableSnapshots(resourceId, session);
- }
-}
+++ /dev/null
-/*
- * SonarQube, open source software quality management tool.
- * Copyright (C) 2008-2014 SonarSource
- * mailto:contact AT sonarsource DOT com
- *
- * SonarQube 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.
- *
- * SonarQube 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.core.computation.dbcleaner.period;
-
-import com.google.common.collect.Lists;
-import org.slf4j.LoggerFactory;
-import org.sonar.api.utils.DateUtils;
-import org.sonar.core.purge.PurgeableSnapshotDto;
-
-import java.util.Date;
-import java.util.List;
-
-class DeleteAllFilter implements Filter {
- private final Date before;
-
- public DeleteAllFilter(Date before) {
- this.before = before;
- }
-
- @Override
- public List<PurgeableSnapshotDto> filter(List<PurgeableSnapshotDto> history) {
- List<PurgeableSnapshotDto> result = Lists.newArrayList();
- for (PurgeableSnapshotDto snapshot : history) {
- if (snapshot.getDate().before(before)) {
- result.add(snapshot);
- }
- }
- return result;
- }
-
- @Override
- public void log() {
- LoggerFactory.getLogger(getClass()).info("-> Delete data prior to: " + DateUtils.formatDate(before));
- }
-}
+++ /dev/null
-/*
- * SonarQube, open source software quality management tool.
- * Copyright (C) 2008-2014 SonarSource
- * mailto:contact AT sonarsource DOT com
- *
- * SonarQube 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.
- *
- * SonarQube 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.core.computation.dbcleaner.period;
-
-import org.sonar.core.purge.PurgeableSnapshotDto;
-
-import java.util.List;
-
-interface Filter {
- List<PurgeableSnapshotDto> filter(List<PurgeableSnapshotDto> snapshots);
-
- void log();
-}
+++ /dev/null
-/*
- * SonarQube, open source software quality management tool.
- * Copyright (C) 2008-2014 SonarSource
- * mailto:contact AT sonarsource DOT com
- *
- * SonarQube 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.
- *
- * SonarQube 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.core.computation.dbcleaner.period;
-
-import com.google.common.collect.Lists;
-import org.apache.commons.lang.time.DateUtils;
-import org.sonar.api.config.Settings;
-import org.sonar.core.computation.dbcleaner.DbCleanerConstants;
-
-import java.util.Calendar;
-import java.util.Date;
-import java.util.List;
-
-class Filters {
- private final List<Filter> all = Lists.newArrayList();
-
- Filters(Settings settings) {
- Date dateToStartKeepingOneSnapshotByDay = getDateFromHours(settings, DbCleanerConstants.HOURS_BEFORE_KEEPING_ONLY_ONE_SNAPSHOT_BY_DAY);
- Date dateToStartKeepingOneSnapshotByWeek = getDateFromWeeks(settings, DbCleanerConstants.WEEKS_BEFORE_KEEPING_ONLY_ONE_SNAPSHOT_BY_WEEK);
- Date dateToStartKeepingOneSnapshotByMonth = getDateFromWeeks(settings, DbCleanerConstants.WEEKS_BEFORE_KEEPING_ONLY_ONE_SNAPSHOT_BY_MONTH);
- Date dateToStartDeletingAllSnapshots = getDateFromWeeks(settings, DbCleanerConstants.WEEKS_BEFORE_DELETING_ALL_SNAPSHOTS);
-
- all.add(new KeepOneFilter(dateToStartKeepingOneSnapshotByWeek, dateToStartKeepingOneSnapshotByDay, Calendar.DAY_OF_YEAR, "day"));
- all.add(new KeepOneFilter(dateToStartKeepingOneSnapshotByMonth, dateToStartKeepingOneSnapshotByWeek, Calendar.WEEK_OF_YEAR, "week"));
- all.add(new KeepOneFilter(dateToStartDeletingAllSnapshots, dateToStartKeepingOneSnapshotByMonth, Calendar.MONTH, "month"));
- all.add(new DeleteAllFilter(dateToStartDeletingAllSnapshots));
- }
-
- static Date getDateFromWeeks(Settings settings, String propertyKey) {
- int weeks = settings.getInt(propertyKey);
- return DateUtils.addWeeks(new Date(), -weeks);
- }
-
- static Date getDateFromHours(Settings settings, String propertyKey) {
- int hours = settings.getInt(propertyKey);
- return DateUtils.addHours(new Date(), -hours);
- }
-
- List<Filter> all() {
- return all;
- }
-}
+++ /dev/null
-/*
- * SonarQube, open source software quality management tool.
- * Copyright (C) 2008-2014 SonarSource
- * mailto:contact AT sonarsource DOT com
- *
- * SonarQube 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.
- *
- * SonarQube 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.core.computation.dbcleaner.period;
-
-import com.google.common.collect.Lists;
-import org.apache.commons.lang.time.DateUtils;
-import org.sonar.core.purge.PurgeableSnapshotDto;
-
-import java.util.Calendar;
-import java.util.Date;
-import java.util.GregorianCalendar;
-import java.util.List;
-
-final class Interval {
- List<PurgeableSnapshotDto> snapshots = Lists.newArrayList();
-
- void add(PurgeableSnapshotDto snapshot) {
- snapshots.add(snapshot);
- }
-
- List<PurgeableSnapshotDto> get() {
- return snapshots;
- }
-
- int count() {
- return snapshots.size();
- }
-
- static List<Interval> group(List<PurgeableSnapshotDto> snapshots, Date start, Date end, int calendarField) {
- List<Interval> intervals = Lists.newArrayList();
-
- GregorianCalendar calendar = new GregorianCalendar();
- int lastYear = -1;
- int lastFieldValue = -1;
- Interval currentInterval = null;
-
- for (PurgeableSnapshotDto snapshot : snapshots) {
- if (!DateUtils.isSameDay(start, snapshot.getDate()) && snapshot.getDate().after(start) &&
- (snapshot.getDate().before(end) || DateUtils.isSameDay(end, snapshot.getDate()))) {
- calendar.setTime(snapshot.getDate());
- int currentFieldValue = calendar.get(calendarField);
- int currentYear = calendar.get(Calendar.YEAR);
- if (lastYear!=currentYear || lastFieldValue != currentFieldValue) {
- currentInterval = new Interval();
- intervals.add(currentInterval);
- }
- lastFieldValue = currentFieldValue;
- lastYear = currentYear;
- if (currentInterval != null) {
- currentInterval.add(snapshot);
- }
- }
- }
- return intervals;
- }
-}
+++ /dev/null
-/*
- * SonarQube, open source software quality management tool.
- * Copyright (C) 2008-2014 SonarSource
- * mailto:contact AT sonarsource DOT com
- *
- * SonarQube 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.
- *
- * SonarQube 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.core.computation.dbcleaner.period;
-
-import com.google.common.annotations.VisibleForTesting;
-import com.google.common.collect.Lists;
-import org.slf4j.LoggerFactory;
-import org.sonar.api.utils.DateUtils;
-import org.sonar.core.purge.PurgeableSnapshotDto;
-
-import java.util.Date;
-import java.util.List;
-
-class KeepOneFilter implements Filter {
-
- private final Date start;
- private final Date end;
- private final int dateField;
- private final String label;
-
- KeepOneFilter(Date start, Date end, int calendarField, String label) {
- this.start = start;
- this.end = end;
- this.dateField = calendarField;
- this.label = label;
- }
-
- @Override
- public List<PurgeableSnapshotDto> filter(List<PurgeableSnapshotDto> history) {
- List<Interval> intervals = Interval.group(history, start, end, dateField);
- List<PurgeableSnapshotDto> result = Lists.newArrayList();
- for (Interval interval : intervals) {
- appendSnapshotsToDelete(interval, result);
- }
-
- return result;
- }
-
- @Override
- public void log() {
- LoggerFactory.getLogger(getClass()).info("-> Keep one snapshot per " + label + " between " + DateUtils.formatDate(start) + " and " + DateUtils.formatDate(end));
- }
-
- private void appendSnapshotsToDelete(Interval interval, List<PurgeableSnapshotDto> toDelete) {
- if (interval.count() > 1) {
- List<PurgeableSnapshotDto> deletables = Lists.newArrayList();
- List<PurgeableSnapshotDto> toKeep = Lists.newArrayList();
- for (PurgeableSnapshotDto snapshot : interval.get()) {
- if (isDeletable(snapshot)) {
- deletables.add(snapshot);
- } else {
- toKeep.add(snapshot);
- }
- }
-
- if (!toKeep.isEmpty()) {
- toDelete.addAll(deletables);
-
- } else if (deletables.size() > 1) {
- // keep one snapshot
- toDelete.addAll(deletables.subList(1, deletables.size()));
- }
- }
- }
-
- @VisibleForTesting
- static boolean isDeletable(PurgeableSnapshotDto snapshot) {
- return !snapshot.isLast() && !snapshot.hasEvents();
- }
-
-}
+++ /dev/null
-/*
- * SonarQube, open source software quality management tool.
- * Copyright (C) 2008-2014 SonarSource
- * mailto:contact AT sonarsource DOT com
- *
- * SonarQube 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.
- *
- * SonarQube 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.core.computation.dbcleaner.period;
-
-import javax.annotation.ParametersAreNonnullByDefault;
import org.sonar.api.CoreProperties;
import org.sonar.api.config.PropertyDefinition;
import org.sonar.api.resources.Qualifiers;
-import org.sonar.core.computation.dbcleaner.DataCleanerProperties;
+import org.sonar.server.computation.dbcleaner.DataCleanerProperties;
import java.util.List;
import org.sonar.api.config.Settings;
import org.sonar.api.resources.Scopes;
import org.sonar.api.utils.System2;
-import org.sonar.core.computation.dbcleaner.DbCleanerConstants;
+import org.sonar.server.computation.dbcleaner.DbCleanerConstants;
import javax.annotation.CheckForNull;
* @deprecated (is used by the plugin views only. Will rely on the implementation when views analysis views moved on the server side)
*/
@Deprecated
-public interface DbCleanerConstants extends org.sonar.core.computation.dbcleaner.DbCleanerConstants {
+public interface DbCleanerConstants extends org.sonar.server.computation.dbcleaner.DbCleanerConstants {
}
--- /dev/null
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2014 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube 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.
+ *
+ * SonarQube 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.computation.dbcleaner;
+
+import org.sonar.api.CoreProperties;
+import org.sonar.api.PropertyType;
+import org.sonar.api.config.PropertyDefinition;
+import org.sonar.api.resources.Qualifiers;
+
+import java.util.Arrays;
+import java.util.List;
+
+public final class DataCleanerProperties {
+
+ private DataCleanerProperties() {
+ }
+
+ public static List<PropertyDefinition> all() {
+ return Arrays.asList(
+ PropertyDefinition.builder(DbCleanerConstants.PROPERTY_CLEAN_DIRECTORY)
+ .defaultValue("true")
+ .name("Clean directory/package history")
+ .description("If set to true, no history is kept at directory/package level. Setting this to false can cause database bloat.")
+ .type(PropertyType.BOOLEAN)
+ .onQualifiers(Qualifiers.PROJECT)
+ .category(CoreProperties.CATEGORY_GENERAL)
+ .subCategory(CoreProperties.SUBCATEGORY_DATABASE_CLEANER)
+ .index(1)
+ .build(),
+
+ PropertyDefinition.builder(DbCleanerConstants.DAYS_BEFORE_DELETING_CLOSED_ISSUES)
+ .defaultValue("30")
+ .name("Delete closed issues after")
+ .description("Issues that have been closed for more than this number of days will be deleted.")
+ .type(PropertyType.INTEGER)
+ .onQualifiers(Qualifiers.PROJECT)
+ .category(CoreProperties.CATEGORY_GENERAL)
+ .subCategory(CoreProperties.SUBCATEGORY_DATABASE_CLEANER)
+ .index(2)
+ .build(),
+
+ PropertyDefinition.builder(DbCleanerConstants.HOURS_BEFORE_KEEPING_ONLY_ONE_SNAPSHOT_BY_DAY)
+ .defaultValue("24")
+ .name("Keep only one snapshot a day after")
+ .description("After this number of hours, if there are several snapshots during the same day, "
+ + "the DbCleaner keeps the most recent one and fully deletes the other ones.")
+ .type(PropertyType.INTEGER)
+ .onQualifiers(Qualifiers.PROJECT)
+ .category(CoreProperties.CATEGORY_GENERAL)
+ .subCategory(CoreProperties.SUBCATEGORY_DATABASE_CLEANER)
+ .index(3)
+ .build(),
+
+ PropertyDefinition.builder(DbCleanerConstants.WEEKS_BEFORE_KEEPING_ONLY_ONE_SNAPSHOT_BY_WEEK)
+ .defaultValue("4")
+ .name("Keep only one snapshot a week after")
+ .description("After this number of weeks, if there are several snapshots during the same week, "
+ + "the DbCleaner keeps the most recent one and fully deletes the other ones")
+ .type(PropertyType.INTEGER)
+ .onQualifiers(Qualifiers.PROJECT)
+ .category(CoreProperties.CATEGORY_GENERAL)
+ .subCategory(CoreProperties.SUBCATEGORY_DATABASE_CLEANER)
+ .index(4)
+ .build(),
+
+ PropertyDefinition.builder(DbCleanerConstants.WEEKS_BEFORE_KEEPING_ONLY_ONE_SNAPSHOT_BY_MONTH)
+ .defaultValue("52")
+ .name("Keep only one snapshot a month after")
+ .description("After this number of weeks, if there are several snapshots during the same month, "
+ + "the DbCleaner keeps the most recent one and fully deletes the other ones.")
+ .type(PropertyType.INTEGER)
+ .onQualifiers(Qualifiers.PROJECT)
+ .category(CoreProperties.CATEGORY_GENERAL)
+ .subCategory(CoreProperties.SUBCATEGORY_DATABASE_CLEANER)
+ .index(5)
+ .build(),
+
+ PropertyDefinition.builder(DbCleanerConstants.WEEKS_BEFORE_DELETING_ALL_SNAPSHOTS)
+ .defaultValue("260")
+ .name("Delete all snapshots after")
+ .description("After this number of weeks, all snapshots are fully deleted.")
+ .type(PropertyType.INTEGER)
+ .onQualifiers(Qualifiers.PROJECT)
+ .category(CoreProperties.CATEGORY_GENERAL)
+ .subCategory(CoreProperties.SUBCATEGORY_DATABASE_CLEANER)
+ .index(6)
+ .build()
+ );
+ }
+}
--- /dev/null
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2014 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube 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.
+ *
+ * SonarQube 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.computation.dbcleaner;
+
+public interface DbCleanerConstants {
+
+ String PLUGIN_KEY = "dbcleaner";
+ String PLUGIN_NAME = "DbCleaner";
+ String PROPERTY_CLEAN_DIRECTORY = "sonar.dbcleaner.cleanDirectory";
+
+ String HOURS_BEFORE_KEEPING_ONLY_ONE_SNAPSHOT_BY_DAY = "sonar.dbcleaner.hoursBeforeKeepingOnlyOneSnapshotByDay";
+ String WEEKS_BEFORE_KEEPING_ONLY_ONE_SNAPSHOT_BY_WEEK = "sonar.dbcleaner.weeksBeforeKeepingOnlyOneSnapshotByWeek";
+ String WEEKS_BEFORE_KEEPING_ONLY_ONE_SNAPSHOT_BY_MONTH = "sonar.dbcleaner.weeksBeforeKeepingOnlyOneSnapshotByMonth";
+ String WEEKS_BEFORE_DELETING_ALL_SNAPSHOTS = "sonar.dbcleaner.weeksBeforeDeletingAllSnapshots";
+ String DAYS_BEFORE_DELETING_CLOSED_ISSUES = "sonar.dbcleaner.daysBeforeDeletingClosedIssues";
+}
--- /dev/null
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2014 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube 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.
+ *
+ * SonarQube 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.computation.dbcleaner;
+
+import com.google.common.annotations.VisibleForTesting;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.sonar.api.CoreProperties;
+import org.sonar.api.config.Settings;
+import org.sonar.api.resources.Qualifiers;
+import org.sonar.api.utils.TimeUtils;
+import org.sonar.server.computation.dbcleaner.period.DefaultPeriodCleaner;
+import org.sonar.core.purge.IdUuidPair;
+import org.sonar.core.purge.PurgeConfiguration;
+import org.sonar.core.purge.PurgeDao;
+import org.sonar.core.purge.PurgeProfiler;
+import org.sonar.core.resource.ResourceDao;
+import org.sonar.core.resource.ResourceDto;
+import org.sonar.plugins.dbcleaner.api.PurgeTask;
+
+import static org.sonar.core.purge.PurgeConfiguration.newDefaultPurgeConfiguration;
+
+/**
+ * @since 2.14
+ */
+public class DefaultPurgeTask implements PurgeTask {
+ private static final Logger LOG = LoggerFactory.getLogger(DefaultPurgeTask.class);
+ private final PurgeProfiler profiler;
+ private final PurgeDao purgeDao;
+ private final ResourceDao resourceDao;
+ private final Settings settings;
+ private final DefaultPeriodCleaner periodCleaner;
+
+ public DefaultPurgeTask(PurgeDao purgeDao, ResourceDao resourceDao, Settings settings, DefaultPeriodCleaner periodCleaner, PurgeProfiler profiler) {
+ this.purgeDao = purgeDao;
+ this.resourceDao = resourceDao;
+ this.settings = settings;
+ this.periodCleaner = periodCleaner;
+ this.profiler = profiler;
+ }
+
+ @Override
+ public DefaultPurgeTask delete(long resourceId) {
+ ResourceDto project = resourceDao.getResource(resourceId);
+ purgeDao.deleteResourceTree(new IdUuidPair(project.getId(), project.getUuid()));
+ return this;
+ }
+
+ @VisibleForTesting
+ boolean isNotViewNorSubview(String resourceQualifier) {
+ return !(Qualifiers.VIEW.equals(resourceQualifier) || Qualifiers.SUBVIEW.equals(resourceQualifier));
+ }
+
+ @Override
+ public DefaultPurgeTask purge(long resourceId) {
+ long start = System.currentTimeMillis();
+ String resourceQualifier = resourceDao.getResource(resourceId).getQualifier();
+ if (isNotViewNorSubview(resourceQualifier)) {
+ profiler.reset();
+ cleanHistoricalData(resourceId);
+ doPurge(resourceId);
+ if (settings.getBoolean(CoreProperties.PROFILING_LOG_PROPERTY)) {
+ long duration = System.currentTimeMillis() - start;
+ LOG.info("\n -------- Profiling for purge: " + TimeUtils.formatDuration(duration) + " --------\n");
+ profiler.dump(duration, LOG);
+ LOG.info("\n -------- End of profiling for purge --------\n");
+ }
+ }
+ return this;
+ }
+
+ private void cleanHistoricalData(long resourceId) {
+ try {
+ periodCleaner.clean(resourceId);
+ } catch (Exception e) {
+ // purge errors must no fail the batch
+ LOG.error("Fail to clean historical data [id=" + resourceId + "]", e);
+ }
+ }
+
+ private void doPurge(long resourceId) {
+ try {
+ purgeDao.purge(newPurgeConfigurationOnResource(resourceId));
+ } catch (Exception e) {
+ // purge errors must no fail the report analysis
+ LOG.error("Fail to purge data [id=" + resourceId + "]", e);
+ }
+ }
+
+ public PurgeConfiguration newPurgeConfigurationOnResource(long resourceId) {
+ return newDefaultPurgeConfiguration(settings, resourceId);
+ }
+}
--- /dev/null
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2014 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube 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.
+ *
+ * SonarQube 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.computation.dbcleaner;
+
+import javax.annotation.ParametersAreNonnullByDefault;
--- /dev/null
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2014 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube 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.
+ *
+ * SonarQube 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.computation.dbcleaner.period;
+
+import com.google.common.annotations.VisibleForTesting;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.sonar.api.ServerExtension;
+import org.sonar.api.config.Settings;
+import org.sonar.api.task.TaskExtension;
+import org.sonar.api.utils.DateUtils;
+import org.sonar.core.persistence.DbSession;
+import org.sonar.core.persistence.MyBatis;
+import org.sonar.core.purge.PurgeDao;
+import org.sonar.core.purge.PurgeSnapshotQuery;
+import org.sonar.core.purge.PurgeableSnapshotDto;
+
+import java.util.List;
+
+public class DefaultPeriodCleaner implements TaskExtension, ServerExtension {
+
+ private static final Logger LOG = LoggerFactory.getLogger(DefaultPeriodCleaner.class);
+ private PurgeDao purgeDao;
+ private Settings settings;
+ private MyBatis mybatis;
+
+ public DefaultPeriodCleaner(PurgeDao purgeDao, Settings settings, MyBatis mybatis) {
+ this.purgeDao = purgeDao;
+ this.settings = settings;
+ this.mybatis = mybatis;
+ }
+
+ public void clean(long projectId) {
+ clean(projectId, settings);
+ }
+
+ public void clean(long projectId, Settings settings) {
+ DbSession session = mybatis.openSession(true);
+ try {
+ doClean(projectId, new Filters(settings).all(), session);
+ } finally {
+ MyBatis.closeQuietly(session);
+ }
+ }
+
+ public void clean(DbSession session, long projectId, Settings settings) {
+ doClean(projectId, new Filters(settings).all(), session);
+ }
+
+ @VisibleForTesting
+ void doClean(long projectId, List<Filter> filters, DbSession session) {
+ List<PurgeableSnapshotDto> history = selectProjectSnapshots(projectId, session);
+ for (Filter filter : filters) {
+ filter.log();
+ delete(filter.filter(history), session);
+ }
+ }
+
+ private void delete(List<PurgeableSnapshotDto> snapshots, DbSession session) {
+ for (PurgeableSnapshotDto snapshot : snapshots) {
+ LOG.info("<- Delete snapshot: " + DateUtils.formatDateTime(snapshot.getDate()) + " [" + snapshot.getSnapshotId() + "]");
+ purgeDao.deleteSnapshots(PurgeSnapshotQuery.create().setRootSnapshotId(snapshot.getSnapshotId()), session);
+ purgeDao.deleteSnapshots(PurgeSnapshotQuery.create().setId(snapshot.getSnapshotId()), session);
+ }
+ }
+
+ private List<PurgeableSnapshotDto> selectProjectSnapshots(long resourceId, DbSession session) {
+ return purgeDao.selectPurgeableSnapshots(resourceId, session);
+ }
+}
--- /dev/null
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2014 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube 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.
+ *
+ * SonarQube 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.computation.dbcleaner.period;
+
+import com.google.common.collect.Lists;
+import org.slf4j.LoggerFactory;
+import org.sonar.api.utils.DateUtils;
+import org.sonar.core.purge.PurgeableSnapshotDto;
+
+import java.util.Date;
+import java.util.List;
+
+class DeleteAllFilter implements Filter {
+ private final Date before;
+
+ public DeleteAllFilter(Date before) {
+ this.before = before;
+ }
+
+ @Override
+ public List<PurgeableSnapshotDto> filter(List<PurgeableSnapshotDto> history) {
+ List<PurgeableSnapshotDto> result = Lists.newArrayList();
+ for (PurgeableSnapshotDto snapshot : history) {
+ if (snapshot.getDate().before(before)) {
+ result.add(snapshot);
+ }
+ }
+ return result;
+ }
+
+ @Override
+ public void log() {
+ LoggerFactory.getLogger(getClass()).info("-> Delete data prior to: " + DateUtils.formatDate(before));
+ }
+}
--- /dev/null
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2014 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube 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.
+ *
+ * SonarQube 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.computation.dbcleaner.period;
+
+import org.sonar.core.purge.PurgeableSnapshotDto;
+
+import java.util.List;
+
+interface Filter {
+ List<PurgeableSnapshotDto> filter(List<PurgeableSnapshotDto> snapshots);
+
+ void log();
+}
--- /dev/null
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2014 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube 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.
+ *
+ * SonarQube 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.computation.dbcleaner.period;
+
+import com.google.common.collect.Lists;
+import org.apache.commons.lang.time.DateUtils;
+import org.sonar.api.config.Settings;
+import org.sonar.server.computation.dbcleaner.DbCleanerConstants;
+
+import java.util.Calendar;
+import java.util.Date;
+import java.util.List;
+
+class Filters {
+ private final List<Filter> all = Lists.newArrayList();
+
+ Filters(Settings settings) {
+ Date dateToStartKeepingOneSnapshotByDay = getDateFromHours(settings, DbCleanerConstants.HOURS_BEFORE_KEEPING_ONLY_ONE_SNAPSHOT_BY_DAY);
+ Date dateToStartKeepingOneSnapshotByWeek = getDateFromWeeks(settings, DbCleanerConstants.WEEKS_BEFORE_KEEPING_ONLY_ONE_SNAPSHOT_BY_WEEK);
+ Date dateToStartKeepingOneSnapshotByMonth = getDateFromWeeks(settings, DbCleanerConstants.WEEKS_BEFORE_KEEPING_ONLY_ONE_SNAPSHOT_BY_MONTH);
+ Date dateToStartDeletingAllSnapshots = getDateFromWeeks(settings, DbCleanerConstants.WEEKS_BEFORE_DELETING_ALL_SNAPSHOTS);
+
+ all.add(new KeepOneFilter(dateToStartKeepingOneSnapshotByWeek, dateToStartKeepingOneSnapshotByDay, Calendar.DAY_OF_YEAR, "day"));
+ all.add(new KeepOneFilter(dateToStartKeepingOneSnapshotByMonth, dateToStartKeepingOneSnapshotByWeek, Calendar.WEEK_OF_YEAR, "week"));
+ all.add(new KeepOneFilter(dateToStartDeletingAllSnapshots, dateToStartKeepingOneSnapshotByMonth, Calendar.MONTH, "month"));
+ all.add(new DeleteAllFilter(dateToStartDeletingAllSnapshots));
+ }
+
+ static Date getDateFromWeeks(Settings settings, String propertyKey) {
+ int weeks = settings.getInt(propertyKey);
+ return DateUtils.addWeeks(new Date(), -weeks);
+ }
+
+ static Date getDateFromHours(Settings settings, String propertyKey) {
+ int hours = settings.getInt(propertyKey);
+ return DateUtils.addHours(new Date(), -hours);
+ }
+
+ List<Filter> all() {
+ return all;
+ }
+}
--- /dev/null
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2014 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube 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.
+ *
+ * SonarQube 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.computation.dbcleaner.period;
+
+import com.google.common.collect.Lists;
+import org.apache.commons.lang.time.DateUtils;
+import org.sonar.core.purge.PurgeableSnapshotDto;
+
+import java.util.Calendar;
+import java.util.Date;
+import java.util.GregorianCalendar;
+import java.util.List;
+
+final class Interval {
+ List<PurgeableSnapshotDto> snapshots = Lists.newArrayList();
+
+ void add(PurgeableSnapshotDto snapshot) {
+ snapshots.add(snapshot);
+ }
+
+ List<PurgeableSnapshotDto> get() {
+ return snapshots;
+ }
+
+ int count() {
+ return snapshots.size();
+ }
+
+ static List<Interval> group(List<PurgeableSnapshotDto> snapshots, Date start, Date end, int calendarField) {
+ List<Interval> intervals = Lists.newArrayList();
+
+ GregorianCalendar calendar = new GregorianCalendar();
+ int lastYear = -1;
+ int lastFieldValue = -1;
+ Interval currentInterval = null;
+
+ for (PurgeableSnapshotDto snapshot : snapshots) {
+ if (!DateUtils.isSameDay(start, snapshot.getDate()) && snapshot.getDate().after(start) &&
+ (snapshot.getDate().before(end) || DateUtils.isSameDay(end, snapshot.getDate()))) {
+ calendar.setTime(snapshot.getDate());
+ int currentFieldValue = calendar.get(calendarField);
+ int currentYear = calendar.get(Calendar.YEAR);
+ if (lastYear!=currentYear || lastFieldValue != currentFieldValue) {
+ currentInterval = new Interval();
+ intervals.add(currentInterval);
+ }
+ lastFieldValue = currentFieldValue;
+ lastYear = currentYear;
+ if (currentInterval != null) {
+ currentInterval.add(snapshot);
+ }
+ }
+ }
+ return intervals;
+ }
+}
--- /dev/null
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2014 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube 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.
+ *
+ * SonarQube 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.computation.dbcleaner.period;
+
+import com.google.common.annotations.VisibleForTesting;
+import com.google.common.collect.Lists;
+import org.slf4j.LoggerFactory;
+import org.sonar.api.utils.DateUtils;
+import org.sonar.core.purge.PurgeableSnapshotDto;
+
+import java.util.Date;
+import java.util.List;
+
+class KeepOneFilter implements Filter {
+
+ private final Date start;
+ private final Date end;
+ private final int dateField;
+ private final String label;
+
+ KeepOneFilter(Date start, Date end, int calendarField, String label) {
+ this.start = start;
+ this.end = end;
+ this.dateField = calendarField;
+ this.label = label;
+ }
+
+ @Override
+ public List<PurgeableSnapshotDto> filter(List<PurgeableSnapshotDto> history) {
+ List<Interval> intervals = Interval.group(history, start, end, dateField);
+ List<PurgeableSnapshotDto> result = Lists.newArrayList();
+ for (Interval interval : intervals) {
+ appendSnapshotsToDelete(interval, result);
+ }
+
+ return result;
+ }
+
+ @Override
+ public void log() {
+ LoggerFactory.getLogger(getClass()).info("-> Keep one snapshot per " + label + " between " + DateUtils.formatDate(start) + " and " + DateUtils.formatDate(end));
+ }
+
+ private void appendSnapshotsToDelete(Interval interval, List<PurgeableSnapshotDto> toDelete) {
+ if (interval.count() > 1) {
+ List<PurgeableSnapshotDto> deletables = Lists.newArrayList();
+ List<PurgeableSnapshotDto> toKeep = Lists.newArrayList();
+ for (PurgeableSnapshotDto snapshot : interval.get()) {
+ if (isDeletable(snapshot)) {
+ deletables.add(snapshot);
+ } else {
+ toKeep.add(snapshot);
+ }
+ }
+
+ if (!toKeep.isEmpty()) {
+ toDelete.addAll(deletables);
+
+ } else if (deletables.size() > 1) {
+ // keep one snapshot
+ toDelete.addAll(deletables.subList(1, deletables.size()));
+ }
+ }
+ }
+
+ @VisibleForTesting
+ static boolean isDeletable(PurgeableSnapshotDto snapshot) {
+ return !snapshot.isLast() && !snapshot.hasEvents();
+ }
+
+}
--- /dev/null
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2014 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube 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.
+ *
+ * SonarQube 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.computation.dbcleaner.period;
+
+import javax.annotation.ParametersAreNonnullByDefault;
+++ /dev/null
-/*
- * SonarQube, open source software quality management tool.
- * Copyright (C) 2008-2014 SonarSource
- * mailto:contact AT sonarsource DOT com
- *
- * SonarQube 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.
- *
- * SonarQube 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.core.computation.dbcleaner;
-
-import org.junit.Test;
-
-import static org.fest.assertions.Assertions.assertThat;
-
-public class DataCleanerPropertiesTest {
-
- @Test
- public void shouldGetExtensions() {
- assertThat(DataCleanerProperties.all()).hasSize(6);
- }
-}
+++ /dev/null
-/*
- * SonarQube, open source software quality management tool.
- * Copyright (C) 2008-2014 SonarSource
- * mailto:contact AT sonarsource DOT com
- *
- * SonarQube 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.
- *
- * SonarQube 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.core.computation.dbcleaner;
-
-import org.sonar.api.utils.DateUtils;
-import org.sonar.core.purge.PurgeableSnapshotDto;
-
-public final class DbCleanerTestUtils {
-
- private DbCleanerTestUtils() {
- }
-
- public static PurgeableSnapshotDto createSnapshotWithDate(long snapshotId, String date) {
- PurgeableSnapshotDto snapshot = new PurgeableSnapshotDto();
- snapshot.setSnapshotId(snapshotId);
- snapshot.setDate(DateUtils.parseDate(date));
- return snapshot;
- }
-
- public static PurgeableSnapshotDto createSnapshotWithDateTime(long snapshotId, String datetime) {
- PurgeableSnapshotDto snapshot = new PurgeableSnapshotDto();
- snapshot.setSnapshotId(snapshotId);
- snapshot.setDate(DateUtils.parseDateTime(datetime));
- return snapshot;
- }
-
-}
+++ /dev/null
-/*
- * SonarQube, open source software quality management tool.
- * Copyright (C) 2008-2014 SonarSource
- * mailto:contact AT sonarsource DOT com
- *
- * SonarQube 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.
- *
- * SonarQube 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.core.computation.dbcleaner;
-
-import ch.qos.logback.classic.Logger;
-import org.junit.Before;
-import org.junit.Test;
-import org.mockito.ArgumentMatcher;
-import org.sonar.api.CoreProperties;
-import org.sonar.api.config.PropertyDefinitions;
-import org.sonar.api.config.Settings;
-import org.sonar.api.resources.Qualifiers;
-import org.sonar.api.resources.Scopes;
-import org.sonar.core.computation.dbcleaner.period.DefaultPeriodCleaner;
-import org.sonar.core.purge.IdUuidPair;
-import org.sonar.core.purge.PurgeConfiguration;
-import org.sonar.core.purge.PurgeDao;
-import org.sonar.core.purge.PurgeProfiler;
-import org.sonar.core.resource.ResourceDao;
-import org.sonar.core.resource.ResourceDto;
-
-import static org.fest.assertions.Assertions.assertThat;
-import static org.mockito.Matchers.any;
-import static org.mockito.Matchers.anyLong;
-import static org.mockito.Matchers.argThat;
-import static org.mockito.Mockito.*;
-
-public class DefaultPurgeTaskTest {
-
- private DefaultPurgeTask sut;
- private ResourceDao resourceDao;
- private PurgeDao purgeDao;
- private Settings settings;
- private DefaultPeriodCleaner periodCleaner;
- private PurgeProfiler profiler;
-
- @Before
- public void before() throws Exception {
- this.purgeDao = mock(PurgeDao.class);
- this.resourceDao = mock(ResourceDao.class);
- when(resourceDao.getResource(anyLong())).thenReturn(new ResourceDto().setQualifier(Qualifiers.PROJECT));
-
- this.settings = mock(Settings.class);
- this.periodCleaner = mock(DefaultPeriodCleaner.class);
- this.profiler = mock(PurgeProfiler.class);
-
- this.sut = new DefaultPurgeTask(purgeDao, resourceDao, settings, periodCleaner, profiler);
- }
-
- @Test
- public void shouldNotDeleteHistoricalDataOfDirectories() {
- PurgeDao purgeDao = mock(PurgeDao.class);
- Settings settings = new Settings(new PropertyDefinitions(DataCleanerProperties.all()));
- settings.setProperty(DbCleanerConstants.PROPERTY_CLEAN_DIRECTORY, "false");
- DefaultPurgeTask task = new DefaultPurgeTask(purgeDao, resourceDao, settings, mock(DefaultPeriodCleaner.class), mock(PurgeProfiler.class));
-
- task.purge(1L);
-
- verify(purgeDao).purge(argThat(new ArgumentMatcher<PurgeConfiguration>() {
- @Override
- public boolean matches(Object o) {
- PurgeConfiguration conf = (PurgeConfiguration) o;
- return conf.rootProjectId() == 1L && conf.scopesWithoutHistoricalData().length == 1 && conf.scopesWithoutHistoricalData()[0].equals(Scopes.FILE);
- }
- }));
- }
-
- @Test
- public void shouldDeleteHistoricalDataOfDirectoriesByDefault() {
- PurgeDao purgeDao = mock(PurgeDao.class);
- Settings settings = new Settings(new PropertyDefinitions(DataCleanerProperties.all()));
- DefaultPurgeTask task = new DefaultPurgeTask(purgeDao, resourceDao, settings, mock(DefaultPeriodCleaner.class), mock(PurgeProfiler.class));
-
- task.purge(1L);
-
- verify(purgeDao).purge(argThat(new ArgumentMatcher<PurgeConfiguration>() {
- @Override
- public boolean matches(Object o) {
- PurgeConfiguration conf = (PurgeConfiguration) o;
- return conf.rootProjectId() == 1L &&
- conf.scopesWithoutHistoricalData().length == 2 &&
- conf.scopesWithoutHistoricalData()[0].equals(Scopes.DIRECTORY) &&
- conf.scopesWithoutHistoricalData()[1].equals(Scopes.FILE);
- }
- }));
- }
-
- @Test
- public void shouldNotFailOnErrors() {
- PurgeDao purgeDao = mock(PurgeDao.class);
- when(purgeDao.purge(any(PurgeConfiguration.class))).thenThrow(new RuntimeException());
- DefaultPurgeTask task = new DefaultPurgeTask(purgeDao, resourceDao, new Settings(), mock(DefaultPeriodCleaner.class), mock(PurgeProfiler.class));
-
- task.purge(1L);
-
- verify(purgeDao, times(1)).purge(any(PurgeConfiguration.class));
- }
-
- @Test
- public void shouldDumpProfiling() {
- PurgeConfiguration conf = new PurgeConfiguration(1L, new String[0], 30);
- PurgeDao purgeDao = mock(PurgeDao.class);
- when(purgeDao.purge(conf)).thenThrow(new RuntimeException());
- Settings settings = new Settings(new PropertyDefinitions(DataCleanerProperties.all()));
- settings.setProperty(CoreProperties.PROFILING_LOG_PROPERTY, true);
- PurgeProfiler profiler = mock(PurgeProfiler.class);
-
- DefaultPurgeTask task = new DefaultPurgeTask(purgeDao, resourceDao, settings, mock(DefaultPeriodCleaner.class), profiler);
- task.purge(1L);
-
- verify(profiler).dump(anyLong(), any(Logger.class));
- }
-
- @Test
- public void recognize_view_and_subview() {
- boolean viewCheck = sut.isNotViewNorSubview(Qualifiers.VIEW);
- boolean subViewCheck = sut.isNotViewNorSubview(Qualifiers.SUBVIEW);
-
- assertThat(viewCheck).isFalse();
- assertThat(subViewCheck).isFalse();
- }
-
- @Test
- public void call_dao_delete_when_deleting() throws Exception {
- when(resourceDao.getResource(123L)).thenReturn(new ResourceDto().setId(123L).setUuid("A"));
-
- sut.delete(123L);
-
- verify(purgeDao, times(1)).deleteResourceTree(any(IdUuidPair.class));
- }
-}
+++ /dev/null
-/*
- * SonarQube, open source software quality management tool.
- * Copyright (C) 2008-2014 SonarSource
- * mailto:contact AT sonarsource DOT com
- *
- * SonarQube 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.
- *
- * SonarQube 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.core.computation.dbcleaner;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.slf4j.Logger;
-import org.sonar.api.CoreProperties;
-import org.sonar.api.config.Settings;
-import org.sonar.core.computation.dbcleaner.period.DefaultPeriodCleaner;
-import org.sonar.core.persistence.DbSession;
-import org.sonar.core.purge.PurgeConfiguration;
-import org.sonar.core.purge.PurgeDao;
-import org.sonar.core.purge.PurgeProfiler;
-
-import static org.mockito.Matchers.any;
-import static org.mockito.Matchers.anyLong;
-import static org.mockito.Mockito.*;
-
-public class ProjectPurgeTaskTest {
-
- private ProjectPurgeTask sut;
- private PurgeDao dao;
- private PurgeProfiler profiler;
- private DefaultPeriodCleaner periodCleaner;
-
- @Before
- public void before() throws Exception {
- this.dao = mock(PurgeDao.class);
- this.profiler = mock(PurgeProfiler.class);
- this.periodCleaner = mock(DefaultPeriodCleaner.class);
-
- this.sut = new ProjectPurgeTask(dao, periodCleaner, profiler);
- }
-
- @Test
- public void no_profiling_when_property_is_false() throws Exception {
- Settings settings = mock(Settings.class);
- when(settings.getBoolean(CoreProperties.PROFILING_LOG_PROPERTY)).thenReturn(false);
-
- sut.purge(mock(DbSession.class), mock(PurgeConfiguration.class), settings);
-
- verify(profiler, never()).dump(anyLong(), any(Logger.class));
- }
-
- @Test
- public void profiling_when_property_is_true() throws Exception {
- Settings settings = mock(Settings.class);
- when(settings.getBoolean(CoreProperties.PROFILING_LOG_PROPERTY)).thenReturn(true);
-
- sut.purge(mock(DbSession.class), mock(PurgeConfiguration.class), settings);
-
- verify(profiler, times(1)).dump(anyLong(), any(Logger.class));
- }
-
- @Test
- public void if_dao_purge_fails_it_should_not_interrupt_program_execution() throws Exception {
- doThrow(RuntimeException.class).when(dao).purge(any(DbSession.class), any(PurgeConfiguration.class));
-
- sut.purge(mock(DbSession.class), mock(PurgeConfiguration.class), mock(Settings.class));
-
- verify(dao, times(1)).purge(any(DbSession.class), any(PurgeConfiguration.class));
- }
-
- @Test
- public void if_profiler_cleaning_fails_it_should_not_interrupt_program_execution() throws Exception {
- doThrow(RuntimeException.class).when(periodCleaner).clean(any(DbSession.class), anyLong(), any(Settings.class));
-
- sut.purge(mock(DbSession.class), mock(PurgeConfiguration.class), mock(Settings.class));
-
- verify(periodCleaner, times(1)).clean(any(DbSession.class), anyLong(), any(Settings.class));
- }
-}
+++ /dev/null
-/*
- * SonarQube, open source software quality management tool.
- * Copyright (C) 2008-2014 SonarSource
- * mailto:contact AT sonarsource DOT com
- *
- * SonarQube 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.
- *
- * SonarQube 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.core.computation.dbcleaner.period;
-
-import org.apache.commons.lang.ObjectUtils;
-import org.hamcrest.BaseMatcher;
-import org.junit.Test;
-import org.mockito.ArgumentMatcher;
-import org.mockito.invocation.InvocationOnMock;
-import org.mockito.stubbing.Answer;
-import org.sonar.api.config.Settings;
-import org.sonar.core.persistence.DbSession;
-import org.sonar.core.persistence.MyBatis;
-import org.sonar.core.purge.PurgeDao;
-import org.sonar.core.purge.PurgeSnapshotQuery;
-import org.sonar.core.purge.PurgeableSnapshotDto;
-
-import java.util.Arrays;
-import java.util.Date;
-
-import static org.mockito.Matchers.anyListOf;
-import static org.mockito.Matchers.argThat;
-import static org.mockito.Matchers.eq;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.times;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
-
-public class DefaultPeriodCleanerTest {
-
- @Test
- public void doClean() {
- PurgeDao dao = mock(PurgeDao.class);
- DbSession session = mock(DbSession.class);
- when(dao.selectPurgeableSnapshots(123L, session)).thenReturn(Arrays.asList(
- new PurgeableSnapshotDto().setSnapshotId(999L).setDate(new Date())));
- Filter filter1 = newLazyFilter();
- Filter filter2 = newLazyFilter();
-
- DefaultPeriodCleaner cleaner = new DefaultPeriodCleaner(dao, mock(Settings.class), mock(MyBatis.class));
- cleaner.doClean(123L, Arrays.asList(filter1, filter2), session);
-
- verify(filter1).log();
- verify(filter2).log();
- verify(dao, times(2)).deleteSnapshots(argThat(newRootSnapshotQuery()), eq(session));
- verify(dao, times(2)).deleteSnapshots(argThat(newSnapshotIdQuery()), eq(session));
- }
-
- private BaseMatcher<PurgeSnapshotQuery> newRootSnapshotQuery() {
- return new ArgumentMatcher<PurgeSnapshotQuery>() {
- @Override
- public boolean matches(Object o) {
- PurgeSnapshotQuery query = (PurgeSnapshotQuery) o;
- return ObjectUtils.equals(query.getRootSnapshotId(), 999L);
- }
- };
- }
-
- private BaseMatcher<PurgeSnapshotQuery> newSnapshotIdQuery() {
- return new ArgumentMatcher<PurgeSnapshotQuery>() {
- @Override
- public boolean matches(Object o) {
- PurgeSnapshotQuery query = (PurgeSnapshotQuery) o;
- return ObjectUtils.equals(query.getId(), 999L);
- }
- };
- }
-
- private Filter newLazyFilter() {
- Filter filter1 = mock(Filter.class);
- when(filter1.filter(anyListOf(PurgeableSnapshotDto.class))).thenAnswer(new Answer<Object>() {
- public Object answer(InvocationOnMock invocation) throws Throwable {
- return invocation.getArguments()[0];
- }
- });
- return filter1;
- }
-}
+++ /dev/null
-/*
- * SonarQube, open source software quality management tool.
- * Copyright (C) 2008-2014 SonarSource
- * mailto:contact AT sonarsource DOT com
- *
- * SonarQube 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.
- *
- * SonarQube 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.core.computation.dbcleaner.period;
-
-import org.junit.Test;
-import org.sonar.api.utils.DateUtils;
-import org.sonar.core.computation.dbcleaner.DbCleanerTestUtils;
-import org.sonar.core.purge.PurgeableSnapshotDto;
-
-import java.util.Arrays;
-import java.util.List;
-
-import static org.fest.assertions.Assertions.assertThat;
-
-public class DeleteAllFilterTest {
-
- @Test
- public void shouldDeleteAllSnapshotsPriorToDate() {
- Filter filter = new DeleteAllFilter(DateUtils.parseDate("2011-12-25"));
-
- List<PurgeableSnapshotDto> toDelete = filter.filter(Arrays.asList(
- DbCleanerTestUtils.createSnapshotWithDate(1L, "2010-01-01"),
- DbCleanerTestUtils.createSnapshotWithDate(2L, "2010-12-25"),
- DbCleanerTestUtils.createSnapshotWithDate(3L, "2012-01-01")
- ));
-
- assertThat(toDelete).onProperty("snapshotId").containsOnly(1L, 2L);
- }
-}
+++ /dev/null
-/*
- * SonarQube, open source software quality management tool.
- * Copyright (C) 2008-2014 SonarSource
- * mailto:contact AT sonarsource DOT com
- *
- * SonarQube 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.
- *
- * SonarQube 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.core.computation.dbcleaner.period;
-
-import org.junit.Test;
-import org.sonar.api.utils.DateUtils;
-import org.sonar.core.purge.PurgeableSnapshotDto;
-
-import java.util.Arrays;
-import java.util.Calendar;
-import java.util.GregorianCalendar;
-import java.util.List;
-
-import static org.hamcrest.Matchers.is;
-import static org.junit.Assert.assertThat;
-import static org.sonar.core.computation.dbcleaner.DbCleanerTestUtils.createSnapshotWithDate;
-import static org.sonar.core.computation.dbcleaner.DbCleanerTestUtils.createSnapshotWithDateTime;
-
-public class IntervalTest {
- static int calendarField(Interval interval, int field) {
- if (interval.count() == 0) {
- return -1;
- }
-
- PurgeableSnapshotDto first = interval.get().iterator().next();
- GregorianCalendar cal = new GregorianCalendar();
- cal.setTime(first.getDate());
- return cal.get(field);
- }
-
- @Test
- public void shouldGroupByIntervals() {
- List<PurgeableSnapshotDto> snapshots = Arrays.asList(
- createSnapshotWithDate(1L, "2011-04-03"),
-
- createSnapshotWithDate(2L, "2011-05-01"),
- createSnapshotWithDate(3L, "2011-05-19"),
-
- createSnapshotWithDate(4L, "2011-06-02"),
- createSnapshotWithDate(5L, "2011-06-20"),
-
- createSnapshotWithDate(6L, "2012-06-29") // out of scope
- );
-
- List<Interval> intervals = Interval.group(snapshots, DateUtils.parseDate("2010-01-01"), DateUtils.parseDate("2011-12-31"), Calendar.MONTH);
- assertThat(intervals.size(), is(3));
-
- assertThat(intervals.get(0).count(), is(1));
- assertThat(calendarField(intervals.get(0), Calendar.MONTH), is(Calendar.APRIL));
-
- assertThat(intervals.get(1).count(), is(2));
- assertThat(calendarField(intervals.get(1), Calendar.MONTH), is(Calendar.MAY));
-
- assertThat(intervals.get(2).count(), is(2));
- assertThat(calendarField(intervals.get(2), Calendar.MONTH), is(Calendar.JUNE));
- }
-
- @Test
- public void shouldNotJoinMonthsOfDifferentYears() {
- List<PurgeableSnapshotDto> snapshots = Arrays.asList(
- createSnapshotWithDate(1L, "2010-04-03"),
- createSnapshotWithDate(2L, "2011-04-13")
- );
-
- List<Interval> intervals = Interval.group(snapshots, DateUtils.parseDate("2010-01-01"), DateUtils.parseDate("2011-12-31"), Calendar.MONTH);
- assertThat(intervals.size(), is(2));
-
- assertThat(intervals.get(0).count(), is(1));
- assertThat(calendarField(intervals.get(0), Calendar.MONTH), is(Calendar.APRIL));
- assertThat(calendarField(intervals.get(0), Calendar.YEAR), is(2010));
-
- assertThat(intervals.get(1).count(), is(1));
- assertThat(calendarField(intervals.get(1), Calendar.MONTH), is(Calendar.APRIL));
- assertThat(calendarField(intervals.get(1), Calendar.YEAR), is(2011));
- }
-
- @Test
- public void shouldIgnoreTimeWhenGroupingByIntervals() {
- List<PurgeableSnapshotDto> snapshots = Arrays.asList(
- createSnapshotWithDateTime(1L, "2011-05-25T16:16:48+0100"),
- createSnapshotWithDateTime(2L, "2012-01-26T16:16:48+0100"),
- createSnapshotWithDateTime(3L, "2012-01-27T16:16:48+0100")
- );
-
- List<Interval> intervals = Interval.group(snapshots, DateUtils.parseDate("2011-05-25"), DateUtils.parseDate("2012-01-26"), Calendar.MONTH);
- assertThat(intervals.size(), is(1));
- assertThat(intervals.get(0).count(), is(1));
- assertThat(intervals.get(0).get().get(0).getSnapshotId(), is(2L));
- }
-}
+++ /dev/null
-/*
- * SonarQube, open source software quality management tool.
- * Copyright (C) 2008-2014 SonarSource
- * mailto:contact AT sonarsource DOT com
- *
- * SonarQube 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.
- *
- * SonarQube 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.core.computation.dbcleaner.period;
-
-import com.google.common.base.Function;
-import com.google.common.collect.Iterables;
-import org.junit.Test;
-import org.sonar.api.utils.DateUtils;
-import org.sonar.core.purge.PurgeableSnapshotDto;
-
-import javax.annotation.Nullable;
-
-import java.util.Arrays;
-import java.util.Calendar;
-import java.util.List;
-
-import static com.google.common.collect.Lists.newArrayList;
-import static org.fest.assertions.Assertions.assertThat;
-import static org.sonar.core.computation.dbcleaner.DbCleanerTestUtils.createSnapshotWithDate;
-
-public class KeepOneFilterTest {
-
- private static List<Long> snapshotIds(List<PurgeableSnapshotDto> snapshotDtos) {
- return newArrayList(Iterables.transform(snapshotDtos, new Function<PurgeableSnapshotDto, Long>() {
- @Override
- public Long apply(@Nullable PurgeableSnapshotDto input) {
- return input != null ? input.getSnapshotId() : null;
- }
- }));
- }
-
- @Test
- public void shouldOnlyOneSnapshotPerInterval() {
- Filter filter = new KeepOneFilter(DateUtils.parseDate("2011-03-25"), DateUtils.parseDate("2011-08-25"), Calendar.MONTH, "month");
-
- List<PurgeableSnapshotDto> toDelete = filter.filter(Arrays.<PurgeableSnapshotDto>asList(
- createSnapshotWithDate(1L, "2010-01-01"), // out of scope -> keep
- createSnapshotWithDate(2L, "2011-05-01"), // may -> keep
- createSnapshotWithDate(3L, "2011-05-02"), // may -> to be deleted
- createSnapshotWithDate(4L, "2011-05-19"), // may -> to be deleted
- createSnapshotWithDate(5L, "2011-06-01"), // june -> keep
- createSnapshotWithDate(6L, "2012-01-01") // out of scope -> keep
- ));
-
- assertThat(toDelete).hasSize(2);
-
- List<Long> snapshotIds = snapshotIds(toDelete);
- assertThat(snapshotIds).contains(3L);
- assertThat(snapshotIds.contains(4L));
- }
-
- @Test
- public void shouldKeepNonDeletableSnapshots() {
- Filter filter = new KeepOneFilter(DateUtils.parseDate("2011-03-25"), DateUtils.parseDate("2011-08-25"), Calendar.MONTH, "month");
-
- List<PurgeableSnapshotDto> toDelete = filter.filter(Arrays.<PurgeableSnapshotDto>asList(
- createSnapshotWithDate(1L, "2011-05-01"), // to be deleted
- createSnapshotWithDate(2L, "2011-05-02").setLast(true),
- createSnapshotWithDate(3L, "2011-05-19").setHasEvents(true).setLast(false),
- createSnapshotWithDate(4L, "2011-05-23") // to be deleted
- ));
-
- assertThat(toDelete).hasSize(2);
-
- List<Long> snapshotIds = snapshotIds(toDelete);
- assertThat(snapshotIds).contains(1L);
- assertThat(snapshotIds.contains(4L));
- }
-
- @Test
- public void test_isDeletable() {
- assertThat(KeepOneFilter.isDeletable(createSnapshotWithDate(1L, "2011-05-01"))).isTrue();
- assertThat(KeepOneFilter.isDeletable(createSnapshotWithDate(1L, "2011-05-01").setLast(true))).isFalse();
- assertThat(KeepOneFilter.isDeletable(createSnapshotWithDate(1L, "2011-05-01").setHasEvents(true))).isFalse();
- }
-
-}
--- /dev/null
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2014 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube 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.
+ *
+ * SonarQube 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.computation.dbcleaner;
+
+import org.junit.Test;
+
+import static org.fest.assertions.Assertions.assertThat;
+
+public class DataCleanerPropertiesTest {
+
+ @Test
+ public void shouldGetExtensions() {
+ assertThat(DataCleanerProperties.all()).hasSize(6);
+ }
+}
--- /dev/null
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2014 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube 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.
+ *
+ * SonarQube 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.computation.dbcleaner;
+
+import org.sonar.api.utils.DateUtils;
+import org.sonar.core.purge.PurgeableSnapshotDto;
+
+public final class DbCleanerTestUtils {
+
+ private DbCleanerTestUtils() {
+ }
+
+ public static PurgeableSnapshotDto createSnapshotWithDate(long snapshotId, String date) {
+ PurgeableSnapshotDto snapshot = new PurgeableSnapshotDto();
+ snapshot.setSnapshotId(snapshotId);
+ snapshot.setDate(DateUtils.parseDate(date));
+ return snapshot;
+ }
+
+ public static PurgeableSnapshotDto createSnapshotWithDateTime(long snapshotId, String datetime) {
+ PurgeableSnapshotDto snapshot = new PurgeableSnapshotDto();
+ snapshot.setSnapshotId(snapshotId);
+ snapshot.setDate(DateUtils.parseDateTime(datetime));
+ return snapshot;
+ }
+
+}
--- /dev/null
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2014 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube 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.
+ *
+ * SonarQube 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.computation.dbcleaner;
+
+import ch.qos.logback.classic.Logger;
+import org.junit.Before;
+import org.junit.Test;
+import org.mockito.ArgumentMatcher;
+import org.sonar.api.CoreProperties;
+import org.sonar.api.config.PropertyDefinitions;
+import org.sonar.api.config.Settings;
+import org.sonar.api.resources.Qualifiers;
+import org.sonar.api.resources.Scopes;
+import org.sonar.server.computation.dbcleaner.period.DefaultPeriodCleaner;
+import org.sonar.core.purge.IdUuidPair;
+import org.sonar.core.purge.PurgeConfiguration;
+import org.sonar.core.purge.PurgeDao;
+import org.sonar.core.purge.PurgeProfiler;
+import org.sonar.core.resource.ResourceDao;
+import org.sonar.core.resource.ResourceDto;
+
+import static org.fest.assertions.Assertions.assertThat;
+import static org.mockito.Matchers.any;
+import static org.mockito.Matchers.anyLong;
+import static org.mockito.Matchers.argThat;
+import static org.mockito.Mockito.*;
+
+public class DefaultPurgeTaskTest {
+
+ private DefaultPurgeTask sut;
+ private ResourceDao resourceDao;
+ private PurgeDao purgeDao;
+ private Settings settings;
+ private DefaultPeriodCleaner periodCleaner;
+ private PurgeProfiler profiler;
+
+ @Before
+ public void before() throws Exception {
+ this.purgeDao = mock(PurgeDao.class);
+ this.resourceDao = mock(ResourceDao.class);
+ when(resourceDao.getResource(anyLong())).thenReturn(new ResourceDto().setQualifier(Qualifiers.PROJECT));
+
+ this.settings = mock(Settings.class);
+ this.periodCleaner = mock(DefaultPeriodCleaner.class);
+ this.profiler = mock(PurgeProfiler.class);
+
+ this.sut = new DefaultPurgeTask(purgeDao, resourceDao, settings, periodCleaner, profiler);
+ }
+
+ @Test
+ public void shouldNotDeleteHistoricalDataOfDirectories() {
+ PurgeDao purgeDao = mock(PurgeDao.class);
+ Settings settings = new Settings(new PropertyDefinitions(DataCleanerProperties.all()));
+ settings.setProperty(DbCleanerConstants.PROPERTY_CLEAN_DIRECTORY, "false");
+ DefaultPurgeTask task = new DefaultPurgeTask(purgeDao, resourceDao, settings, mock(DefaultPeriodCleaner.class), mock(PurgeProfiler.class));
+
+ task.purge(1L);
+
+ verify(purgeDao).purge(argThat(new ArgumentMatcher<PurgeConfiguration>() {
+ @Override
+ public boolean matches(Object o) {
+ PurgeConfiguration conf = (PurgeConfiguration) o;
+ return conf.rootProjectId() == 1L && conf.scopesWithoutHistoricalData().length == 1 && conf.scopesWithoutHistoricalData()[0].equals(Scopes.FILE);
+ }
+ }));
+ }
+
+ @Test
+ public void shouldDeleteHistoricalDataOfDirectoriesByDefault() {
+ PurgeDao purgeDao = mock(PurgeDao.class);
+ Settings settings = new Settings(new PropertyDefinitions(DataCleanerProperties.all()));
+ DefaultPurgeTask task = new DefaultPurgeTask(purgeDao, resourceDao, settings, mock(DefaultPeriodCleaner.class), mock(PurgeProfiler.class));
+
+ task.purge(1L);
+
+ verify(purgeDao).purge(argThat(new ArgumentMatcher<PurgeConfiguration>() {
+ @Override
+ public boolean matches(Object o) {
+ PurgeConfiguration conf = (PurgeConfiguration) o;
+ return conf.rootProjectId() == 1L &&
+ conf.scopesWithoutHistoricalData().length == 2 &&
+ conf.scopesWithoutHistoricalData()[0].equals(Scopes.DIRECTORY) &&
+ conf.scopesWithoutHistoricalData()[1].equals(Scopes.FILE);
+ }
+ }));
+ }
+
+ @Test
+ public void shouldNotFailOnErrors() {
+ PurgeDao purgeDao = mock(PurgeDao.class);
+ when(purgeDao.purge(any(PurgeConfiguration.class))).thenThrow(new RuntimeException());
+ DefaultPurgeTask task = new DefaultPurgeTask(purgeDao, resourceDao, new Settings(), mock(DefaultPeriodCleaner.class), mock(PurgeProfiler.class));
+
+ task.purge(1L);
+
+ verify(purgeDao, times(1)).purge(any(PurgeConfiguration.class));
+ }
+
+ @Test
+ public void shouldDumpProfiling() {
+ PurgeConfiguration conf = new PurgeConfiguration(1L, new String[0], 30);
+ PurgeDao purgeDao = mock(PurgeDao.class);
+ when(purgeDao.purge(conf)).thenThrow(new RuntimeException());
+ Settings settings = new Settings(new PropertyDefinitions(DataCleanerProperties.all()));
+ settings.setProperty(CoreProperties.PROFILING_LOG_PROPERTY, true);
+ PurgeProfiler profiler = mock(PurgeProfiler.class);
+
+ DefaultPurgeTask task = new DefaultPurgeTask(purgeDao, resourceDao, settings, mock(DefaultPeriodCleaner.class), profiler);
+ task.purge(1L);
+
+ verify(profiler).dump(anyLong(), any(Logger.class));
+ }
+
+ @Test
+ public void recognize_view_and_subview() {
+ boolean viewCheck = sut.isNotViewNorSubview(Qualifiers.VIEW);
+ boolean subViewCheck = sut.isNotViewNorSubview(Qualifiers.SUBVIEW);
+
+ assertThat(viewCheck).isFalse();
+ assertThat(subViewCheck).isFalse();
+ }
+
+ @Test
+ public void call_dao_delete_when_deleting() throws Exception {
+ when(resourceDao.getResource(123L)).thenReturn(new ResourceDto().setId(123L).setUuid("A"));
+
+ sut.delete(123L);
+
+ verify(purgeDao, times(1)).deleteResourceTree(any(IdUuidPair.class));
+ }
+}
--- /dev/null
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2014 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube 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.
+ *
+ * SonarQube 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.computation.dbcleaner.period;
+
+import org.apache.commons.lang.ObjectUtils;
+import org.hamcrest.BaseMatcher;
+import org.junit.Test;
+import org.mockito.ArgumentMatcher;
+import org.mockito.invocation.InvocationOnMock;
+import org.mockito.stubbing.Answer;
+import org.sonar.api.config.Settings;
+import org.sonar.core.persistence.DbSession;
+import org.sonar.core.persistence.MyBatis;
+import org.sonar.core.purge.PurgeDao;
+import org.sonar.core.purge.PurgeSnapshotQuery;
+import org.sonar.core.purge.PurgeableSnapshotDto;
+
+import java.util.Arrays;
+import java.util.Date;
+
+import static org.mockito.Matchers.anyListOf;
+import static org.mockito.Matchers.argThat;
+import static org.mockito.Matchers.eq;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+public class DefaultPeriodCleanerTest {
+
+ @Test
+ public void doClean() {
+ PurgeDao dao = mock(PurgeDao.class);
+ DbSession session = mock(DbSession.class);
+ when(dao.selectPurgeableSnapshots(123L, session)).thenReturn(Arrays.asList(
+ new PurgeableSnapshotDto().setSnapshotId(999L).setDate(new Date())));
+ Filter filter1 = newLazyFilter();
+ Filter filter2 = newLazyFilter();
+
+ DefaultPeriodCleaner cleaner = new DefaultPeriodCleaner(dao, mock(Settings.class), mock(MyBatis.class));
+ cleaner.doClean(123L, Arrays.asList(filter1, filter2), session);
+
+ verify(filter1).log();
+ verify(filter2).log();
+ verify(dao, times(2)).deleteSnapshots(argThat(newRootSnapshotQuery()), eq(session));
+ verify(dao, times(2)).deleteSnapshots(argThat(newSnapshotIdQuery()), eq(session));
+ }
+
+ private BaseMatcher<PurgeSnapshotQuery> newRootSnapshotQuery() {
+ return new ArgumentMatcher<PurgeSnapshotQuery>() {
+ @Override
+ public boolean matches(Object o) {
+ PurgeSnapshotQuery query = (PurgeSnapshotQuery) o;
+ return ObjectUtils.equals(query.getRootSnapshotId(), 999L);
+ }
+ };
+ }
+
+ private BaseMatcher<PurgeSnapshotQuery> newSnapshotIdQuery() {
+ return new ArgumentMatcher<PurgeSnapshotQuery>() {
+ @Override
+ public boolean matches(Object o) {
+ PurgeSnapshotQuery query = (PurgeSnapshotQuery) o;
+ return ObjectUtils.equals(query.getId(), 999L);
+ }
+ };
+ }
+
+ private Filter newLazyFilter() {
+ Filter filter1 = mock(Filter.class);
+ when(filter1.filter(anyListOf(PurgeableSnapshotDto.class))).thenAnswer(new Answer<Object>() {
+ public Object answer(InvocationOnMock invocation) throws Throwable {
+ return invocation.getArguments()[0];
+ }
+ });
+ return filter1;
+ }
+}
--- /dev/null
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2014 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube 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.
+ *
+ * SonarQube 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.computation.dbcleaner.period;
+
+import org.junit.Test;
+import org.sonar.api.utils.DateUtils;
+import org.sonar.server.computation.dbcleaner.DbCleanerTestUtils;
+import org.sonar.core.purge.PurgeableSnapshotDto;
+
+import java.util.Arrays;
+import java.util.List;
+
+import static org.fest.assertions.Assertions.assertThat;
+
+public class DeleteAllFilterTest {
+
+ @Test
+ public void shouldDeleteAllSnapshotsPriorToDate() {
+ Filter filter = new DeleteAllFilter(DateUtils.parseDate("2011-12-25"));
+
+ List<PurgeableSnapshotDto> toDelete = filter.filter(Arrays.asList(
+ DbCleanerTestUtils.createSnapshotWithDate(1L, "2010-01-01"),
+ DbCleanerTestUtils.createSnapshotWithDate(2L, "2010-12-25"),
+ DbCleanerTestUtils.createSnapshotWithDate(3L, "2012-01-01")
+ ));
+
+ assertThat(toDelete).onProperty("snapshotId").containsOnly(1L, 2L);
+ }
+}
--- /dev/null
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2014 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube 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.
+ *
+ * SonarQube 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.computation.dbcleaner.period;
+
+import org.junit.Test;
+import org.sonar.api.utils.DateUtils;
+import org.sonar.core.purge.PurgeableSnapshotDto;
+import org.sonar.server.computation.dbcleaner.DbCleanerTestUtils;
+
+import java.util.Arrays;
+import java.util.Calendar;
+import java.util.GregorianCalendar;
+import java.util.List;
+
+import static org.hamcrest.Matchers.is;
+import static org.junit.Assert.assertThat;
+
+public class IntervalTest {
+ static int calendarField(Interval interval, int field) {
+ if (interval.count() == 0) {
+ return -1;
+ }
+
+ PurgeableSnapshotDto first = interval.get().iterator().next();
+ GregorianCalendar cal = new GregorianCalendar();
+ cal.setTime(first.getDate());
+ return cal.get(field);
+ }
+
+ @Test
+ public void shouldGroupByIntervals() {
+ List<PurgeableSnapshotDto> snapshots = Arrays.asList(
+ DbCleanerTestUtils.createSnapshotWithDate(1L, "2011-04-03"),
+
+ DbCleanerTestUtils.createSnapshotWithDate(2L, "2011-05-01"),
+ DbCleanerTestUtils.createSnapshotWithDate(3L, "2011-05-19"),
+
+ DbCleanerTestUtils.createSnapshotWithDate(4L, "2011-06-02"),
+ DbCleanerTestUtils.createSnapshotWithDate(5L, "2011-06-20"),
+
+ DbCleanerTestUtils.createSnapshotWithDate(6L, "2012-06-29") // out of scope
+ );
+
+ List<Interval> intervals = Interval.group(snapshots, DateUtils.parseDate("2010-01-01"), DateUtils.parseDate("2011-12-31"), Calendar.MONTH);
+ assertThat(intervals.size(), is(3));
+
+ assertThat(intervals.get(0).count(), is(1));
+ assertThat(calendarField(intervals.get(0), Calendar.MONTH), is(Calendar.APRIL));
+
+ assertThat(intervals.get(1).count(), is(2));
+ assertThat(calendarField(intervals.get(1), Calendar.MONTH), is(Calendar.MAY));
+
+ assertThat(intervals.get(2).count(), is(2));
+ assertThat(calendarField(intervals.get(2), Calendar.MONTH), is(Calendar.JUNE));
+ }
+
+ @Test
+ public void shouldNotJoinMonthsOfDifferentYears() {
+ List<PurgeableSnapshotDto> snapshots = Arrays.asList(
+ DbCleanerTestUtils.createSnapshotWithDate(1L, "2010-04-03"),
+ DbCleanerTestUtils.createSnapshotWithDate(2L, "2011-04-13")
+ );
+
+ List<Interval> intervals = Interval.group(snapshots, DateUtils.parseDate("2010-01-01"), DateUtils.parseDate("2011-12-31"), Calendar.MONTH);
+ assertThat(intervals.size(), is(2));
+
+ assertThat(intervals.get(0).count(), is(1));
+ assertThat(calendarField(intervals.get(0), Calendar.MONTH), is(Calendar.APRIL));
+ assertThat(calendarField(intervals.get(0), Calendar.YEAR), is(2010));
+
+ assertThat(intervals.get(1).count(), is(1));
+ assertThat(calendarField(intervals.get(1), Calendar.MONTH), is(Calendar.APRIL));
+ assertThat(calendarField(intervals.get(1), Calendar.YEAR), is(2011));
+ }
+
+ @Test
+ public void shouldIgnoreTimeWhenGroupingByIntervals() {
+ List<PurgeableSnapshotDto> snapshots = Arrays.asList(
+ DbCleanerTestUtils.createSnapshotWithDateTime(1L, "2011-05-25T16:16:48+0100"),
+ DbCleanerTestUtils.createSnapshotWithDateTime(2L, "2012-01-26T16:16:48+0100"),
+ DbCleanerTestUtils.createSnapshotWithDateTime(3L, "2012-01-27T16:16:48+0100")
+ );
+
+ List<Interval> intervals = Interval.group(snapshots, DateUtils.parseDate("2011-05-25"), DateUtils.parseDate("2012-01-26"), Calendar.MONTH);
+ assertThat(intervals.size(), is(1));
+ assertThat(intervals.get(0).count(), is(1));
+ assertThat(intervals.get(0).get().get(0).getSnapshotId(), is(2L));
+ }
+}
--- /dev/null
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2014 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube 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.
+ *
+ * SonarQube 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.computation.dbcleaner.period;
+
+import com.google.common.base.Function;
+import com.google.common.collect.Iterables;
+import org.junit.Test;
+import org.sonar.api.utils.DateUtils;
+import org.sonar.core.purge.PurgeableSnapshotDto;
+import org.sonar.server.computation.dbcleaner.DbCleanerTestUtils;
+
+import javax.annotation.Nullable;
+
+import java.util.Arrays;
+import java.util.Calendar;
+import java.util.List;
+
+import static com.google.common.collect.Lists.newArrayList;
+import static org.fest.assertions.Assertions.assertThat;
+
+public class KeepOneFilterTest {
+
+ private static List<Long> snapshotIds(List<PurgeableSnapshotDto> snapshotDtos) {
+ return newArrayList(Iterables.transform(snapshotDtos, new Function<PurgeableSnapshotDto, Long>() {
+ @Override
+ public Long apply(@Nullable PurgeableSnapshotDto input) {
+ return input != null ? input.getSnapshotId() : null;
+ }
+ }));
+ }
+
+ @Test
+ public void shouldOnlyOneSnapshotPerInterval() {
+ Filter filter = new KeepOneFilter(DateUtils.parseDate("2011-03-25"), DateUtils.parseDate("2011-08-25"), Calendar.MONTH, "month");
+
+ List<PurgeableSnapshotDto> toDelete = filter.filter(Arrays.<PurgeableSnapshotDto>asList(
+ DbCleanerTestUtils.createSnapshotWithDate(1L, "2010-01-01"), // out of scope -> keep
+ DbCleanerTestUtils.createSnapshotWithDate(2L, "2011-05-01"), // may -> keep
+ DbCleanerTestUtils.createSnapshotWithDate(3L, "2011-05-02"), // may -> to be deleted
+ DbCleanerTestUtils.createSnapshotWithDate(4L, "2011-05-19"), // may -> to be deleted
+ DbCleanerTestUtils.createSnapshotWithDate(5L, "2011-06-01"), // june -> keep
+ DbCleanerTestUtils.createSnapshotWithDate(6L, "2012-01-01") // out of scope -> keep
+ ));
+
+ assertThat(toDelete).hasSize(2);
+
+ List<Long> snapshotIds = snapshotIds(toDelete);
+ assertThat(snapshotIds).contains(3L);
+ assertThat(snapshotIds.contains(4L));
+ }
+
+ @Test
+ public void shouldKeepNonDeletableSnapshots() {
+ Filter filter = new KeepOneFilter(DateUtils.parseDate("2011-03-25"), DateUtils.parseDate("2011-08-25"), Calendar.MONTH, "month");
+
+ List<PurgeableSnapshotDto> toDelete = filter.filter(Arrays.<PurgeableSnapshotDto>asList(
+ DbCleanerTestUtils.createSnapshotWithDate(1L, "2011-05-01"), // to be deleted
+ DbCleanerTestUtils.createSnapshotWithDate(2L, "2011-05-02").setLast(true),
+ DbCleanerTestUtils.createSnapshotWithDate(3L, "2011-05-19").setHasEvents(true).setLast(false),
+ DbCleanerTestUtils.createSnapshotWithDate(4L, "2011-05-23") // to be deleted
+ ));
+
+ assertThat(toDelete).hasSize(2);
+
+ List<Long> snapshotIds = snapshotIds(toDelete);
+ assertThat(snapshotIds).contains(1L);
+ assertThat(snapshotIds.contains(4L));
+ }
+
+ @Test
+ public void test_isDeletable() {
+ assertThat(KeepOneFilter.isDeletable(DbCleanerTestUtils.createSnapshotWithDate(1L, "2011-05-01"))).isTrue();
+ assertThat(KeepOneFilter.isDeletable(DbCleanerTestUtils.createSnapshotWithDate(1L, "2011-05-01").setLast(true))).isFalse();
+ assertThat(KeepOneFilter.isDeletable(DbCleanerTestUtils.createSnapshotWithDate(1L, "2011-05-01").setHasEvents(true))).isFalse();
+ }
+
+}