@@ -26,7 +26,6 @@ public class BatchWsModule extends Module { | |||
protected void configureModule() { | |||
add( | |||
BatchIndex.class, | |||
GlobalAction.class, | |||
ProjectAction.class, | |||
ProjectDataLoader.class, | |||
IssuesAction.class, |
@@ -1,113 +0,0 @@ | |||
/* | |||
* SonarQube | |||
* Copyright (C) 2009-2016 SonarSource SA | |||
* mailto:contact AT sonarsource DOT com | |||
* | |||
* This program is free software; you can redistribute it and/or | |||
* modify it under the terms of the GNU Lesser General Public | |||
* License as published by the Free Software Foundation; either | |||
* version 3 of the License, or (at your option) any later version. | |||
* | |||
* This program is distributed in the hope that it will be useful, | |||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |||
* Lesser General Public License for more details. | |||
* | |||
* You should have received a copy of the GNU Lesser General Public License | |||
* along with this program; if not, write to the Free Software Foundation, | |||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | |||
*/ | |||
package org.sonar.server.batch; | |||
import org.apache.commons.io.IOUtils; | |||
import org.sonar.api.server.ws.Request; | |||
import org.sonar.api.server.ws.Response; | |||
import org.sonar.api.server.ws.WebService; | |||
import org.sonar.db.DbClient; | |||
import org.sonar.db.DbSession; | |||
import org.sonar.db.MyBatis; | |||
import org.sonar.db.metric.MetricDto; | |||
import org.sonar.db.property.PropertiesDao; | |||
import org.sonar.db.property.PropertyDto; | |||
import org.sonar.scanner.protocol.input.GlobalRepositories; | |||
import org.sonar.server.exceptions.ForbiddenException; | |||
import org.sonar.server.user.UserSession; | |||
import org.sonarqube.ws.MediaTypes; | |||
import static org.sonar.core.permission.GlobalPermissions.SCAN_EXECUTION; | |||
public class GlobalAction implements BatchWsAction { | |||
private final DbClient dbClient; | |||
private final PropertiesDao propertiesDao; | |||
private final UserSession userSession; | |||
public GlobalAction(DbClient dbClient, PropertiesDao propertiesDao, UserSession userSession) { | |||
this.dbClient = dbClient; | |||
this.propertiesDao = propertiesDao; | |||
this.userSession = userSession; | |||
} | |||
@Override | |||
public void define(WebService.NewController controller) { | |||
controller.createAction("global") | |||
.setDescription("Return metrics and global properties") | |||
.setResponseExample(getClass().getResource("global-example.json")) | |||
.setSince("4.5") | |||
.setInternal(true) | |||
.setHandler(this); | |||
} | |||
@Override | |||
public void handle(Request request, Response response) throws Exception { | |||
boolean hasScanPerm = userSession.hasPermission(SCAN_EXECUTION); | |||
boolean isLogged = userSession.isLoggedIn(); | |||
if (!isLogged && !hasScanPerm) { | |||
throw new ForbiddenException(Messages.NO_PERMISSION); | |||
} | |||
DbSession session = dbClient.openSession(false); | |||
try { | |||
GlobalRepositories ref = new GlobalRepositories(); | |||
addMetrics(ref, session); | |||
addSettings(ref, hasScanPerm, isLogged, session); | |||
response.stream().setMediaType(MediaTypes.JSON); | |||
IOUtils.write(ref.toJson(), response.stream().output()); | |||
} finally { | |||
MyBatis.closeQuietly(session); | |||
} | |||
} | |||
private void addMetrics(GlobalRepositories ref, DbSession session) { | |||
for (MetricDto metric : dbClient.metricDao().selectEnabled(session)) { | |||
ref.addMetric( | |||
new org.sonar.scanner.protocol.input.Metric(metric.getId(), metric.getKey(), | |||
metric.getValueType(), | |||
metric.getDescription(), | |||
metric.getDirection(), | |||
metric.getKey(), | |||
metric.isQualitative(), | |||
metric.isUserManaged(), | |||
metric.getWorstValue(), | |||
metric.getBestValue(), | |||
metric.isOptimizedBestValue())); | |||
} | |||
} | |||
private void addSettings(GlobalRepositories ref, boolean hasScanPerm, boolean isLogged, DbSession session) { | |||
for (PropertyDto propertyDto : propertiesDao.selectGlobalProperties(session)) { | |||
String key = propertyDto.getKey(); | |||
String value = propertyDto.getValue(); | |||
if (isPropertyAllowed(key, hasScanPerm, isLogged)) { | |||
ref.addGlobalSetting(key, value); | |||
} | |||
} | |||
} | |||
private static boolean isPropertyAllowed(String key, boolean hasScanPerm, boolean isLogged) { | |||
return !key.contains(".secured") || hasScanPerm || (key.contains(".license") && isLogged); | |||
} | |||
} |
@@ -29,7 +29,7 @@ public class BatchWsModuleTest { | |||
public void verify_count_of_added_components() { | |||
ComponentContainer container = new ComponentContainer(); | |||
new BatchWsModule().configure(container); | |||
assertThat(container.size()).isEqualTo(9); | |||
assertThat(container.size()).isEqualTo(8); | |||
} | |||
} |
@@ -30,7 +30,6 @@ import org.junit.runner.RunWith; | |||
import org.mockito.Mock; | |||
import org.mockito.runners.MockitoJUnitRunner; | |||
import org.sonar.db.DbClient; | |||
import org.sonar.db.property.PropertiesDao; | |||
import org.sonar.server.component.ComponentFinder; | |||
import org.sonar.server.issue.index.IssueIndex; | |||
import org.sonar.server.tester.UserSessionRule; | |||
@@ -59,7 +58,6 @@ public class BatchWsTest { | |||
@Before | |||
public void before() { | |||
tester = new WsTester(new BatchWs(batchIndex, | |||
new GlobalAction(mock(DbClient.class), mock(PropertiesDao.class), userSessionRule), | |||
new ProjectAction(mock(ProjectDataLoader.class)), | |||
new IssuesAction(mock(DbClient.class), mock(IssueIndex.class), userSessionRule, mock(ComponentFinder.class)))); | |||
} |
@@ -1,138 +0,0 @@ | |||
/* | |||
* SonarQube | |||
* Copyright (C) 2009-2016 SonarSource SA | |||
* mailto:contact AT sonarsource DOT com | |||
* | |||
* This program is free software; you can redistribute it and/or | |||
* modify it under the terms of the GNU Lesser General Public | |||
* License as published by the Free Software Foundation; either | |||
* version 3 of the License, or (at your option) any later version. | |||
* | |||
* This program is distributed in the hope that it will be useful, | |||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |||
* Lesser General Public License for more details. | |||
* | |||
* You should have received a copy of the GNU Lesser General Public License | |||
* along with this program; if not, write to the Free Software Foundation, | |||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | |||
*/ | |||
package org.sonar.server.batch; | |||
import org.junit.Before; | |||
import org.junit.Rule; | |||
import org.junit.Test; | |||
import org.junit.rules.ExpectedException; | |||
import org.junit.runner.RunWith; | |||
import org.mockito.Mock; | |||
import org.mockito.runners.MockitoJUnitRunner; | |||
import org.sonar.db.DbClient; | |||
import org.sonar.db.DbSession; | |||
import org.sonar.db.metric.MetricDao; | |||
import org.sonar.db.metric.MetricDto; | |||
import org.sonar.db.property.PropertiesDao; | |||
import org.sonar.db.property.PropertyDto; | |||
import org.sonar.server.exceptions.ForbiddenException; | |||
import org.sonar.server.tester.UserSessionRule; | |||
import org.sonar.server.ws.WsTester; | |||
import static com.google.common.collect.Lists.newArrayList; | |||
import static org.mockito.Mockito.mock; | |||
import static org.mockito.Mockito.when; | |||
import static org.sonar.core.permission.GlobalPermissions.SCAN_EXECUTION; | |||
@RunWith(MockitoJUnitRunner.class) | |||
public class GlobalActionTest { | |||
@Rule | |||
public UserSessionRule userSessionRule = UserSessionRule.standalone(); | |||
@Rule | |||
public ExpectedException thrown = ExpectedException.none(); | |||
@Mock | |||
DbSession session; | |||
@Mock | |||
MetricDao metricDao; | |||
@Mock | |||
PropertiesDao propertiesDao; | |||
WsTester tester; | |||
@Before | |||
public void setUp() { | |||
DbClient dbClient = mock(DbClient.class); | |||
when(dbClient.openSession(false)).thenReturn(session); | |||
when(dbClient.metricDao()).thenReturn(metricDao); | |||
tester = new WsTester(new BatchWs(mock(BatchIndex.class), new GlobalAction(dbClient, propertiesDao, userSessionRule))); | |||
} | |||
@Test | |||
public void return_metrics() throws Exception { | |||
userSessionRule.setGlobalPermissions(SCAN_EXECUTION); | |||
when(metricDao.selectEnabled(session)).thenReturn(newArrayList( | |||
new MetricDto().setId(1).setKey("coverage").setDescription("Coverage by unit tests").setValueType("PERCENT").setQualitative(true) | |||
.setWorstValue(0d).setBestValue(100d).setOptimizedBestValue(false).setDirection(1).setEnabled(true) | |||
)); | |||
WsTester.TestRequest request = tester.newGetRequest("batch", "global"); | |||
request.execute().assertJson(getClass(), "return_global_referentials.json"); | |||
} | |||
@Test | |||
public void return_global_settings() throws Exception { | |||
userSessionRule.setGlobalPermissions(SCAN_EXECUTION); | |||
when(propertiesDao.selectGlobalProperties(session)).thenReturn(newArrayList( | |||
new PropertyDto().setKey("foo").setValue("bar"), | |||
new PropertyDto().setKey("foo.secured").setValue("1234"), | |||
new PropertyDto().setKey("foo.license.secured").setValue("5678") | |||
)); | |||
WsTester.TestRequest request = tester.newGetRequest("batch", "global"); | |||
request.execute().assertJson(getClass(), "return_global_settings.json"); | |||
} | |||
@Test | |||
public void does_not_return_secured_settings_without_scan_permission_but_being_logged() throws Exception { | |||
userSessionRule.login("john"); | |||
when(propertiesDao.selectGlobalProperties(session)).thenReturn(newArrayList( | |||
new PropertyDto().setKey("foo").setValue("bar"), | |||
new PropertyDto().setKey("foo.secured").setValue("1234") | |||
)); | |||
WsTester.TestRequest request = tester.newGetRequest("batch", "global"); | |||
request.execute().assertJson(getClass(), "not_return_secured_settings_without_scan_but_being_logged.json"); | |||
} | |||
@Test | |||
public void return_license_settings_without_scan_permission_but_being_logged() throws Exception { | |||
userSessionRule.login("john"); | |||
when(propertiesDao.selectGlobalProperties(session)).thenReturn(newArrayList( | |||
new PropertyDto().setKey("foo").setValue("bar"), | |||
new PropertyDto().setKey("foo.license.secured").setValue("5678") | |||
)); | |||
WsTester.TestRequest request = tester.newGetRequest("batch", "global"); | |||
request.execute().assertJson(getClass(), "return_only_license_settings_without_scan_but_with_preview_permission.json"); | |||
} | |||
@Test | |||
public void access_forbidden_without_preview_permission_and_not_logged() throws Exception { | |||
userSessionRule.setGlobalPermissions(); | |||
when(propertiesDao.selectGlobalProperties(session)).thenReturn(newArrayList( | |||
new PropertyDto().setKey("foo").setValue("bar"), | |||
new PropertyDto().setKey("foo.secured").setValue("1234"), | |||
new PropertyDto().setKey("foo.license.secured").setValue("5678") | |||
)); | |||
thrown.expect(ForbiddenException.class); | |||
tester.newGetRequest("batch", "global").execute(); | |||
} | |||
} |
@@ -1,7 +0,0 @@ | |||
{ | |||
"timestamp": 0, | |||
"metrics": [], | |||
"globalSettings": { | |||
"foo" : "bar" | |||
} | |||
} |
@@ -1,19 +0,0 @@ | |||
{ | |||
"timestamp": 0, | |||
"metrics": [ | |||
{ | |||
"id": 1, | |||
"key": "coverage", | |||
"valueType": "PERCENT", | |||
"description": "Coverage by unit tests", | |||
"direction": 1, | |||
"name": "coverage", | |||
"qualitative": true, | |||
"userManaged": false, | |||
"worstValue": 0.0, | |||
"bestValue": 100.0, | |||
"optimizedBestValue": false | |||
} | |||
], | |||
"globalSettings": {} | |||
} |
@@ -1,9 +0,0 @@ | |||
{ | |||
"timestamp": 0, | |||
"metrics": [], | |||
"globalSettings": { | |||
"foo" : "bar", | |||
"foo.secured" : "1234", | |||
"foo.license.secured" : "5678" | |||
} | |||
} |
@@ -1,8 +0,0 @@ | |||
{ | |||
"timestamp": 0, | |||
"metrics": [], | |||
"globalSettings": { | |||
"foo" : "bar", | |||
"foo.license.secured" : "5678" | |||
} | |||
} |
@@ -1,72 +0,0 @@ | |||
/* | |||
* SonarQube | |||
* Copyright (C) 2009-2016 SonarSource SA | |||
* mailto:contact AT sonarsource DOT com | |||
* | |||
* This program is free software; you can redistribute it and/or | |||
* modify it under the terms of the GNU Lesser General Public | |||
* License as published by the Free Software Foundation; either | |||
* version 3 of the License, or (at your option) any later version. | |||
* | |||
* This program is distributed in the hope that it will be useful, | |||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |||
* Lesser General Public License for more details. | |||
* | |||
* You should have received a copy of the GNU Lesser General Public License | |||
* along with this program; if not, write to the Free Software Foundation, | |||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | |||
*/ | |||
package org.sonar.scanner.protocol.input; | |||
import java.util.ArrayList; | |||
import java.util.Collection; | |||
import java.util.HashMap; | |||
import java.util.Map; | |||
import org.sonar.scanner.protocol.GsonHelper; | |||
/** | |||
* Container for all global data going from server to batch. | |||
* This is not an API since server and batch always share the same version. | |||
*/ | |||
public class GlobalRepositories { | |||
private long timestamp; | |||
private Collection<Metric> metrics = new ArrayList<>(); | |||
private Map<String, String> globalSettings = new HashMap<>(); | |||
public Map<String, String> globalSettings() { | |||
return globalSettings; | |||
} | |||
public GlobalRepositories addGlobalSetting(String key, String value) { | |||
globalSettings.put(key, value); | |||
return this; | |||
} | |||
public Collection<Metric> metrics() { | |||
return metrics; | |||
} | |||
public GlobalRepositories addMetric(Metric metric) { | |||
metrics.add(metric); | |||
return this; | |||
} | |||
public long timestamp() { | |||
return timestamp; | |||
} | |||
public void setTimestamp(long timestamp) { | |||
this.timestamp = timestamp; | |||
} | |||
public String toJson() { | |||
return GsonHelper.create().toJson(this); | |||
} | |||
public static GlobalRepositories fromJson(String json) { | |||
return GsonHelper.create().fromJson(json, GlobalRepositories.class); | |||
} | |||
} |
@@ -1,120 +0,0 @@ | |||
/* | |||
* SonarQube | |||
* Copyright (C) 2009-2016 SonarSource SA | |||
* mailto:contact AT sonarsource DOT com | |||
* | |||
* This program is free software; you can redistribute it and/or | |||
* modify it under the terms of the GNU Lesser General Public | |||
* License as published by the Free Software Foundation; either | |||
* version 3 of the License, or (at your option) any later version. | |||
* | |||
* This program is distributed in the hope that it will be useful, | |||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |||
* Lesser General Public License for more details. | |||
* | |||
* You should have received a copy of the GNU Lesser General Public License | |||
* along with this program; if not, write to the Free Software Foundation, | |||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | |||
*/ | |||
package org.sonar.scanner.protocol.input; | |||
import javax.annotation.CheckForNull; | |||
import javax.annotation.Nullable; | |||
public class Metric { | |||
private final int id; | |||
private final String key; | |||
private final String valueType; | |||
private final String description; | |||
private final int direction; | |||
private final String name; | |||
private final boolean qualitative; | |||
private final boolean userManaged; | |||
private final Double worstValue; | |||
private final Double bestValue; | |||
private final boolean optimizedBestValue; | |||
public Metric(int id, | |||
String key, | |||
String valueType, | |||
@Nullable String description, | |||
int direction, | |||
String name, | |||
boolean qualitative, | |||
boolean userManaged, | |||
@Nullable Double worstValue, | |||
@Nullable Double bestValue, | |||
boolean optimizedBestValue) { | |||
this.id = id; | |||
this.key = key; | |||
this.valueType = valueType; | |||
this.description = description; | |||
this.direction = direction; | |||
this.name = name; | |||
this.qualitative = qualitative; | |||
this.userManaged = userManaged; | |||
this.worstValue = worstValue; | |||
this.bestValue = bestValue; | |||
this.optimizedBestValue = optimizedBestValue; | |||
} | |||
public int id() { | |||
return id; | |||
} | |||
public String key() { | |||
return key; | |||
} | |||
public String valueType() { | |||
return valueType; | |||
} | |||
@CheckForNull | |||
public String description() { | |||
return description; | |||
} | |||
public int direction() { | |||
return direction; | |||
} | |||
public String name() { | |||
return name; | |||
} | |||
public boolean isQualitative() { | |||
return qualitative; | |||
} | |||
public boolean isUserManaged() { | |||
return userManaged; | |||
} | |||
@CheckForNull | |||
public Double worstValue() { | |||
return worstValue; | |||
} | |||
@CheckForNull | |||
public Double bestValue() { | |||
return bestValue; | |||
} | |||
public boolean isOptimizedBestValue() { | |||
return optimizedBestValue; | |||
} | |||
} |
@@ -1,67 +0,0 @@ | |||
/* | |||
* SonarQube | |||
* Copyright (C) 2009-2016 SonarSource SA | |||
* mailto:contact AT sonarsource DOT com | |||
* | |||
* This program is free software; you can redistribute it and/or | |||
* modify it under the terms of the GNU Lesser General Public | |||
* License as published by the Free Software Foundation; either | |||
* version 3 of the License, or (at your option) any later version. | |||
* | |||
* This program is distributed in the hope that it will be useful, | |||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |||
* Lesser General Public License for more details. | |||
* | |||
* You should have received a copy of the GNU Lesser General Public License | |||
* along with this program; if not, write to the Free Software Foundation, | |||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | |||
*/ | |||
package org.sonar.scanner.protocol.input; | |||
import org.apache.commons.io.IOUtils; | |||
import org.junit.Test; | |||
import org.sonar.scanner.protocol.input.GlobalRepositories; | |||
import org.sonar.scanner.protocol.input.Metric; | |||
import static net.javacrumbs.jsonunit.assertj.JsonAssert.assertThatJson; | |||
import static org.assertj.core.api.Assertions.assertThat; | |||
public class GlobalRepositoriesTest { | |||
@Test | |||
public void to_json() throws Exception { | |||
GlobalRepositories ref = new GlobalRepositories(); | |||
ref.addMetric(new Metric(1, "ncloc", "INT", "Description", -1, "NCLOC", true, false, 2.0, 1.0, true)); | |||
ref.addGlobalSetting("prop", "value"); | |||
ref.setTimestamp(10); | |||
assertThatJson(ref.toJson()) | |||
.isEqualTo(IOUtils.toString(getClass().getResource("GlobalRepositoriesTest/expected.json"))); | |||
} | |||
@Test | |||
public void from_json() { | |||
GlobalRepositories ref = GlobalRepositories | |||
.fromJson( | |||
"{timestamp:1," | |||
+ "metrics:[{id:1,key:ncloc,valueType:DATA,description:Description,direction:-1,name:NCLOC,qualitative:true,userManaged:false,worstValue:2.0,bestValue:1.0,optimizedBestValue:true}]," | |||
+ "globalSettings:{prop:value}}"); | |||
assertThat(ref.timestamp()).isEqualTo(1); | |||
Metric metric = ref.metrics().iterator().next(); | |||
assertThat(metric.id()).isEqualTo(1); | |||
assertThat(metric.key()).isEqualTo("ncloc"); | |||
assertThat(metric.valueType()).isEqualTo("DATA"); | |||
assertThat(metric.description()).isEqualTo("Description"); | |||
assertThat(metric.direction()).isEqualTo(-1); | |||
assertThat(metric.name()).isEqualTo("NCLOC"); | |||
assertThat(metric.isQualitative()).isTrue(); | |||
assertThat(metric.isUserManaged()).isFalse(); | |||
assertThat(metric.worstValue()).isEqualTo(2.0); | |||
assertThat(metric.bestValue()).isEqualTo(1.0); | |||
assertThat(metric.isOptimizedBestValue()).isTrue(); | |||
assertThat(ref.globalSettings()).containsEntry("prop", "value"); | |||
} | |||
} |
@@ -1,21 +0,0 @@ | |||
{ | |||
"timestamp": 10, | |||
"metrics": [ | |||
{ | |||
"id": 1, | |||
"key": "ncloc", | |||
"valueType": "INT", | |||
"description": "Description", | |||
"direction": -1, | |||
"name": "NCLOC", | |||
"qualitative": true, | |||
"userManaged": false, | |||
"worstValue": 2.0, | |||
"bestValue": 1.0, | |||
"optimizedBestValue": true | |||
} | |||
], | |||
"globalSettings": { | |||
"prop": "value" | |||
} | |||
} |
@@ -1,23 +0,0 @@ | |||
{ | |||
"timestamp": 10, | |||
"settingsByModule": { | |||
"foo": { | |||
"prop1": "value1", | |||
"prop2": "value2", | |||
"prop": "value" | |||
} | |||
}, | |||
"fileDataByModuleAndPath": { | |||
"foo": { | |||
"src/main/java/Foo.java": { | |||
"hash": "xyz", | |||
"needBlame": true | |||
}, | |||
"src/main/java/Foo2.java": { | |||
"hash": "xyz", | |||
"needBlame": false | |||
} | |||
} | |||
}, | |||
"lastAnalysisDate": "2014-05-18T15:50:45+0100" | |||
} |
@@ -1 +0,0 @@ | |||
{"total":3225,"p":30,"ps":500,"rules":[]} |
@@ -1 +0,0 @@ | |||
{"total":290,"p":1,"ps":2,"rules":[{"key":"squid:S1194","internalKey":"S1194","repo":"squid","name":"\"java.lang.Error\" should not be extended","severity":"MAJOR","lang":"java"},{"key":"squid:ObjectFinalizeOverridenCallsSuperFinalizeCheck","internalKey":"ObjectFinalizeOverridenCallsSuperFinalizeCheck","repo":"squid","name":"super.finalize() should be called at the end of Object.finalize() implementations","severity":"BLOCKER","lang":"java"}]} |