private final BatchIndex batchIndex;
private final GlobalRepositoryAction globalRepositoryAction;
private final ProjectRepositoryAction projectRepositoryAction;
+ private final IssuesAction issuesAction;
- public BatchWs(BatchIndex batchIndex, GlobalRepositoryAction globalRepositoryAction, ProjectRepositoryAction projectRepositoryAction) {
+ public BatchWs(BatchIndex batchIndex, GlobalRepositoryAction globalRepositoryAction, ProjectRepositoryAction projectRepositoryAction, IssuesAction issuesAction) {
this.batchIndex = batchIndex;
this.globalRepositoryAction = globalRepositoryAction;
this.projectRepositoryAction = projectRepositoryAction;
+ this.issuesAction = issuesAction;
}
@Override
defineFileAction(controller);
globalRepositoryAction.define(controller);
projectRepositoryAction.define(controller);
+ issuesAction.define(controller);
controller.done();
}
public void handle(Request request, Response response) throws Exception {
UserSession userSession = UserSession.get();
boolean hasScanPerm = userSession.hasGlobalPermission(GlobalPermissions.SCAN_EXECUTION);
- boolean hasDryRunPerm = userSession.hasGlobalPermission(GlobalPermissions.DRY_RUN_EXECUTION);
+ boolean hasDryRunPerm = userSession.hasGlobalPermission(GlobalPermissions.PREVIEW_EXECUTION);
DbSession session = dbClient.openSession(false);
try {
--- /dev/null
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2014 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * SonarQube is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+package org.sonar.server.batch;
+
+import com.google.common.base.Charsets;
+import org.apache.ibatis.session.ResultContext;
+import org.apache.ibatis.session.ResultHandler;
+import org.sonar.api.server.ws.Request;
+import org.sonar.api.server.ws.RequestHandler;
+import org.sonar.api.server.ws.Response;
+import org.sonar.api.server.ws.WebService;
+import org.sonar.api.web.UserRole;
+import org.sonar.batch.protocol.input.issues.PreviousIssue;
+import org.sonar.batch.protocol.input.issues.PreviousIssueHelper;
+import org.sonar.core.component.ComponentDto;
+import org.sonar.core.issue.db.BatchIssueDto;
+import org.sonar.core.permission.GlobalPermissions;
+import org.sonar.core.persistence.DbSession;
+import org.sonar.core.persistence.MyBatis;
+import org.sonar.server.db.DbClient;
+import org.sonar.server.plugins.MimeTypes;
+import org.sonar.server.user.UserSession;
+
+import javax.annotation.Nullable;
+
+import java.io.OutputStreamWriter;
+
+public class IssuesAction implements RequestHandler {
+
+ private static final String PARAM_KEY = "key";
+
+ private final DbClient dbClient;
+
+ public IssuesAction(DbClient dbClient) {
+ this.dbClient = dbClient;
+ }
+
+ void define(WebService.NewController controller) {
+ WebService.NewAction action = controller.createAction("issues")
+ .setDescription("Return open issues")
+ .setSince("5.1")
+ .setInternal(true)
+ .setHandler(this);
+
+ action
+ .createParam(PARAM_KEY)
+ .setRequired(true)
+ .setDescription("Project or module key")
+ .setExampleValue("org.codehaus.sonar:sonar");
+ }
+
+ @Override
+ public void handle(Request request, Response response) throws Exception {
+ UserSession.get().checkGlobalPermission(GlobalPermissions.PREVIEW_EXECUTION);
+ final String moduleKey = request.mandatoryParam(PARAM_KEY);
+
+ PreviousIssueHelper previousIssueHelper = PreviousIssueHelper.create(new OutputStreamWriter(response.stream().output(), Charsets.UTF_8));
+ DbSession session = dbClient.openSession(false);
+ try {
+ ComponentDto moduleOrProject = dbClient.componentDao().getByKey(session, moduleKey);
+ UserSession.get().checkComponentPermission(UserRole.USER, moduleKey);
+
+ response.stream().setMediaType(MimeTypes.JSON);
+ BatchIssueResultHandler batchIssueResultHandler = new BatchIssueResultHandler(previousIssueHelper);
+ if (moduleOrProject.isRootProject()) {
+ dbClient.issueDao().selectNonClosedIssuesByProjectUuid(session, moduleOrProject.uuid(), batchIssueResultHandler);
+ } else {
+ dbClient.issueDao().selectNonClosedIssuesByModuleUuid(session, moduleOrProject.uuid(), batchIssueResultHandler);
+ }
+
+ } finally {
+ previousIssueHelper.close();
+ MyBatis.closeQuietly(session);
+ }
+ }
+
+ private static class BatchIssueResultHandler implements ResultHandler {
+ private final PreviousIssueHelper previousIssueHelper;
+
+ public BatchIssueResultHandler(PreviousIssueHelper previousIssueHelper) {
+ this.previousIssueHelper = previousIssueHelper;
+ }
+
+ @Override
+ public void handleResult(ResultContext rc) {
+ previousIssueHelper.addIssue((BatchIssueDto) rc.getResultObject(), new BatchIssueFunction());
+ }
+ }
+
+ private static class BatchIssueFunction implements PreviousIssueHelper.Function<BatchIssueDto, PreviousIssue> {
+ @Override
+ public PreviousIssue apply(@Nullable BatchIssueDto batchIssueDto) {
+ if (batchIssueDto != null) {
+ return new PreviousIssue()
+ .setKey(batchIssueDto.getKey())
+ .setComponentPath(batchIssueDto.getComponentPath())
+ .setChecksum(batchIssueDto.getChecksum())
+ .setAssigneeLogin(batchIssueDto.getAssigneeLogin())
+ .setAssigneeFullname(batchIssueDto.getAssigneeName())
+ .setLine(batchIssueDto.getLine())
+ .setRuleKey(batchIssueDto.getRuleRepo(), batchIssueDto.getRuleKey())
+ .setMessage(batchIssueDto.getMessage())
+ .setResolution(batchIssueDto.getResolution())
+ .setStatus(batchIssueDto.getStatus());
+ }
+ return null;
+ }
+ }
+}
}
private void addSettingsToChildrenModules(ProjectReferentials ref, String moduleKey, Map<String, String> parentProperties, TreeModuleSettings treeModuleSettings,
- boolean hasScanPerm, DbSession session) {
+ boolean hasScanPerm, DbSession session) {
Map<String, String> currentParentProperties = newHashMap();
currentParentProperties.putAll(parentProperties);
currentParentProperties.putAll(getPropertiesMap(treeModuleSettings.findModuleSettings(moduleKey), hasScanPerm));
private void checkPermission(boolean preview) {
UserSession userSession = UserSession.get();
boolean hasScanPerm = userSession.hasGlobalPermission(GlobalPermissions.SCAN_EXECUTION);
- boolean hasPreviewPerm = userSession.hasGlobalPermission(GlobalPermissions.DRY_RUN_EXECUTION);
+ boolean hasPreviewPerm = userSession.hasGlobalPermission(GlobalPermissions.PREVIEW_EXECUTION);
if (!hasPreviewPerm && !hasScanPerm) {
throw new ForbiddenException("You're not authorized to execute any SonarQube analysis. Please contact your SonarQube administrator.");
}
*/
package org.sonar.server.issue.db;
+import org.apache.ibatis.session.ResultHandler;
import org.sonar.core.issue.db.IssueDto;
import org.sonar.core.issue.db.IssueMapper;
import org.sonar.core.persistence.DaoComponent;
return mapper(session).selectByKeys(keys);
}
+ public void selectNonClosedIssuesByModuleUuid(DbSession session, String moduleUuid, ResultHandler handler) {
+ session.select("org.sonar.core.issue.db.IssueMapper.selectNonClosedIssuesByModuleUuid", moduleUuid, handler);
+ }
+
+ public void selectNonClosedIssuesByProjectUuid(DbSession session, String projectUuid, ResultHandler handler) {
+ session.select("org.sonar.core.issue.db.IssueMapper.selectNonClosedIssuesByProjectUuid", projectUuid, handler);
+ }
+
public void insert(DbSession session, IssueDto dto) {
mapper(session).insert(dto);
}
import javax.annotation.CheckForNull;
import javax.annotation.Nullable;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.Date;
-import java.util.List;
-import java.util.Map;
+import java.util.*;
public class IssueDoc extends BaseDoc implements Issue {
return getNullableField(IssueIndexDefinition.FIELD_ISSUE_FILE_PATH);
}
- public void setKey(@Nullable String s) {
+ public IssueDoc setKey(@Nullable String s) {
setField(IssueIndexDefinition.FIELD_ISSUE_KEY, s);
+ return this;
}
- public void setComponentUuid(@Nullable String s) {
+ public IssueDoc setComponentUuid(@Nullable String s) {
setField(IssueIndexDefinition.FIELD_ISSUE_COMPONENT_UUID, s);
+ return this;
}
- public void setModuleUuid(@Nullable String s) {
+ public IssueDoc setModuleUuid(@Nullable String s) {
setField(IssueIndexDefinition.FIELD_ISSUE_MODULE_UUID, s);
+ return this;
}
- public void setProjectUuid(@Nullable String s) {
+ public IssueDoc setProjectUuid(@Nullable String s) {
setField(IssueIndexDefinition.FIELD_ISSUE_PROJECT_UUID, s);
+ return this;
}
- public void setRuleKey(@Nullable String s) {
+ public IssueDoc setRuleKey(@Nullable String s) {
setField(IssueIndexDefinition.FIELD_ISSUE_RULE_KEY, s);
+ return this;
}
- public void setLanguage(@Nullable String s) {
+ public IssueDoc setLanguage(@Nullable String s) {
setField(IssueIndexDefinition.FIELD_ISSUE_LANGUAGE, s);
+ return this;
}
- public void setSeverity(@Nullable String s) {
+ public IssueDoc setSeverity(@Nullable String s) {
setField(IssueIndexDefinition.FIELD_ISSUE_SEVERITY, s);
setField(IssueIndexDefinition.FIELD_ISSUE_SEVERITY_VALUE, Severity.ALL.indexOf(s));
+ return this;
}
- public void setMessage(@Nullable String s) {
+ public IssueDoc setMessage(@Nullable String s) {
setField(IssueIndexDefinition.FIELD_ISSUE_MESSAGE, s);
+ return this;
}
- public void setLine(@Nullable Integer i) {
+ public IssueDoc setLine(@Nullable Integer i) {
setField(IssueIndexDefinition.FIELD_ISSUE_LINE, i);
+ return this;
}
- public void setEffortToFix(@Nullable Double d) {
+ public IssueDoc setEffortToFix(@Nullable Double d) {
setField(IssueIndexDefinition.FIELD_ISSUE_EFFORT, d);
+ return this;
}
- public void setStatus(@Nullable String s) {
+ public IssueDoc setStatus(@Nullable String s) {
setField(IssueIndexDefinition.FIELD_ISSUE_STATUS, s);
+ return this;
}
- public void setResolution(@Nullable String s) {
+ public IssueDoc setResolution(@Nullable String s) {
setField(IssueIndexDefinition.FIELD_ISSUE_RESOLUTION, s);
+ return this;
}
- public void setReporter(@Nullable String s) {
+ public IssueDoc setReporter(@Nullable String s) {
setField(IssueIndexDefinition.FIELD_ISSUE_REPORTER, s);
+ return this;
}
- public void setAssignee(@Nullable String s) {
+ public IssueDoc setAssignee(@Nullable String s) {
setField(IssueIndexDefinition.FIELD_ISSUE_ASSIGNEE, s);
+ return this;
}
- public void setFuncUpdateDate(@Nullable Date d) {
+ public IssueDoc setFuncUpdateDate(@Nullable Date d) {
setField(IssueIndexDefinition.FIELD_ISSUE_FUNC_UPDATED_AT, d);
+ return this;
}
- public void setFuncCreationDate(@Nullable Date d) {
+ public IssueDoc setFuncCreationDate(@Nullable Date d) {
setField(IssueIndexDefinition.FIELD_ISSUE_FUNC_CREATED_AT, d);
+ return this;
}
- public void setTechnicalUpdateDate(@Nullable Date d) {
+ public IssueDoc setTechnicalUpdateDate(@Nullable Date d) {
setField(IssueIndexDefinition.FIELD_ISSUE_TECHNICAL_UPDATED_AT, d);
+ return this;
}
- public void setFuncCloseDate(@Nullable Date d) {
+ public IssueDoc setFuncCloseDate(@Nullable Date d) {
setField(IssueIndexDefinition.FIELD_ISSUE_FUNC_CLOSED_AT, d);
+ return this;
}
- public void setAttributes(@Nullable String s) {
+ public IssueDoc setAttributes(@Nullable String s) {
setField(IssueIndexDefinition.FIELD_ISSUE_ATTRIBUTES, s);
+ return this;
}
- public void setAuthorLogin(@Nullable String s) {
+ public IssueDoc setAuthorLogin(@Nullable String s) {
setField(IssueIndexDefinition.FIELD_ISSUE_AUTHOR_LOGIN, s);
+ return this;
}
- public void setActionPlanKey(@Nullable String s) {
+ public IssueDoc setActionPlanKey(@Nullable String s) {
setField(IssueIndexDefinition.FIELD_ISSUE_ACTION_PLAN, s);
+ return this;
}
- public void setDebt(@Nullable Long l) {
+ public IssueDoc setDebt(@Nullable Long l) {
setField(IssueIndexDefinition.FIELD_ISSUE_DEBT, l);
+ return this;
}
- public void setFilePath(@Nullable String s) {
+ public IssueDoc setFilePath(@Nullable String s) {
setField(IssueIndexDefinition.FIELD_ISSUE_FILE_PATH, s);
+ return this;
}
- public void setModuleUuidPath(@Nullable String s) {
+ public IssueDoc setModuleUuidPath(@Nullable String s) {
setField(IssueIndexDefinition.FIELD_ISSUE_MODULE_PATH, s);
+ return this;
}
@Override
return getNullableField(IssueIndexDefinition.FIELD_ISSUE_TAGS);
}
- public void setTags(@Nullable Collection<String> tags) {
+ public IssueDoc setTags(@Nullable Collection<String> tags) {
setField(IssueIndexDefinition.FIELD_ISSUE_TAGS, tags);
+ return this;
}
}
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.action.search.SearchType;
import org.elasticsearch.common.unit.TimeValue;
-import org.elasticsearch.index.query.BoolFilterBuilder;
-import org.elasticsearch.index.query.FilterBuilder;
-import org.elasticsearch.index.query.FilterBuilders;
-import org.elasticsearch.index.query.OrFilterBuilder;
-import org.elasticsearch.index.query.QueryBuilder;
-import org.elasticsearch.index.query.QueryBuilders;
+import org.elasticsearch.index.query.*;
import org.elasticsearch.search.aggregations.AggregationBuilder;
import org.elasticsearch.search.aggregations.AggregationBuilders;
import org.elasticsearch.search.aggregations.bucket.filter.FilterAggregationBuilder;
import org.sonar.server.es.Sorting;
import org.sonar.server.issue.IssueQuery;
import org.sonar.server.issue.filter.IssueFilterParameters;
-import org.sonar.server.search.BaseIndex;
-import org.sonar.server.search.FacetValue;
-import org.sonar.server.search.IndexDefinition;
-import org.sonar.server.search.QueryContext;
-import org.sonar.server.search.Result;
-import org.sonar.server.search.SearchClient;
-import org.sonar.server.search.StickyFacetBuilder;
+import org.sonar.server.search.*;
import org.sonar.server.user.UserSession;
import javax.annotation.CheckForNull;
import javax.annotation.Nullable;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.Date;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
+import java.util.*;
import static com.google.common.collect.Lists.newArrayList;
Terms result = count.addAggregation(aggreg).get().getAggregations().get("_ref");
Map<String, Long> map = Maps.newHashMap();
- for (Bucket bucket: result.getBuckets()) {
+ for (Bucket bucket : result.getBuckets()) {
map.put(bucket.getKey(), bucket.getDocCount());
}
return map;
pico.addSingleton(ProjectRepositoryAction.class);
pico.addSingleton(ProjectRepositoryLoader.class);
pico.addSingleton(SubmitReportWsAction.class);
+ pico.addSingleton(IssuesSearchService.class);
+ pico.addSingleton(IssuesAction.class);
pico.addSingleton(BatchWs.class);
// update center
public void before() throws IOException {
tester = new WsTester(new BatchWs(batchIndex,
new GlobalRepositoryAction(mock(DbClient.class), mock(PropertiesDao.class)),
- new ProjectRepositoryAction(mock(ProjectRepositoryLoader.class))));
+ new ProjectRepositoryAction(mock(ProjectRepositoryLoader.class)),
+ new IssuesAction(mock(DbClient.class))));
}
@Test
when(dbClient.openSession(false)).thenReturn(session);
when(dbClient.metricDao()).thenReturn(metricDao);
- tester = new WsTester(new BatchWs(mock(BatchIndex.class), new GlobalRepositoryAction(dbClient, propertiesDao), mock(ProjectRepositoryAction.class)));
+ tester = new WsTester(new BatchWs(mock(BatchIndex.class), new GlobalRepositoryAction(dbClient, propertiesDao), mock(ProjectRepositoryAction.class), mock(IssuesAction.class)));
}
@Test
@Test
public void return_global_settings() throws Exception {
- MockUserSession.set().setLogin("john").setGlobalPermissions(GlobalPermissions.SCAN_EXECUTION, GlobalPermissions.DRY_RUN_EXECUTION);
+ MockUserSession.set().setLogin("john").setGlobalPermissions(GlobalPermissions.SCAN_EXECUTION, GlobalPermissions.PREVIEW_EXECUTION);
when(propertiesDao.selectGlobalProperties(session)).thenReturn(newArrayList(
new PropertyDto().setKey("foo").setValue("bar"),
@Test
public void return_only_license_settings_without_scan_but_with_preview_permission() throws Exception {
- MockUserSession.set().setLogin("john").setGlobalPermissions(GlobalPermissions.DRY_RUN_EXECUTION);
+ MockUserSession.set().setLogin("john").setGlobalPermissions(GlobalPermissions.PREVIEW_EXECUTION);
when(propertiesDao.selectGlobalProperties(session)).thenReturn(newArrayList(
new PropertyDto().setKey("foo").setValue("bar"),
--- /dev/null
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2014 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * SonarQube is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+package org.sonar.server.batch;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.sonar.api.platform.Server;
+import org.sonar.api.web.UserRole;
+import org.sonar.core.permission.GlobalPermissions;
+import org.sonar.core.persistence.DbSession;
+import org.sonar.core.persistence.DbTester;
+import org.sonar.core.properties.PropertiesDao;
+import org.sonar.server.component.db.ComponentDao;
+import org.sonar.server.db.DbClient;
+import org.sonar.server.exceptions.ForbiddenException;
+import org.sonar.server.issue.db.IssueDao;
+import org.sonar.server.user.MockUserSession;
+import org.sonar.server.ws.WsTester;
+
+import static org.mockito.Mockito.mock;
+
+public class IssuesActionTest {
+
+ private final static String PROJECT_KEY = "struts";
+ private final static String MODULE_KEY = "struts-core";
+
+ WsTester tester;
+
+ IssuesAction issuesAction;
+
+ @Rule
+ public DbTester db = new DbTester();
+
+ private DbSession session;
+
+ @Before
+ public void before() throws Exception {
+ this.session = db.myBatis().openSession(false);
+
+ DbClient dbClient = new DbClient(db.database(), db.myBatis(), new IssueDao(db.myBatis()), new ComponentDao());
+ issuesAction = new IssuesAction(dbClient);
+
+ tester = new WsTester(new BatchWs(
+ new BatchIndex(mock(Server.class)),
+ new GlobalRepositoryAction(mock(DbClient.class), mock(PropertiesDao.class)),
+ new ProjectRepositoryAction(mock(ProjectRepositoryLoader.class)),
+ issuesAction)
+ );
+ }
+
+ @After
+ public void after() {
+ this.session.close();
+ }
+
+ @Test
+ public void return_issues_on_project() throws Exception {
+ db.prepareDbUnit(getClass(), "shared.xml");
+
+ MockUserSession.set().setLogin("henry").setGlobalPermissions(GlobalPermissions.PREVIEW_EXECUTION).addComponentPermission(UserRole.USER, PROJECT_KEY, PROJECT_KEY);
+
+ WsTester.TestRequest request = tester.newGetRequest("batch", "issues").setParam("key", PROJECT_KEY);
+ request.execute().assertJson(getClass(), "issues_on_project-expected.json");
+ }
+
+ @Test
+ public void return_issues_on_module() throws Exception {
+ db.prepareDbUnit(getClass(), "shared.xml");
+
+ MockUserSession.set().setLogin("henry").setGlobalPermissions(GlobalPermissions.PREVIEW_EXECUTION).addComponentPermission(UserRole.USER, PROJECT_KEY, MODULE_KEY);
+
+ WsTester.TestRequest request = tester.newGetRequest("batch", "issues").setParam("key", MODULE_KEY);
+ request.execute().assertJson(getClass(), "issues_on_module-expected.json");
+ }
+
+ @Test(expected = ForbiddenException.class)
+ public void fail_without_preview_permission() throws Exception {
+ db.prepareDbUnit(getClass(), "shared.xml");
+
+ MockUserSession.set().setLogin("henry").setGlobalPermissions(GlobalPermissions.PROVISIONING).addComponentPermission(UserRole.USER, PROJECT_KEY, MODULE_KEY);
+
+ WsTester.TestRequest request = tester.newGetRequest("batch", "issues").setParam("key", MODULE_KEY);
+ request.execute();
+ }
+
+ @Test(expected = ForbiddenException.class)
+ public void fail_without_user_permission_on_project() throws Exception {
+ db.prepareDbUnit(getClass(), "shared.xml");
+
+ MockUserSession.set().setLogin("henry").setGlobalPermissions(GlobalPermissions.PREVIEW_EXECUTION).addComponentPermission(UserRole.CODEVIEWER, PROJECT_KEY, PROJECT_KEY);
+
+ WsTester.TestRequest request = tester.newGetRequest("batch", "issues").setParam("key", MODULE_KEY);
+ request.execute();
+ }
+
+ @Test(expected = ForbiddenException.class)
+ public void fail_without_user_permission_on_module() throws Exception {
+ db.prepareDbUnit(getClass(), "shared.xml");
+
+ MockUserSession.set().setLogin("henry").setGlobalPermissions(GlobalPermissions.PREVIEW_EXECUTION).addComponentPermission(UserRole.CODEVIEWER, PROJECT_KEY, MODULE_KEY);
+
+ WsTester.TestRequest request = tester.newGetRequest("batch", "issues").setParam("key", MODULE_KEY);
+ request.execute();
+ }
+}
public class ProjectRepositoryActionTest {
@Mock
- ProjectRepositoryLoader projectReferentialsLoader;
+ ProjectRepositoryLoader projectRepositoryLoader;
WsTester tester;
@Before
public void setUp() throws Exception {
tester = new WsTester(new BatchWs(mock(BatchIndex.class), mock(GlobalRepositoryAction.class),
- new ProjectRepositoryAction(projectReferentialsLoader)));
+ new ProjectRepositoryAction(projectRepositoryLoader), mock(IssuesAction.class)));
}
@Test
when(projectReferentials.toJson()).thenReturn("{\"settingsByModule\": {}}");
ArgumentCaptor<ProjectRepositoryQuery> queryArgumentCaptor = ArgumentCaptor.forClass(ProjectRepositoryQuery.class);
- when(projectReferentialsLoader.load(queryArgumentCaptor.capture())).thenReturn(projectReferentials);
+ when(projectRepositoryLoader.load(queryArgumentCaptor.capture())).thenReturn(projectReferentials);
WsTester.TestRequest request = tester.newGetRequest("batch", "project")
.setParam("key", projectKey)
@Test
public void not_returned_secured_settings_with_only_preview_permission() throws Exception {
- MockUserSession.set().setLogin("john").setGlobalPermissions(GlobalPermissions.DRY_RUN_EXECUTION);
+ MockUserSession.set().setLogin("john").setGlobalPermissions(GlobalPermissions.PREVIEW_EXECUTION);
ComponentDto project = ComponentTesting.newProjectDto();
tester.get(DbClient.class).componentDao().insert(dbSession, project);
@Test
public void fail_when_not_preview_and_only_dry_run_permission() throws Exception {
- MockUserSession.set().setLogin("john").setGlobalPermissions(GlobalPermissions.DRY_RUN_EXECUTION);
+ MockUserSession.set().setLogin("john").setGlobalPermissions(GlobalPermissions.PREVIEW_EXECUTION);
ComponentDto project = ComponentTesting.newProjectDto();
tester.get(DbClient.class).componentDao().insert(dbSession, project);
}
@Test
- public void add_file_data_on_single_project() throws Exception {
+ public void return_file_data_from_single_project() throws Exception {
MockUserSession.set().setLogin("john").setGlobalPermissions(GlobalPermissions.SCAN_EXECUTION);
ComponentDto project = ComponentTesting.newProjectDto();
}
@Test
- public void add_file_data_on_multi_modules() throws Exception {
+ public void return_file_data_from_multi_modules() throws Exception {
MockUserSession.set().setLogin("john").setGlobalPermissions(GlobalPermissions.SCAN_EXECUTION);
ComponentDto project = ComponentTesting.newProjectDto();
assertThat(ref.fileData(module.key(), moduleFile.path()).hash()).isEqualTo("789456");
}
+ @Test
+ public void return_file_data_from_module() throws Exception {
+ MockUserSession.set().setLogin("john").setGlobalPermissions(GlobalPermissions.SCAN_EXECUTION);
+
+ ComponentDto project = ComponentTesting.newProjectDto();
+ tester.get(DbClient.class).componentDao().insert(dbSession, project);
+ addDefaultProfile();
+
+ // File on project
+ ComponentDto projectFile = ComponentTesting.newFileDto(project, "projectFile");
+ tester.get(DbClient.class).componentDao().insert(dbSession, projectFile);
+ tester.get(FileSourceDao.class).insert(newFileSourceDto(projectFile).setSrcHash("123456"));
+
+ ComponentDto module = ComponentTesting.newModuleDto(project);
+ tester.get(DbClient.class).componentDao().insert(dbSession, module);
+
+ // File on module
+ ComponentDto moduleFile = ComponentTesting.newFileDto(module, "moduleFile");
+ tester.get(DbClient.class).componentDao().insert(dbSession, moduleFile);
+ tester.get(FileSourceDao.class).insert(newFileSourceDto(moduleFile).setSrcHash("789456"));
+
+ dbSession.commit();
+
+ ProjectReferentials ref = loader.load(ProjectRepositoryQuery.create().setModuleKey(module.key()));
+ assertThat(ref.fileData(module.key(), moduleFile.path()).hash()).isEqualTo("789456");
+ assertThat(ref.fileData(project.key(), projectFile.path())).isNull();
+ }
+
private void addDefaultProfile() {
QualityProfileDto profileDto = QProfileTesting.newDto(QProfileName.createFor(ServerTester.Xoo.KEY, "SonarQube way"), "abcd").setRulesUpdatedAt(
DateUtils.formatDateTime(new Date()));
import org.sonar.server.search.BaseDoc;
import org.sonar.test.TestUtils;
+import java.io.File;
import java.io.FileInputStream;
import java.util.Collections;
import java.util.List;
public void putDocuments(String index, String type, Class<?> testClass, String... jsonPaths) throws Exception {
BulkRequestBuilder bulk = client.prepareBulk().setRefresh(true);
for (String path : jsonPaths) {
- bulk.add(new IndexRequest(index, type).source(IOUtils.toString(
- new FileInputStream(TestUtils.getResource(testClass, path)))));
+ File file = TestUtils.getResource(testClass, path);
+ if (file == null) {
+ throw new IllegalArgumentException(String.format("File '%s' hasn't been found in folder '%s'", path, testClass.getSimpleName()));
+ }
+ bulk.add(new IndexRequest(index, type).source(IOUtils.toString(new FileInputStream(file))));
}
bulk.get();
}
*/
package org.sonar.server.issue.db;
+import org.apache.ibatis.executor.result.DefaultResultHandler;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
+import org.sonar.api.issue.Issue;
import org.sonar.api.rule.RuleKey;
import org.sonar.api.utils.DateUtils;
-import org.sonar.api.utils.System2;
import org.sonar.core.component.ComponentDto;
+import org.sonar.core.issue.db.BatchIssueDto;
import org.sonar.core.issue.db.IssueDto;
import org.sonar.core.persistence.AbstractDaoTestCase;
import org.sonar.core.persistence.DbSession;
import java.util.List;
import static org.assertj.core.api.Assertions.assertThat;
-import static org.mockito.Mockito.mock;
public class IssueDaoTest extends AbstractDaoTestCase {
private IssueDao dao;
private DbSession session;
- private System2 system2;
@Before
public void before() throws Exception {
this.session = getMyBatis().openSession(false);
- this.system2 = mock(System2.class);
this.dao = new IssueDao(getMyBatis());
}
assertThat(issue.getProjectKey()).isEqualTo("struts");
}
+ @Test
+ public void select_non_closed_issues_by_module_uuid() {
+ setupData("shared", "select_non_closed_issues_by_module_uuid");
+
+ // BCDE is a non-root module, we should find 2 issues from classes and one on itself
+ DefaultResultHandler handler = new DefaultResultHandler();
+ dao.selectNonClosedIssuesByModuleUuid(session, "BCDE", handler);
+ assertThat(handler.getResultList()).extracting("key").containsOnly("100", "101", "103");
+
+ // DBCA is a a simple project with a single file
+ handler = new DefaultResultHandler();
+ dao.selectNonClosedIssuesByModuleUuid(session, "DBCA", handler);
+ assertThat(handler.getResultList()).hasSize(1);
+
+ BatchIssueDto batchIssueDto = (BatchIssueDto) handler.getResultList().get(0);
+ assertThat(batchIssueDto.getKey()).isEqualTo("1000");
+ assertThat(batchIssueDto.getRuleKey()).isEqualTo("AvoidCycle");
+ assertThat(batchIssueDto.getRuleRepo()).isEqualTo("squid");
+ assertThat(batchIssueDto.getMessage()).isEqualTo("Avoid this");
+ assertThat(batchIssueDto.getLine()).isEqualTo(200);
+ assertThat(batchIssueDto.getResolution()).isEqualTo(Issue.RESOLUTION_FALSE_POSITIVE);
+ assertThat(batchIssueDto.getStatus()).isEqualTo(Issue.STATUS_RESOLVED);
+ assertThat(batchIssueDto.getComponentPath()).isEqualTo("src/main/java/Sample.java");
+ assertThat(batchIssueDto.getChecksum()).isEqualTo("123456");
+ assertThat(batchIssueDto.getAssigneeLogin()).isEqualTo("john");
+ assertThat(batchIssueDto.getAssigneeName()).isEqualTo("John Doo");
+ }
+
+ @Test
+ public void select_non_closed_issues_by_project_uuid() {
+ setupData("shared", "select_non_closed_issues_by_project_uuid");
+
+ // ABCD is the root module, we should find all 4 issues
+ DefaultResultHandler handler = new DefaultResultHandler();
+ dao.selectNonClosedIssuesByProjectUuid(session, "ABCD", handler);
+ assertThat(handler.getResultList()).hasSize(4);
+
+ // DBCA is a a simple project with a single file
+ handler = new DefaultResultHandler();
+ dao.selectNonClosedIssuesByProjectUuid(session, "DBCA", handler);
+ assertThat(handler.getResultList()).hasSize(1);
+
+ BatchIssueDto batchIssueDto = (BatchIssueDto) handler.getResultList().get(0);
+ assertThat(batchIssueDto.getKey()).isEqualTo("1000");
+ assertThat(batchIssueDto.getRuleKey()).isEqualTo("AvoidCycle");
+ assertThat(batchIssueDto.getRuleRepo()).isEqualTo("squid");
+ assertThat(batchIssueDto.getMessage()).isEqualTo("Avoid this");
+ assertThat(batchIssueDto.getLine()).isEqualTo(200);
+ assertThat(batchIssueDto.getResolution()).isEqualTo(Issue.RESOLUTION_FALSE_POSITIVE);
+ assertThat(batchIssueDto.getStatus()).isEqualTo(Issue.STATUS_RESOLVED);
+ assertThat(batchIssueDto.getComponentPath()).isEqualTo("src/main/java/Sample.java");
+ assertThat(batchIssueDto.getChecksum()).isEqualTo("123456");
+ assertThat(batchIssueDto.getAssigneeLogin()).isEqualTo("john");
+ assertThat(batchIssueDto.getAssigneeName()).isEqualTo("John Doo");
+ }
+
@Test
public void insert() throws Exception {
IssueDto dto = new IssueDto();
dao.insert(session, dto);
session.commit();
- checkTables("insert", new String[]{"id"}, "issues");
+ checkTables("insert", new String[] {"id"}, "issues");
}
@Test
dao.update(session, dto);
session.commit();
- checkTables("update", new String[]{"id"}, "issues");
+ checkTables("update", new String[] {"id"}, "issues");
}
}
String currentUser = "dave.loper";
IssueFilterDto sharedFilter = new IssueFilterDto().setId(1L).setName("My filter").setUserLogin(currentUser).setShared(true);
- when(authorizationDao.selectGlobalPermissions(currentUser)).thenReturn(newArrayList(GlobalPermissions.DRY_RUN_EXECUTION));
+ when(authorizationDao.selectGlobalPermissions(currentUser)).thenReturn(newArrayList(GlobalPermissions.PREVIEW_EXECUTION));
when(issueFilterDao.selectById(1L)).thenReturn(sharedFilter);
try {
public void should_execute_from_issue_query() {
IssueQuery issueQuery = IssueQuery.builder().build();
QueryContext queryContext = new QueryContext().setPage(2, 50);
-
+
Result<Issue> result = mock(Result.class);
when(result.getHits()).thenReturn(newArrayList((Issue) new DefaultIssue()));
when(result.getTotal()).thenReturn(100L);
import org.mockito.Mock;
import org.mockito.runners.MockitoJUnitRunner;
import org.sonar.api.web.UserRole;
-import org.sonar.core.permission.GlobalPermissions;
-import org.sonar.core.permission.PermissionQuery;
-import org.sonar.core.permission.PermissionTemplateDao;
-import org.sonar.core.permission.PermissionTemplateDto;
-import org.sonar.core.permission.PermissionTemplateGroupDto;
-import org.sonar.core.permission.PermissionTemplateUserDto;
+import org.sonar.core.permission.*;
import org.sonar.core.persistence.DbSession;
import org.sonar.core.persistence.MyBatis;
import org.sonar.core.properties.PropertiesDao;
List<PermissionTemplateUserDto> usersPermissions = Lists.newArrayList(
buildUserPermission("user_scan", GlobalPermissions.SCAN_EXECUTION),
- buildUserPermission("user_dry_run", GlobalPermissions.DRY_RUN_EXECUTION),
+ buildUserPermission("user_dry_run", GlobalPermissions.PREVIEW_EXECUTION),
buildUserPermission("user_scan_and_dry_run", GlobalPermissions.SCAN_EXECUTION),
- buildUserPermission("user_scan_and_dry_run", GlobalPermissions.DRY_RUN_EXECUTION)
+ buildUserPermission("user_scan_and_dry_run", GlobalPermissions.PREVIEW_EXECUTION)
);
List<PermissionTemplateGroupDto> groupsPermissions = Lists.newArrayList(
buildGroupPermission("admin_group", GlobalPermissions.SYSTEM_ADMIN),
buildGroupPermission("scan_group", GlobalPermissions.SCAN_EXECUTION),
- buildGroupPermission(null, GlobalPermissions.DRY_RUN_EXECUTION)
+ buildGroupPermission(null, GlobalPermissions.PREVIEW_EXECUTION)
);
PermissionTemplateDto permissionTemplateDto = new PermissionTemplateDto()
assertThat(permissionTemplate.getUsersForPermission(GlobalPermissions.DASHBOARD_SHARING)).isEmpty();
assertThat(permissionTemplate.getUsersForPermission(GlobalPermissions.SCAN_EXECUTION)).extracting("userName").containsOnly("user_scan", "user_scan_and_dry_run");
- assertThat(permissionTemplate.getUsersForPermission(GlobalPermissions.DRY_RUN_EXECUTION)).extracting("userName").containsOnly("user_dry_run", "user_scan_and_dry_run");
+ assertThat(permissionTemplate.getUsersForPermission(GlobalPermissions.PREVIEW_EXECUTION)).extracting("userName").containsOnly("user_dry_run", "user_scan_and_dry_run");
assertThat(permissionTemplate.getGroupsForPermission(GlobalPermissions.DASHBOARD_SHARING)).isEmpty();
assertThat(permissionTemplate.getGroupsForPermission(GlobalPermissions.SCAN_EXECUTION)).extracting("groupName").containsOnly("scan_group");
assertThat(permissionTemplate.getGroupsForPermission(GlobalPermissions.SYSTEM_ADMIN)).extracting("groupName").containsOnly("admin_group");
--- /dev/null
+[
+ {
+ "key": "EFGH",
+ "componentPath": "src/main/java/Action.java",
+ "ruleKey": "AvoidCycle",
+ "ruleRepo": "squid",
+ "line": 200,
+ "message": "Do not use this method",
+ "resolution": "FALSE-POSITIVE",
+ "status": "RESOLVED",
+ "checksum": "123456",
+ "assigneeLogin": "john",
+ "assigneeFullname": "John Doo"
+ }
+]
+
--- /dev/null
+[
+ {
+ "key": "EFGH",
+ "componentPath": "src/main/java/Action.java",
+ "ruleKey": "AvoidCycle",
+ "ruleRepo": "squid",
+ "line": 200,
+ "message": "Do not use this method",
+ "resolution": "FALSE-POSITIVE",
+ "status": "RESOLVED",
+ "checksum": "123456",
+ "assigneeLogin": "john",
+ "assigneeFullname": "John Doo"
+ }
+]
+
--- /dev/null
+<dataset>
+
+ <!-- Multi module project -->
+ <projects id="399" kee="struts" root_id="[null]" qualifier="TRK" scope="PRJ" uuid="ABCD" project_uuid="ABCD" module_uuid="[null]" module_uuid_path="." path="[null]"/>
+ <projects id="400" kee="struts-core" root_id="399" qualifier="BRC" scope="PRJ" uuid="BCDE" project_uuid="ABCD" module_uuid="ABCD" module_uuid_path=".ABCD.BCDE."
+ path="struts-core"/>
+ <projects id="401" kee="Action.java" root_id="400" qualifier="CLA" scope="PRJ" uuid="CDEF" project_uuid="ABCD" module_uuid="BCDE" module_uuid_path=".ABCD.BCDE."
+ path="src/main/java/Action.java"/>
+
+ <rules id="500" tags="[null]" system_tags="[null]" plugin_rule_key="AvoidCycle" plugin_name="squid" language="java"/>
+
+ <users id="10" login="john" name="John Doo" active="[true]"/>
+
+ <!-- Open Issue on a file -->
+ <issues
+ id="100"
+ kee="EFGH"
+ component_id="401"
+ root_component_id="399"
+ rule_id="500"
+ severity="BLOCKER"
+ manual_severity="[false]"
+ message="Do not use this method"
+ line="200"
+ effort_to_fix="[null]"
+ status="RESOLVED"
+ resolution="FALSE-POSITIVE"
+ checksum="123456"
+ reporter="user"
+ assignee="john"
+ author_login="[null]"
+ issue_attributes="[null]"
+ issue_creation_date="2013-04-16"
+ issue_update_date="2013-04-16"
+ issue_close_date="2013-04-16"
+ created_at="1400000000000"
+ updated_at="[null]"
+ />
+
+</dataset>
--- /dev/null
+<dataset>
+
+ <!-- Open Issue on a file -->
+ <issues
+ id="100"
+ kee="100"
+ component_id="401"
+ root_component_id="399"
+ rule_id="500"
+ severity="BLOCKER"
+ manual_severity="[false]"
+ message="[null]"
+ line="200"
+ effort_to_fix="[null]"
+ status="OPEN"
+ resolution="[null]"
+ checksum="[null]"
+ reporter="user"
+ assignee="user"
+ author_login="[null]"
+ issue_attributes="[null]"
+ issue_creation_date="2013-04-16"
+ issue_update_date="2013-04-16"
+ issue_close_date="2013-04-16"
+ created_at="1400000000000"
+ updated_at="[null]"
+ />
+
+ <!-- Open Issue on a file -->
+ <issues
+ id="101"
+ kee="101"
+ component_id="402"
+ root_component_id="399"
+ rule_id="501"
+ severity="MAJOR"
+ manual_severity="[false]"
+ message="[null]"
+ line="120"
+ effort_to_fix="[null]"
+ status="OPEN"
+ resolution="[null]"
+ checksum="[null]"
+ reporter="[null]"
+ assignee="user"
+ author_login="[null]"
+ issue_attributes="[null]"
+ issue_creation_date="2013-04-16"
+ issue_update_date="2013-04-16"
+ issue_close_date="2013-04-16"
+ created_at="1400000000000"
+ updated_at="[null]"
+ />
+
+ <!-- Closed Issue on a file -->
+ <issues
+ id="102"
+ kee="102"
+ component_id="402"
+ root_component_id="399"
+ rule_id="501"
+ severity="MAJOR"
+ manual_severity="[false]"
+ message="[null]"
+ line="120"
+ effort_to_fix="[null]"
+ status="CLOSED"
+ resolution="FIXED"
+ checksum="[null]"
+ reporter="[null]"
+ assignee="user"
+ author_login="[null]"
+ issue_attributes="[null]"
+ issue_creation_date="2013-04-16"
+ issue_update_date="2013-04-16"
+ issue_close_date="2013-04-16"
+ created_at="1400000000000"
+ updated_at="[null]"
+ />
+
+ <!-- Open Issue on a sub module -->
+ <issues
+ id="103"
+ kee="103"
+ component_id="400"
+ root_component_id="399"
+ rule_id="501"
+ severity="MAJOR"
+ manual_severity="[false]"
+ message="[null]"
+ line="[null]"
+ effort_to_fix="[null]"
+ status="OPEN"
+ resolution="[null]"
+ checksum="[null]"
+ reporter="[null]"
+ assignee="user"
+ author_login="[null]"
+ issue_attributes="[null]"
+ issue_creation_date="2013-04-16"
+ issue_update_date="2013-04-16"
+ issue_close_date="2013-04-16"
+ created_at="1400000000000"
+ updated_at="[null]"
+ />
+
+ <!-- Open Issue on a root module -->
+ <issues
+ id="104"
+ kee="104"
+ component_id="399"
+ root_component_id="399"
+ rule_id="501"
+ severity="MAJOR"
+ manual_severity="[false]"
+ message="[null]"
+ line="[null]"
+ effort_to_fix="[null]"
+ status="OPEN"
+ resolution="[null]"
+ checksum="[null]"
+ reporter="[null]"
+ assignee="user"
+ author_login="[null]"
+ issue_attributes="[null]"
+ issue_creation_date="2013-04-16"
+ issue_update_date="2013-04-16"
+ issue_close_date="2013-04-16"
+ created_at="1400000000000"
+ updated_at="[null]"
+ />
+
+ <!-- Open Issue on a file of the single project -->
+ <issues
+ id="1000"
+ kee="1000"
+ component_id="1001"
+ root_component_id="1000"
+ rule_id="500"
+ severity="BLOCKER"
+ manual_severity="[false]"
+ message="Avoid this"
+ line="200"
+ effort_to_fix="[null]"
+ status="RESOLVED"
+ resolution="FALSE-POSITIVE"
+ checksum="123456"
+ reporter="user"
+ assignee="john"
+ author_login="[null]"
+ issue_attributes="[null]"
+ issue_creation_date="2013-04-16"
+ issue_update_date="2013-04-16"
+ issue_close_date="2013-04-16"
+ created_at="1400000000000"
+ updated_at="[null]"
+ />
+
+</dataset>
--- /dev/null
+<dataset>
+
+ <!-- Open Issue on a file -->
+ <issues
+ id="100"
+ kee="100"
+ component_id="401"
+ root_component_id="399"
+ rule_id="500"
+ severity="BLOCKER"
+ manual_severity="[false]"
+ message="[null]"
+ line="200"
+ effort_to_fix="[null]"
+ status="OPEN"
+ resolution="[null]"
+ checksum="[null]"
+ reporter="user"
+ assignee="user"
+ author_login="[null]"
+ issue_attributes="[null]"
+ issue_creation_date="2013-04-16"
+ issue_update_date="2013-04-16"
+ issue_close_date="2013-04-16"
+ created_at="1400000000000"
+ updated_at="[null]"
+ />
+
+ <!-- Open Issue on a file -->
+ <issues
+ id="101"
+ kee="101"
+ component_id="402"
+ root_component_id="399"
+ rule_id="501"
+ severity="MAJOR"
+ manual_severity="[false]"
+ message="[null]"
+ line="120"
+ effort_to_fix="[null]"
+ status="OPEN"
+ resolution="[null]"
+ checksum="[null]"
+ reporter="[null]"
+ assignee="user"
+ author_login="[null]"
+ issue_attributes="[null]"
+ issue_creation_date="2013-04-16"
+ issue_update_date="2013-04-16"
+ issue_close_date="2013-04-16"
+ created_at="1400000000000"
+ updated_at="[null]"
+ />
+
+ <!-- Closed Issue on a file -->
+ <issues
+ id="102"
+ kee="102"
+ component_id="402"
+ root_component_id="399"
+ rule_id="501"
+ severity="MAJOR"
+ manual_severity="[false]"
+ message="[null]"
+ line="120"
+ effort_to_fix="[null]"
+ status="CLOSED"
+ resolution="FIXED"
+ checksum="[null]"
+ reporter="[null]"
+ assignee="user"
+ author_login="[null]"
+ issue_attributes="[null]"
+ issue_creation_date="2013-04-16"
+ issue_update_date="2013-04-16"
+ issue_close_date="2013-04-16"
+ created_at="1400000000000"
+ updated_at="[null]"
+ />
+
+ <!-- Open Issue on a sub module -->
+ <issues
+ id="103"
+ kee="103"
+ component_id="400"
+ root_component_id="399"
+ rule_id="501"
+ severity="MAJOR"
+ manual_severity="[false]"
+ message="[null]"
+ line="[null]"
+ effort_to_fix="[null]"
+ status="OPEN"
+ resolution="[null]"
+ checksum="[null]"
+ reporter="[null]"
+ assignee="user"
+ author_login="[null]"
+ issue_attributes="[null]"
+ issue_creation_date="2013-04-16"
+ issue_update_date="2013-04-16"
+ issue_close_date="2013-04-16"
+ created_at="1400000000000"
+ updated_at="[null]"
+ />
+
+ <!-- Open Issue on a root module -->
+ <issues
+ id="104"
+ kee="104"
+ component_id="399"
+ root_component_id="399"
+ rule_id="501"
+ severity="MAJOR"
+ manual_severity="[false]"
+ message="[null]"
+ line="[null]"
+ effort_to_fix="[null]"
+ status="OPEN"
+ resolution="[null]"
+ checksum="[null]"
+ reporter="[null]"
+ assignee="user"
+ author_login="[null]"
+ issue_attributes="[null]"
+ issue_creation_date="2013-04-16"
+ issue_update_date="2013-04-16"
+ issue_close_date="2013-04-16"
+ created_at="1400000000000"
+ updated_at="[null]"
+ />
+
+ <!-- Open Issue on a file of the single project -->
+ <issues
+ id="1000"
+ kee="1000"
+ component_id="1001"
+ root_component_id="1000"
+ rule_id="500"
+ severity="BLOCKER"
+ manual_severity="[false]"
+ message="Avoid this"
+ line="200"
+ effort_to_fix="[null]"
+ status="RESOLVED"
+ resolution="FALSE-POSITIVE"
+ checksum="123456"
+ reporter="user"
+ assignee="john"
+ author_login="[null]"
+ issue_attributes="[null]"
+ issue_creation_date="2013-04-16"
+ issue_update_date="2013-04-16"
+ issue_close_date="2013-04-16"
+ created_at="1400000000000"
+ updated_at="[null]"
+ />
+
+</dataset>
<group_roles id="1" group_id="[null]" resource_id="399" role="user"/>
- <projects id="399" kee="struts" root_id="[null]" qualifier="TRK" scope="PRJ" uuid="ABCD"/>
- <projects id="400" kee="struts-core" root_id="399" qualifier="BRC" scope="PRJ" uuid="BCDE"/>
- <projects id="401" kee="Action.java" root_id="400" qualifier="CLA" scope="PRJ" uuid="CDEF"/>
- <projects id="402" kee="Filter.java" root_id="400" qualifier="CLA" scope="PRJ" uuid="DEFG"/>
+ <!-- Multi module project -->
+ <projects id="399" kee="struts" root_id="[null]" qualifier="TRK" scope="PRJ" uuid="ABCD" project_uuid="ABCD" module_uuid="[null]" module_uuid_path="." path="[null]"/>
+ <projects id="400" kee="struts-core" root_id="399" qualifier="BRC" scope="PRJ" uuid="BCDE" project_uuid="ABCD" module_uuid="ABCD" module_uuid_path=".ABCD.BCDE."
+ path="struts-core"/>
+ <projects id="401" kee="Action.java" root_id="400" qualifier="CLA" scope="PRJ" uuid="CDEF" project_uuid="ABCD" module_uuid="BCDE" module_uuid_path=".ABCD.BCDE."
+ path="src/main/java/Action.java"/>
+ <projects id="402" kee="Filter.java" root_id="400" qualifier="CLA" scope="PRJ" uuid="DEFG" project_uuid="ABCD" module_uuid="BCDE" module_uuid_path=".ABCD.BCDE."
+ path="src/main/java/Filter.java"/>
+
+ <!-- Single project -->
+ <projects id="1000" kee="sample" root_id="[null]" qualifier="TRK" scope="PRJ" uuid="DBCA" project_uuid="DBCA" module_uuid="[null]" module_uuid_path="."/>
+ <projects id="1001" kee="Sample.java" root_id="1000" qualifier="CLA" scope="PRJ" uuid="EDCB" project_uuid="DBCA" module_uuid="DBCA" module_uuid_path=".DBCA."
+ path="src/main/java/Sample.java"/>
<snapshots id="100" project_id="399" root_snapshot_id="[null]" parent_snapshot_id="[null]" root_project_id="399"
path="" islast="[true]"/>
<rules id="500" tags="[null]" system_tags="[null]" plugin_rule_key="AvoidCycle" plugin_name="squid" language="java"/>
<rules id="501" tags="[null]" system_tags="[null]" plugin_rule_key="NullRef" plugin_name="squid" language="xoo"/>
+ <users id="1" login="john" name="John Doo" active="[true]"/>
+
</dataset>
import javax.annotation.Nullable;
+import java.io.Closeable;
import java.io.IOException;
import java.io.Reader;
import java.io.Writer;
import java.util.Iterator;
import java.util.NoSuchElementException;
-public class PreviousIssueHelper {
+public class PreviousIssueHelper implements Closeable {
private final Gson gson = GsonHelper.create();
+ JsonWriter writer;
- private PreviousIssueHelper() {
+ private PreviousIssueHelper(Writer out) {
+ try {
+ this.writer = new JsonWriter(out);
+ writer.setIndent(" ");
+ writer.beginArray();
+ } catch (IOException e) {
+ throw new IllegalStateException("Unable to open writer", e);
+ }
}
- public static PreviousIssueHelper create() {
- return new PreviousIssueHelper();
+ public static PreviousIssueHelper create(Writer out) {
+ return new PreviousIssueHelper(out);
}
public static interface Function<F, T> {
T apply(@Nullable F from);
}
- public <G> void streamIssues(Writer out, Iterable<G> issues, Function<G, PreviousIssue> converter) {
+ public <G> void addIssue(G issue, Function<G, PreviousIssue> converter) {
+ gson.toJson(converter.apply(issue), PreviousIssue.class, writer);
+ }
+
+ @Override
+ public void close() {
try {
- JsonWriter writer = new JsonWriter(out);
- writer.setIndent(" ");
- writer.beginArray();
- for (G issue : issues) {
- gson.toJson(converter.apply(issue), PreviousIssue.class, writer);
- }
writer.endArray();
writer.close();
} catch (IOException e) {
- throw new IllegalStateException("Unable to stream issues", e);
+ throw new IllegalStateException("Unable to close write", e);
}
}
import java.io.StringReader;
import java.io.StringWriter;
-import java.util.Arrays;
import java.util.Iterator;
import static org.assertj.core.api.Assertions.assertThat;
@Test
public void writeIssues() throws JSONException {
- PreviousIssueHelper helper = PreviousIssueHelper.create();
StringWriter out = new StringWriter();
+ PreviousIssueHelper helper = PreviousIssueHelper.create(out);
PreviousIssue issue1 = new PreviousIssue();
issue1.setKey("key1");
PreviousIssue issue2 = new PreviousIssue();
issue2.setKey("key2");
- helper.streamIssues(out, Arrays.asList(issue1, issue2), new PreviousIssueHelper.Function<PreviousIssue, PreviousIssue>() {
- @Override
- public PreviousIssue apply(PreviousIssue from) {
- return from;
- }
- });
+ PreviousIssueFunction previousIssueFunction = new PreviousIssueFunction();
+ helper.addIssue(issue1, previousIssueFunction);
+ helper.addIssue(issue2, previousIssueFunction);
+ helper.close();
JSONAssert
.assertEquals(
+
"{\"key\": \"key2\"}]",
out.getBuffer().toString(), true);
+
+ }
+
+ private static class PreviousIssueFunction implements PreviousIssueHelper.Function<PreviousIssue, PreviousIssue> {
+ @Override
+ public PreviousIssue apply(PreviousIssue from) {
+ return from;
+ }
}
@Test
public void readIssues() {
- PreviousIssueHelper helper = PreviousIssueHelper.create();
+ StringWriter out = new StringWriter();
+ PreviousIssueHelper helper = PreviousIssueHelper.create(out);
StringReader reader = new StringReader(
"[{\"key\": \"key1\", \"componentPath\": \"path\", \"ruleKey\": \"rulekey\", \"ruleRepo\": \"repokey\", \"line\": 2,\"message\": \"message\", \"severity\": \"severity\", \"resolution\": \"resolution\", \"status\": \"status\", \"checksum\": \"checksum\",\"assigneeLogin\": \"login\", \"assigneeFullname\": \"fullname\"},"
+
assertThat(issue1.assigneeFullname()).isEqualTo("fullname");
assertThat(issue2.key()).isEqualTo("key2");
+ helper.close();
}
}
package org.sonar.core.component;
import org.sonar.api.component.Component;
+import org.sonar.api.resources.Scopes;
import org.sonar.core.persistence.Dto;
import javax.annotation.CheckForNull;
return this;
}
+ public boolean isRootProject() {
+ return MODULE_UUID_PATH_SEP.equals(moduleUuidPath) && Scopes.PROJECT.equals(scope);
+ }
+
@Override
public boolean equals(Object o) {
if (this == o) {
--- /dev/null
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2014 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * SonarQube is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+package org.sonar.core.issue.db;
+
+public class BatchIssueDto {
+
+ private String kee;
+ private String message;
+ private Integer line;
+ private String status;
+ private String resolution;
+ private String checksum;
+ private String assigneeLogin;
+ private String assigneeName;
+ private String componentPath;
+ private String ruleKey;
+ private String ruleRepo;
+
+ public String getAssigneeLogin() {
+ return assigneeLogin;
+ }
+
+ public BatchIssueDto setAssigneeLogin(String assigneeLogin) {
+ this.assigneeLogin = assigneeLogin;
+ return this;
+ }
+
+ public String getAssigneeName() {
+ return assigneeName;
+ }
+
+ public BatchIssueDto setAssigneeName(String assigneeName) {
+ this.assigneeName = assigneeName;
+ return this;
+ }
+
+ public String getChecksum() {
+ return checksum;
+ }
+
+ public BatchIssueDto setChecksum(String checksum) {
+ this.checksum = checksum;
+ return this;
+ }
+
+ public String getComponentPath() {
+ return componentPath;
+ }
+
+ public BatchIssueDto setComponentPath(String componentPath) {
+ this.componentPath = componentPath;
+ return this;
+ }
+
+ public String getKey() {
+ return kee;
+ }
+
+ public BatchIssueDto setKey(String key) {
+ this.kee = key;
+ return this;
+ }
+
+ public Integer getLine() {
+ return line;
+ }
+
+ public BatchIssueDto setLine(Integer line) {
+ this.line = line;
+ return this;
+ }
+
+ public String getMessage() {
+ return message;
+ }
+
+ public BatchIssueDto setMessage(String message) {
+ this.message = message;
+ return this;
+ }
+
+ public String getResolution() {
+ return resolution;
+ }
+
+ public BatchIssueDto setResolution(String resolution) {
+ this.resolution = resolution;
+ return this;
+ }
+
+ public String getRuleKey() {
+ return ruleKey;
+ }
+
+ public BatchIssueDto setRuleKey(String ruleKey) {
+ this.ruleKey = ruleKey;
+ return this;
+ }
+
+ public String getRuleRepo() {
+ return ruleRepo;
+ }
+
+ public BatchIssueDto setRuleRepo(String ruleRepo) {
+ this.ruleRepo = ruleRepo;
+ return this;
+ }
+
+ public String getStatus() {
+ return status;
+ }
+
+ public BatchIssueDto setStatus(String status) {
+ this.status = status;
+ return this;
+ }
+}
public static final String QUALITY_PROFILE_ADMIN = "profileadmin";
public static final String DASHBOARD_SHARING = "shareDashboard";
public static final String SCAN_EXECUTION = "scan";
- public static final String DRY_RUN_EXECUTION = "dryRunScan";
+ public static final String PREVIEW_EXECUTION = "dryRunScan";
public static final String PROVISIONING = "provisioning";
/**
* All the global permissions values, ordered from {@link #SYSTEM_ADMIN} to {@link #PROVISIONING}.
*/
- public static final List<String> ALL = ImmutableList.of(SYSTEM_ADMIN, QUALITY_PROFILE_ADMIN, DASHBOARD_SHARING, SCAN_EXECUTION, DRY_RUN_EXECUTION, PROVISIONING);
+ public static final List<String> ALL = ImmutableList.of(SYSTEM_ADMIN, QUALITY_PROFILE_ADMIN, DASHBOARD_SHARING, SCAN_EXECUTION, PREVIEW_EXECUTION, PROVISIONING);
private GlobalPermissions() {
// only static methods
import org.apache.ibatis.builder.xml.XMLMapperBuilder;
import org.apache.ibatis.logging.LogFactory;
import org.apache.ibatis.mapping.Environment;
-import org.apache.ibatis.session.Configuration;
-import org.apache.ibatis.session.ExecutorType;
-import org.apache.ibatis.session.SqlSession;
-import org.apache.ibatis.session.SqlSessionFactory;
-import org.apache.ibatis.session.SqlSessionFactoryBuilder;
+import org.apache.ibatis.session.*;
import org.apache.ibatis.transaction.jdbc.JdbcTransactionFactory;
import org.apache.ibatis.type.JdbcType;
import org.slf4j.LoggerFactory;
import org.sonar.core.computation.db.AnalysisReportDto;
import org.sonar.core.computation.db.AnalysisReportMapper;
import org.sonar.core.config.Logback;
-import org.sonar.core.dashboard.ActiveDashboardDto;
-import org.sonar.core.dashboard.ActiveDashboardMapper;
-import org.sonar.core.dashboard.DashboardDto;
-import org.sonar.core.dashboard.DashboardMapper;
-import org.sonar.core.dashboard.WidgetDto;
-import org.sonar.core.dashboard.WidgetMapper;
-import org.sonar.core.dashboard.WidgetPropertyDto;
-import org.sonar.core.dashboard.WidgetPropertyMapper;
+import org.sonar.core.dashboard.*;
import org.sonar.core.dependency.DependencyDto;
import org.sonar.core.dependency.DependencyMapper;
import org.sonar.core.dependency.ResourceSnapshotDto;
import org.sonar.core.duplication.DuplicationUnitDto;
import org.sonar.core.graph.jdbc.GraphDto;
import org.sonar.core.graph.jdbc.GraphDtoMapper;
-import org.sonar.core.issue.db.ActionPlanDto;
-import org.sonar.core.issue.db.ActionPlanMapper;
-import org.sonar.core.issue.db.ActionPlanStatsDto;
-import org.sonar.core.issue.db.ActionPlanStatsMapper;
-import org.sonar.core.issue.db.IssueChangeDto;
-import org.sonar.core.issue.db.IssueChangeMapper;
-import org.sonar.core.issue.db.IssueDto;
-import org.sonar.core.issue.db.IssueFilterDto;
-import org.sonar.core.issue.db.IssueFilterFavouriteDto;
-import org.sonar.core.issue.db.IssueFilterFavouriteMapper;
-import org.sonar.core.issue.db.IssueFilterMapper;
-import org.sonar.core.issue.db.IssueMapper;
-import org.sonar.core.measure.db.MeasureDto;
-import org.sonar.core.measure.db.MeasureFilterDto;
-import org.sonar.core.measure.db.MeasureFilterMapper;
-import org.sonar.core.measure.db.MeasureMapper;
-import org.sonar.core.measure.db.MetricDto;
-import org.sonar.core.measure.db.MetricMapper;
+import org.sonar.core.issue.db.*;
+import org.sonar.core.measure.db.*;
import org.sonar.core.notification.db.NotificationQueueDto;
import org.sonar.core.notification.db.NotificationQueueMapper;
-import org.sonar.core.permission.GroupWithPermissionDto;
-import org.sonar.core.permission.PermissionTemplateDto;
-import org.sonar.core.permission.PermissionTemplateGroupDto;
-import org.sonar.core.permission.PermissionTemplateMapper;
-import org.sonar.core.permission.PermissionTemplateUserDto;
-import org.sonar.core.permission.UserWithPermissionDto;
+import org.sonar.core.permission.*;
import org.sonar.core.persistence.dialect.Dialect;
import org.sonar.core.persistence.migration.v44.Migration44Mapper;
import org.sonar.core.persistence.migration.v45.Migration45Mapper;
import org.sonar.core.purge.IdUuidPair;
import org.sonar.core.purge.PurgeMapper;
import org.sonar.core.purge.PurgeableSnapshotDto;
-import org.sonar.core.qualitygate.db.ProjectQgateAssociationDto;
-import org.sonar.core.qualitygate.db.ProjectQgateAssociationMapper;
-import org.sonar.core.qualitygate.db.QualityGateConditionDto;
-import org.sonar.core.qualitygate.db.QualityGateConditionMapper;
-import org.sonar.core.qualitygate.db.QualityGateDto;
-import org.sonar.core.qualitygate.db.QualityGateMapper;
-import org.sonar.core.qualityprofile.db.ActiveRuleDto;
-import org.sonar.core.qualityprofile.db.ActiveRuleMapper;
-import org.sonar.core.qualityprofile.db.ActiveRuleParamDto;
-import org.sonar.core.qualityprofile.db.QualityProfileDto;
-import org.sonar.core.qualityprofile.db.QualityProfileMapper;
-import org.sonar.core.resource.ResourceDto;
-import org.sonar.core.resource.ResourceIndexDto;
-import org.sonar.core.resource.ResourceIndexerMapper;
-import org.sonar.core.resource.ResourceKeyUpdaterMapper;
-import org.sonar.core.resource.ResourceMapper;
+import org.sonar.core.qualitygate.db.*;
+import org.sonar.core.qualityprofile.db.*;
+import org.sonar.core.resource.*;
import org.sonar.core.rule.RuleDto;
import org.sonar.core.rule.RuleMapper;
import org.sonar.core.rule.RuleParamDto;
import org.sonar.core.technicaldebt.db.RequirementMigrationDto;
import org.sonar.core.template.LoadedTemplateDto;
import org.sonar.core.template.LoadedTemplateMapper;
-import org.sonar.core.user.AuthorDto;
-import org.sonar.core.user.AuthorMapper;
-import org.sonar.core.user.GroupDto;
-import org.sonar.core.user.GroupMapper;
-import org.sonar.core.user.GroupMembershipDto;
-import org.sonar.core.user.GroupMembershipMapper;
-import org.sonar.core.user.GroupRoleDto;
-import org.sonar.core.user.RoleMapper;
-import org.sonar.core.user.UserDto;
-import org.sonar.core.user.UserGroupDto;
-import org.sonar.core.user.UserGroupMapper;
-import org.sonar.core.user.UserMapper;
-import org.sonar.core.user.UserRoleDto;
+import org.sonar.core.user.*;
import java.io.InputStream;
loadAlias(conf, "Measure", MeasureDto.class);
loadAlias(conf, "Metric", MetricDto.class);
loadAlias(conf, "Issue", IssueDto.class);
+ loadAlias(conf, "BatchIssue", BatchIssueDto.class);
loadAlias(conf, "IssueChange", IssueChangeDto.class);
loadAlias(conf, "IssueFilter", IssueFilterDto.class);
loadAlias(conf, "IssueFilterFavourite", IssueFilterFavouriteDto.class);
p.kee as componentKey,
root.kee as projectKey
from issues i
- inner join (select p.id,p.kee from projects p where (p.root_id=#{id} and p.qualifier <> 'BRC') or
- (p.id=#{id})) p on p.id=i.component_id
+ inner join (select p.id,p.kee from projects p where (p.root_id=#{id} and p.qualifier <> 'BRC') or (p.id=#{id})) p on p.id=i.component_id
inner join rules r on r.id=i.rule_id
left outer join projects root on root.id=i.root_component_id
where i.status <> 'CLOSED'
</select>
+ <select id="selectNonClosedIssuesByModuleUuid" parameterType="String" resultType="BatchIssue">
+ SELECT
+ i.kee as kee,
+ i.message as message,
+ i.line as line,
+ i.status as status,
+ i.resolution as resolution,
+ i.checksum as checksum,
+ r.plugin_rule_key as ruleKey,
+ r.plugin_name as ruleRepo,
+ component.path as componentPath,
+ i.assignee as assigneeLogin,
+ u.name as assigneeName
+ FROM issues i
+ INNER JOIN (SELECT p.id,p.path FROM projects p WHERE p.module_uuid=#{uuid} OR p.uuid=#{uuid}) component ON component.id=i.component_id
+ INNER JOIN rules r ON r.id=i.rule_id
+ LEFT OUTER JOIN users u ON u.login=i.assignee
+ WHERE i.status <> 'CLOSED'
+ </select>
+
+ <select id="selectNonClosedIssuesByProjectUuid" parameterType="String" resultType="BatchIssue">
+ SELECT
+ i.kee as kee,
+ i.message as message,
+ i.line as line,
+ i.status as status,
+ i.resolution as resolution,
+ i.checksum as checksum,
+ r.plugin_rule_key as ruleKey,
+ r.plugin_name as ruleRepo,
+ component.path as componentPath,
+ i.assignee as assigneeLogin,
+ u.name as assigneeName
+ FROM issues i
+ INNER JOIN projects component on component.id=i.component_id
+ INNER JOIN projects project on project.uuid=component.project_uuid AND project.uuid=#{uuid}
+ INNER JOIN rules r ON r.id=i.rule_id
+ LEFT OUTER JOIN users u ON u.login=i.assignee
+ WHERE i.status <> 'CLOSED'
+ </select>
+
<select id="selectByKeys" parameterType="map" resultType="Issue">
select
<include refid="issueColumns"/>
setupData("globalGroupPermissions");
assertThat(dao.selectGroupPermissions(session, "sonar-administrators", null)).containsOnly(GlobalPermissions.SYSTEM_ADMIN, GlobalPermissions.QUALITY_PROFILE_ADMIN,
- GlobalPermissions.DASHBOARD_SHARING);
+ GlobalPermissions.DASHBOARD_SHARING);
assertThat(dao.selectGroupPermissions(session, "sonar-users", null)).containsOnly(GlobalPermissions.DASHBOARD_SHARING);
- assertThat(dao.selectGroupPermissions(session, DefaultGroups.ANYONE, null)).containsOnly(GlobalPermissions.DRY_RUN_EXECUTION, GlobalPermissions.SCAN_EXECUTION);
- assertThat(dao.selectGroupPermissions(session, "anyone", null)).containsOnly(GlobalPermissions.DRY_RUN_EXECUTION, GlobalPermissions.SCAN_EXECUTION);
- assertThat(dao.selectGroupPermissions(session, "AnYoNe", null)).containsOnly(GlobalPermissions.DRY_RUN_EXECUTION, GlobalPermissions.SCAN_EXECUTION);
+ assertThat(dao.selectGroupPermissions(session, DefaultGroups.ANYONE, null)).containsOnly(GlobalPermissions.PREVIEW_EXECUTION, GlobalPermissions.SCAN_EXECUTION);
+ assertThat(dao.selectGroupPermissions(session, "anyone", null)).containsOnly(GlobalPermissions.PREVIEW_EXECUTION, GlobalPermissions.SCAN_EXECUTION);
+ assertThat(dao.selectGroupPermissions(session, "AnYoNe", null)).containsOnly(GlobalPermissions.PREVIEW_EXECUTION, GlobalPermissions.SCAN_EXECUTION);
}
@Test