--- /dev/null
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2013 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.dryrun;
+
+import org.apache.commons.io.FileUtils;
+import org.sonar.api.platform.ServerFileSystem;
+import org.sonar.core.properties.PropertiesDao;
+import org.sonar.core.properties.PropertyDto;
+import org.sonar.core.resource.ResourceDao;
+import org.sonar.core.resource.ResourceDto;
+
+import javax.annotation.Nullable;
+
+import java.io.File;
+
+/**
+ * @since 4.0
+ */
+public class DryRunCache {
+
+ public static final String SONAR_DRY_RUN_CACHE_LAST_UPDATE_KEY = "sonar.dryRun.cache.lastUpdate";
+
+ private ServerFileSystem serverFileSystem;
+ private PropertiesDao propertiesDao;
+ private ResourceDao resourceDao;
+
+ public DryRunCache(ServerFileSystem serverFileSystem, PropertiesDao propertiesDao, ResourceDao resourceDao) {
+ this.serverFileSystem = serverFileSystem;
+ this.propertiesDao = propertiesDao;
+ this.resourceDao = resourceDao;
+ }
+
+ private File getRootCacheLocation() {
+ return new File(serverFileSystem.getTempDir(), "dryRun");
+ }
+
+ public File getCacheLocation(@Nullable Long projectId) {
+ return new File(getRootCacheLocation(), projectId != null ? projectId.toString() : "default");
+ }
+
+ public long getModificationTimestamp(@Nullable Long projectId) {
+ if (projectId == null) {
+ PropertyDto dto = propertiesDao.selectGlobalProperty(SONAR_DRY_RUN_CACHE_LAST_UPDATE_KEY);
+ if (dto == null) {
+ return 0;
+ }
+ return Long.valueOf(dto.getValue());
+ }
+ // For modules look for root project last modification timestamp
+ Long rootId = resourceDao.getRootProjectByComponentId(projectId).getId();
+ PropertyDto dto = propertiesDao.selectProjectProperty(rootId, SONAR_DRY_RUN_CACHE_LAST_UPDATE_KEY);
+ if (dto == null) {
+ return 0;
+ }
+ return Long.valueOf(dto.getValue());
+ }
+
+ public void cleanAll() {
+ // Delete folder where dryRun DB are stored
+ FileUtils.deleteQuietly(getRootCacheLocation());
+ // Delete all lastUpdate properties to force generation of new DB
+ propertiesDao.deleteAllProperties(SONAR_DRY_RUN_CACHE_LAST_UPDATE_KEY);
+ }
+
+ public void clean(@Nullable Long resourceId) {
+ // Delete folder where dryRun DB are stored
+ FileUtils.deleteQuietly(getCacheLocation(resourceId));
+ }
+
+ public void reportGlobalModification() {
+ // Delete folder where dryRun DB are stored
+ FileUtils.deleteQuietly(getRootCacheLocation());
+
+ propertiesDao.setProperty(new PropertyDto().setKey(SONAR_DRY_RUN_CACHE_LAST_UPDATE_KEY).setValue(String.valueOf(System.nanoTime())));
+ }
+
+ public void reportResourceModification(long projectId) {
+ // Delete folder where dryRun DB are stored
+ FileUtils.deleteQuietly(getCacheLocation(projectId));
+
+ ResourceDto rootProject = resourceDao.getRootProjectByComponentId(projectId);
+ propertiesDao.setProperty(new PropertyDto().setKey(SONAR_DRY_RUN_CACHE_LAST_UPDATE_KEY).setResourceId(rootProject.getId())
+ .setValue(String.valueOf(System.nanoTime())));
+ }
+}
--- /dev/null
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2013 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.dryrun;
+
+import javax.annotation.ParametersAreNonnullByDefault;
+
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.sonar.api.ServerComponent;
-import org.sonar.api.config.Settings;
import org.sonar.api.issue.Issue;
-import org.sonar.api.platform.ServerFileSystem;
import org.sonar.api.utils.SonarException;
-import org.sonar.core.resource.ResourceDao;
+import org.sonar.core.dryrun.DryRunCache;
import javax.annotation.Nullable;
import javax.sql.DataSource;
import java.util.TreeSet;
public class DryRunDatabaseFactory implements ServerComponent {
- public static final String SONAR_DRY_RUN_CACHE_KEY_PREFIX = "sonar.dryRun.cache.";
- public static final String SONAR_DRY_RUN_CACHE_LAST_UPDATE_KEY = SONAR_DRY_RUN_CACHE_KEY_PREFIX + "lastUpdate";
private static final Logger LOG = LoggerFactory.getLogger(DryRunDatabaseFactory.class);
private static final String DIALECT = "h2";
private static final String DRIVER = "org.h2.Driver";
private static final String PASSWORD = SONAR;
private final Database database;
- private final ServerFileSystem serverFileSystem;
- private final Settings settings;
- private final ResourceDao resourceDao;
+ private DryRunCache dryRunCache;
- public static String getCacheLastUpdateKey(Long rootProjectId) {
- return SONAR_DRY_RUN_CACHE_KEY_PREFIX + rootProjectId + ".lastUpdate";
- }
-
- public DryRunDatabaseFactory(Database database, ServerFileSystem serverFileSystem, Settings settings, ResourceDao resourceDao) {
+ public DryRunDatabaseFactory(Database database, DryRunCache dryRunCache) {
this.database = database;
- this.serverFileSystem = serverFileSystem;
- this.settings = settings;
- this.resourceDao = resourceDao;
- }
-
- private File getRootCacheLocation() {
- return new File(serverFileSystem.getTempDir(), "dryRun");
- }
-
- private File getCacheLocation(@Nullable Long projectId) {
- return new File(getRootCacheLocation(), projectId != null ? projectId.toString() : "default");
+ this.dryRunCache = dryRunCache;
}
private Long getLastTimestampInCache(@Nullable Long projectId) {
- File cacheLocation = getCacheLocation(projectId);
+ File cacheLocation = dryRunCache.getCacheLocation(projectId);
if (!cacheLocation.exists()) {
return null;
}
}
private boolean isValid(@Nullable Long projectId, long lastTimestampInCache) {
- long globalTimestamp = settings.getLong(SONAR_DRY_RUN_CACHE_LAST_UPDATE_KEY);
+ long globalTimestamp = dryRunCache.getModificationTimestamp(null);
if (globalTimestamp > lastTimestampInCache) {
return false;
}
if (projectId != null) {
- // For modules look for root project last modification timestamp
- Long rootId = resourceDao.getRootProjectByComponentId(projectId).getId();
- long projectTimestamp = settings.getLong(getCacheLastUpdateKey(rootId));
+ long projectTimestamp = dryRunCache.getModificationTimestamp(projectId);
if (projectTimestamp > lastTimestampInCache) {
return false;
}
Long lastTimestampInCache = getLastTimestampInCache(projectId);
if (lastTimestampInCache == null || !isValid(projectId, lastTimestampInCache)) {
lastTimestampInCache = System.nanoTime();
- cleanCache(projectId);
+ dryRunCache.clean(projectId);
createNewDatabaseForDryRun(projectId, startup, lastTimestampInCache);
}
return dbFileContent(projectId, lastTimestampInCache);
}
- private void cleanCache(@Nullable Long projectId) {
- FileUtils.deleteQuietly(getCacheLocation(projectId));
- }
-
public String getH2DBName(File location, long timestamp) {
return location.getAbsolutePath() + File.separator + timestamp;
}
}
private void createNewDatabaseForDryRun(Long projectId, long startup, Long lastTimestampInCache) {
- String tmpName = getTemporaryH2DBName(getCacheLocation(projectId), lastTimestampInCache);
- String finalName = getH2DBName(getCacheLocation(projectId), lastTimestampInCache);
+ String tmpName = getTemporaryH2DBName(dryRunCache.getCacheLocation(projectId), lastTimestampInCache);
+ String finalName = getH2DBName(dryRunCache.getCacheLocation(projectId), lastTimestampInCache);
try {
DataSource source = database.getDataSource();
}
private byte[] dbFileContent(@Nullable Long projectId, long timestamp) {
- File cacheLocation = getCacheLocation(projectId);
+ File cacheLocation = dryRunCache.getCacheLocation(projectId);
try {
FileUtils.forceMkdir(cacheLocation);
} catch (IOException e) {
}
}
+ public PropertyDto selectProjectProperty(long resourceId, String propertyKey) {
+ SqlSession session = mybatis.openSession();
+ PropertiesMapper mapper = session.getMapper(PropertiesMapper.class);
+ try {
+ return mapper.selectByKey(new PropertyDto().setKey(propertyKey).setResourceId(resourceId));
+ } finally {
+ MyBatis.closeQuietly(session);
+ }
+ }
+
public void setProperty(PropertyDto property) {
SqlSession session = mybatis.openSession();
PropertiesMapper mapper = session.getMapper(PropertiesMapper.class);
}
}
+ public void deleteAllProperties(String key) {
+ SqlSession session = mybatis.openSession();
+ PropertiesMapper mapper = session.getMapper(PropertiesMapper.class);
+ try {
+ mapper.deleteAllProperties(key);
+ session.commit();
+
+ } finally {
+ MyBatis.closeQuietly(session);
+ }
+ }
+
public void saveGlobalProperties(Map<String, String> properties) {
SqlSession session = mybatis.openBatchSession();
PropertiesMapper mapper = session.getMapper(PropertiesMapper.class);
void deleteGlobalProperty(String key);
+ void deleteAllProperties(String key);
+
void deleteGlobalProperties();
void renamePropertyKey(@Param("oldKey") String oldKey, @Param("newKey") String newKey);
delete from properties where resource_id is null and user_id is null
</delete>
+ <delete id="deleteAllProperties" parameterType="string">
+ delete from properties where prop_key=#{id}
+ </delete>
+
<update id="renamePropertyKey" parameterType="map">
update properties set prop_key = #{newKey} where prop_key=#{oldKey}
</update>
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.TemporaryFolder;
-import org.sonar.api.config.Settings;
-import org.sonar.api.platform.ServerFileSystem;
-import org.sonar.core.resource.ResourceDao;
-import org.sonar.core.resource.ResourceDto;
+import org.sonar.core.dryrun.DryRunCache;
import java.io.File;
import java.io.IOException;
import java.sql.SQLException;
import static org.fest.assertions.Assertions.assertThat;
+import static org.mockito.Matchers.anyLong;
import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
public class DryRunDatabaseFactoryTest extends AbstractDaoTestCase {
DryRunDatabaseFactory localDatabaseFactory;
- ServerFileSystem serverFileSystem = mock(ServerFileSystem.class);
BasicDataSource dataSource;
@Rule
public TemporaryFolder temporaryFolder = new TemporaryFolder();
- private File dryRunCache;
- private ResourceDao resourceDao;
- private Settings settings;
+ private File dryRunCacheFolder;
+ private DryRunCache dryRunCache;
@Before
public void setUp() throws Exception {
File tempFolder = temporaryFolder.newFolder();
- dryRunCache = new File(tempFolder, "dryRun");
- when(serverFileSystem.getTempDir()).thenReturn(tempFolder);
- resourceDao = mock(ResourceDao.class);
- settings = new Settings();
- localDatabaseFactory = new DryRunDatabaseFactory(getDatabase(), serverFileSystem, settings, resourceDao);
+ dryRunCacheFolder = new File(tempFolder, "dryRun");
+ dryRunCache = mock(DryRunCache.class);
+ when(dryRunCache.getCacheLocation(anyLong())).thenReturn(dryRunCacheFolder);
+ when(dryRunCache.getModificationTimestamp(null)).thenReturn(0L);
+ when(dryRunCache.getModificationTimestamp(anyLong())).thenReturn(0L);
+ localDatabaseFactory = new DryRunDatabaseFactory(getDatabase(), dryRunCache);
}
@After
public void should_create_database_without_project() throws IOException, SQLException {
setupData("should_create_database");
- assertThat(new File(dryRunCache, "default")).doesNotExist();
+ assertThat(dryRunCacheFolder).doesNotExist();
byte[] database = localDatabaseFactory.createDatabaseForDryRun(null);
dataSource = createDatabase(database);
assertThat(rowCount("projects")).isZero();
assertThat(rowCount("alerts")).isEqualTo(1);
- assertThat(new File(dryRunCache, "default")).isDirectory();
+ assertThat(dryRunCacheFolder).isDirectory();
}
@Test
public void should_reuse_database_without_project() throws IOException, SQLException {
setupData("should_create_database");
- FileUtils.write(new File(new File(dryRunCache, "default"), "123456.h2.db"), "fakeDbContent");
+ FileUtils.write(new File(dryRunCacheFolder, "123456.h2.db"), "fakeDbContent");
byte[] database = localDatabaseFactory.createDatabaseForDryRun(null);
setupData("should_create_database");
// There is a DB in cache
- File existingDb = new File(new File(dryRunCache, "default"), "123456.h2.db");
+ File existingDb = new File(dryRunCacheFolder, "123456.h2.db");
FileUtils.write(existingDb, "fakeDbContent");
// But last modification timestamp is greater
- settings.setProperty("sonar.dryRun.cache.lastUpdate", "123457");
+ when(dryRunCache.getModificationTimestamp(null)).thenReturn(123457L);
byte[] database = localDatabaseFactory.createDatabaseForDryRun(null);
dataSource = createDatabase(database);
assertThat(rowCount("alerts")).isEqualTo(1);
// Previous cached DB was deleted
- assertThat(existingDb).doesNotExist();
+ verify(dryRunCache).clean(null);
}
@Test
public void should_create_database_with_project() throws IOException, SQLException {
setupData("should_create_database");
- assertThat(new File(dryRunCache, "123")).doesNotExist();
+ assertThat(dryRunCacheFolder).doesNotExist();
byte[] database = localDatabaseFactory.createDatabaseForDryRun(123L);
dataSource = createDatabase(database);
assertThat(rowCount("snapshots")).isEqualTo(1);
assertThat(rowCount("project_measures")).isEqualTo(1);
- assertThat(new File(dryRunCache, "123")).isDirectory();
+ assertThat(dryRunCacheFolder).isDirectory();
}
@Test
public void should_reuse_database_with_project() throws IOException, SQLException {
setupData("should_create_database");
- FileUtils.write(new File(new File(dryRunCache, "123"), "123456.h2.db"), "fakeDbContent");
+ FileUtils.write(new File(dryRunCacheFolder, "123456.h2.db"), "fakeDbContent");
- when(resourceDao.getRootProjectByComponentId(123L)).thenReturn(new ResourceDto().setId(123L));
byte[] database = localDatabaseFactory.createDatabaseForDryRun(123L);
assertThat(new String(database, Charsets.UTF_8)).isEqualTo("fakeDbContent");
public void should_evict_database_with_project() throws IOException, SQLException {
setupData("should_create_database");
- when(resourceDao.getRootProjectByComponentId(123L)).thenReturn(new ResourceDto().setId(123L));
-
// There is a DB in cache
- File existingDb = new File(new File(dryRunCache, "123"), "123456.h2.db");
+ File existingDb = new File(dryRunCacheFolder, "123456.h2.db");
FileUtils.write(existingDb, "fakeDbContent");
// But last project modification timestamp is greater
- settings.setProperty("sonar.dryRun.cache.123.lastUpdate", "123457");
+ when(dryRunCache.getModificationTimestamp(123L)).thenReturn(123457L);
byte[] database = localDatabaseFactory.createDatabaseForDryRun(123L);
dataSource = createDatabase(database);
assertThat(rowCount("project_measures")).isEqualTo(1);
// Previous cached DB was deleted
- assertThat(existingDb).doesNotExist();
+ verify(dryRunCache).clean(123L);
}
@Test
public void should_export_issues_of_project_tree() throws IOException, SQLException {
setupData("multi-modules-with-issues");
- when(serverFileSystem.getTempDir()).thenReturn(temporaryFolder.newFolder());
-
// 300 : root module -> export issues of all modules
byte[] database = localDatabaseFactory.createDatabaseForDryRun(300L);
dataSource = createDatabase(database);
checkTables("deleteGlobalProperty", "properties");
}
+ @Test
+ public void deleteAllProperties() {
+ setupData("deleteAllProperties");
+
+ dao.deleteAllProperties("to_be_deleted");
+
+ checkTables("deleteAllProperties", "properties");
+ }
+
@Test
public void insertGlobalProperties() {
setupData("insertGlobalProperties");
--- /dev/null
+<dataset>
+
+ <!-- global -->
+ <!-- <properties id="1" prop_key="to_be_deleted" text_value="new_global" resource_id="[null]" user_id="[null]"/> -->
+ <properties id="2" prop_key="global.key" text_value="new_global" resource_id="[null]" user_id="[null]"/>
+
+ <!-- project -->
+ <!-- <properties id="3" prop_key="to_be_deleted" text_value="new_project" resource_id="10" user_id="[null]"/> -->
+ <properties id="4" prop_key="project.key" text_value="new_project" resource_id="10" user_id="[null]"/>
+
+ <!-- user -->
+ <!-- <properties id="5" prop_key="to_be_deleted" text_value="new_user" resource_id="[null]" user_id="100"/> -->
+ <properties id="6" prop_key="user.key" text_value="new_user" resource_id="[null]" user_id="100"/>
+
+</dataset>
--- /dev/null
+<dataset>
+
+ <!-- global -->
+ <properties id="1" prop_key="to_be_deleted" text_value="new_global" resource_id="[null]" user_id="[null]"/>
+ <properties id="2" prop_key="global.key" text_value="new_global" resource_id="[null]" user_id="[null]"/>
+
+ <!-- project -->
+ <properties id="3" prop_key="to_be_deleted" text_value="new_project" resource_id="10" user_id="[null]"/>
+ <properties id="4" prop_key="project.key" text_value="new_project" resource_id="10" user_id="[null]"/>
+
+ <!-- user -->
+ <properties id="5" prop_key="to_be_deleted" text_value="new_user" resource_id="[null]" user_id="100"/>
+ <properties id="6" prop_key="user.key" text_value="new_user" resource_id="[null]" user_id="100"/>
+
+</dataset>
import org.apache.commons.lang.StringUtils;
import org.slf4j.LoggerFactory;
import org.sonar.api.database.DatabaseSession;
+import org.sonar.core.dryrun.DryRunCache;
import org.sonar.core.persistence.DatabaseVersion;
import org.sonar.server.platform.PersistentSettings;
-import org.sonar.server.startup.CleanDryRunCache;
import javax.annotation.Nullable;
backupables = new ArrayList<Backupable>();
}
- public Backup(DatabaseSession session, PersistentSettings persistentSettings, CleanDryRunCache cleanDryRunCache) {
+ public Backup(DatabaseSession session, PersistentSettings persistentSettings, DryRunCache dryRunCache) {
this();
this.session = session;
backupables.add(new PropertiesBackup(persistentSettings));
// Note that order is important, because profile can have reference to rule
backupables.add(new RulesBackup(session));
- backupables.add(new ProfilesBackup(session));
+ backupables.add(new ProfilesBackup(session, dryRunCache));
}
/**
import org.sonar.api.measures.Metric;
import org.sonar.api.profiles.Alert;
import org.sonar.api.profiles.RulesProfile;
-import org.sonar.api.rules.*;
+import org.sonar.api.rules.ActiveRule;
+import org.sonar.api.rules.ActiveRuleParam;
+import org.sonar.api.rules.Rule;
+import org.sonar.api.rules.RuleParam;
+import org.sonar.api.rules.RulePriority;
+import org.sonar.core.dryrun.DryRunCache;
import org.sonar.jpa.dao.RulesDao;
-import java.util.*;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
public class ProfilesBackup implements Backupable {
private Collection<RulesProfile> profiles;
private DatabaseSession session;
+ private DryRunCache dryRunCache;
- public ProfilesBackup(DatabaseSession session) {
+ public ProfilesBackup(DatabaseSession session, DryRunCache dryRunCache) {
this.session = session;
+ this.dryRunCache = dryRunCache;
}
/**
public void importXml(SonarConfig sonarConfig) {
if (sonarConfig.getProfiles() != null && !sonarConfig.getProfiles().isEmpty()) {
LoggerFactory.getLogger(getClass()).info("Delete profiles");
- ProfilesManager profilesManager = new ProfilesManager(session, null);
+ ProfilesManager profilesManager = new ProfilesManager(session, null, dryRunCache);
profilesManager.deleteAllProfiles();
RulesDao rulesDao = new RulesDao(session);
private void importAlerts(RulesProfile profile) {
if (profile.getAlerts() != null) {
- for (Iterator<Alert> ia = profile.getAlerts().iterator(); ia.hasNext(); ) {
+ for (Iterator<Alert> ia = profile.getAlerts().iterator(); ia.hasNext();) {
Alert alert = ia.next();
Metric unMarshalledMetric = alert.getMetric();
String validKey = unMarshalledMetric.getKey();
}
private void importActiveRules(RulesDao rulesDao, RulesProfile profile) {
- for (Iterator<ActiveRule> iar = profile.getActiveRules(true).iterator(); iar.hasNext(); ) {
+ for (Iterator<ActiveRule> iar = profile.getActiveRules(true).iterator(); iar.hasNext();) {
ActiveRule activeRule = iar.next();
Rule unMarshalledRule = activeRule.getRule();
Rule matchingRuleInDb = rulesDao.getRuleByKey(unMarshalledRule.getRepositoryKey(), unMarshalledRule.getKey());
activeRule.setRule(matchingRuleInDb);
activeRule.setRulesProfile(profile);
activeRule.getActiveRuleParams();
- for (Iterator<ActiveRuleParam> irp = activeRule.getActiveRuleParams().iterator(); irp.hasNext(); ) {
+ for (Iterator<ActiveRuleParam> irp = activeRule.getActiveRuleParams().iterator(); irp.hasNext();) {
ActiveRuleParam activeRuleParam = irp.next();
RuleParam unMarshalledRP = activeRuleParam.getRuleParam();
RuleParam matchingRPInDb = rulesDao.getRuleParam(matchingRuleInDb, unMarshalledRP.getKey());
import org.apache.commons.lang.StringUtils;
import org.sonar.api.database.DatabaseSession;
import org.sonar.api.profiles.RulesProfile;
-import org.sonar.api.rules.*;
+import org.sonar.api.rules.ActiveRule;
+import org.sonar.api.rules.ActiveRuleChange;
+import org.sonar.api.rules.Rule;
+import org.sonar.api.rules.RuleParam;
+import org.sonar.api.rules.RulePriority;
import org.sonar.api.utils.ValidationMessages;
+import org.sonar.core.dryrun.DryRunCache;
import org.sonar.jpa.dao.BaseDao;
import org.sonar.jpa.dao.RulesDao;
import java.util.List;
-
public class ProfilesManager extends BaseDao {
private RulesDao rulesDao;
+ private DryRunCache dryRunCache;
- public ProfilesManager(DatabaseSession session, RulesDao rulesDao) {
+ public ProfilesManager(DatabaseSession session, RulesDao rulesDao, DryRunCache dryRunCache) {
super(session);
this.rulesDao = rulesDao;
+ this.dryRunCache = dryRunCache;
}
public void copyProfile(int profileId, String newProfileName) {
RulesProfile profile = getSession().getSingleResult(RulesProfile.class, "id", profileId);
RulesProfile toImport = (RulesProfile) profile.clone();
toImport.setName(newProfileName);
- ProfilesBackup pb = new ProfilesBackup(getSession());
+ ProfilesBackup pb = new ProfilesBackup(getSession(), dryRunCache);
pb.importProfile(rulesDao, toImport);
getSession().commit();
+ dryRunCache.reportGlobalModification();
}
public void deleteAllProfiles() {
getSession().removeWithoutFlush(profile);
}
getSession().commit();
+ dryRunCache.reportGlobalModification();
}
// Managing inheritance of profiles
profile.setParentName(newParent == null ? null : newParent.getName());
getSession().saveWithoutFlush(profile);
getSession().commit();
+ dryRunCache.reportGlobalModification();
}
return messages;
}
removeActiveRule(activeRuleToRemove);
}
getSession().commit();
+ dryRunCache.reportGlobalModification();
}
/**
activateOrChange(child, parentActiveRule, userName);
}
getSession().commit();
+ dryRunCache.reportGlobalModification();
}
/**
deactivate(child, parentActiveRule.getRule(), userName);
}
getSession().commit();
+ dryRunCache.reportGlobalModification();
}
/**
}
getSession().commit();
+ dryRunCache.reportGlobalModification();
}
}
import org.slf4j.LoggerFactory;
import org.sonar.api.CoreProperties;
import org.sonar.api.database.configuration.Property;
-import org.sonar.core.persistence.DryRunDatabaseFactory;
+import org.sonar.core.dryrun.DryRunCache;
import org.sonar.core.properties.PropertyDto;
import org.sonar.server.platform.PersistentSettings;
// default permissions properties should not be exported as they reference permission_templates entries in the DB
return !CoreProperties.SERVER_ID.equals(propertyKey)
&& !propertyKey.startsWith(PERMISSION_PROPERTIES_PREFIX)
- && !propertyKey.startsWith(DryRunDatabaseFactory.SONAR_DRY_RUN_CACHE_KEY_PREFIX);
+ && !DryRunCache.SONAR_DRY_RUN_CACHE_LAST_UPDATE_KEY.equals(propertyKey);
}
private boolean shouldNotBeErased(String propertyKey) {
import org.sonar.api.utils.UriReader;
import org.sonar.core.component.SnapshotPerspectives;
import org.sonar.core.config.Logback;
+import org.sonar.core.dryrun.DryRunCache;
import org.sonar.core.i18n.GwtI18n;
import org.sonar.core.i18n.I18nManager;
import org.sonar.core.i18n.RuleI18nManager;
coreContainer.addSingleton(ThreadLocalDatabaseSessionFactory.class);
coreContainer.addPicoAdapter(new DatabaseSessionProvider());
coreContainer.addSingleton(ServerMetadataPersister.class);
- coreContainer.addSingleton(CleanDryRunCache.class);
coreContainer.startComponents();
}
servicesContainer.addSingleton(MeasureFilterExecutor.class);
servicesContainer.addSingleton(MeasureFilterEngine.class);
servicesContainer.addSingleton(DryRunDatabaseFactory.class);
+ servicesContainer.addSingleton(DryRunCache.class);
servicesContainer.addSingleton(DefaultResourcePermissions.class);
servicesContainer.addSingleton(Periods.class);
startupContainer.addSingleton(RenameDeprecatedPropertyKeys.class);
startupContainer.addSingleton(LogServerId.class);
startupContainer.addSingleton(RegisterServletFilters.class);
+ startupContainer.addSingleton(CleanDryRunCache.class);
startupContainer.startComponents();
startupContainer.getComponentByType(ServerLifecycleNotifier.class).notifyStart();
*/
package org.sonar.server.startup;
-import org.apache.commons.io.FileUtils;
-import org.sonar.core.persistence.DryRunDatabaseFactory;
-import org.sonar.server.platform.DefaultServerFileSystem;
-import org.sonar.server.platform.PersistentSettings;
-
-import java.io.File;
-import java.util.Map;
+import org.sonar.core.dryrun.DryRunCache;
/**
* @since 4.0
*/
public class CleanDryRunCache {
- private DefaultServerFileSystem serverFileSystem;
- private PersistentSettings settings;
-
- public CleanDryRunCache(DefaultServerFileSystem serverFileSystem, PersistentSettings settings) {
- this.serverFileSystem = serverFileSystem;
- this.settings = settings;
- }
+ private DryRunCache dryRunCache;
- private File getRootCacheLocation() {
- return new File(serverFileSystem.getTempDir(), "dryRun");
+ public CleanDryRunCache(DryRunCache dryRunCache) {
+ this.dryRunCache = dryRunCache;
}
public void start() {
- clean();
- }
-
- public void clean() {
- // Delete folder where dryRun DB are stored
- FileUtils.deleteQuietly(getRootCacheLocation());
- // Delete all lastUpdate properties to force generation of new DB
- Map<String, String> properties = settings.getProperties();
- for (String propKey : properties.keySet()) {
- if (propKey.startsWith(DryRunDatabaseFactory.SONAR_DRY_RUN_CACHE_KEY_PREFIX)) {
- settings.deleteProperty(propKey);
- }
- }
+ dryRunCache.cleanAll();
}
}
import org.apache.commons.lang.CharEncoding;
import org.custommonkey.xmlunit.Diff;
import org.custommonkey.xmlunit.XMLUnit;
+import org.junit.Before;
import org.junit.Test;
import org.sonar.api.database.DatabaseSession;
import org.sonar.api.database.configuration.Property;
import org.sonar.api.rules.Rule;
import org.sonar.api.rules.RuleParam;
import org.sonar.api.rules.RulePriority;
+import org.sonar.core.dryrun.DryRunCache;
import java.io.IOException;
import java.io.InputStream;
public class BackupTest {
+ private DryRunCache dryRunCache;
+
+ @Before
+ public void prepare() {
+ this.dryRunCache = mock(DryRunCache.class);
+ }
+
@Test
public void shouldExportXml() throws Exception {
SonarConfig sonarConfig = getSonarConfig();
@Test
public void shouldReturnAValidXml() throws Exception {
Backup backup = new Backup(Arrays.asList(new MetricsBackup(null), new PropertiesBackup(null),
- new RulesBackup((DatabaseSession) null), new ProfilesBackup((DatabaseSession) null)));
+ new RulesBackup((DatabaseSession) null), new ProfilesBackup((DatabaseSession) null, dryRunCache)));
SonarConfig sonarConfig = getSonarConfig();
sonarConfig.setMetrics(getMetrics());
sonarConfig.setProperties(getProperties());
@Test
public void shouldImportXml() {
Backup backup = new Backup(Arrays.asList(new MetricsBackup(null), new PropertiesBackup(null),
- new RulesBackup((DatabaseSession) null), new ProfilesBackup((DatabaseSession) null)));
+ new RulesBackup((DatabaseSession) null), new ProfilesBackup((DatabaseSession) null, dryRunCache)));
String xml = getFileFromClasspath("backup-restore-valid.xml");
SonarConfig sonarConfig = backup.getSonarConfigFromXml(xml);
@Test
public void shouldImportXmlWithoutInheritanceInformation() {
Backup backup = new Backup(Arrays.asList(new MetricsBackup(null), new PropertiesBackup(null),
- new RulesBackup((DatabaseSession) null), new ProfilesBackup((DatabaseSession) null)));
+ new RulesBackup((DatabaseSession) null), new ProfilesBackup((DatabaseSession) null, dryRunCache)));
String xml = getFileFromClasspath("backup-restore-without-inheritance.xml");
SonarConfig sonarConfig = backup.getSonarConfigFromXml(xml);
import org.junit.Before;
import org.junit.Test;
import org.sonar.api.profiles.RulesProfile;
+import org.sonar.core.dryrun.DryRunCache;
import org.sonar.jpa.test.AbstractDbUnitTestCase;
import static org.hamcrest.Matchers.is;
import static org.hamcrest.Matchers.nullValue;
import static org.junit.Assert.assertThat;
+import static org.mockito.Mockito.mock;
public class InheritedProfilesTest extends AbstractDbUnitTestCase {
private ProfilesManager profilesManager;
@Before
public void setUp() {
- profilesManager = new ProfilesManager(getSession(), null);
+ profilesManager = new ProfilesManager(getSession(), null, mock(DryRunCache.class));
}
@Test
import org.junit.Before;
import org.junit.Test;
import org.sonar.api.profiles.RulesProfile;
+import org.sonar.core.dryrun.DryRunCache;
import org.sonar.jpa.test.AbstractDbUnitTestCase;
import static org.fest.assertions.Assertions.assertThat;
-
+import static org.mockito.Mockito.mock;
public class ProfilesManagerTest extends AbstractDbUnitTestCase {
@Before
public void before() {
- manager = new ProfilesManager(getSession(), null);
+ manager = new ProfilesManager(getSession(), null, mock(DryRunCache.class));
}
@Test
import org.sonar.api.rules.ActiveRuleParamChange;
import org.sonar.api.rules.Rule;
import org.sonar.api.rules.RulePriority;
+import org.sonar.core.dryrun.DryRunCache;
import org.sonar.jpa.test.AbstractDbUnitTestCase;
import static org.fest.assertions.Assertions.assertThat;
+import static org.mockito.Mockito.mock;
public class RuleChangeTest extends AbstractDbUnitTestCase {
private ProfilesManager profilesManager;
@Before
public void setUp() {
- profilesManager = new ProfilesManager(getSession(), null);
+ profilesManager = new ProfilesManager(getSession(), null, mock(DryRunCache.class));
}
@Test
public void should_track_rule_activation() {
setupData("initialData");
profilesManager.activated(2, 3, "admin");
- checkTables("ruleActivated", new String[]{"change_date"}, "active_rule_changes");
+ checkTables("ruleActivated", new String[] {"change_date"}, "active_rule_changes");
}
@Test
public void should_track_rule_deactivation() {
setupData("initialData");
profilesManager.deactivated(2, 3, "admin");
- checkTables("ruleDeactivated", new String[]{"change_date"}, "active_rule_changes");
+ checkTables("ruleDeactivated", new String[] {"change_date"}, "active_rule_changes");
}
@Test
public void should_track_rule_param_change() {
setupData("initialData");
profilesManager.ruleParamChanged(2, 3, "param1", "20", "30", "admin");
- checkTables("ruleParamChanged", new String[]{"change_date"}, "active_rule_changes", "active_rule_param_changes");
+ checkTables("ruleParamChanged", new String[] {"change_date"}, "active_rule_changes", "active_rule_param_changes");
}
@Test
public void should_track_rule_severity_change() {
setupData("initialData");
profilesManager.ruleSeverityChanged(2, 3, RulePriority.BLOCKER, RulePriority.CRITICAL, "admin");
- checkTables("ruleSeverityChanged", new String[]{"change_date"}, "active_rule_changes");
+ checkTables("ruleSeverityChanged", new String[] {"change_date"}, "active_rule_changes");
}
@Test
public void should_track_rule_revert() {
setupData("ruleReverted");
profilesManager.revert(2, 3, "admin");
- checkTables("ruleReverted", new String[]{"change_date"}, "active_rule_changes", "active_rule_param_changes");
+ checkTables("ruleReverted", new String[] {"change_date"}, "active_rule_changes", "active_rule_param_changes");
}
@Test
public void should_track_change_parent_profile() {
setupData("changeParentProfile");
profilesManager.changeParentProfile(2, "parent", "admin");
- checkTables("changeParentProfile", new String[]{"change_date"}, "active_rule_changes");
+ checkTables("changeParentProfile", new String[] {"change_date"}, "active_rule_changes");
}
@Test
setupData("initialData");
Rule rule = getSession().reattach(Rule.class, 1);
profilesManager.removeActivatedRules(rule);
- checkTables("removeActivatedRules", new String[]{"change_date"}, "active_rule_changes", "active_rules");
+ checkTables("removeActivatedRules", new String[] {"change_date"}, "active_rule_changes", "active_rules");
}
-
}