Browse Source

SONAR-3895 optimize loading of project settings

tags/3.4
Simon Brandhof 11 years ago
parent
commit
2bdd7679ed
20 changed files with 361 additions and 267 deletions
  1. 0
    4
      sonar-batch/pom.xml
  2. 1
    0
      sonar-batch/src/main/java/org/sonar/batch/bootstrap/BatchModule.java
  3. 0
    1
      sonar-batch/src/main/java/org/sonar/batch/bootstrap/BatchPluginRepository.java
  4. 105
    0
      sonar-batch/src/main/java/org/sonar/batch/bootstrap/BatchSettings.java
  5. 0
    6
      sonar-batch/src/main/java/org/sonar/batch/bootstrap/BootstrapModule.java
  6. 16
    10
      sonar-batch/src/main/java/org/sonar/batch/bootstrap/BootstrapSettings.java
  7. 0
    2
      sonar-batch/src/main/java/org/sonar/batch/bootstrap/ProjectModule.java
  8. 19
    19
      sonar-batch/src/main/java/org/sonar/batch/bootstrap/ProjectSettings.java
  9. 1
    1
      sonar-batch/src/main/java/org/sonar/batch/bootstrap/UnsupportedProperties.java
  10. 0
    75
      sonar-batch/src/main/java/org/sonar/batch/bootstrap/WsConnector.java
  11. 0
    69
      sonar-batch/src/main/java/org/sonar/batch/config/BootstrapSettingsLoader.java
  12. 9
    10
      sonar-batch/src/main/java/org/sonar/batch/local/DryRunDatabase.java
  13. 116
    0
      sonar-batch/src/test/java/org/sonar/batch/bootstrap/BatchSettingsTest.java
  14. 16
    8
      sonar-batch/src/test/java/org/sonar/batch/bootstrap/BootstrapSettingsTest.java
  15. 1
    8
      sonar-batch/src/test/java/org/sonar/batch/bootstrap/ProjectModuleTest.java
  16. 2
    1
      sonar-batch/src/test/java/org/sonar/batch/bootstrap/ProjectSettingsTest.java
  17. 2
    1
      sonar-batch/src/test/java/org/sonar/batch/bootstrap/UnsupportedPropertiesTest.java
  18. 4
    4
      sonar-batch/src/test/java/org/sonar/batch/local/DryRunDatabaseTest.java
  19. 0
    48
      sonar-server/src/main/webapp/WEB-INF/app/controllers/api/synchro_controller.rb
  20. 69
    0
      sonar-server/src/main/webapp/WEB-INF/app/controllers/batch_bootstrap_controller.rb

+ 0
- 4
sonar-batch/pom.xml View File

@@ -34,10 +34,6 @@
<groupId>org.codehaus.sonar</groupId>
<artifactId>sonar-squid</artifactId>
</dependency>
<dependency>
<groupId>org.codehaus.sonar</groupId>
<artifactId>sonar-ws-client</artifactId>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>

+ 1
- 0
sonar-batch/src/main/java/org/sonar/batch/bootstrap/BatchModule.java View File

@@ -70,6 +70,7 @@ public class BatchModule extends Module {
}

