.subAggregation(facetTopAggregation));
}
- public List<String> listTags(OrganizationDto organization, @Nullable String textQuery, int size) {
+ public List<String> listTags(@Nullable OrganizationDto organization, @Nullable String textQuery, int size) {
int maxPageSize = 500;
checkArgument(size <= maxPageSize, "Page size must be lower than or equals to " + maxPageSize);
if (size <= 0) {
return emptyList();
}
+ BoolQueryBuilder esQuery = boolQuery()
+ .filter(createAuthorizationFilter(true));
+ if (organization != null) {
+ esQuery.filter(termQuery(FIELD_ISSUE_ORGANIZATION_UUID, organization.getUuid()));
+ }
+
SearchRequestBuilder requestBuilder = client
.prepareSearch(INDEX_TYPE_ISSUE)
- .setQuery(boolQuery()
- .filter(createAuthorizationFilter(true))
- .filter(termQuery(FIELD_ISSUE_ORGANIZATION_UUID, organization.getUuid())))
+ .setQuery(esQuery)
.setSize(0);
TermsAggregationBuilder termsAggregation = AggregationBuilders.terms(AGGREGATION_NAME_FOR_TAGS)
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
-import java.util.Optional;
import java.util.SortedSet;
import java.util.TreeSet;
+import javax.annotation.CheckForNull;
import javax.annotation.Nullable;
import org.sonar.api.server.ws.Request;
import org.sonar.api.server.ws.Response;
import org.sonar.db.DbSession;
import org.sonar.db.organization.OrganizationDto;
import org.sonar.server.issue.index.IssueIndex;
-import org.sonar.server.organization.DefaultOrganizationProvider;
import org.sonar.server.rule.index.RuleIndex;
-import org.sonar.server.ws.WsUtils;
+import static org.sonar.server.ws.WsUtils.checkFoundWithOptional;
import static org.sonarqube.ws.client.component.ComponentsWsParameters.PARAM_ORGANIZATION;
/**
private final IssueIndex issueIndex;
private final RuleIndex ruleIndex;
private final DbClient dbClient;
- private final DefaultOrganizationProvider defaultOrganizationProvider;
- public TagsAction(IssueIndex issueIndex, RuleIndex ruleIndex, DbClient dbClient, DefaultOrganizationProvider defaultOrganizationProvider) {
+ public TagsAction(IssueIndex issueIndex, RuleIndex ruleIndex, DbClient dbClient) {
this.issueIndex = issueIndex;
this.ruleIndex = ruleIndex;
this.dbClient = dbClient;
- this.defaultOrganizationProvider = defaultOrganizationProvider;
}
private static void writeResponse(Response response, List<String> tags) {
writeResponse(response, tags);
}
- private List<String> listTags(OrganizationDto organization, @Nullable String textQuery, int pageSize) {
+ private List<String> listTags(@Nullable OrganizationDto organization, @Nullable String textQuery, int pageSize) {
Collection<String> issueTags = issueIndex.listTags(organization, textQuery, pageSize);
Collection<String> ruleTags = ruleIndex.listTags(organization, textQuery, pageSize);
return resultAsList.size() > pageSize && pageSize > 0 ? resultAsList.subList(0, pageSize) : resultAsList;
}
+ @CheckForNull
private OrganizationDto getOrganization(@Nullable String organizationKey) {
try (DbSession dbSession = dbClient.openSession(false)) {
- String organizationOrDefaultKey = Optional.ofNullable(organizationKey)
- .orElseGet(defaultOrganizationProvider.get()::getKey);
- return WsUtils.checkFoundWithOptional(
- dbClient.organizationDao().selectByKey(dbSession, organizationOrDefaultKey),
- "No organization with key '%s'", organizationOrDefaultKey);
+ return organizationKey == null ? null
+ : checkFoundWithOptional(dbClient.organizationDao().selectByKey(dbSession, organizationKey), "No organization with key '%s'", organizationKey);
}
}
package org.sonar.server.rule.index;
import com.google.common.base.Joiner;
+import com.google.common.collect.ImmutableList;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
return EsUtils.termsKeys(esResponse.getAggregations().get(AGGREGATION_NAME));
}
- public List<String> listTags(OrganizationDto organization, @Nullable String query, int size) {
+ public List<String> listTags(@Nullable OrganizationDto organization, @Nullable String query, int size) {
int maxPageSize = 500;
checkArgument(size <= maxPageSize, "Page size must be lower than or equals to " + maxPageSize);
if (size <= 0) {
return emptyList();
}
+ ImmutableList.Builder<String> scopes = ImmutableList.<String>builder()
+ .add(RuleExtensionScope.system().getScope());
+ if (organization != null) {
+ scopes.add(RuleExtensionScope.organization(organization).getScope());
+ }
TermsQueryBuilder scopeFilter = QueryBuilders.termsQuery(
FIELD_RULE_EXTENSION_SCOPE,
- RuleExtensionScope.system().getScope(),
- RuleExtensionScope.organization(organization).getScope());
+ scopes.build().toArray(new String[0]));
TermsAggregationBuilder termsAggregation = AggregationBuilders.terms(AGGREGATION_NAME_FOR_TAGS)
.field(FIELD_RULE_EXTENSION_TAGS)
ruleIndexer.commitAndIndex(db.getSession(), asList(r1.getKey(), r2.getKey()));
OrganizationDto org = db.organizations().insert();
+ OrganizationDto anotherOrg = db.organizations().insert();
ComponentDto project = ComponentTesting.newPrivateProjectDto(newOrganizationDto());
ComponentDto file = newFileDto(project, null);
indexIssues(
+ newDoc("I42", file).setOrganizationUuid(anotherOrg.getUuid()).setRuleKey(r1.getKey().toString()).setTags(of("another")),
newDoc("I1", file).setOrganizationUuid(org.getUuid()).setRuleKey(r1.getKey().toString()).setTags(of("convention", "java8", "bug")),
newDoc("I2", file).setOrganizationUuid(org.getUuid()).setRuleKey(r1.getKey().toString()).setTags(of("convention", "bug")),
newDoc("I3", file).setOrganizationUuid(org.getUuid()).setRuleKey(r2.getKey().toString()),
assertThat(underTest.listTags(org, null, 1)).containsOnly("bug");
assertThat(underTest.listTags(org, null, 100)).containsOnly("convention", "java8", "bug");
assertThat(underTest.listTags(org, "invalidRegexp[", 100)).isEmpty();
+ assertThat(underTest.listTags(null, null, 100)).containsExactlyInAnyOrder("another", "convention", "java8", "bug");
}
@Test
import org.sonar.server.issue.index.IssueIndexDefinition;
import org.sonar.server.issue.index.IssueIndexer;
import org.sonar.server.issue.index.IssueIteratorFactory;
-import org.sonar.server.organization.TestDefaultOrganizationProvider;
import org.sonar.server.permission.index.AuthorizationTypeSupport;
import org.sonar.server.permission.index.PermissionIndexerDao;
import org.sonar.server.permission.index.PermissionIndexerTester;
private IssueIndex issueIndex = new IssueIndex(esTester.client(), System2.INSTANCE, userSession, new AuthorizationTypeSupport(userSession));
private RuleIndex ruleIndex = new RuleIndex(esTester.client(), System2.INSTANCE);
- private WsActionTester ws = new WsActionTester(new TagsAction(issueIndex, ruleIndex, dbTester.getDbClient(), TestDefaultOrganizationProvider.from(dbTester)));
+ private WsActionTester ws = new WsActionTester(new TagsAction(issueIndex, ruleIndex, dbTester.getDbClient()));
private OrganizationDto organization;
@Before
assertJson(result).isSimilarTo("{\"tags\":[]}");
}
+ @Test
+ public void without_organization_parameter_is_cross_organization() {
+ userSession.logIn();
+ OrganizationDto organization = dbTester.organizations().insert();
+ OrganizationDto anotherOrganization = dbTester.organizations().insert();
+ insertIssueWithBrowsePermission(organization, insertRuleWithoutTags(), "tag1");
+ insertIssueWithBrowsePermission(anotherOrganization, insertRuleWithoutTags(), "tag2");
+
+ String result = ws.newRequest().execute().getInput();
+
+ assertJson(result).isSimilarTo("{\"tags\":[\"tag1\", \"tag2\"]}");
+ }
+
@Test
public void json_example() throws Exception {
userSession.logIn();
return dbTester.rules().insert(setSystemTags());
}
+ private void insertIssueWithBrowsePermission(OrganizationDto organization, RuleDefinitionDto rule, String... tags) {
+ IssueDto issue = insertIssueWithoutBrowsePermission(organization, rule, tags);
+ grantAccess(issue);
+ }
+
private void insertIssueWithBrowsePermission(RuleDefinitionDto rule, String... tags) {
IssueDto issue = insertIssueWithoutBrowsePermission(rule, tags);
grantAccess(issue);
}
private IssueDto insertIssueWithoutBrowsePermission(RuleDefinitionDto rule, String... tags) {
+ return insertIssueWithoutBrowsePermission(organization, rule, tags);
+ }
+
+ private IssueDto insertIssueWithoutBrowsePermission(OrganizationDto organization, RuleDefinitionDto rule, String... tags) {
IssueDto issue = dbTester.issues().insertIssue(organization, i -> i.setRule(rule).setTags(asList(tags)));
ComponentDto project = dbTester.getDbClient().componentDao().selectByUuid(dbTester.getSession(), issue.getProjectUuid()).get();
userSession.addProjectPermission(USER, project);
import com.sonar.orchestrator.Orchestrator;
import com.sonar.orchestrator.build.SonarScanner;
-import org.sonarqube.tests.Category6Suite;
import java.util.ArrayList;
import java.util.List;
import javax.annotation.Nullable;
import org.junit.Rule;
import org.junit.Test;
import org.sonarqube.qa.util.Tester;
+import org.sonarqube.tests.Category6Suite;
import org.sonarqube.ws.Organizations.Organization;
+import org.sonarqube.ws.Projects.CreateWsResponse;
import org.sonarqube.ws.Users.CreateWsResponse.User;
import org.sonarqube.ws.client.issue.SearchRequest;
import org.sonarqube.ws.client.permission.AddUserRequest;
import util.ItUtils;
import static java.util.Arrays.asList;
+import static java.util.Collections.singletonList;
import static org.apache.commons.lang.RandomStringUtils.randomAlphabetic;
import static org.assertj.core.api.Assertions.assertThat;
import static util.ItUtils.newProjectKey;
.setName(randomAlphabetic(10))
.setVisibility("private")
.build());
- analyzeProject(projectKey);
+ analyzeProject(organization.getKey(), projectKey);
String issue = tester.wsClient().issues().search(new SearchRequest()).getIssues(0).getKey();
tester.wsClient().issues().setTags(issue, "bla", "blubb");
String[] publicTags = {"bad-practice", "convention", "pitfall"};
String[] privateTags = {"bad-practice", "bla", "blubb", "convention", "pitfall"};
- String defaultOrganization = null;
+ String defaultOrganization = tester.organizations().getDefaultOrganization().getKey();
// anonymous must not see custom tags of private project
{
}
}
+ @Test
+ public void tags_across_organizations() {
+ Organization organization = tester.organizations().generate();
+ Organization anotherOrganization = tester.organizations().generate();
+ restoreProfile(orchestrator, IssueTagsTest.class.getResource("/issue/one-issue-per-line-profile.xml"), organization.getKey());
+ restoreProfile(orchestrator, IssueTagsTest.class.getResource("/issue/one-issue-per-line-profile.xml"), anotherOrganization.getKey());
+ CreateWsResponse.Project project = tester.projects().provision(organization);
+ CreateWsResponse.Project anotherProject = tester.projects().provision(anotherOrganization);
+ analyzeProject(organization.getKey(), project.getKey());
+ analyzeProject(anotherOrganization.getKey(), anotherProject.getKey());
+ String issue = tester.wsClient().issues().search(new SearchRequest().setProjectKeys(singletonList(project.getKey()))).getIssues(0).getKey();
+ String anotherIssue = tester.wsClient().issues().search(new SearchRequest().setProjectKeys(singletonList(anotherProject.getKey()))).getIssues(0).getKey();
+ tester.wsClient().issues().setTags(issue, "first-tag");
+ tester.wsClient().issues().setTags(anotherIssue, "another-tag");
+
+ assertThat(tester.wsClient().issues().getTags(null).content()).contains("first-tag", "another-tag");
+ }
+
private void addMemberToOrganization(User member) {
tester.organizations().service().addMember(organization.getKey(), member.getLogin());
}
expectedTags);
}
- private void analyzeProject(String projectKey) {
+ private void analyzeProject(String organizationKey, String projectKey) {
List<String> keyValueProperties = new ArrayList<>(asList(
"sonar.projectKey", projectKey,
- "sonar.organization", organization.getKey(),
+ "sonar.organization", organizationKey,
"sonar.profile", "one-issue-per-line-profile",
"sonar.login", "admin", "sonar.password", "admin",
"sonar.scm.disabled", "false"));