private void registerCoreComponents() {
container.addSingleton(BatchSettings.class);
container.addSingleton(EmailSettings.class);
container.addSingleton(I18nManager.class);
container.addSingleton(RuleI18nManager.class);

+ 0
- 1
sonar-batch/src/main/java/org/sonar/batch/bootstrap/BatchPluginRepository.java View File

@@ -30,7 +30,6 @@ import org.sonar.api.Plugin;
import org.sonar.api.config.Settings;
import org.sonar.api.platform.PluginMetadata;
import org.sonar.api.platform.PluginRepository;
import org.sonar.batch.config.BootstrapSettings;
import org.sonar.core.plugins.PluginClassloaders;
import org.sonar.core.plugins.PluginInstaller;
import org.sonar.core.plugins.RemotePlugin;

+ 105
- 0
sonar-batch/src/main/java/org/sonar/batch/bootstrap/BatchSettings.java View File

@@ -0,0 +1,105 @@
/*
* Sonar, open source software quality management tool.
* Copyright (C) 2008-2012 SonarSource
* mailto:contact AT sonarsource DOT com
*
* Sonar 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.
*
* Sonar 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 Sonar; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02
*/
package org.sonar.batch.bootstrap;

import com.google.common.collect.Maps;
import org.apache.commons.configuration.Configuration;
import org.apache.commons.lang.StringUtils;
import org.json.simple.JSONValue;
import org.slf4j.LoggerFactory;
import org.sonar.api.CoreProperties;
import org.sonar.api.batch.bootstrap.ProjectReactor;
import org.sonar.api.config.Settings;

import javax.annotation.Nullable;

import java.util.List;
import java.util.Map;

public class BatchSettings extends Settings {
private Configuration deprecatedConfiguration;

// Keep module settings for initialization of ProjectSettings
// module key -> <key,val>
private Map<String, Map<String, String>> moduleProperties = Maps.newHashMap();

public BatchSettings(BootstrapSettings bootstrapSettings, ProjectReactor reactor, ServerClient client,
Configuration deprecatedConfiguration) {
super(bootstrapSettings.getDefinitions());
this.deprecatedConfiguration = deprecatedConfiguration;
init(bootstrapSettings, reactor, client);
}

private void init(BootstrapSettings bootstrapSettings, ProjectReactor reactor, ServerClient client) {
LoggerFactory.getLogger(BatchSettings.class).info("Load project settings");

String branch = bootstrapSettings.getString(CoreProperties.PROJECT_BRANCH_PROPERTY);
String projectKey = reactor.getRoot().getKey();
if (StringUtils.isNotBlank(branch)) {
projectKey = String.format("%s:%s", projectKey, branch);
}
downloadSettings(client, projectKey);


// order is important -> bottom-up. The last one overrides all the others.
addProperties(reactor.getRoot().getProperties());
addEnvironmentVariables();
addSystemProperties();
}

private void downloadSettings(ServerClient client, String projectKey) {
String jsonText = client.request("/batch_bootstrap/properties?project=" + projectKey);
List<Map<String, String>> json = (List<Map<String, String>>) JSONValue.parse(jsonText);
for (Map<String, String> jsonProperty : json) {
String key = jsonProperty.get("k");
String value = jsonProperty.get("v");
String moduleKey = jsonProperty.get("p");
if (moduleKey == null || projectKey.equals(moduleKey)) {
setProperty(key, value);
} else {
Map<String, String> map = moduleProperties.get(moduleKey);
if (map == null) {
map = Maps.newHashMap();
moduleProperties.put(moduleKey, map);
}
map.put(key, value);
}
}
}

public Map<String, String> getModuleProperties(String projectKey) {
return moduleProperties.get(projectKey);
}

@Override
protected void doOnSetProperty(String key, @Nullable String value) {
deprecatedConfiguration.setProperty(key, value);
}

@Override
protected void doOnRemoveProperty(String key) {
deprecatedConfiguration.clearProperty(key);
}

@Override
protected void doOnClearProperties() {
deprecatedConfiguration.clear();
}
}

+ 0
- 6
sonar-batch/src/main/java/org/sonar/batch/bootstrap/BootstrapModule.java View File

@@ -26,10 +26,7 @@ import org.sonar.api.utils.UriReader;
import org.sonar.batch.FakeMavenPluginExecutor;
import org.sonar.batch.MavenPluginExecutor;
import org.sonar.batch.ServerMetadata;
import org.sonar.batch.config.BootstrapSettings;
import org.sonar.batch.config.BootstrapSettingsLoader;
import org.sonar.core.config.Logback;
import org.sonar.wsclient.Sonar;

/**
* Level 1 components
@@ -55,13 +52,10 @@ public class BootstrapModule extends Module {
container.addSingleton(Logback.class);
container.addSingleton(ServerClient.class);
container.addSingleton(ServerMetadata.class);
container.addSingleton(WsConnector.class);
container.addSingleton(Sonar.class);
container.addSingleton(TempDirectories.class);
container.addSingleton(HttpDownloader.class);
container.addSingleton(UriReader.class);
container.addSingleton(PluginDownloader.class);
container.addSingleton(BootstrapSettingsLoader.class);
for (Object component : boostrapperComponents) {
if (component != null) {
container.addSingleton(component);

sonar-batch/src/main/java/org/sonar/batch/config/BootstrapSettings.java → sonar-batch/src/main/java/org/sonar/batch/bootstrap/BootstrapSettings.java View File

@@ -17,13 +17,14 @@
* License along with Sonar; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02
*/
package org.sonar.batch.config;
package org.sonar.batch.bootstrap;

import org.apache.commons.configuration.Configuration;
import org.sonar.api.batch.bootstrap.ProjectReactor;
import org.sonar.api.config.PropertyDefinitions;
import org.sonar.api.config.Settings;
import org.sonar.core.config.ConfigurationUtils;

import javax.annotation.Nullable;

/**
* @since 2.12
@@ -36,23 +37,28 @@ public class BootstrapSettings extends Settings {
super(propertyDefinitions);
this.reactor = reactor;
this.deprecatedConfiguration = deprecatedConfiguration;
load();
init();
}

private BootstrapSettings load() {
clear();

private void init() {
// order is important -> bottom-up. The last one overrides all the others.
addProperties(reactor.getRoot().getProperties());
addEnvironmentVariables();
addSystemProperties();
}

updateDeprecatedCommonsConfiguration();
@Override
protected void doOnSetProperty(String key, @Nullable String value) {
deprecatedConfiguration.setProperty(key, value);
}

return this;
@Override
protected void doOnRemoveProperty(String key) {
deprecatedConfiguration.clearProperty(key);
}

public void updateDeprecatedCommonsConfiguration() {
ConfigurationUtils.copyToCommonsConfiguration(properties, deprecatedConfiguration);
@Override
protected void doOnClearProperties() {
deprecatedConfiguration.clear();
}
}

+ 0
- 2
sonar-batch/src/main/java/org/sonar/batch/bootstrap/ProjectModule.java View File

@@ -37,8 +37,6 @@ import org.sonar.batch.ProjectTree;
import org.sonar.batch.ResourceFilters;
import org.sonar.batch.ViolationFilters;
import org.sonar.batch.components.TimeMachineConfiguration;
import org.sonar.batch.config.ProjectSettings;
import org.sonar.batch.config.UnsupportedProperties;
import org.sonar.batch.events.EventBus;
import org.sonar.batch.index.DefaultIndex;
import org.sonar.batch.index.ResourcePersister;

sonar-batch/src/main/java/org/sonar/batch/config/ProjectSettings.java → sonar-batch/src/main/java/org/sonar/batch/bootstrap/ProjectSettings.java View File

@@ -17,7 +17,7 @@
* License along with Sonar; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02
*/
package org.sonar.batch.config;
package org.sonar.batch.bootstrap;

import com.google.common.collect.Lists;
import org.apache.commons.configuration.Configuration;
@@ -26,14 +26,11 @@ import org.slf4j.LoggerFactory;
import org.sonar.api.CoreProperties;
import org.sonar.api.batch.bootstrap.ProjectDefinition;
import org.sonar.api.config.Settings;
import org.sonar.core.config.ConfigurationUtils;
import org.sonar.wsclient.Sonar;
import org.sonar.wsclient.services.Property;
import org.sonar.wsclient.services.PropertyQuery;

import javax.annotation.Nullable;

import java.util.List;
import java.util.Map;

/**
* @since 2.12
@@ -42,41 +39,44 @@ public class ProjectSettings extends Settings {

private Configuration deprecatedCommonsConf;

public ProjectSettings(BootstrapSettings bootstrapSettings, ProjectDefinition project,
Sonar wsClient, Configuration deprecatedCommonsConf) {
super(bootstrapSettings.getDefinitions());
public ProjectSettings(BatchSettings batchSettings, ProjectDefinition project, Configuration deprecatedCommonsConf) {
super(batchSettings.getDefinitions());

LoggerFactory.getLogger(ProjectSettings.class).info("Load module settings");
this.deprecatedCommonsConf = deprecatedCommonsConf;
if (project.getParent() == null) {
// root project -> no need to reload settings
copy(bootstrapSettings);
copy(batchSettings);
} else {
init(project, bootstrapSettings, wsClient);
init(project, batchSettings);
}
}

private void copy(BootstrapSettings bootstrapSettings) {
setProperties(bootstrapSettings);
private void copy(BatchSettings batchSettings) {
setProperties(batchSettings);
}

private ProjectSettings init(ProjectDefinition project, BootstrapSettings bootstrapSettings, Sonar wsClient) {
addPersistedProperties(project, bootstrapSettings, wsClient);
private ProjectSettings init(ProjectDefinition project, BatchSettings batchSettings) {
addProjectProperties(project, batchSettings);
addBuildProperties(project);
addEnvironmentVariables();
addSystemProperties();
//addProgrammaticProperties();
return this;
}

private void addPersistedProperties(ProjectDefinition project, BootstrapSettings bootstrapSettings, Sonar wsClient) {
String branch = bootstrapSettings.getString(CoreProperties.PROJECT_BRANCH_PROPERTY);
private void addProjectProperties(ProjectDefinition project, BatchSettings batchSettings) {
String branch = batchSettings.getString(CoreProperties.PROJECT_BRANCH_PROPERTY);
String projectKey = project.getKey();
if (StringUtils.isNotBlank(branch)) {
projectKey = String.format("%s:%s", projectKey, branch);
}
List<Property> wsProperties = wsClient.findAll(PropertyQuery.createForAll().setResourceKeyOrId(projectKey));
for (Property wsProperty : wsProperties) {
setProperty(wsProperty.getKey(), wsProperty.getValue());
addProperties(batchSettings.getProperties());
Map<String, String> moduleProps = batchSettings.getModuleProperties(projectKey);
if (moduleProps != null) {
for (Map.Entry<String, String> entry : moduleProps.entrySet()) {
setProperty(entry.getKey(), entry.getValue());
}
}
}


sonar-batch/src/main/java/org/sonar/batch/config/UnsupportedProperties.java → sonar-batch/src/main/java/org/sonar/batch/bootstrap/UnsupportedProperties.java View File

@@ -17,7 +17,7 @@
* License along with Sonar; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02
*/
package org.sonar.batch.config;
package org.sonar.batch.bootstrap;

import org.sonar.api.BatchComponent;
import org.sonar.api.config.Settings;

+ 0
- 75
sonar-batch/src/main/java/org/sonar/batch/bootstrap/WsConnector.java View File

@@ -1,75 +0,0 @@
/*
* Sonar, open source software quality management tool.
* Copyright (C) 2008-2012 SonarSource
* mailto:contact AT sonarsource DOT com
*
* Sonar 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.
*
* Sonar 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 Sonar; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02
*/
package org.sonar.batch.bootstrap;

import org.sonar.wsclient.connectors.Connector;
import org.sonar.wsclient.services.CreateQuery;
import org.sonar.wsclient.services.DeleteQuery;
import org.sonar.wsclient.services.Query;
import org.sonar.wsclient.services.UpdateQuery;

/**
* @since 3.4
*/
public class WsConnector extends Connector {

private ServerClient server;

public WsConnector(ServerClient server) {
this.server = server;
}

/**
* @return JSON response or null if 404 NOT FOUND error
* @throws org.sonar.wsclient.connectors.ConnectionException
* if connection error or HTTP status not in (200, 404)
*/
@Override
public String execute(Query<?> query) {
return server.request(query.getUrl());
}

/**
* @return JSON response or null if 404 NOT FOUND error
* @since 2.2
*/
@Override
public String execute(CreateQuery<?> query) {
throw new UnsupportedOperationException();
}

/**
* @return JSON response or null if 404 NOT FOUND error
* @since 2.2
*/
@Override
public String execute(DeleteQuery query) {
throw new UnsupportedOperationException();
}

/**
* @return JSON response or null if 404 NOT FOUND error
* @since 2.6
*/
@Override
public String execute(UpdateQuery<?> query) {
throw new UnsupportedOperationException();
}
}

+ 0
- 69
sonar-batch/src/main/java/org/sonar/batch/config/BootstrapSettingsLoader.java View File

@@ -1,69 +0,0 @@
/*
* Sonar, open source software quality management tool.
* Copyright (C) 2008-2012 SonarSource
* mailto:contact AT sonarsource DOT com
*
* Sonar 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.
*
* Sonar 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 Sonar; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02
*/
package org.sonar.batch.config;

import org.apache.commons.lang.StringUtils;
import org.slf4j.LoggerFactory;
import org.sonar.api.CoreProperties;
import org.sonar.api.batch.bootstrap.ProjectReactor;
import org.sonar.wsclient.Sonar;
import org.sonar.wsclient.services.Property;
import org.sonar.wsclient.services.PropertyQuery;

import java.util.List;

/**
* Load global settings and project settings. Note that the definition of modules is
* incomplete before the execution of ProjectBuilder extensions, so module settings
* are not loaded yet.
* @since 3.4
*/
public final class BootstrapSettingsLoader {

private BootstrapSettings settings;
private ProjectReactor reactor;
private Sonar wsClient;

public BootstrapSettingsLoader(BootstrapSettings settings, ProjectReactor reactor, Sonar wsClient) {
this.settings = settings;
this.reactor = reactor;
this.wsClient = wsClient;
}

public void start() {
LoggerFactory.getLogger(BootstrapSettingsLoader.class).info("Load project settings");
String branch = settings.getString(CoreProperties.PROJECT_BRANCH_PROPERTY);
String projectKey = reactor.getRoot().getKey();
if (StringUtils.isNotBlank(branch)) {
projectKey = String.format("%s:%s", projectKey, branch);
}
List<Property> wsProperties = wsClient.findAll(PropertyQuery.createForAll().setResourceKeyOrId(projectKey));
for (Property wsProperty : wsProperties) {
setIfNotDefined(wsProperty);
}
settings.updateDeprecatedCommonsConfiguration();
}

private void setIfNotDefined(Property wsProperty) {
if (!settings.hasKey(wsProperty.getKey())) {
settings.setProperty(wsProperty.getKey(), wsProperty.getValue());
}
}
}

+ 9
- 10
sonar-batch/src/main/java/org/sonar/batch/local/DryRunDatabase.java View File

@@ -43,7 +43,6 @@ import java.io.IOException;
public class DryRunDatabase implements BatchComponent {
private static final Logger LOG = LoggerFactory.getLogger(DryRunDatabase.class);

private static final String API_SYNCHRO = "/api/synchro";
private static final String DIALECT = "h2";
private static final String DRIVER = "org.h2.Driver";
private static final String URL = "jdbc:h2:";
@@ -57,8 +56,8 @@ public class DryRunDatabase implements BatchComponent {
private final ProjectReactor reactor;

public DryRunDatabase(DryRun dryRun, Settings settings, ServerClient server, TempDirectories tempDirectories, ProjectReactor reactor,
// project reactor must be completely built
ProjectReactorReady reactorReady) {
// project reactor must be completely built
ProjectReactorReady reactorReady) {
this.dryRun = dryRun;
this.settings = settings;
this.server = server;
@@ -81,7 +80,7 @@ public class DryRunDatabase implements BatchComponent {

private void downloadDatabase(String projectKey, File toFile) {
try {
server.download(API_SYNCHRO + "?resource=" + projectKey, toFile);
server.download("/batch_bootstrap/db?project=" + projectKey, toFile);
} catch (SonarException e) {
Throwable rootCause = Throwables.getRootCause(e);
if (rootCause instanceof FileNotFoundException) {
@@ -95,11 +94,11 @@ public class DryRunDatabase implements BatchComponent {

private void replaceSettings(String databasePath) {
settings
.setProperty("sonar.jdbc.schema", "")
.setProperty(DatabaseProperties.PROP_DIALECT, DIALECT)
.setProperty(DatabaseProperties.PROP_DRIVER, DRIVER)
.setProperty(DatabaseProperties.PROP_USER, USER)
.setProperty(DatabaseProperties.PROP_PASSWORD, PASSWORD)
.setProperty(DatabaseProperties.PROP_URL, URL + databasePath);
.setProperty("sonar.jdbc.schema", "")
.setProperty(DatabaseProperties.PROP_DIALECT, DIALECT)
.setProperty(DatabaseProperties.PROP_DRIVER, DRIVER)
.setProperty(DatabaseProperties.PROP_USER, USER)
.setProperty(DatabaseProperties.PROP_PASSWORD, PASSWORD)
.setProperty(DatabaseProperties.PROP_URL, URL + databasePath);
}
}

+ 116
- 0
sonar-batch/src/test/java/org/sonar/batch/bootstrap/BatchSettingsTest.java View File

@@ -0,0 +1,116 @@
/*
* Sonar, open source software quality management tool.
* Copyright (C) 2008-2012 SonarSource
* mailto:contact AT sonarsource DOT com
*
* Sonar 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.
*
* Sonar 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 Sonar; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02
*/
package org.sonar.batch.bootstrap;

import org.apache.commons.configuration.BaseConfiguration;
import org.apache.commons.configuration.Configuration;
import org.junit.Before;
import org.junit.Test;
import org.sonar.api.batch.bootstrap.ProjectDefinition;
import org.sonar.api.batch.bootstrap.ProjectReactor;
import org.sonar.api.config.PropertyDefinitions;

import java.util.Map;

import static org.fest.assertions.Assertions.assertThat;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;

public class BatchSettingsTest {

Configuration deprecatedConf;
ServerClient client;
ProjectDefinition project;
ProjectReactor reactor;
BootstrapSettings bootstrapSettings;

@Before
public void before() {
project = ProjectDefinition.create();
project.setKey("struts");
reactor = new ProjectReactor(project);
deprecatedConf = new BaseConfiguration();
client = mock(ServerClient.class);
when(client.request("/batch_bootstrap/properties?project=struts")).thenReturn(
"[{\"k\":\"sonar.cpd.cross\",\"v\":\"true\"}," +
"{\"k\":\"sonar.java.coveragePlugin\",\"v\":\"jacoco\",\"p\":\"struts\"}," +
"{\"k\":\"sonar.java.coveragePlugin\",\"v\":\"cobertura\",\"p\":\"struts-core\"}]"
);
bootstrapSettings = new BootstrapSettings(new PropertyDefinitions(), reactor, deprecatedConf);
}

@Test
public void should_load_system_props() {
System.setProperty("BatchSettingsTest.testSystemProp", "system");
BatchSettings batchSettings = new BatchSettings(bootstrapSettings, reactor, client, deprecatedConf);
assertThat(batchSettings.getString("BatchSettingsTest.testSystemProp")).isEqualTo("system");
}

@Test
public void should_load_build_props() {
project.setProperty("build.prop", "build");
BatchSettings batchSettings = new BatchSettings(bootstrapSettings, reactor, client, deprecatedConf);
assertThat(batchSettings.getString("build.prop")).isEqualTo("build");
}

@Test
public void should_load_global_settings() {
BatchSettings batchSettings = new BatchSettings(bootstrapSettings, reactor, client, deprecatedConf);
assertThat(batchSettings.getBoolean("sonar.cpd.cross")).isTrue();
}

@Test
public void should_load_project_root_settings() {
BatchSettings batchSettings = new BatchSettings(bootstrapSettings, reactor, client, deprecatedConf);
assertThat(batchSettings.getString("sonar.java.coveragePlugin")).isEqualTo("jacoco");
}

@Test
public void should_keep_module_settings_for_later() {
BatchSettings batchSettings = new BatchSettings(bootstrapSettings, reactor, client, deprecatedConf);
Map<String, String> moduleSettings = batchSettings.getModuleProperties("struts-core");
assertThat(moduleSettings).hasSize(1);
assertThat(moduleSettings.get("sonar.java.coveragePlugin")).isEqualTo("cobertura");
}

@Test
public void system_props_should_override_build_props() {
System.setProperty("BatchSettingsTest.testSystemProp", "system");
project.setProperty("BatchSettingsTest.testSystemProp", "build");
BatchSettings batchSettings = new BatchSettings(bootstrapSettings, reactor, client, deprecatedConf);
assertThat(batchSettings.getString("BatchSettingsTest.testSystemProp")).isEqualTo("system");
}

@Test
public void should_forward_to_deprecated_commons_configuration() {
BatchSettings batchSettings = new BatchSettings(bootstrapSettings, reactor, client, deprecatedConf);

assertThat(deprecatedConf.getString("sonar.cpd.cross")).isEqualTo("true");
assertThat(deprecatedConf.getString("sonar.java.coveragePlugin")).isEqualTo("jacoco");

batchSettings.removeProperty("sonar.cpd.cross");
assertThat(deprecatedConf.getString("sonar.cpd.cross")).isNull();
assertThat(deprecatedConf.getString("sonar.java.coveragePlugin")).isEqualTo("jacoco");

batchSettings.clear();
assertThat(deprecatedConf.getString("sonar.cpd.cross")).isNull();
assertThat(deprecatedConf.getString("sonar.java.coveragePlugin")).isNull();
}
}

sonar-batch/src/test/java/org/sonar/batch/config/BootstrapSettingsTest.java → sonar-batch/src/test/java/org/sonar/batch/bootstrap/BootstrapSettingsTest.java View File

@@ -17,7 +17,7 @@
* License along with Sonar; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02
*/
package org.sonar.batch.config;
package org.sonar.batch.bootstrap;

import org.apache.commons.configuration.BaseConfiguration;
import org.junit.Test;
@@ -25,8 +25,7 @@ import org.sonar.api.batch.bootstrap.ProjectDefinition;
import org.sonar.api.batch.bootstrap.ProjectReactor;
import org.sonar.api.config.PropertyDefinitions;

import static org.hamcrest.CoreMatchers.is;
import static org.junit.Assert.assertThat;
import static org.fest.assertions.Assertions.assertThat;

public class BootstrapSettingsTest {

@@ -39,7 +38,7 @@ public class BootstrapSettingsTest {
ProjectReactor reactor = new ProjectReactor(project);
BootstrapSettings settings = new BootstrapSettings(new PropertyDefinitions(), reactor, new BaseConfiguration());

assertThat(settings.getString("foo"), is("bar"));
assertThat(settings.getString("foo")).isEqualTo("bar");
}

@Test
@@ -51,18 +50,27 @@ public class BootstrapSettingsTest {
ProjectReactor reactor = new ProjectReactor(project);
BootstrapSettings settings = new BootstrapSettings(new PropertyDefinitions(), reactor, new BaseConfiguration());

assertThat(settings.getString("BootstrapSettingsTest.testEnv"), is("env"));
assertThat(settings.getString("BootstrapSettingsTest.testEnv")).isEqualTo("env");
}

@Test
public void shouldForwardToCommonsConfiguration() {
ProjectDefinition project = ProjectDefinition.create();
project.setProperty("hello", "world");
project.setProperty("foo", "bar");

ProjectReactor reactor = new ProjectReactor(project);
BaseConfiguration deprecatedConfiguration = new BaseConfiguration();
new BootstrapSettings(new PropertyDefinitions(), reactor, deprecatedConfiguration);
BootstrapSettings settings = new BootstrapSettings(new PropertyDefinitions(), reactor, deprecatedConfiguration);

assertThat(deprecatedConfiguration.getString("hello")).isEqualTo("world");
assertThat(deprecatedConfiguration.getString("foo")).isEqualTo("bar");

settings.removeProperty("foo");
assertThat(deprecatedConfiguration.getString("foo")).isNull();
assertThat(deprecatedConfiguration.getString("hello")).isEqualTo("world");

assertThat(deprecatedConfiguration.getString("foo"), is("bar"));
settings.clear();
assertThat(deprecatedConfiguration.getString("foo")).isNull();
assertThat(deprecatedConfiguration.getString("hello")).isNull();
}
}

+ 1
- 8
sonar-batch/src/test/java/org/sonar/batch/bootstrap/ProjectModuleTest.java View File

@@ -22,8 +22,6 @@ package org.sonar.batch.bootstrap;
import org.apache.commons.configuration.PropertiesConfiguration;
import org.junit.Test;
import org.mockito.Matchers;
import org.mockito.MockSettings;
import org.mockito.Mockito;
import org.sonar.api.batch.InstantiationStrategy;
import org.sonar.api.batch.bootstrap.ProjectDefinition;
import org.sonar.api.database.model.Snapshot;
@@ -31,11 +29,7 @@ import org.sonar.api.platform.ComponentContainer;
import org.sonar.api.resources.Project;
import org.sonar.api.resources.Resource;
import org.sonar.batch.ProjectTree;
import org.sonar.batch.config.BootstrapSettings;
import org.sonar.batch.config.ProjectSettings;
import org.sonar.batch.index.ResourcePersister;
import org.sonar.core.properties.PropertiesDao;
import org.sonar.wsclient.Sonar;

import static org.fest.assertions.Assertions.assertThat;
import static org.mockito.Matchers.any;
@@ -62,8 +56,7 @@ public class ProjectModuleTest {
container.addSingleton(extensionInstaller);
container.addSingleton(projectTree);
container.addSingleton(resourcePersister);
container.addSingleton(mock(Sonar.class));
container.addSingleton(mock(BootstrapSettings.class));
container.addSingleton(mock(BatchSettings.class));
}
};


sonar-batch/src/test/java/org/sonar/batch/config/ProjectSettingsTest.java → sonar-batch/src/test/java/org/sonar/batch/bootstrap/ProjectSettingsTest.java View File

@@ -17,11 +17,12 @@
* License along with Sonar; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02
*/
package org.sonar.batch.config;
package org.sonar.batch.bootstrap;

import org.hamcrest.core.Is;
import org.junit.Test;
import org.sonar.api.batch.bootstrap.ProjectDefinition;
import org.sonar.batch.bootstrap.ProjectSettings;

import java.util.List;


sonar-batch/src/test/java/org/sonar/batch/config/UnsupportedPropertiesTest.java → sonar-batch/src/test/java/org/sonar/batch/bootstrap/UnsupportedPropertiesTest.java View File

@@ -17,12 +17,13 @@
* License along with Sonar; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02
*/
package org.sonar.batch.config;
package org.sonar.batch.bootstrap;

import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;
import org.sonar.api.config.Settings;
import org.sonar.batch.bootstrap.UnsupportedProperties;

public class UnsupportedPropertiesTest {


+ 4
- 4
sonar-batch/src/test/java/org/sonar/batch/local/DryRunDatabaseTest.java View File

@@ -76,7 +76,7 @@ public class DryRunDatabaseTest {

dryRunDatabase.start();

verify(server).download("/api/synchro?resource=group:project", databaseFile);
verify(server).download("/batch_bootstrap/db?project=group:project", databaseFile);
}

@Test
@@ -97,7 +97,7 @@ public class DryRunDatabaseTest {
public void should_fail_on_unknown_project() {
when(dryRun.isEnabled()).thenReturn(true);
when(tempDirectories.getFile("dry_run", "db.h2.db")).thenReturn(new File("/tmp/dry_run/db.h2.db"));
doThrow(new SonarException(new FileNotFoundException())).when(server).download("/api/synchro?resource=group:project", new File("/tmp/dry_run/db.h2.db"));
doThrow(new SonarException(new FileNotFoundException())).when(server).download("/batch_bootstrap/db?project=group:project", new File("/tmp/dry_run/db.h2.db"));

thrown.expect(SonarException.class);
thrown.expectMessage("Project [group:project] doesn't exist on server");
@@ -109,7 +109,7 @@ public class DryRunDatabaseTest {
public void should_fail_on_invalid_role() {
when(dryRun.isEnabled()).thenReturn(true);
when(tempDirectories.getFile("dry_run", "db.h2.db")).thenReturn(new File("/tmp/dry_run/db.h2.db"));
doThrow(new SonarException(new IOException("HTTP 401"))).when(server).download("/api/synchro?resource=group:project", new File("/tmp/dry_run/db.h2.db"));
doThrow(new SonarException(new IOException("HTTP 401"))).when(server).download("/batch_bootstrap/db?project=group:project", new File("/tmp/dry_run/db.h2.db"));

thrown.expect(SonarException.class);
thrown.expectMessage("You don't have access rights to project [group:project]");
@@ -121,7 +121,7 @@ public class DryRunDatabaseTest {
public void should_fail() {
when(dryRun.isEnabled()).thenReturn(true);
when(tempDirectories.getFile("dry_run", "db.h2.db")).thenReturn(new File("/tmp/dry_run/db.h2.db"));
doThrow(new SonarException("BUG")).when(server).download("/api/synchro?resource=group:project", new File("/tmp/dry_run/db.h2.db"));
doThrow(new SonarException("BUG")).when(server).download("/batch_bootstrap/db?project=group:project", new File("/tmp/dry_run/db.h2.db"));

thrown.expect(SonarException.class);
thrown.expectMessage("BUG");

+ 0
- 48
sonar-server/src/main/webapp/WEB-INF/app/controllers/api/synchro_controller.rb View File

@@ -1,48 +0,0 @@
#
# Sonar, entreprise quality control tool.
# Copyright (C) 2008-2012 SonarSource
# mailto:contact AT sonarsource DOT com
#
# Sonar 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.
#
# Sonar 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 Sonar; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02
#

require "json"

class Api::SynchroController < Api::ApiController

# curl http://localhost:9000/api/synchro?resource=<resource> -v [-u user:password]
def index
require_parameters :resource
load_resource()

resource_id = @resource.id if @resource
dbFileContent = java_facade.createDatabaseForDryRun(resource_id)

send_data String.from_java_bytes(dbFileContent)
end

private

def load_resource
resource_key = params[:resource]
@resource = Project.by_key(resource_key)
if @resource
access_denied unless is_user?(@resource)
else
#access_denied unless is_user?(nil)
end
end
end


+ 69
- 0
sonar-server/src/main/webapp/WEB-INF/app/controllers/batch_bootstrap_controller.rb View File

@@ -0,0 +1,69 @@
#
# Sonar, entreprise quality control tool.
# Copyright (C) 2008-2012 SonarSource
# mailto:contact AT sonarsource DOT com
#
# Sonar 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.
#
# Sonar 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 Sonar; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02
#

# Since 3.4
class BatchBootstrapController < ApplicationController

# GET /batch_bootstrap/db?project=<key or id>
def db
require_parameters :project
project = load_project()
db_content = java_facade.createDatabaseForDryRun(project ? project.id : nil)

send_data String.from_java_bytes(db_content)
end

# GET /batch_bootstrap/properties?project=<key or id>
def properties
require_parameters :project

json_properties=Property.find(:all, :conditions => ['user_id is null and resource_id is null']).map{|property| to_json_property(property)}

root_project = load_project()
if root_project
Project.find(:all, :select => 'id,kee', :conditions => ['enabled=? and (root_id=? or id=?)', true, root_project.id, root_project.id]).each do |project|
json_properties.concat(Property.find(:all, :conditions => ['user_id is null and resource_id=?', project.id]).map{|property| to_json_property(property, project.kee)})
end
end

has_admin_role=has_role?(:admin, root_project)
json_properties=json_properties.select{|prop| allowed?(prop[:k], has_admin_role)}

render :json => JSON(json_properties)
end

private

def load_project
project = Project.by_key(params[:project])
return access_denied if project && !has_role?(:user, project)
project
end

def to_json_property(property, project_key=nil)
hash={:k => property.key, :v => property.text_value.to_s}
hash[:p]=project_key if project_key
hash
end

def allowed?(property_key, has_admin_role)
!property_key.end_with?('.secured') || has_admin_role
end
end

Loading…
Cancel
Save