From 1f7ec8261807a71285de63fd21d9c688f40d8ef8 Mon Sep 17 00:00:00 2001 From: Daniel Schwarz Date: Sat, 25 Nov 2017 08:26:13 +0100 Subject: [PATCH] Reduce the dependency between sonar-server and sonar-ws By copying the sonar-ws ...Request classes into the ...Action classes (as static inner classes). This will make the refactoring of sonar-ws towards generated Request classes a lot easier. --- .../sonar/server/ce/ws/ActivityAction.java | 146 +++++- .../server/ce/ws/ActivityStatusAction.java | 38 +- .../server/component/ws/SearchAction.java | 79 ++- .../component/ws/SearchProjectsAction.java | 140 +++++- .../sonar/server/component/ws/ShowAction.java | 53 +- .../sonar/server/component/ws/TreeAction.java | 166 ++++++- .../server/favorite/ws/SearchAction.java | 24 +- .../sonar/server/issue/IssueQueryFactory.java | 1 - .../org/sonar/server/issue/SearchRequest.java | 456 ++++++++++++++++++ .../server/issue/ws/AddCommentAction.java | 20 +- .../server/issue/ws/ComponentTagsAction.java | 2 +- .../server/issue/ws/EditCommentAction.java | 20 +- .../sonar/server/issue/ws/SearchAction.java | 2 +- .../issue/ws/SearchAdditionalField.java | 2 +- .../server/measure/ws/ComponentAction.java | 90 +++- .../measure/ws/ComponentTreeAction.java | 287 ++++++++++- .../measure/ws/ComponentTreeDataLoader.java | 336 ------------- .../measure/ws/ComponentTreeRequest.java | 224 +++++++++ .../server/measure/ws/ComponentTreeSort.java | 1 - .../sonar/server/measure/ws/HasMeasure.java | 8 +- .../server/measure/ws/MeasuresWsModule.java | 1 - .../sonar/server/measure/ws/SearchAction.java | 56 ++- .../measure/ws/SearchHistoryAction.java | 129 ++++- .../measure/ws/SearchHistoryResult.java | 13 +- .../server/notification/ws/AddAction.java | 45 +- .../server/notification/ws/RemoveAction.java | 45 +- .../permission/ws/PermissionsWsModule.java | 3 - .../ws/SearchProjectPermissionsAction.java | 160 +++++- .../SearchProjectPermissionsDataLoader.java | 121 ----- .../AddProjectCreatorToTemplateAction.java | 77 ++- .../ws/template/AddUserToTemplateAction.java | 61 ++- .../ws/template/ApplyTemplateAction.java | 61 ++- .../ws/template/BulkApplyTemplateAction.java | 105 +++- .../ws/template/CreateTemplateAction.java | 51 +- .../ws/template/DeleteTemplateAction.java | 39 +- ...emoveProjectCreatorFromTemplateAction.java | 77 ++- .../RemoveUserFromTemplateAction.java | 61 ++- .../ws/template/SearchTemplatesAction.java | 102 +++- .../template/SearchTemplatesDataLoader.java | 102 ---- .../ws/template/SetDefaultTemplateAction.java | 51 +- .../ws/template/UpdateTemplateAction.java | 49 +- .../server/project/ws/BulkDeleteAction.java | 1 - .../project/ws/BulkUpdateKeyAction.java | 90 +++- .../sonar/server/project/ws/CreateAction.java | 91 +++- .../server/project/ws/ProjectsWsModule.java | 1 - .../sonar/server/project/ws/SearchAction.java | 1 - .../project/ws/SearchMyProjectsAction.java | 121 ++++- .../ws/SearchMyProjectsDataLoader.java | 102 ---- .../server/project/ws/SearchRequest.java | 179 +++++++ .../server/project/ws/UpdateKeyAction.java | 65 ++- .../projectanalysis/ws/CreateEventAction.java | 62 ++- .../projectanalysis/ws/DeleteAction.java | 42 +- .../projectanalysis/ws/DeleteEventAction.java | 21 +- .../projectanalysis/ws/SearchAction.java | 3 +- .../server/projectanalysis/ws/SearchData.java | 1 - .../projectanalysis/ws/SearchRequest.java | 142 ++++++ .../projectanalysis/ws/UpdateEventAction.java | 23 +- .../server/projectlink/ws/CreateAction.java | 45 +- .../server/projectlink/ws/DeleteAction.java | 13 +- .../server/projectlink/ws/SearchAction.java | 25 +- .../qualityprofile/ws/CreateAction.java | 67 ++- .../qualityprofile/ws/SearchAction.java | 56 ++- .../qualityprofile/ws/SearchGroupsAction.java | 1 - .../qualityprofile/ws/SearchUsersAction.java | 1 - .../qualityprofile/ws/SearchUsersRequest.java | 127 +++++ .../sonar/server/rule/ws/SearchAction.java | 125 ++++- .../setting/ws/ListDefinitionsAction.java | 24 +- .../sonar/server/setting/ws/ResetAction.java | 35 +- .../sonar/server/setting/ws/SetAction.java | 72 ++- .../sonar/server/setting/ws/ValuesAction.java | 36 +- .../sonar/server/user/ws/CreateAction.java | 107 +++- .../sonar/server/user/ws/GroupsAction.java | 102 +++- .../sonar/server/user/ws/SearchAction.java | 76 ++- .../sonar/server/user/ws/UpdateAction.java | 80 ++- .../server/usertoken/ws/GenerateAction.java | 25 +- .../server/usertoken/ws/RevokeAction.java | 25 +- .../server/usertoken/ws/SearchAction.java | 20 +- .../server/component/ws/SearchActionTest.java | 2 +- .../ws/SearchProjectsActionTest.java | 7 +- .../server/issue/IssueQueryFactoryTest.java | 1 - .../server/issue/ws/BulkChangeActionTest.java | 174 ++++++- .../issue/ws/ComponentTagsActionTest.java | 2 +- .../measure/ws/ComponentTreeActionTest.java | 2 +- .../measure/ws/ComponentTreeSortTest.java | 1 - .../measure/ws/MeasuresWsModuleTest.java | 2 +- .../server/measure/ws/MeasuresWsTest.java | 2 +- .../measure/ws/SearchHistoryActionTest.java | 5 +- .../server/notification/ws/AddActionTest.java | 66 ++- .../notification/ws/RemoveActionTest.java | 2 +- .../ws/SearchMembersActionTest.java | 61 ++- .../ws/PermissionsWsModuleTest.java | 2 +- .../SearchProjectPermissionsActionTest.java | 3 +- .../template/SearchTemplatesActionTest.java | 6 +- .../server/project/ws/CreateActionTest.java | 2 +- .../project/ws/ProjectsWsModuleTest.java | 2 +- .../server/project/ws/SearchActionTest.java | 1 - .../ws/SearchMyProjectsActionTest.java | 2 +- .../ws/SearchMyProjectsDataLoaderTest.java | 50 -- .../ws/CreateEventActionTest.java | 107 +--- .../projectanalysis/ws/SearchActionTest.java | 1 - .../server/user/ws/CreateActionTest.java | 2 +- .../ws/client/measure/SearchRequest.java | 2 +- .../ws/client/settings/SettingsService.java | 4 +- .../client/users/ChangePasswordRequest.java | 75 --- .../ws/client/users/CreateRequest.java | 135 ------ .../ws/client/users/DeactivateRequest.java | 48 -- .../ws/client/users/GroupsRequest.java | 119 ----- .../ws/client/users/SearchRequest.java | 98 ---- .../ws/client/users/UpdateRequest.java | 102 ---- .../ws/client/users/UsersService.java | 191 -------- .../ws/client/users/package-info.java | 26 - 111 files changed, 4906 insertions(+), 1910 deletions(-) create mode 100644 server/sonar-server/src/main/java/org/sonar/server/issue/SearchRequest.java delete mode 100644 server/sonar-server/src/main/java/org/sonar/server/measure/ws/ComponentTreeDataLoader.java create mode 100644 server/sonar-server/src/main/java/org/sonar/server/measure/ws/ComponentTreeRequest.java delete mode 100644 server/sonar-server/src/main/java/org/sonar/server/permission/ws/SearchProjectPermissionsDataLoader.java delete mode 100644 server/sonar-server/src/main/java/org/sonar/server/permission/ws/template/SearchTemplatesDataLoader.java delete mode 100644 server/sonar-server/src/main/java/org/sonar/server/project/ws/SearchMyProjectsDataLoader.java create mode 100644 server/sonar-server/src/main/java/org/sonar/server/project/ws/SearchRequest.java create mode 100644 server/sonar-server/src/main/java/org/sonar/server/projectanalysis/ws/SearchRequest.java create mode 100644 server/sonar-server/src/main/java/org/sonar/server/qualityprofile/ws/SearchUsersRequest.java delete mode 100644 server/sonar-server/src/test/java/org/sonar/server/project/ws/SearchMyProjectsDataLoaderTest.java delete mode 100644 sonar-ws/src/main/java/org/sonarqube/ws/client/users/ChangePasswordRequest.java delete mode 100644 sonar-ws/src/main/java/org/sonarqube/ws/client/users/CreateRequest.java delete mode 100644 sonar-ws/src/main/java/org/sonarqube/ws/client/users/DeactivateRequest.java delete mode 100644 sonar-ws/src/main/java/org/sonarqube/ws/client/users/GroupsRequest.java delete mode 100644 sonar-ws/src/main/java/org/sonarqube/ws/client/users/SearchRequest.java delete mode 100644 sonar-ws/src/main/java/org/sonarqube/ws/client/users/UpdateRequest.java delete mode 100644 sonar-ws/src/main/java/org/sonarqube/ws/client/users/UsersService.java delete mode 100644 sonar-ws/src/main/java/org/sonarqube/ws/client/users/package-info.java diff --git a/server/sonar-server/src/main/java/org/sonar/server/ce/ws/ActivityAction.java b/server/sonar-server/src/main/java/org/sonar/server/ce/ws/ActivityAction.java index a98f78d1d91..bd0fcf9de81 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/ce/ws/ActivityAction.java +++ b/server/sonar-server/src/main/java/org/sonar/server/ce/ws/ActivityAction.java @@ -31,7 +31,6 @@ import javax.annotation.CheckForNull; import javax.annotation.Nullable; import org.sonar.api.resources.Qualifiers; import org.sonar.api.server.ws.Change; -import org.sonar.api.server.ws.Request; import org.sonar.api.server.ws.Response; import org.sonar.api.server.ws.WebService; import org.sonar.api.server.ws.WebService.Param; @@ -49,7 +48,6 @@ import org.sonar.db.component.ComponentQuery; import org.sonar.server.user.UserSession; import org.sonarqube.ws.Ce; import org.sonarqube.ws.Ce.ActivityResponse; -import org.sonarqube.ws.client.ce.ActivityRequest; import static java.lang.Boolean.parseBoolean; import static java.lang.Integer.parseInt; @@ -157,12 +155,12 @@ public class ActivityAction implements CeWsAction { } @Override - public void handle(Request wsRequest, Response wsResponse) throws Exception { + public void handle(org.sonar.api.server.ws.Request wsRequest, Response wsResponse) throws Exception { ActivityResponse activityResponse = doHandle(toSearchWsRequest(wsRequest)); writeProtobuf(activityResponse, wsRequest, wsResponse); } - private ActivityResponse doHandle(ActivityRequest request) { + private ActivityResponse doHandle(Request request) { try (DbSession dbSession = dbClient.openSession(false)) { ComponentDto component = loadComponent(dbSession, request); @@ -187,7 +185,7 @@ public class ActivityAction implements CeWsAction { } @CheckForNull - private ComponentDto loadComponent(DbSession dbSession, ActivityRequest request) { + private ComponentDto loadComponent(DbSession dbSession, Request request) { String componentId = request.getComponentId(); if (componentId == null) { return null; @@ -206,7 +204,7 @@ public class ActivityAction implements CeWsAction { } } - private Optional searchTaskByUuid(DbSession dbSession, ActivityRequest request) { + private Optional searchTaskByUuid(DbSession dbSession, Request request) { String textQuery = request.getQ(); if (textQuery == null) { return Optional.absent(); @@ -221,7 +219,7 @@ public class ActivityAction implements CeWsAction { return activity.map(ceActivityDto -> Optional.of(formatter.formatActivity(dbSession, ceActivityDto, null))).orElseGet(Optional::absent); } - private CeTaskQuery buildQuery(DbSession dbSession, ActivityRequest request, @Nullable ComponentDto component) { + private CeTaskQuery buildQuery(DbSession dbSession, Request request, @Nullable ComponentDto component) { CeTaskQuery query = new CeTaskQuery(); query.setType(request.getType()); query.setOnlyCurrents(parseBoolean(request.getOnlyCurrents())); @@ -252,12 +250,12 @@ public class ActivityAction implements CeWsAction { return dbClient.componentDao().selectByQuery(dbSession, componentDtoQuery, 0, CeTaskQuery.MAX_COMPONENT_UUIDS); } - private List loadQueuedTasks(DbSession dbSession, ActivityRequest request, CeTaskQuery query) { + private List loadQueuedTasks(DbSession dbSession, Request request, CeTaskQuery query) { List dtos = dbClient.ceQueueDao().selectByQueryInDescOrder(dbSession, query, parseInt(request.getPs())); return formatter.formatQueue(dbSession, dtos); } - private List loadPastTasks(DbSession dbSession, ActivityRequest request, CeTaskQuery query) { + private List loadPastTasks(DbSession dbSession, Request request, CeTaskQuery query) { List dtos = dbClient.ceActivityDao().selectByQuery(dbSession, query, forPage(1).andSize(parseInt(request.getPs()))); return formatter.formatActivity(dbSession, dtos); } @@ -282,8 +280,8 @@ public class ActivityAction implements CeWsAction { return wsResponseBuilder.build(); } - private static ActivityRequest toSearchWsRequest(Request request) { - ActivityRequest activityWsRequest = new ActivityRequest() + private static Request toSearchWsRequest(org.sonar.api.server.ws.Request request) { + Request activityWsRequest = new Request() .setComponentId(request.param(PARAM_COMPONENT_ID)) .setQ(defaultString(request.param(Param.TEXT_QUERY), request.param(PARAM_COMPONENT_QUERY))) .setStatus(request.paramAsStrings(PARAM_STATUS)) @@ -297,4 +295,130 @@ public class ActivityAction implements CeWsAction { PARAM_COMPONENT_ID, PARAM_COMPONENT_QUERY); return activityWsRequest; } + + private static class Request { + + private String componentId; + private String maxExecutedAt; + private String minSubmittedAt; + private String onlyCurrents; + private String ps; + private String q; + private List status; + private String type; + + /** + * Example value: "AU-TpxcA-iU5OvuD2FL0" + */ + private Request setComponentId(String componentId) { + this.componentId = componentId; + return this; + } + + private String getComponentId() { + return componentId; + } + + /** + * Example value: "2017-10-19T13:00:00+0200" + */ + private Request setMaxExecutedAt(String maxExecutedAt) { + this.maxExecutedAt = maxExecutedAt; + return this; + } + + private String getMaxExecutedAt() { + return maxExecutedAt; + } + + /** + * Example value: "2017-10-19T13:00:00+0200" + */ + private Request setMinSubmittedAt(String minSubmittedAt) { + this.minSubmittedAt = minSubmittedAt; + return this; + } + + private String getMinSubmittedAt() { + return minSubmittedAt; + } + + /** + * Possible values: + *
    + *
  • "true"
  • + *
  • "false"
  • + *
  • "yes"
  • + *
  • "no"
  • + *
+ */ + private Request setOnlyCurrents(String onlyCurrents) { + this.onlyCurrents = onlyCurrents; + return this; + } + + private String getOnlyCurrents() { + return onlyCurrents; + } + + /** + * Example value: "20" + */ + private Request setPs(String ps) { + this.ps = ps; + return this; + } + + private String getPs() { + return ps; + } + + /** + * Example value: "Apache" + */ + private Request setQ(String q) { + this.q = q; + return this; + } + + private String getQ() { + return q; + } + + /** + * Example value: "IN_PROGRESS,SUCCESS" + * Possible values: + *
    + *
  • "SUCCESS"
  • + *
  • "FAILED"
  • + *
  • "CANCELED"
  • + *
  • "PENDING"
  • + *
  • "IN_PROGRESS"
  • + *
+ */ + private Request setStatus(List status) { + this.status = status; + return this; + } + + private List getStatus() { + return status; + } + + /** + * Example value: "REPORT" + * Possible values: + *
    + *
  • "REPORT"
  • + *
+ */ + private Request setType(String type) { + this.type = type; + return this; + } + + private String getType() { + return type; + } + } } diff --git a/server/sonar-server/src/main/java/org/sonar/server/ce/ws/ActivityStatusAction.java b/server/sonar-server/src/main/java/org/sonar/server/ce/ws/ActivityStatusAction.java index d626c356732..84a7a34cda2 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/ce/ws/ActivityStatusAction.java +++ b/server/sonar-server/src/main/java/org/sonar/server/ce/ws/ActivityStatusAction.java @@ -21,7 +21,6 @@ package org.sonar.server.ce.ws; import com.google.common.base.Optional; import org.sonar.api.server.ws.Change; -import org.sonar.api.server.ws.Request; import org.sonar.api.server.ws.Response; import org.sonar.api.server.ws.WebService; import org.sonar.api.web.UserRole; @@ -35,7 +34,6 @@ import org.sonar.server.component.ComponentFinder; import org.sonar.server.user.UserSession; import org.sonar.server.ws.KeyExamples; import org.sonarqube.ws.Ce.ActivityStatusWsResponse; -import org.sonarqube.ws.client.ce.ActivityStatusRequest; import static org.sonar.server.component.ComponentFinder.ParamNames.COMPONENT_ID_AND_KEY; import static org.sonar.server.ws.WsUtils.writeProtobuf; @@ -75,12 +73,12 @@ public class ActivityStatusAction implements CeWsAction { } @Override - public void handle(Request request, Response response) throws Exception { + public void handle(org.sonar.api.server.ws.Request request, Response response) throws Exception { ActivityStatusWsResponse activityStatusResponse = doHandle(toWsRequest(request)); writeProtobuf(activityStatusResponse, request, response); } - private ActivityStatusWsResponse doHandle(ActivityStatusRequest request) { + private ActivityStatusWsResponse doHandle(Request request) { try (DbSession dbSession = dbClient.openSession(false)) { Optional component = searchComponent(dbSession, request); String componentUuid = component.isPresent() ? component.get().uuid() : null; @@ -97,7 +95,7 @@ public class ActivityStatusAction implements CeWsAction { } } - private Optional searchComponent(DbSession dbSession, ActivityStatusRequest request) { + private Optional searchComponent(DbSession dbSession, Request request) { ComponentDto component = null; if (hasComponentInRequest(request)) { component = componentFinder.getByUuidOrKey(dbSession, request.getComponentId(), request.getComponentKey(), COMPONENT_ID_AND_KEY); @@ -113,13 +111,37 @@ public class ActivityStatusAction implements CeWsAction { } } - private static boolean hasComponentInRequest(ActivityStatusRequest request) { + private static boolean hasComponentInRequest(Request request) { return request.getComponentId() != null || request.getComponentKey() != null; } - private static ActivityStatusRequest toWsRequest(Request request) { - return new ActivityStatusRequest() + private static Request toWsRequest(org.sonar.api.server.ws.Request request) { + return new Request() .setComponentId(request.param(PARAM_COMPONENT_ID)) .setComponentKey(request.param(DEPRECATED_PARAM_COMPONENT_KEY)); } + + private static class Request { + + private String componentId; + private String componentKey; + + public Request setComponentId(String componentId) { + this.componentId = componentId; + return this; + } + + public String getComponentId() { + return componentId; + } + + public Request setComponentKey(String componentKey) { + this.componentKey = componentKey; + return this; + } + + public String getComponentKey() { + return componentKey; + } + } } diff --git a/server/sonar-server/src/main/java/org/sonar/server/component/ws/SearchAction.java b/server/sonar-server/src/main/java/org/sonar/server/component/ws/SearchAction.java index 2307faf3e85..c6f95f7d8ab 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/component/ws/SearchAction.java +++ b/server/sonar-server/src/main/java/org/sonar/server/component/ws/SearchAction.java @@ -26,7 +26,6 @@ import java.util.Set; import org.sonar.api.i18n.I18n; import org.sonar.api.resources.Languages; import org.sonar.api.resources.ResourceTypes; -import org.sonar.api.server.ws.Request; import org.sonar.api.server.ws.Response; import org.sonar.api.server.ws.WebService; import org.sonar.api.server.ws.WebService.Param; @@ -43,9 +42,12 @@ import org.sonar.server.organization.DefaultOrganizationProvider; import org.sonar.server.ws.WsUtils; import org.sonarqube.ws.Components; import org.sonarqube.ws.Components.SearchWsResponse; -import org.sonarqube.ws.client.component.SearchRequest; + +import javax.annotation.CheckForNull; +import javax.annotation.Nullable; import static com.google.common.base.Preconditions.checkArgument; +import static java.util.Objects.requireNonNull; import static java.util.stream.Collectors.toMap; import static org.sonar.core.util.Protobuf.setNullable; import static org.sonar.core.util.stream.MoreCollectors.toHashSet; @@ -111,12 +113,12 @@ public class SearchAction implements ComponentsWsAction { } @Override - public void handle(Request wsRequest, Response wsResponse) throws Exception { + public void handle(org.sonar.api.server.ws.Request wsRequest, Response wsResponse) throws Exception { SearchWsResponse searchWsResponse = doHandle(toSearchWsRequest(wsRequest)); writeProtobuf(searchWsResponse, wsRequest, wsResponse); } - private static SearchRequest toSearchWsRequest(Request request) { + private static SearchRequest toSearchWsRequest(org.sonar.api.server.ws.Request request) { return new SearchRequest() .setOrganization(request.param(PARAM_ORGANIZATION)) .setQualifiers(request.mandatoryParamAsStrings(PARAM_QUALIFIERS)) @@ -197,4 +199,73 @@ public class SearchAction implements ComponentsWsAction { return builder.build(); } + static class SearchRequest { + private String organization; + private List qualifiers; + private Integer page; + private Integer pageSize; + private String query; + private String language; + + @CheckForNull + public String getOrganization() { + return organization; + } + + public SearchRequest setOrganization(@Nullable String organization) { + this.organization = organization; + return this; + } + + public List getQualifiers() { + return qualifiers; + } + + public SearchRequest setQualifiers(List qualifiers) { + this.qualifiers = requireNonNull(qualifiers); + return this; + } + + @CheckForNull + public Integer getPage() { + return page; + } + + public SearchRequest setPage(int page) { + this.page = page; + return this; + } + + @CheckForNull + public Integer getPageSize() { + return pageSize; + } + + public SearchRequest setPageSize(int pageSize) { + this.pageSize = pageSize; + return this; + } + + @CheckForNull + public String getQuery() { + return query; + } + + public SearchRequest setQuery(@Nullable String query) { + this.query = query; + return this; + } + + @CheckForNull + public String getLanguage() { + return language; + } + + public SearchRequest setLanguage(@Nullable String language) { + this.language = language; + return this; + } + } + + } diff --git a/server/sonar-server/src/main/java/org/sonar/server/component/ws/SearchProjectsAction.java b/server/sonar-server/src/main/java/org/sonar/server/component/ws/SearchProjectsAction.java index f114bd780c5..1a6a662e18b 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/component/ws/SearchProjectsAction.java +++ b/server/sonar-server/src/main/java/org/sonar/server/component/ws/SearchProjectsAction.java @@ -21,6 +21,7 @@ package org.sonar.server.component.ws; import com.google.common.collect.ImmutableMap; import com.google.common.collect.Ordering; +import java.util.ArrayList; import java.util.Collections; import java.util.LinkedHashMap; import java.util.List; @@ -32,6 +33,7 @@ import java.util.function.Function; import java.util.stream.Collector; import java.util.stream.Collectors; import java.util.stream.Stream; +import javax.annotation.CheckForNull; import javax.annotation.Nullable; import org.sonar.api.resources.Qualifiers; import org.sonar.api.server.ws.Change; @@ -58,12 +60,13 @@ import org.sonar.server.user.UserSession; import org.sonarqube.ws.Common; import org.sonarqube.ws.Components.Component; import org.sonarqube.ws.Components.SearchProjectsWsResponse; -import org.sonarqube.ws.client.component.SearchProjectsRequest; import static com.google.common.base.MoreObjects.firstNonNull; +import static com.google.common.base.Preconditions.checkArgument; import static com.google.common.collect.Sets.newHashSet; import static java.lang.String.format; import static java.util.Collections.emptyMap; +import static java.util.Objects.requireNonNull; import static org.sonar.api.measures.CoreMetrics.ALERT_STATUS_KEY; import static org.sonar.api.server.ws.WebService.Param.FIELDS; import static org.sonar.api.utils.DateUtils.formatDateTime; @@ -82,13 +85,13 @@ import static org.sonar.server.ws.WsUtils.writeProtobuf; import static org.sonarqube.ws.client.component.ComponentsWsParameters.ACTION_SEARCH_PROJECTS; import static org.sonarqube.ws.client.component.ComponentsWsParameters.PARAM_FILTER; import static org.sonarqube.ws.client.component.ComponentsWsParameters.PARAM_ORGANIZATION; -import static org.sonarqube.ws.client.component.SearchProjectsRequest.DEFAULT_PAGE_SIZE; -import static org.sonarqube.ws.client.component.SearchProjectsRequest.MAX_PAGE_SIZE; import static org.sonarqube.ws.client.project.ProjectsWsParameters.FILTER_LANGUAGES; import static org.sonarqube.ws.client.project.ProjectsWsParameters.FILTER_TAGS; public class SearchProjectsAction implements ComponentsWsAction { + public static final int MAX_PAGE_SIZE = 500; + public static final int DEFAULT_PAGE_SIZE = 100; private static final String ANALYSIS_DATE = "analysisDate"; private static final String LEAK_PERIOD_DATE = "leakPeriodDate"; private static final Set POSSIBLE_FIELDS = newHashSet(ANALYSIS_DATE, LEAK_PERIOD_DATE); @@ -289,7 +292,7 @@ public class SearchProjectsAction implements ComponentsWsAction { } private static SearchProjectsRequest toRequest(Request httpRequest) { - SearchProjectsRequest.Builder request = SearchProjectsRequest.builder() + RequestBuilder request = new RequestBuilder() .setOrganization(httpRequest.param(PARAM_ORGANIZATION)) .setFilter(httpRequest.param(PARAM_FILTER)) .setSort(httpRequest.mandatoryParam(Param.SORT)) @@ -467,4 +470,133 @@ public class SearchProjectsAction implements ComponentsWsAction { this.query = query; } } + + static class SearchProjectsRequest { + + private final int page; + private final int pageSize; + private final String organization; + private final String filter; + private final List facets; + private final String sort; + private final Boolean asc; + private final List additionalFields; + + private SearchProjectsRequest(RequestBuilder builder) { + this.page = builder.page; + this.pageSize = builder.pageSize; + this.organization = builder.organization; + this.filter = builder.filter; + this.facets = builder.facets; + this.sort = builder.sort; + this.asc = builder.asc; + this.additionalFields = builder.additionalFields; + } + + @CheckForNull + public String getOrganization() { + return organization; + } + + @CheckForNull + public String getFilter() { + return filter; + } + + public List getFacets() { + return facets; + } + + @CheckForNull + public String getSort() { + return sort; + } + + public int getPageSize() { + return pageSize; + } + + public int getPage() { + return page; + } + + @CheckForNull + public Boolean getAsc() { + return asc; + } + + public List getAdditionalFields() { + return additionalFields; + } + + public static RequestBuilder builder() { + return new RequestBuilder(); + } + } + + static class RequestBuilder { + private String organization; + private Integer page; + private Integer pageSize; + private String filter; + private List facets = new ArrayList<>(); + private String sort; + private Boolean asc; + private List additionalFields = new ArrayList<>(); + + private RequestBuilder() { + // enforce static factory method + } + + public RequestBuilder setOrganization(@Nullable String organization) { + this.organization = organization; + return this; + } + + public RequestBuilder setFilter(@Nullable String filter) { + this.filter = filter; + return this; + } + + public RequestBuilder setFacets(List facets) { + this.facets = requireNonNull(facets); + return this; + } + + public RequestBuilder setPage(int page) { + this.page = page; + return this; + } + + public RequestBuilder setPageSize(int pageSize) { + this.pageSize = pageSize; + return this; + } + + public RequestBuilder setSort(@Nullable String sort) { + this.sort = sort; + return this; + } + + public RequestBuilder setAsc(boolean asc) { + this.asc = asc; + return this; + } + + public RequestBuilder setAdditionalFields(List additionalFields) { + this.additionalFields = requireNonNull(additionalFields, "additional fields cannot be null"); + return this; + } + + public SearchProjectsRequest build() { + if (page == null) { + page = 1; + } + if (pageSize == null) { + pageSize = DEFAULT_PAGE_SIZE; + } + checkArgument(pageSize <= MAX_PAGE_SIZE, "Page size must not be greater than %s", MAX_PAGE_SIZE); + return new SearchProjectsRequest(this); + } + } } diff --git a/server/sonar-server/src/main/java/org/sonar/server/component/ws/ShowAction.java b/server/sonar-server/src/main/java/org/sonar/server/component/ws/ShowAction.java index 3799794e012..f7bd7a58a85 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/component/ws/ShowAction.java +++ b/server/sonar-server/src/main/java/org/sonar/server/component/ws/ShowAction.java @@ -23,7 +23,6 @@ import java.util.List; import java.util.Optional; import java.util.stream.IntStream; import org.sonar.api.server.ws.Change; -import org.sonar.api.server.ws.Request; import org.sonar.api.server.ws.Response; import org.sonar.api.server.ws.WebService; import org.sonar.api.web.UserRole; @@ -35,7 +34,9 @@ import org.sonar.db.organization.OrganizationDto; import org.sonar.server.component.ComponentFinder; import org.sonar.server.user.UserSession; import org.sonarqube.ws.Components.ShowWsResponse; -import org.sonarqube.ws.client.component.ShowRequest; + +import javax.annotation.CheckForNull; +import javax.annotation.Nullable; import static com.google.common.base.Preconditions.checkArgument; import static java.lang.String.format; @@ -99,14 +100,14 @@ public class ShowAction implements ComponentsWsAction { } @Override - public void handle(Request request, Response response) throws Exception { - ShowRequest showRequest = toShowWsRequest(request); + public void handle(org.sonar.api.server.ws.Request request, Response response) throws Exception { + Request showRequest = toShowWsRequest(request); ShowWsResponse showWsResponse = doHandle(showRequest); writeProtobuf(showWsResponse, request, response); } - private ShowWsResponse doHandle(ShowRequest request) { + private ShowWsResponse doHandle(Request request) { try (DbSession dbSession = dbClient.openSession(false)) { ComponentDto component = loadComponent(dbSession, request); Optional lastAnalysis = dbClient.snapshotDao().selectLastAnalysisByComponentUuid(dbSession, component.projectUuid()); @@ -116,7 +117,7 @@ public class ShowAction implements ComponentsWsAction { } } - private ComponentDto loadComponent(DbSession dbSession, ShowRequest request) { + private ComponentDto loadComponent(DbSession dbSession, Request request) { String componentId = request.getId(); String componentKey = request.getKey(); String branch = request.getBranch(); @@ -139,10 +140,46 @@ public class ShowAction implements ComponentsWsAction { return response.build(); } - private static ShowRequest toShowWsRequest(Request request) { - return new ShowRequest() + private static Request toShowWsRequest(org.sonar.api.server.ws.Request request) { + return new Request() .setId(request.param(PARAM_COMPONENT_ID)) .setKey(request.param(PARAM_COMPONENT)) .setBranch(request.param(PARAM_BRANCH)); } + + private static class Request { + private String id; + private String key; + private String branch; + + @CheckForNull + public String getId() { + return id; + } + + public Request setId(@Nullable String id) { + this.id = id; + return this; + } + + @CheckForNull + public String getKey() { + return key; + } + + public Request setKey(@Nullable String key) { + this.key = key; + return this; + } + + @CheckForNull + public String getBranch() { + return branch; + } + + public Request setBranch(@Nullable String branch) { + this.branch = branch; + return this; + } + } } diff --git a/server/sonar-server/src/main/java/org/sonar/server/component/ws/TreeAction.java b/server/sonar-server/src/main/java/org/sonar/server/component/ws/TreeAction.java index e2c31ae4325..6a6ac04d049 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/component/ws/TreeAction.java +++ b/server/sonar-server/src/main/java/org/sonar/server/component/ws/TreeAction.java @@ -32,10 +32,10 @@ import java.util.Objects; import java.util.Optional; import java.util.Set; import javax.annotation.CheckForNull; +import javax.annotation.Nullable; import org.sonar.api.i18n.I18n; import org.sonar.api.resources.ResourceTypes; import org.sonar.api.server.ws.Change; -import org.sonar.api.server.ws.Request; import org.sonar.api.server.ws.Response; import org.sonar.api.server.ws.WebService; import org.sonar.api.server.ws.WebService.Param; @@ -52,7 +52,6 @@ import org.sonar.server.component.ComponentFinder; import org.sonar.server.user.UserSession; import org.sonarqube.ws.Components; import org.sonarqube.ws.Components.TreeWsResponse; -import org.sonarqube.ws.client.component.TreeRequest; import static com.google.common.base.Preconditions.checkArgument; import static java.lang.String.CASE_INSENSITIVE_ORDER; @@ -144,10 +143,10 @@ public class TreeAction implements ComponentsWsAction { .setExampleValue(NAME_SORT + ", " + PATH_SORT); action.createParam(Param.TEXT_QUERY) - .setDescription(format("Limit search to:
    " + + .setDescription("Limit search to:
      " + "
    • component names that contain the supplied string
    • " + "
    • component keys that are exactly the same as the supplied string
    • " + - "
    ")) + "
") .setMinimumLength(QUERY_MINIMUM_LENGTH) .setExampleValue("FILE_NAM"); @@ -165,12 +164,12 @@ public class TreeAction implements ComponentsWsAction { } @Override - public void handle(Request request, Response response) throws Exception { + public void handle(org.sonar.api.server.ws.Request request, Response response) throws Exception { TreeWsResponse treeWsResponse = doHandle(toTreeWsRequest(request)); writeProtobuf(treeWsResponse, request, response); } - private TreeWsResponse doHandle(TreeRequest treeRequest) { + private TreeWsResponse doHandle(Request treeRequest) { try (DbSession dbSession = dbClient.openSession(false)) { ComponentDto baseComponent = loadComponent(dbSession, treeRequest); checkPermissions(baseComponent); @@ -189,7 +188,7 @@ public class TreeAction implements ComponentsWsAction { } } - private ComponentDto loadComponent(DbSession dbSession, TreeRequest request) { + private ComponentDto loadComponent(DbSession dbSession, Request request) { String componentId = request.getBaseComponentId(); String componentKey = request.getBaseComponentKey(); String branch = request.getBranch(); @@ -234,7 +233,7 @@ public class TreeAction implements ComponentsWsAction { } private static Components.Component.Builder toWsComponent(ComponentDto component, OrganizationDto organizationDto, - Map referenceComponentsByUuid) { + Map referenceComponentsByUuid) { Components.Component.Builder wsComponent = componentDtoToWsComponent(component, organizationDto, Optional.empty()); ComponentDto referenceComponent = referenceComponentsByUuid.get(component.getCopyResourceUuid()); @@ -246,7 +245,7 @@ public class TreeAction implements ComponentsWsAction { return wsComponent; } - private ComponentTreeQuery toComponentTreeQuery(TreeRequest request, ComponentDto baseComponent) { + private ComponentTreeQuery toComponentTreeQuery(Request request, ComponentDto baseComponent) { List childrenQualifiers = childrenQualifiers(request, baseComponent.qualifier()); ComponentTreeQuery.Builder query = ComponentTreeQuery.builder() @@ -263,7 +262,7 @@ public class TreeAction implements ComponentsWsAction { } @CheckForNull - private List childrenQualifiers(TreeRequest request, String baseQualifier) { + private List childrenQualifiers(Request request, String baseQualifier) { List requestQualifiers = request.getQualifiers(); List childrenQualifiers = null; if (LEAVES_STRATEGY.equals(request.getStrategy())) { @@ -283,8 +282,8 @@ public class TreeAction implements ComponentsWsAction { return new ArrayList<>(qualifiersIntersection); } - private static TreeRequest toTreeWsRequest(Request request) { - return new TreeRequest() + private static Request toTreeWsRequest(org.sonar.api.server.ws.Request request) { + return new Request() .setBaseComponentId(request.param(PARAM_COMPONENT_ID)) .setBaseComponentKey(request.param(PARAM_COMPONENT)) .setBranch(request.param(PARAM_BRANCH)) @@ -297,12 +296,12 @@ public class TreeAction implements ComponentsWsAction { .setPageSize(request.mandatoryParamAsInt(Param.PAGE_SIZE)); } - private static List paginateComponents(List components, TreeRequest wsRequest) { + private static List paginateComponents(List components, Request wsRequest) { return components.stream().skip(offset(wsRequest.getPage(), wsRequest.getPageSize())) .limit(wsRequest.getPageSize()).collect(toList()); } - public static List sortComponents(List components, TreeRequest wsRequest) { + private static List sortComponents(List components, Request wsRequest) { List sortParameters = wsRequest.getSort(); if (sortParameters == null || sortParameters.isEmpty()) { return components; @@ -334,4 +333,143 @@ public class TreeAction implements ComponentsWsAction { return ordering.nullsLast().onResultOf(function); } + private static class Request { + private String baseComponentId; + private String baseComponentKey; + private String component; + private String branch; + private String strategy; + private List qualifiers; + private String query; + private List sort; + private Boolean asc; + private Integer page; + private Integer pageSize; + + /** + * @deprecated since 6.4, please use {@link #getComponent()} instead + */ + @Deprecated + @CheckForNull + private String getBaseComponentId() { + return baseComponentId; + } + + /** + * @deprecated since 6.4, please use {@link #setComponent(String)} instead + */ + @Deprecated + private Request setBaseComponentId(@Nullable String baseComponentId) { + this.baseComponentId = baseComponentId; + return this; + } + + /** + * @deprecated since 6.4, please use {@link #getComponent()} instead + */ + @Deprecated + @CheckForNull + private String getBaseComponentKey() { + return baseComponentKey; + } + + /** + * @deprecated since 6.4, please use {@link #setComponent(String)} instead + */ + @Deprecated + private Request setBaseComponentKey(@Nullable String baseComponentKey) { + this.baseComponentKey = baseComponentKey; + return this; + } + + public Request setComponent(@Nullable String component) { + this.component = component; + return this; + } + + @CheckForNull + private String getComponent() { + return component; + } + + @CheckForNull + private String getBranch() { + return branch; + } + + private Request setBranch(@Nullable String branch) { + this.branch = branch; + return this; + } + + @CheckForNull + private String getStrategy() { + return strategy; + } + + private Request setStrategy(@Nullable String strategy) { + this.strategy = strategy; + return this; + } + + @CheckForNull + private List getQualifiers() { + return qualifiers; + } + + private Request setQualifiers(@Nullable List qualifiers) { + this.qualifiers = qualifiers; + return this; + } + + @CheckForNull + private String getQuery() { + return query; + } + + private Request setQuery(@Nullable String query) { + this.query = query; + return this; + } + + @CheckForNull + private List getSort() { + return sort; + } + + private Request setSort(@Nullable List sort) { + this.sort = sort; + return this; + } + + private Boolean getAsc() { + return asc; + } + + private Request setAsc(@Nullable Boolean asc) { + this.asc = asc; + return this; + } + + @CheckForNull + private Integer getPage() { + return page; + } + + private Request setPage(@Nullable Integer page) { + this.page = page; + return this; + } + + @CheckForNull + private Integer getPageSize() { + return pageSize; + } + + private Request setPageSize(@Nullable Integer pageSize) { + this.pageSize = pageSize; + return this; + } + } + } diff --git a/server/sonar-server/src/main/java/org/sonar/server/favorite/ws/SearchAction.java b/server/sonar-server/src/main/java/org/sonar/server/favorite/ws/SearchAction.java index 6b7b6ce40be..50f20a4e8f0 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/favorite/ws/SearchAction.java +++ b/server/sonar-server/src/main/java/org/sonar/server/favorite/ws/SearchAction.java @@ -38,7 +38,6 @@ import org.sonar.server.user.UserSession; import org.sonarqube.ws.Common; import org.sonarqube.ws.Favorites.Favorite; import org.sonarqube.ws.Favorites.SearchResponse; -import org.sonarqube.ws.client.favorites.SearchRequest; import static com.google.common.base.Preconditions.checkArgument; import static org.sonar.core.util.Protobuf.setNullable; @@ -160,4 +159,27 @@ public class SearchAction implements FavoritesWsAction { return builder.build(); } + private static class SearchRequest { + + private String p; + private String ps; + + public SearchRequest setP(String p) { + this.p = p; + return this; + } + + public String getP() { + return p; + } + + public SearchRequest setPs(String ps) { + this.ps = ps; + return this; + } + + public String getPs() { + return ps; + } + } } diff --git a/server/sonar-server/src/main/java/org/sonar/server/issue/IssueQueryFactory.java b/server/sonar-server/src/main/java/org/sonar/server/issue/IssueQueryFactory.java index a4a2f341f48..fb225976eb5 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/issue/IssueQueryFactory.java +++ b/server/sonar-server/src/main/java/org/sonar/server/issue/IssueQueryFactory.java @@ -53,7 +53,6 @@ import org.sonar.db.component.ComponentDto; import org.sonar.db.component.SnapshotDto; import org.sonar.db.organization.OrganizationDto; import org.sonar.server.user.UserSession; -import org.sonarqube.ws.client.issue.SearchRequest; import static com.google.common.base.Preconditions.checkArgument; import static com.google.common.collect.Lists.newArrayList; diff --git a/server/sonar-server/src/main/java/org/sonar/server/issue/SearchRequest.java b/server/sonar-server/src/main/java/org/sonar/server/issue/SearchRequest.java new file mode 100644 index 00000000000..fd8f4ded409 --- /dev/null +++ b/server/sonar-server/src/main/java/org/sonar/server/issue/SearchRequest.java @@ -0,0 +1,456 @@ +/* + * SonarQube + * Copyright (C) 2009-2017 SonarSource SA + * mailto:info 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.issue; + +import java.util.List; +import javax.annotation.CheckForNull; +import javax.annotation.Nullable; + +public class SearchRequest { + private List actionPlans; + private List additionalFields; + private Boolean asc; + private Boolean assigned; + private List assignees; + private List authors; + private List componentKeys; + private List componentRootUuids; + private List componentRoots; + private List componentUuids; + private List components; + private String createdAfter; + private String createdAt; + private String createdBefore; + private String createdInLast; + private List directories; + private String facetMode; + private List facets; + private List fileUuids; + private List issues; + private List languages; + private List moduleUuids; + private Boolean onComponentOnly; + private String branch; + private String organization; + private Integer page; + private Integer pageSize; + private List projectKeys; + private List projectUuids; + private List projects; + private List resolutions; + private Boolean resolved; + private List rules; + private Boolean sinceLeakPeriod; + private String sort; + private List severities; + private List statuses; + private List tags; + private List types; + + @CheckForNull + public List getActionPlans() { + return actionPlans; + } + + public SearchRequest setActionPlans(@Nullable List actionPlans) { + this.actionPlans = actionPlans; + return this; + } + + @CheckForNull + public List getAdditionalFields() { + return additionalFields; + } + + public SearchRequest setAdditionalFields(@Nullable List additionalFields) { + this.additionalFields = additionalFields; + return this; + } + + @CheckForNull + public Boolean getAsc() { + return asc; + } + + public SearchRequest setAsc(boolean asc) { + this.asc = asc; + return this; + } + + @CheckForNull + public Boolean getAssigned() { + return assigned; + } + + public SearchRequest setAssigned(@Nullable Boolean assigned) { + this.assigned = assigned; + return this; + } + + @CheckForNull + public List getAssignees() { + return assignees; + } + + public SearchRequest setAssignees(@Nullable List assignees) { + this.assignees = assignees; + return this; + } + + @CheckForNull + public List getAuthors() { + return authors; + } + + public SearchRequest setAuthors(@Nullable List authors) { + this.authors = authors; + return this; + } + + @CheckForNull + public List getComponentKeys() { + return componentKeys; + } + + public SearchRequest setComponentKeys(@Nullable List componentKeys) { + this.componentKeys = componentKeys; + return this; + } + + @CheckForNull + public List getComponentUuids() { + return componentUuids; + } + + public SearchRequest setComponentUuids(@Nullable List componentUuids) { + this.componentUuids = componentUuids; + return this; + } + + @CheckForNull + public String getCreatedAfter() { + return createdAfter; + } + + public SearchRequest setCreatedAfter(@Nullable String createdAfter) { + this.createdAfter = createdAfter; + return this; + } + + @CheckForNull + public String getCreatedAt() { + return createdAt; + } + + public SearchRequest setCreatedAt(@Nullable String createdAt) { + this.createdAt = createdAt; + return this; + } + + @CheckForNull + public String getCreatedBefore() { + return createdBefore; + } + + public SearchRequest setCreatedBefore(@Nullable String createdBefore) { + this.createdBefore = createdBefore; + return this; + } + + @CheckForNull + public String getCreatedInLast() { + return createdInLast; + } + + public SearchRequest setCreatedInLast(@Nullable String createdInLast) { + this.createdInLast = createdInLast; + return this; + } + + @CheckForNull + public List getDirectories() { + return directories; + } + + public SearchRequest setDirectories(@Nullable List directories) { + this.directories = directories; + return this; + } + + @CheckForNull + public String getFacetMode() { + return facetMode; + } + + public SearchRequest setFacetMode(@Nullable String facetMode) { + this.facetMode = facetMode; + return this; + } + + @CheckForNull + public List getFacets() { + return facets; + } + + public SearchRequest setFacets(@Nullable List facets) { + this.facets = facets; + return this; + } + + @CheckForNull + public List getFileUuids() { + return fileUuids; + } + + public SearchRequest setFileUuids(@Nullable List fileUuids) { + this.fileUuids = fileUuids; + return this; + } + + @CheckForNull + public List getIssues() { + return issues; + } + + public SearchRequest setIssues(@Nullable List issues) { + this.issues = issues; + return this; + } + + @CheckForNull + public List getLanguages() { + return languages; + } + + public SearchRequest setLanguages(@Nullable List languages) { + this.languages = languages; + return this; + } + + @CheckForNull + public List getModuleUuids() { + return moduleUuids; + } + + public SearchRequest setModuleUuids(@Nullable List moduleUuids) { + this.moduleUuids = moduleUuids; + return this; + } + + @CheckForNull + public Boolean getOnComponentOnly() { + return onComponentOnly; + } + + public SearchRequest setOnComponentOnly(Boolean onComponentOnly) { + this.onComponentOnly = onComponentOnly; + return this; + } + + @CheckForNull + public String getOrganization() { + return organization; + } + + public SearchRequest setOrganization(@Nullable String s) { + this.organization = s; + return this; + } + + @CheckForNull + public Integer getPage() { + return page; + } + + public SearchRequest setPage(int page) { + this.page = page; + return this; + } + + @CheckForNull + public Integer getPageSize() { + return pageSize; + } + + public SearchRequest setPageSize(int pageSize) { + this.pageSize = pageSize; + return this; + } + + @CheckForNull + public List getProjectKeys() { + return projectKeys; + } + + public SearchRequest setProjectKeys(@Nullable List projectKeys) { + this.projectKeys = projectKeys; + return this; + } + + @CheckForNull + public List getProjectUuids() { + return projectUuids; + } + + public SearchRequest setProjectUuids(@Nullable List projectUuids) { + this.projectUuids = projectUuids; + return this; + } + + @CheckForNull + public List getResolutions() { + return resolutions; + } + + public SearchRequest setResolutions(@Nullable List resolutions) { + this.resolutions = resolutions; + return this; + } + + @CheckForNull + public Boolean getResolved() { + return resolved; + } + + public SearchRequest setResolved(@Nullable Boolean resolved) { + this.resolved = resolved; + return this; + } + + @CheckForNull + public List getRules() { + return rules; + } + + public SearchRequest setRules(@Nullable List rules) { + this.rules = rules; + return this; + } + + @CheckForNull + public Boolean getSinceLeakPeriod() { + return sinceLeakPeriod; + } + + public SearchRequest setSinceLeakPeriod(@Nullable Boolean sinceLeakPeriod) { + this.sinceLeakPeriod = sinceLeakPeriod; + return this; + } + + @CheckForNull + public String getSort() { + return sort; + } + + public SearchRequest setSort(@Nullable String sort) { + this.sort = sort; + return this; + } + + @CheckForNull + public List getSeverities() { + return severities; + } + + public SearchRequest setSeverities(@Nullable List severities) { + this.severities = severities; + return this; + } + + @CheckForNull + public List getStatuses() { + return statuses; + } + + public SearchRequest setStatuses(@Nullable List statuses) { + this.statuses = statuses; + return this; + } + + @CheckForNull + public List getTags() { + return tags; + } + + public SearchRequest setTags(@Nullable List tags) { + this.tags = tags; + return this; + } + + @CheckForNull + public List getTypes() { + return types; + } + + public SearchRequest setTypes(@Nullable List types) { + this.types = types; + return this; + } + + @CheckForNull + public List getComponentRootUuids() { + return componentRootUuids; + } + + public SearchRequest setComponentRootUuids(List componentRootUuids) { + this.componentRootUuids = componentRootUuids; + return this; + } + + @CheckForNull + public List getComponentRoots() { + return componentRoots; + } + + public SearchRequest setComponentRoots(@Nullable List componentRoots) { + this.componentRoots = componentRoots; + return this; + } + + @CheckForNull + public List getComponents() { + return components; + } + + public SearchRequest setComponents(@Nullable List components) { + this.components = components; + return this; + } + + @CheckForNull + public List getProjects() { + return projects; + } + + public SearchRequest setProjects(@Nullable List projects) { + this.projects = projects; + return this; + } + + @CheckForNull + public String getBranch() { + return branch; + } + + public SearchRequest setBranch(@Nullable String branch) { + this.branch = branch; + return this; + } +} diff --git a/server/sonar-server/src/main/java/org/sonar/server/issue/ws/AddCommentAction.java b/server/sonar-server/src/main/java/org/sonar/server/issue/ws/AddCommentAction.java index 9eed23186c1..ad9ede47da1 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/issue/ws/AddCommentAction.java +++ b/server/sonar-server/src/main/java/org/sonar/server/issue/ws/AddCommentAction.java @@ -35,11 +35,11 @@ import org.sonar.server.issue.IssueFieldsSetter; import org.sonar.server.issue.IssueFinder; import org.sonar.server.issue.IssueUpdater; import org.sonar.server.user.UserSession; -import org.sonarqube.ws.client.issue.AddCommentRequest; import org.sonarqube.ws.client.issue.IssuesWsParameters; import static com.google.common.base.Preconditions.checkArgument; import static com.google.common.base.Strings.isNullOrEmpty; +import static java.util.Objects.requireNonNull; import static org.sonar.core.util.Uuids.UUID_EXAMPLE_01; import static org.sonarqube.ws.client.issue.IssuesWsParameters.PARAM_ISSUE; import static org.sonarqube.ws.client.issue.IssuesWsParameters.PARAM_TEXT; @@ -109,4 +109,22 @@ public class AddCommentAction implements IssuesWsAction { return wsRequest; } + private static class AddCommentRequest { + + private final String issue; + private final String text; + + private AddCommentRequest(String issue, String text) { + this.issue = requireNonNull(issue, "Issue key cannot be null"); + this.text = requireNonNull(text, "Text cannot be null"); + } + + public String getIssue() { + return issue; + } + + public String getText() { + return text; + } + } } diff --git a/server/sonar-server/src/main/java/org/sonar/server/issue/ws/ComponentTagsAction.java b/server/sonar-server/src/main/java/org/sonar/server/issue/ws/ComponentTagsAction.java index 5bb5d38c8f1..7e1ed580894 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/issue/ws/ComponentTagsAction.java +++ b/server/sonar-server/src/main/java/org/sonar/server/issue/ws/ComponentTagsAction.java @@ -29,7 +29,7 @@ import org.sonar.api.utils.text.JsonWriter; import org.sonar.server.issue.IssueQuery; import org.sonar.server.issue.IssueQueryFactory; import org.sonar.server.issue.index.IssueIndex; -import org.sonarqube.ws.client.issue.SearchRequest; +import org.sonar.server.issue.SearchRequest; import static java.util.Collections.singletonList; import static org.sonar.api.server.ws.WebService.Param.PAGE_SIZE; diff --git a/server/sonar-server/src/main/java/org/sonar/server/issue/ws/EditCommentAction.java b/server/sonar-server/src/main/java/org/sonar/server/issue/ws/EditCommentAction.java index e834162237e..cc7244edb26 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/issue/ws/EditCommentAction.java +++ b/server/sonar-server/src/main/java/org/sonar/server/issue/ws/EditCommentAction.java @@ -37,11 +37,11 @@ import org.sonar.db.issue.IssueDto; import org.sonar.server.exceptions.NotFoundException; import org.sonar.server.issue.IssueFinder; import org.sonar.server.user.UserSession; -import org.sonarqube.ws.client.issue.EditCommentRequest; import static com.google.common.base.Preconditions.checkArgument; import static com.google.common.base.Strings.isNullOrEmpty; import static java.lang.String.format; +import static java.util.Objects.requireNonNull; import static org.sonar.core.util.Uuids.UUID_EXAMPLE_01; import static org.sonarqube.ws.client.issue.IssuesWsParameters.ACTION_EDIT_COMMENT; import static org.sonarqube.ws.client.issue.IssuesWsParameters.PARAM_COMMENT; @@ -152,4 +152,22 @@ public class EditCommentAction implements IssuesWsAction { } } + public static class EditCommentRequest { + + private final String comment; + private final String text; + + public EditCommentRequest(String comment, String text) { + this.comment = requireNonNull(comment, "Comment key cannot be null"); + this.text = requireNonNull(text, "Text cannot be null"); + } + + public String getComment() { + return comment; + } + + public String getText() { + return text; + } + } } diff --git a/server/sonar-server/src/main/java/org/sonar/server/issue/ws/SearchAction.java b/server/sonar-server/src/main/java/org/sonar/server/issue/ws/SearchAction.java index b8b744d83eb..2d2355dc612 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/issue/ws/SearchAction.java +++ b/server/sonar-server/src/main/java/org/sonar/server/issue/ws/SearchAction.java @@ -51,7 +51,7 @@ import org.sonar.server.issue.IssueQueryFactory; import org.sonar.server.issue.index.IssueIndex; import org.sonar.server.user.UserSession; import org.sonarqube.ws.Issues.SearchWsResponse; -import org.sonarqube.ws.client.issue.SearchRequest; +import org.sonar.server.issue.SearchRequest; import static com.google.common.base.Preconditions.checkArgument; import static com.google.common.collect.Iterables.concat; diff --git a/server/sonar-server/src/main/java/org/sonar/server/issue/ws/SearchAdditionalField.java b/server/sonar-server/src/main/java/org/sonar/server/issue/ws/SearchAdditionalField.java index 0c8ef7e9224..431a5aa9140 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/issue/ws/SearchAdditionalField.java +++ b/server/sonar-server/src/main/java/org/sonar/server/issue/ws/SearchAdditionalField.java @@ -26,7 +26,7 @@ import java.util.HashMap; import java.util.List; import java.util.Map; import javax.annotation.CheckForNull; -import org.sonarqube.ws.client.issue.SearchRequest; +import org.sonar.server.issue.SearchRequest; public enum SearchAdditionalField { diff --git a/server/sonar-server/src/main/java/org/sonar/server/measure/ws/ComponentAction.java b/server/sonar-server/src/main/java/org/sonar/server/measure/ws/ComponentAction.java index fd5d78e90ef..59633ac3d74 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/measure/ws/ComponentAction.java +++ b/server/sonar-server/src/main/java/org/sonar/server/measure/ws/ComponentAction.java @@ -53,7 +53,6 @@ import org.sonar.server.measure.ws.MetricDtoWithBestValue.MetricDtoToMetricDtoWi import org.sonar.server.user.UserSession; import org.sonarqube.ws.Measures; import org.sonarqube.ws.Measures.ComponentWsResponse; -import org.sonarqube.ws.client.measure.ComponentRequest; import static com.google.common.base.Preconditions.checkArgument; import static java.lang.String.format; @@ -181,7 +180,7 @@ public class ComponentAction implements MeasuresWsAction { } private static ComponentWsResponse buildResponse(ComponentRequest request, ComponentDto component, Optional refComponent, List measures, - List metrics, List periods) { + List metrics, List periods) { ComponentWsResponse.Builder response = ComponentWsResponse.newBuilder(); Map metricsById = Maps.uniqueIndex(metrics, MetricDto::getId); Map measuresByMetric = new HashMap<>(); @@ -282,4 +281,91 @@ public class ComponentAction implements MeasuresWsAction { private void checkPermissions(ComponentDto baseComponent) { userSession.checkComponentPermission(UserRole.USER, baseComponent); } + + private static class ComponentRequest { + private String componentId; + private String component; + private String branch; + private List metricKeys; + private List additionalFields; + private String developerId; + private String developerKey; + + /** + * @deprecated since 6.6, please use {@link #getComponent()} instead + */ + @Deprecated + @CheckForNull + private String getComponentId() { + return componentId; + } + + /** + * @deprecated since 6.6, please use {@link #setComponent(String)} instead + */ + @Deprecated + private ComponentRequest setComponentId(@Nullable String componentId) { + this.componentId = componentId; + return this; + } + + @CheckForNull + private String getComponent() { + return component; + } + + private ComponentRequest setComponent(@Nullable String component) { + this.component = component; + return this; + } + + @CheckForNull + private String getBranch() { + return branch; + } + + private ComponentRequest setBranch(@Nullable String branch) { + this.branch = branch; + return this; + } + + private List getMetricKeys() { + return metricKeys; + } + + private ComponentRequest setMetricKeys(@Nullable List metricKeys) { + this.metricKeys = metricKeys; + return this; + } + + @CheckForNull + private List getAdditionalFields() { + return additionalFields; + } + + private ComponentRequest setAdditionalFields(@Nullable List additionalFields) { + this.additionalFields = additionalFields; + return this; + } + + @CheckForNull + private String getDeveloperId() { + return developerId; + } + + private ComponentRequest setDeveloperId(@Nullable String developerId) { + this.developerId = developerId; + return this; + } + + @CheckForNull + private String getDeveloperKey() { + return developerKey; + } + + private ComponentRequest setDeveloperKey(@Nullable String developerKey) { + this.developerKey = developerKey; + return this; + } + } } diff --git a/server/sonar-server/src/main/java/org/sonar/server/measure/ws/ComponentTreeAction.java b/server/sonar-server/src/main/java/org/sonar/server/measure/ws/ComponentTreeAction.java index b9f79a6beef..e47c71bb1a6 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/measure/ws/ComponentTreeAction.java +++ b/server/sonar-server/src/main/java/org/sonar/server/measure/ws/ComponentTreeAction.java @@ -20,14 +20,32 @@ package org.sonar.server.measure.ws; import com.google.common.base.Joiner; +import com.google.common.collect.FluentIterable; +import com.google.common.collect.HashBasedTable; import com.google.common.collect.ImmutableMap; import com.google.common.collect.ImmutableSet; import com.google.common.collect.ImmutableSortedSet; +import com.google.common.collect.Lists; +import com.google.common.collect.Maps; +import com.google.common.collect.Sets; +import com.google.common.collect.Table; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.HashSet; +import java.util.LinkedHashSet; import java.util.List; import java.util.Map; +import java.util.Objects; import java.util.Optional; import java.util.Set; +import java.util.function.Function; +import java.util.stream.Stream; +import javax.annotation.CheckForNull; +import javax.annotation.Nonnull; +import javax.annotation.Nullable; import org.sonar.api.i18n.I18n; +import org.sonar.api.resources.Qualifiers; import org.sonar.api.resources.ResourceTypes; import org.sonar.api.server.ws.Change; import org.sonar.api.server.ws.Request; @@ -35,31 +53,49 @@ import org.sonar.api.server.ws.Response; import org.sonar.api.server.ws.WebService; import org.sonar.api.server.ws.WebService.Param; import org.sonar.api.utils.Paging; +import org.sonar.api.web.UserRole; +import org.sonar.core.util.stream.MoreCollectors; +import org.sonar.db.DbClient; +import org.sonar.db.DbSession; import org.sonar.db.component.ComponentDto; +import org.sonar.db.component.ComponentTreeQuery; import org.sonar.db.component.ComponentTreeQuery.Strategy; +import org.sonar.db.component.SnapshotDto; +import org.sonar.db.measure.MeasureDto; +import org.sonar.db.measure.MeasureTreeQuery; import org.sonar.db.metric.MetricDto; +import org.sonar.db.metric.MetricDtoFunctions; +import org.sonar.server.component.ComponentFinder; +import org.sonar.server.exceptions.NotFoundException; +import org.sonar.server.user.UserSession; import org.sonarqube.ws.Measures; import org.sonarqube.ws.Measures.ComponentTreeWsResponse; -import org.sonarqube.ws.client.measure.ComponentTreeRequest; import static com.google.common.base.Preconditions.checkArgument; +import static com.google.common.base.Preconditions.checkState; import static java.lang.String.format; import static java.util.Collections.emptyList; +import static java.util.Collections.emptyMap; +import static java.util.Objects.requireNonNull; import static org.sonar.api.measures.Metric.ValueType.DATA; import static org.sonar.api.measures.Metric.ValueType.DISTRIB; +import static org.sonar.api.utils.Paging.offset; import static org.sonar.core.util.Uuids.UUID_EXAMPLE_02; import static org.sonar.db.component.ComponentTreeQuery.Strategy.CHILDREN; import static org.sonar.db.component.ComponentTreeQuery.Strategy.LEAVES; +import static org.sonar.server.component.ComponentFinder.ParamNames.BASE_COMPONENT_ID_AND_KEY; +import static org.sonar.server.component.ComponentFinder.ParamNames.DEVELOPER_ID_AND_KEY; import static org.sonar.server.measure.ws.ComponentDtoToWsComponent.componentDtoToWsComponent; import static org.sonar.server.measure.ws.MeasureDtoToWsMeasure.updateMeasureBuilder; import static org.sonar.server.measure.ws.MeasuresWsParametersBuilder.createAdditionalFieldsParameter; import static org.sonar.server.measure.ws.MeasuresWsParametersBuilder.createDeveloperParameters; import static org.sonar.server.measure.ws.MeasuresWsParametersBuilder.createMetricKeysParameter; import static org.sonar.server.measure.ws.MetricDtoToWsMetric.metricDtoToWsMetric; +import static org.sonar.server.measure.ws.SnapshotDtoToWsPeriods.snapshotToWsPeriods; import static org.sonar.server.ws.KeyExamples.KEY_BRANCH_EXAMPLE_001; import static org.sonar.server.ws.KeyExamples.KEY_PROJECT_EXAMPLE_001; -import static org.sonar.server.ws.WsParameterBuilder.createQualifiersParameter; import static org.sonar.server.ws.WsParameterBuilder.QualifierParameterContext.newQualifierParameterContext; +import static org.sonar.server.ws.WsParameterBuilder.createQualifiersParameter; import static org.sonar.server.ws.WsUtils.checkRequest; import static org.sonar.server.ws.WsUtils.writeProtobuf; import static org.sonarqube.ws.client.measure.MeasuresWsParameters.ACTION_COMPONENT_TREE; @@ -119,14 +155,19 @@ public class ComponentTreeAction implements MeasuresWsAction { static final Set FORBIDDEN_METRIC_TYPES = ImmutableSet.of(DISTRIB.name(), DATA.name()); private static final int MAX_METRIC_KEYS = 15; private static final Joiner COMMA_JOINER = Joiner.on(", "); + private static final Set QUALIFIERS_ELIGIBLE_FOR_BEST_VALUE = ImmutableSet.of(Qualifiers.FILE, Qualifiers.UNIT_TEST_FILE); - private final ComponentTreeDataLoader dataLoader; + private final DbClient dbClient; + private final ComponentFinder componentFinder; + private final UserSession userSession; private final I18n i18n; private final ResourceTypes resourceTypes; - public ComponentTreeAction(ComponentTreeDataLoader dataLoader, I18n i18n, + public ComponentTreeAction(DbClient dbClient, ComponentFinder componentFinder, UserSession userSession, I18n i18n, ResourceTypes resourceTypes) { - this.dataLoader = dataLoader; + this.dbClient = dbClient; + this.componentFinder = componentFinder; + this.userSession = userSession; this.i18n = i18n; this.resourceTypes = resourceTypes; } @@ -220,7 +261,7 @@ public class ComponentTreeAction implements MeasuresWsAction { } private ComponentTreeWsResponse doHandle(ComponentTreeRequest request) { - ComponentTreeData data = dataLoader.load(request); + ComponentTreeData data = load(request); if (data.getComponents() == null) { return emptyResponse(data.getBaseComponent(), request); } @@ -344,4 +385,238 @@ public class ComponentTreeAction implements MeasuresWsAction { return wsComponent; } + private ComponentTreeData load(ComponentTreeRequest wsRequest) { + try (DbSession dbSession = dbClient.openSession(false)) { + ComponentDto baseComponent = loadComponent(dbSession, wsRequest); + checkPermissions(baseComponent); + Optional baseSnapshot = dbClient.snapshotDao().selectLastAnalysisByRootComponentUuid(dbSession, baseComponent.projectUuid()); + if (!baseSnapshot.isPresent()) { + return ComponentTreeData.builder() + .setBaseComponent(baseComponent) + .build(); + } + Long developerId = searchDeveloperId(dbSession, wsRequest); + + ComponentTreeQuery componentTreeQuery = toComponentTreeQuery(wsRequest, baseComponent); + List components = searchComponents(dbSession, componentTreeQuery); + List metrics = searchMetrics(dbSession, wsRequest); + Table measuresByComponentUuidAndMetric = searchMeasuresByComponentUuidAndMetric(dbSession, baseComponent, componentTreeQuery, + components, + metrics, developerId); + + components = filterComponents(components, measuresByComponentUuidAndMetric, metrics, wsRequest); + components = sortComponents(components, wsRequest, metrics, measuresByComponentUuidAndMetric); + + int componentCount = components.size(); + components = paginateComponents(components, wsRequest); + + return ComponentTreeData.builder() + .setBaseComponent(baseComponent) + .setComponentsFromDb(components) + .setComponentCount(componentCount) + .setMeasuresByComponentUuidAndMetric(measuresByComponentUuidAndMetric) + .setMetrics(metrics) + .setPeriods(snapshotToWsPeriods(baseSnapshot.get())) + .setReferenceComponentsByUuid(searchReferenceComponentsById(dbSession, components)) + .build(); + } + } + + private ComponentDto loadComponent(DbSession dbSession, ComponentTreeRequest request) { + String componentKey = request.getComponent(); + String componentId = request.getBaseComponentId(); + String branch = request.getBranch(); + checkArgument(componentId == null || branch == null, "'%s' and '%s' parameters cannot be used at the same time", DEPRECATED_PARAM_BASE_COMPONENT_ID, PARAM_BRANCH); + return branch == null + ? componentFinder.getByUuidOrKey(dbSession, componentId, componentKey, BASE_COMPONENT_ID_AND_KEY) + : componentFinder.getByKeyAndBranch(dbSession, componentKey, branch); + } + + @CheckForNull + private Long searchDeveloperId(DbSession dbSession, ComponentTreeRequest wsRequest) { + if (wsRequest.getDeveloperId() == null && wsRequest.getDeveloperKey() == null) { + return null; + } + + return componentFinder.getByUuidOrKey(dbSession, wsRequest.getDeveloperId(), wsRequest.getDeveloperKey(), DEVELOPER_ID_AND_KEY).getId(); + } + + private Map searchReferenceComponentsById(DbSession dbSession, List components) { + List referenceComponentUUids = components.stream() + .map(ComponentDto::getCopyResourceUuid) + .filter(Objects::nonNull) + .collect(MoreCollectors.toList(components.size())); + if (referenceComponentUUids.isEmpty()) { + return emptyMap(); + } + + return FluentIterable.from(dbClient.componentDao().selectByUuids(dbSession, referenceComponentUUids)) + .uniqueIndex(ComponentDto::uuid); + } + + private List searchComponents(DbSession dbSession, ComponentTreeQuery componentTreeQuery) { + Collection qualifiers = componentTreeQuery.getQualifiers(); + if (qualifiers != null && qualifiers.isEmpty()) { + return Collections.emptyList(); + } + return dbClient.componentDao().selectDescendants(dbSession, componentTreeQuery); + } + + private List searchMetrics(DbSession dbSession, ComponentTreeRequest request) { + List metricKeys = requireNonNull(request.getMetricKeys()); + List metrics = dbClient.metricDao().selectByKeys(dbSession, metricKeys); + if (metrics.size() < metricKeys.size()) { + List foundMetricKeys = Lists.transform(metrics, MetricDto::getKey); + Set missingMetricKeys = Sets.difference( + new LinkedHashSet<>(metricKeys), + new LinkedHashSet<>(foundMetricKeys)); + + throw new NotFoundException(format("The following metric keys are not found: %s", COMMA_JOINER.join(missingMetricKeys))); + } + String forbiddenMetrics = metrics.stream() + .filter(metric -> ComponentTreeAction.FORBIDDEN_METRIC_TYPES.contains(metric.getValueType())) + .map(MetricDto::getKey) + .sorted() + .collect(MoreCollectors.join(COMMA_JOINER)); + checkArgument(forbiddenMetrics.isEmpty(), "Metrics %s can't be requested in this web service. Please use api/measures/component", forbiddenMetrics); + return metrics; + } + + private Table searchMeasuresByComponentUuidAndMetric(DbSession dbSession, ComponentDto baseComponent, + ComponentTreeQuery componentTreeQuery, List components, List metrics, @Nullable Long developerId) { + + Map metricsById = Maps.uniqueIndex(metrics, MetricDto::getId); + MeasureTreeQuery measureQuery = MeasureTreeQuery.builder() + .setStrategy(MeasureTreeQuery.Strategy.valueOf(componentTreeQuery.getStrategy().name())) + .setNameOrKeyQuery(componentTreeQuery.getNameOrKeyQuery()) + .setQualifiers(componentTreeQuery.getQualifiers()) + .setPersonId(developerId) + .setMetricIds(new ArrayList<>(metricsById.keySet())) + .build(); + + Table measuresByComponentUuidAndMetric = HashBasedTable.create(components.size(), metrics.size()); + dbClient.measureDao().selectTreeByQuery(dbSession, baseComponent, measureQuery, result -> { + MeasureDto measureDto = result.getResultObject(); + measuresByComponentUuidAndMetric.put( + measureDto.getComponentUuid(), + metricsById.get(measureDto.getMetricId()), + ComponentTreeData.Measure.createFromMeasureDto(measureDto)); + }); + + addBestValuesToMeasures(measuresByComponentUuidAndMetric, components, metrics); + + return measuresByComponentUuidAndMetric; + } + + /** + * Conditions for best value measure: + *
    + *
  • component is a production file or test file
  • + *
  • metric is optimized for best value
  • + *
+ */ + private static void addBestValuesToMeasures(Table measuresByComponentUuidAndMetric, List components, + List metrics) { + List metricDtosWithBestValueMeasure = metrics.stream() + .filter(MetricDtoFunctions.isOptimizedForBestValue()) + .map(new MetricDtoToMetricDtoWithBestValue()) + .collect(MoreCollectors.toList(metrics.size())); + if (metricDtosWithBestValueMeasure.isEmpty()) { + return; + } + + Stream componentsEligibleForBestValue = components.stream().filter(ComponentTreeAction::isFileComponent); + componentsEligibleForBestValue.forEach(component -> { + for (MetricDtoWithBestValue metricWithBestValue : metricDtosWithBestValueMeasure) { + if (measuresByComponentUuidAndMetric.get(component.uuid(), metricWithBestValue.getMetric()) == null) { + measuresByComponentUuidAndMetric.put(component.uuid(), metricWithBestValue.getMetric(), + ComponentTreeData.Measure.createFromMeasureDto(metricWithBestValue.getBestValue())); + } + } + }); + } + + private static List filterComponents(List components, + Table measuresByComponentUuidAndMetric, List metrics, ComponentTreeRequest wsRequest) { + if (!componentWithMeasuresOnly(wsRequest)) { + return components; + } + + String metricKeyToSort = wsRequest.getMetricSort(); + Optional metricToSort = metrics.stream().filter(m -> metricKeyToSort.equals(m.getKey())).findFirst(); + checkState(metricToSort.isPresent(), "Metric '%s' not found", metricKeyToSort, wsRequest.getMetricKeys()); + + return components + .stream() + .filter(new HasMeasure(measuresByComponentUuidAndMetric, metricToSort.get(), wsRequest.getMetricPeriodSort())) + .collect(MoreCollectors.toList(components.size())); + } + + private static boolean componentWithMeasuresOnly(ComponentTreeRequest wsRequest) { + return WITH_MEASURES_ONLY_METRIC_SORT_FILTER.equals(wsRequest.getMetricSortFilter()); + } + + private static List sortComponents(List components, ComponentTreeRequest wsRequest, List metrics, + Table measuresByComponentUuidAndMetric) { + return ComponentTreeSort.sortComponents(components, wsRequest, metrics, measuresByComponentUuidAndMetric); + } + + private static List paginateComponents(List components, ComponentTreeRequest wsRequest) { + return components.stream() + .skip(offset(wsRequest.getPage(), wsRequest.getPageSize())) + .limit(wsRequest.getPageSize()) + .collect(MoreCollectors.toList(wsRequest.getPageSize())); + } + + @CheckForNull + private List childrenQualifiers(ComponentTreeRequest request, String baseQualifier) { + List requestQualifiers = request.getQualifiers(); + List childrenQualifiers = null; + if (LEAVES_STRATEGY.equals(request.getStrategy())) { + childrenQualifiers = resourceTypes.getLeavesQualifiers(baseQualifier); + } + + if (requestQualifiers == null) { + return childrenQualifiers; + } + + if (childrenQualifiers == null) { + return requestQualifiers; + } + + Sets.SetView qualifiersIntersection = Sets.intersection(new HashSet<>(childrenQualifiers), new HashSet(requestQualifiers)); + + return new ArrayList<>(qualifiersIntersection); + } + + private ComponentTreeQuery toComponentTreeQuery(ComponentTreeRequest wsRequest, ComponentDto baseComponent) { + List childrenQualifiers = childrenQualifiers(wsRequest, baseComponent.qualifier()); + + ComponentTreeQuery.Builder componentTreeQueryBuilder = ComponentTreeQuery.builder() + .setBaseUuid(baseComponent.uuid()) + .setStrategy(STRATEGIES.get(wsRequest.getStrategy())); + + if (wsRequest.getQuery() != null) { + componentTreeQueryBuilder.setNameOrKeyQuery(wsRequest.getQuery()); + } + if (childrenQualifiers != null) { + componentTreeQueryBuilder.setQualifiers(childrenQualifiers); + } + return componentTreeQueryBuilder.build(); + } + + private void checkPermissions(ComponentDto baseComponent) { + userSession.checkComponentPermission(UserRole.USER, baseComponent); + } + + public static boolean isFileComponent(@Nonnull ComponentDto input) { + return QUALIFIERS_ELIGIBLE_FOR_BEST_VALUE.contains(input.qualifier()); + } + + private static class MetricDtoToMetricDtoWithBestValue implements Function { + @Override + public MetricDtoWithBestValue apply(@Nonnull MetricDto input) { + return new MetricDtoWithBestValue(input); + } + } } diff --git a/server/sonar-server/src/main/java/org/sonar/server/measure/ws/ComponentTreeDataLoader.java b/server/sonar-server/src/main/java/org/sonar/server/measure/ws/ComponentTreeDataLoader.java deleted file mode 100644 index fc2dba8ae1f..00000000000 --- a/server/sonar-server/src/main/java/org/sonar/server/measure/ws/ComponentTreeDataLoader.java +++ /dev/null @@ -1,336 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2017 SonarSource SA - * mailto:info 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.measure.ws; - -import com.google.common.base.Joiner; -import com.google.common.collect.FluentIterable; -import com.google.common.collect.HashBasedTable; -import com.google.common.collect.ImmutableSet; -import com.google.common.collect.Lists; -import com.google.common.collect.Maps; -import com.google.common.collect.Sets; -import com.google.common.collect.Table; -import java.util.ArrayList; -import java.util.Collection; -import java.util.Collections; -import java.util.HashSet; -import java.util.LinkedHashSet; -import java.util.List; -import java.util.Map; -import java.util.Objects; -import java.util.Optional; -import java.util.Set; -import java.util.function.Function; -import java.util.function.Predicate; -import java.util.stream.Stream; -import javax.annotation.CheckForNull; -import javax.annotation.Nonnull; -import javax.annotation.Nullable; -import org.sonar.api.resources.Qualifiers; -import org.sonar.api.resources.ResourceTypes; -import org.sonar.api.web.UserRole; -import org.sonar.core.util.stream.MoreCollectors; -import org.sonar.db.DbClient; -import org.sonar.db.DbSession; -import org.sonar.db.component.ComponentDto; -import org.sonar.db.component.ComponentTreeQuery; -import org.sonar.db.component.SnapshotDto; -import org.sonar.db.measure.MeasureDto; -import org.sonar.db.measure.MeasureTreeQuery; -import org.sonar.db.metric.MetricDto; -import org.sonar.db.metric.MetricDtoFunctions; -import org.sonar.server.component.ComponentFinder; -import org.sonar.server.exceptions.NotFoundException; -import org.sonar.server.measure.ws.ComponentTreeData.Measure; -import org.sonar.server.user.UserSession; -import org.sonarqube.ws.client.measure.ComponentTreeRequest; - -import static com.google.common.base.Preconditions.checkArgument; -import static com.google.common.base.Preconditions.checkState; -import static java.lang.String.format; -import static java.util.Collections.emptyMap; -import static java.util.Objects.requireNonNull; -import static org.sonar.api.utils.Paging.offset; -import static org.sonar.server.component.ComponentFinder.ParamNames.BASE_COMPONENT_ID_AND_KEY; -import static org.sonar.server.component.ComponentFinder.ParamNames.DEVELOPER_ID_AND_KEY; -import static org.sonar.server.measure.ws.ComponentTreeAction.LEAVES_STRATEGY; -import static org.sonar.server.measure.ws.ComponentTreeAction.STRATEGIES; -import static org.sonar.server.measure.ws.ComponentTreeAction.WITH_MEASURES_ONLY_METRIC_SORT_FILTER; -import static org.sonar.server.measure.ws.SnapshotDtoToWsPeriods.snapshotToWsPeriods; -import static org.sonarqube.ws.client.measure.MeasuresWsParameters.DEPRECATED_PARAM_BASE_COMPONENT_ID; -import static org.sonarqube.ws.client.measure.MeasuresWsParameters.PARAM_BRANCH; - -public class ComponentTreeDataLoader { - private static final Set QUALIFIERS_ELIGIBLE_FOR_BEST_VALUE = ImmutableSet.of(Qualifiers.FILE, Qualifiers.UNIT_TEST_FILE); - private static final Joiner COMA_JOINER = Joiner.on(", "); - - private final DbClient dbClient; - private final ComponentFinder componentFinder; - private final UserSession userSession; - private final ResourceTypes resourceTypes; - - public ComponentTreeDataLoader(DbClient dbClient, ComponentFinder componentFinder, UserSession userSession, ResourceTypes resourceTypes) { - this.dbClient = dbClient; - this.componentFinder = componentFinder; - this.userSession = userSession; - this.resourceTypes = resourceTypes; - } - - ComponentTreeData load(ComponentTreeRequest wsRequest) { - try (DbSession dbSession = dbClient.openSession(false)) { - ComponentDto baseComponent = loadComponent(dbSession, wsRequest); - checkPermissions(baseComponent); - Optional baseSnapshot = dbClient.snapshotDao().selectLastAnalysisByRootComponentUuid(dbSession, baseComponent.projectUuid()); - if (!baseSnapshot.isPresent()) { - return ComponentTreeData.builder() - .setBaseComponent(baseComponent) - .build(); - } - Long developerId = searchDeveloperId(dbSession, wsRequest); - - ComponentTreeQuery componentTreeQuery = toComponentTreeQuery(wsRequest, baseComponent); - List components = searchComponents(dbSession, componentTreeQuery); - List metrics = searchMetrics(dbSession, wsRequest); - Table measuresByComponentUuidAndMetric = searchMeasuresByComponentUuidAndMetric(dbSession, baseComponent, componentTreeQuery, - components, - metrics, developerId); - - components = filterComponents(components, measuresByComponentUuidAndMetric, metrics, wsRequest); - components = sortComponents(components, wsRequest, metrics, measuresByComponentUuidAndMetric); - - int componentCount = components.size(); - components = paginateComponents(components, wsRequest); - - return ComponentTreeData.builder() - .setBaseComponent(baseComponent) - .setComponentsFromDb(components) - .setComponentCount(componentCount) - .setMeasuresByComponentUuidAndMetric(measuresByComponentUuidAndMetric) - .setMetrics(metrics) - .setPeriods(snapshotToWsPeriods(baseSnapshot.get())) - .setReferenceComponentsByUuid(searchReferenceComponentsById(dbSession, components)) - .build(); - } - } - - private ComponentDto loadComponent(DbSession dbSession, ComponentTreeRequest request) { - String componentKey = request.getComponent(); - String componentId = request.getBaseComponentId(); - String branch = request.getBranch(); - checkArgument(componentId == null || branch == null, "'%s' and '%s' parameters cannot be used at the same time", DEPRECATED_PARAM_BASE_COMPONENT_ID, PARAM_BRANCH); - return branch == null - ? componentFinder.getByUuidOrKey(dbSession, componentId, componentKey, BASE_COMPONENT_ID_AND_KEY) - : componentFinder.getByKeyAndBranch(dbSession, componentKey, branch); - } - - @CheckForNull - private Long searchDeveloperId(DbSession dbSession, ComponentTreeRequest wsRequest) { - if (wsRequest.getDeveloperId() == null && wsRequest.getDeveloperKey() == null) { - return null; - } - - return componentFinder.getByUuidOrKey(dbSession, wsRequest.getDeveloperId(), wsRequest.getDeveloperKey(), DEVELOPER_ID_AND_KEY).getId(); - } - - private Map searchReferenceComponentsById(DbSession dbSession, List components) { - List referenceComponentUUids = components.stream() - .map(ComponentDto::getCopyResourceUuid) - .filter(Objects::nonNull) - .collect(MoreCollectors.toList(components.size())); - if (referenceComponentUUids.isEmpty()) { - return emptyMap(); - } - - return FluentIterable.from(dbClient.componentDao().selectByUuids(dbSession, referenceComponentUUids)) - .uniqueIndex(ComponentDto::uuid); - } - - private List searchComponents(DbSession dbSession, ComponentTreeQuery componentTreeQuery) { - Collection qualifiers = componentTreeQuery.getQualifiers(); - if (qualifiers != null && qualifiers.isEmpty()) { - return Collections.emptyList(); - } - return dbClient.componentDao().selectDescendants(dbSession, componentTreeQuery); - } - - private List searchMetrics(DbSession dbSession, ComponentTreeRequest request) { - List metricKeys = requireNonNull(request.getMetricKeys()); - List metrics = dbClient.metricDao().selectByKeys(dbSession, metricKeys); - if (metrics.size() < metricKeys.size()) { - List foundMetricKeys = Lists.transform(metrics, MetricDto::getKey); - Set missingMetricKeys = Sets.difference( - new LinkedHashSet<>(metricKeys), - new LinkedHashSet<>(foundMetricKeys)); - - throw new NotFoundException(format("The following metric keys are not found: %s", COMA_JOINER.join(missingMetricKeys))); - } - String forbiddenMetrics = metrics.stream() - .filter(metric -> ComponentTreeAction.FORBIDDEN_METRIC_TYPES.contains(metric.getValueType())) - .map(MetricDto::getKey) - .sorted() - .collect(MoreCollectors.join(COMA_JOINER)); - checkArgument(forbiddenMetrics.isEmpty(), "Metrics %s can't be requested in this web service. Please use api/measures/component", forbiddenMetrics); - return metrics; - } - - private Table searchMeasuresByComponentUuidAndMetric(DbSession dbSession, ComponentDto baseComponent, - ComponentTreeQuery componentTreeQuery, - List components, List metrics, @Nullable Long developerId) { - - Map metricsById = Maps.uniqueIndex(metrics, MetricDto::getId); - MeasureTreeQuery measureQuery = MeasureTreeQuery.builder() - .setStrategy(MeasureTreeQuery.Strategy.valueOf(componentTreeQuery.getStrategy().name())) - .setNameOrKeyQuery(componentTreeQuery.getNameOrKeyQuery()) - .setQualifiers(componentTreeQuery.getQualifiers()) - .setPersonId(developerId) - .setMetricIds(new ArrayList<>(metricsById.keySet())) - .build(); - - Table measuresByComponentUuidAndMetric = HashBasedTable.create(components.size(), metrics.size()); - dbClient.measureDao().selectTreeByQuery(dbSession, baseComponent, measureQuery, result -> { - MeasureDto measureDto = result.getResultObject(); - measuresByComponentUuidAndMetric.put( - measureDto.getComponentUuid(), - metricsById.get(measureDto.getMetricId()), - Measure.createFromMeasureDto(measureDto)); - }); - - addBestValuesToMeasures(measuresByComponentUuidAndMetric, components, metrics); - - return measuresByComponentUuidAndMetric; - } - - /** - * Conditions for best value measure: - *
    - *
  • component is a production file or test file
  • - *
  • metric is optimized for best value
  • - *
- */ - private static void addBestValuesToMeasures(Table measuresByComponentUuidAndMetric, List components, - List metrics) { - List metricDtosWithBestValueMeasure = metrics.stream() - .filter(MetricDtoFunctions.isOptimizedForBestValue()) - .map(new MetricDtoToMetricDtoWithBestValue()) - .collect(MoreCollectors.toList(metrics.size())); - if (metricDtosWithBestValueMeasure.isEmpty()) { - return; - } - - Stream componentsEligibleForBestValue = components.stream().filter(IsFileComponent.INSTANCE); - componentsEligibleForBestValue.forEach(component -> { - for (MetricDtoWithBestValue metricWithBestValue : metricDtosWithBestValueMeasure) { - if (measuresByComponentUuidAndMetric.get(component.uuid(), metricWithBestValue.getMetric()) == null) { - measuresByComponentUuidAndMetric.put(component.uuid(), metricWithBestValue.getMetric(), - Measure.createFromMeasureDto(metricWithBestValue.getBestValue())); - } - } - }); - } - - private static List filterComponents(List components, - Table measuresByComponentUuidAndMetric, List metrics, ComponentTreeRequest wsRequest) { - if (!componentWithMeasuresOnly(wsRequest)) { - return components; - } - - String metricKeyToSort = wsRequest.getMetricSort(); - Optional metricToSort = metrics.stream().filter(m -> metricKeyToSort.equals(m.getKey())).findFirst(); - checkState(metricToSort.isPresent(), "Metric '%s' not found", metricKeyToSort, wsRequest.getMetricKeys()); - - return components - .stream() - .filter(new HasMeasure(measuresByComponentUuidAndMetric, metricToSort.get(), wsRequest)) - .collect(MoreCollectors.toList(components.size())); - } - - private static boolean componentWithMeasuresOnly(ComponentTreeRequest wsRequest) { - return WITH_MEASURES_ONLY_METRIC_SORT_FILTER.equals(wsRequest.getMetricSortFilter()); - } - - private static List sortComponents(List components, ComponentTreeRequest wsRequest, List metrics, - Table measuresByComponentUuidAndMetric) { - return ComponentTreeSort.sortComponents(components, wsRequest, metrics, measuresByComponentUuidAndMetric); - } - - private static List paginateComponents(List components, ComponentTreeRequest wsRequest) { - return components.stream() - .skip(offset(wsRequest.getPage(), wsRequest.getPageSize())) - .limit(wsRequest.getPageSize()) - .collect(MoreCollectors.toList(wsRequest.getPageSize())); - } - - @CheckForNull - private List childrenQualifiers(ComponentTreeRequest request, String baseQualifier) { - List requestQualifiers = request.getQualifiers(); - List childrenQualifiers = null; - if (LEAVES_STRATEGY.equals(request.getStrategy())) { - childrenQualifiers = resourceTypes.getLeavesQualifiers(baseQualifier); - } - - if (requestQualifiers == null) { - return childrenQualifiers; - } - - if (childrenQualifiers == null) { - return requestQualifiers; - } - - Sets.SetView qualifiersIntersection = Sets.intersection(new HashSet<>(childrenQualifiers), new HashSet(requestQualifiers)); - - return new ArrayList<>(qualifiersIntersection); - } - - private ComponentTreeQuery toComponentTreeQuery(ComponentTreeRequest wsRequest, ComponentDto baseComponent) { - List childrenQualifiers = childrenQualifiers(wsRequest, baseComponent.qualifier()); - - ComponentTreeQuery.Builder componentTreeQueryBuilder = ComponentTreeQuery.builder() - .setBaseUuid(baseComponent.uuid()) - .setStrategy(STRATEGIES.get(wsRequest.getStrategy())); - - if (wsRequest.getQuery() != null) { - componentTreeQueryBuilder.setNameOrKeyQuery(wsRequest.getQuery()); - } - if (childrenQualifiers != null) { - componentTreeQueryBuilder.setQualifiers(childrenQualifiers); - } - return componentTreeQueryBuilder.build(); - } - - private void checkPermissions(ComponentDto baseComponent) { - userSession.checkComponentPermission(UserRole.USER, baseComponent); - } - - private enum IsFileComponent implements Predicate { - INSTANCE; - - @Override - public boolean test(@Nonnull ComponentDto input) { - return QUALIFIERS_ELIGIBLE_FOR_BEST_VALUE.contains(input.qualifier()); - } - } - - private static class MetricDtoToMetricDtoWithBestValue implements Function { - @Override - public MetricDtoWithBestValue apply(@Nonnull MetricDto input) { - return new MetricDtoWithBestValue(input); - } - } -} diff --git a/server/sonar-server/src/main/java/org/sonar/server/measure/ws/ComponentTreeRequest.java b/server/sonar-server/src/main/java/org/sonar/server/measure/ws/ComponentTreeRequest.java new file mode 100644 index 00000000000..909a133e1bc --- /dev/null +++ b/server/sonar-server/src/main/java/org/sonar/server/measure/ws/ComponentTreeRequest.java @@ -0,0 +1,224 @@ +/* + * SonarQube + * Copyright (C) 2009-2017 SonarSource SA + * mailto:info 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.measure.ws; + +import java.util.List; +import javax.annotation.CheckForNull; +import javax.annotation.Nullable; + +class ComponentTreeRequest { + + private String baseComponentId; + private String baseComponentKey; + private String component; + private String branch; + private String strategy; + private List qualifiers; + private List additionalFields; + private String query; + private List sort; + private Boolean asc; + private String metricSort; + private Integer metricPeriodSort; + private String metricSortFilter; + private List metricKeys; + private Integer page; + private Integer pageSize; + private String developerId; + private String developerKey; + + /** + * @deprecated since 6.6, please use {@link #getComponent()} instead + */ + @Deprecated + @CheckForNull + public String getBaseComponentId() { + return baseComponentId; + } + + /** + * @deprecated since 6.6, please use {@link #setComponent(String)} instead + */ + @Deprecated + public ComponentTreeRequest setBaseComponentId(@Nullable String baseComponentId) { + this.baseComponentId = baseComponentId; + return this; + } + + @CheckForNull + public String getComponent() { + return component; + } + + public ComponentTreeRequest setComponent(@Nullable String component) { + this.component = component; + return this; + } + + @CheckForNull + public String getBranch() { + return branch; + } + + public ComponentTreeRequest setBranch(@Nullable String branch) { + this.branch = branch; + return this; + } + + @CheckForNull + public String getStrategy() { + return strategy; + } + + public ComponentTreeRequest setStrategy(String strategy) { + this.strategy = strategy; + return this; + } + + @CheckForNull + public List getQualifiers() { + return qualifiers; + } + + public ComponentTreeRequest setQualifiers(@Nullable List qualifiers) { + this.qualifiers = qualifiers; + return this; + } + + @CheckForNull + public List getAdditionalFields() { + return additionalFields; + } + + public ComponentTreeRequest setAdditionalFields(@Nullable List additionalFields) { + this.additionalFields = additionalFields; + return this; + } + + @CheckForNull + public String getQuery() { + return query; + } + + public ComponentTreeRequest setQuery(@Nullable String query) { + this.query = query; + return this; + } + + @CheckForNull + public List getSort() { + return sort; + } + + public ComponentTreeRequest setSort(@Nullable List sort) { + this.sort = sort; + return this; + } + + @CheckForNull + public String getMetricSort() { + return metricSort; + } + + public ComponentTreeRequest setMetricSort(@Nullable String metricSort) { + this.metricSort = metricSort; + return this; + } + + @CheckForNull + public String getMetricSortFilter() { + return metricSortFilter; + } + + public ComponentTreeRequest setMetricSortFilter(@Nullable String metricSortFilter) { + this.metricSortFilter = metricSortFilter; + return this; + } + + @CheckForNull + public List getMetricKeys() { + return metricKeys; + } + + public ComponentTreeRequest setMetricKeys(List metricKeys) { + this.metricKeys = metricKeys; + return this; + } + + @CheckForNull + public Boolean getAsc() { + return asc; + } + + public ComponentTreeRequest setAsc(@Nullable Boolean asc) { + this.asc = asc; + return this; + } + + @CheckForNull + public Integer getPage() { + return page; + } + + public ComponentTreeRequest setPage(int page) { + this.page = page; + return this; + } + + @CheckForNull + public Integer getPageSize() { + return pageSize; + } + + public ComponentTreeRequest setPageSize(int pageSize) { + this.pageSize = pageSize; + return this; + } + + @CheckForNull + public Integer getMetricPeriodSort() { + return metricPeriodSort; + } + + public ComponentTreeRequest setMetricPeriodSort(@Nullable Integer metricPeriodSort) { + this.metricPeriodSort = metricPeriodSort; + return this; + } + + @CheckForNull + public String getDeveloperId() { + return developerId; + } + + public ComponentTreeRequest setDeveloperId(@Nullable String developerId) { + this.developerId = developerId; + return this; + } + + @CheckForNull + public String getDeveloperKey() { + return developerKey; + } + + public ComponentTreeRequest setDeveloperKey(@Nullable String developerKey) { + this.developerKey = developerKey; + return this; + } +} diff --git a/server/sonar-server/src/main/java/org/sonar/server/measure/ws/ComponentTreeSort.java b/server/sonar-server/src/main/java/org/sonar/server/measure/ws/ComponentTreeSort.java index cf881dd6126..28ac65e7091 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/measure/ws/ComponentTreeSort.java +++ b/server/sonar-server/src/main/java/org/sonar/server/measure/ws/ComponentTreeSort.java @@ -35,7 +35,6 @@ import org.sonar.api.measures.Metric.ValueType; import org.sonar.db.component.ComponentDto; import org.sonar.db.metric.MetricDto; import org.sonar.server.exceptions.BadRequestException; -import org.sonarqube.ws.client.measure.ComponentTreeRequest; import static java.lang.String.CASE_INSENSITIVE_ORDER; import static java.lang.String.format; diff --git a/server/sonar-server/src/main/java/org/sonar/server/measure/ws/HasMeasure.java b/server/sonar-server/src/main/java/org/sonar/server/measure/ws/HasMeasure.java index 3f0b7ed5bdb..6db3622a14f 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/measure/ws/HasMeasure.java +++ b/server/sonar-server/src/main/java/org/sonar/server/measure/ws/HasMeasure.java @@ -22,18 +22,18 @@ package org.sonar.server.measure.ws; import com.google.common.collect.Table; import java.util.function.Predicate; import javax.annotation.Nonnull; +import javax.annotation.Nullable; + import org.sonar.db.component.ComponentDto; import org.sonar.db.metric.MetricDto; -import org.sonarqube.ws.client.measure.ComponentTreeRequest; import static org.sonar.server.measure.ws.ComponentTreeData.Measure; class HasMeasure implements Predicate { private final Predicate predicate; - HasMeasure(Table table, MetricDto metric, ComponentTreeRequest request) { - Integer periodIndex = request.getMetricPeriodSort(); - this.predicate = periodIndex == null + HasMeasure(Table table, MetricDto metric, @Nullable Integer metricPeriodSort) { + this.predicate = metricPeriodSort == null ? new HasAbsoluteValue(table, metric) : new HasValueOnPeriod(table, metric); } diff --git a/server/sonar-server/src/main/java/org/sonar/server/measure/ws/MeasuresWsModule.java b/server/sonar-server/src/main/java/org/sonar/server/measure/ws/MeasuresWsModule.java index e4b098e66df..651c4916c0e 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/measure/ws/MeasuresWsModule.java +++ b/server/sonar-server/src/main/java/org/sonar/server/measure/ws/MeasuresWsModule.java @@ -25,7 +25,6 @@ public class MeasuresWsModule extends Module { @Override protected void configureModule() { add( - ComponentTreeDataLoader.class, MeasuresWs.class, ComponentTreeAction.class, ComponentAction.class, diff --git a/server/sonar-server/src/main/java/org/sonar/server/measure/ws/SearchAction.java b/server/sonar-server/src/main/java/org/sonar/server/measure/ws/SearchAction.java index 27672b442e4..dbbda02517f 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/measure/ws/SearchAction.java +++ b/server/sonar-server/src/main/java/org/sonar/server/measure/ws/SearchAction.java @@ -39,7 +39,6 @@ import org.sonar.db.metric.MetricDto; import org.sonar.server.user.UserSession; import org.sonarqube.ws.Measures.Measure; import org.sonarqube.ws.Measures.SearchWsResponse; -import org.sonarqube.ws.client.measure.SearchRequest; import static com.google.common.base.Preconditions.checkArgument; import static java.util.Comparator.comparing; @@ -61,6 +60,7 @@ import static org.sonarqube.ws.client.measure.MeasuresWsParameters.PARAM_PROJECT public class SearchAction implements MeasuresWsAction { + private static final int MAX_NB_PROJECTS = 100; private static final Set ALLOWED_QUALIFIERS = ImmutableSet.of(PROJECT, APP, VIEW, SUBVIEW); private final UserSession userSession; @@ -78,7 +78,7 @@ public class SearchAction implements MeasuresWsAction { .setDescription("Search for project measures ordered by project names.
" + "At most %d projects can be provided.
" + "Returns the projects with the 'Browse' permission.", - SearchRequest.MAX_NB_PROJECTS) + MAX_NB_PROJECTS) .setSince("6.2") .setResponseExample(getClass().getResource("search-example.json")) .setHandler(this); @@ -196,4 +196,56 @@ public class SearchAction implements MeasuresWsAction { .collect(toList()); } } + + private static class SearchRequest { + + private final List metricKeys; + private final List projectKeys; + + public SearchRequest(Builder builder) { + metricKeys = builder.metricKeys; + projectKeys = builder.projectKeys; + } + + public List getMetricKeys() { + return metricKeys; + } + + public List getProjectKeys() { + return projectKeys; + } + + public static Builder builder() { + return new Builder(); + } + + } + + private static class Builder { + private List metricKeys; + private List projectKeys; + + private Builder() { + // enforce method constructor + } + + public Builder setMetricKeys(List metricKeys) { + this.metricKeys = metricKeys; + return this; + } + + public Builder setProjectKeys(List projectKeys) { + this.projectKeys = projectKeys; + return this; + } + + public SearchAction.SearchRequest build() { + checkArgument(metricKeys != null && !metricKeys.isEmpty(), "Metric keys must be provided"); + checkArgument(projectKeys != null && !projectKeys.isEmpty(), "Project keys must be provided"); + int nbComponents = projectKeys.size(); + checkArgument(nbComponents <= MAX_NB_PROJECTS, + "%s projects provided, more than maximum authorized (%s)", nbComponents, MAX_NB_PROJECTS); + return new SearchAction.SearchRequest(this); + } + } } diff --git a/server/sonar-server/src/main/java/org/sonar/server/measure/ws/SearchHistoryAction.java b/server/sonar-server/src/main/java/org/sonar/server/measure/ws/SearchHistoryAction.java index f2e4ac95748..c76decf6792 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/measure/ws/SearchHistoryAction.java +++ b/server/sonar-server/src/main/java/org/sonar/server/measure/ws/SearchHistoryAction.java @@ -45,7 +45,9 @@ import org.sonar.server.component.ComponentFinder; import org.sonar.server.user.UserSession; import org.sonar.server.ws.KeyExamples; import org.sonarqube.ws.Measures.SearchHistoryResponse; -import org.sonarqube.ws.client.measure.SearchHistoryRequest; + +import javax.annotation.CheckForNull; +import javax.annotation.Nullable; import static java.lang.String.format; import static org.sonar.api.utils.DateUtils.parseEndingDateOrDateTime; @@ -60,10 +62,12 @@ import static org.sonarqube.ws.client.measure.MeasuresWsParameters.PARAM_COMPONE import static org.sonarqube.ws.client.measure.MeasuresWsParameters.PARAM_FROM; import static org.sonarqube.ws.client.measure.MeasuresWsParameters.PARAM_METRICS; import static org.sonarqube.ws.client.measure.MeasuresWsParameters.PARAM_TO; -import static org.sonarqube.ws.client.measure.SearchHistoryRequest.DEFAULT_PAGE_SIZE; -import static org.sonarqube.ws.client.measure.SearchHistoryRequest.MAX_PAGE_SIZE; public class SearchHistoryAction implements MeasuresWsAction { + + private static final int MAX_PAGE_SIZE = 1_000; + private static final int DEFAULT_PAGE_SIZE = 100; + private final DbClient dbClient; private final ComponentFinder componentFinder; private final UserSession userSession; @@ -142,7 +146,7 @@ public class SearchHistoryAction implements MeasuresWsAction { try (DbSession dbSession = dbClient.openSession(false)) { ComponentDto component = searchComponent(request, dbSession); - SearchHistoryResult result = new SearchHistoryResult(request) + SearchHistoryResult result = new SearchHistoryResult(request.page, request.pageSize) .setComponent(component) .setAnalyses(searchAnalyses(dbSession, request, component)) .setMetrics(searchMetrics(dbSession, request)); @@ -201,4 +205,121 @@ public class SearchHistoryAction implements MeasuresWsAction { return componentFinder.getByKey(dbSession, componentKey); } + static class SearchHistoryRequest { + private final String component; + private final String branch; + private final List metrics; + private final String from; + private final String to; + private final int page; + private final int pageSize; + + public SearchHistoryRequest(Builder builder) { + this.component = builder.component; + this.branch = builder.branch; + this.metrics = builder.metrics; + this.from = builder.from; + this.to = builder.to; + this.page = builder.page; + this.pageSize = builder.pageSize; + } + + public String getComponent() { + return component; + } + + @CheckForNull + public String getBranch() { + return branch; + } + + public List getMetrics() { + return metrics; + } + + @CheckForNull + public String getFrom() { + return from; + } + + @CheckForNull + public String getTo() { + return to; + } + + public int getPage() { + return page; + } + + public int getPageSize() { + return pageSize; + } + + public static Builder builder() { + return new Builder(); + } + } + + static class Builder { + private String component; + private String branch; + private List metrics; + private String from; + private String to; + private int page = 1; + private int pageSize = DEFAULT_PAGE_SIZE; + + private Builder() { + // enforce build factory method + } + + public Builder setComponent(String component) { + this.component = component; + return this; + } + + public Builder setBranch(@Nullable String branch) { + this.branch = branch; + return this; + } + + public Builder setMetrics(List metrics) { + this.metrics = metrics; + return this; + } + + public Builder setFrom(@Nullable String from) { + this.from = from; + return this; + } + + public Builder setTo(@Nullable String to) { + this.to = to; + return this; + } + + public Builder setPage(int page) { + this.page = page; + return this; + } + + public Builder setPageSize(int pageSize) { + this.pageSize = pageSize; + return this; + } + + public SearchHistoryRequest build() { + checkArgument(component != null && !component.isEmpty(), "Component key is required"); + checkArgument(metrics != null && !metrics.isEmpty(), "Metric keys are required"); + checkArgument(pageSize <= MAX_PAGE_SIZE, "Page size (%d) must be lower than or equal to %d", pageSize, MAX_PAGE_SIZE); + + return new SearchHistoryRequest(this); + } + + private static void checkArgument(boolean condition, String message, Object... args) { + if (!condition) { + throw new IllegalArgumentException(format(message, args)); + } + } + } } diff --git a/server/sonar-server/src/main/java/org/sonar/server/measure/ws/SearchHistoryResult.java b/server/sonar-server/src/main/java/org/sonar/server/measure/ws/SearchHistoryResult.java index 22d7440bbd0..9b0cc84cacc 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/measure/ws/SearchHistoryResult.java +++ b/server/sonar-server/src/main/java/org/sonar/server/measure/ws/SearchHistoryResult.java @@ -31,7 +31,6 @@ import org.sonar.db.component.SnapshotDto; import org.sonar.db.measure.MeasureDto; import org.sonar.db.metric.MetricDto; import org.sonarqube.ws.Common; -import org.sonarqube.ws.client.measure.SearchHistoryRequest; import static java.util.Collections.emptyList; import static java.util.Objects.requireNonNull; @@ -40,15 +39,17 @@ import static org.sonar.db.metric.MetricDtoFunctions.isOptimizedForBestValue; import static org.sonar.server.measure.ws.MetricDtoWithBestValue.isEligibleForBestValue; class SearchHistoryResult { - private final SearchHistoryRequest request; + private final int page; + private final int pageSize; private List analyses; private List metrics; private List measures; private Common.Paging paging; private ComponentDto component; - SearchHistoryResult(SearchHistoryRequest request) { - this.request = request; + SearchHistoryResult(int page, int pageSize) { + this.page = page; + this.pageSize = pageSize; } public ComponentDto getComponent() { @@ -66,8 +67,8 @@ class SearchHistoryResult { } SearchHistoryResult setAnalyses(List analyses) { - this.paging = Common.Paging.newBuilder().setPageIndex(request.getPage()).setPageSize(request.getPageSize()).setTotal(analyses.size()).build(); - this.analyses = analyses.stream().skip(offset(request.getPage(), request.getPageSize())).limit(request.getPageSize()).collect(MoreCollectors.toList()); + this.paging = Common.Paging.newBuilder().setPageIndex(page).setPageSize(pageSize).setTotal(analyses.size()).build(); + this.analyses = analyses.stream().skip(offset(page, pageSize)).limit(pageSize).collect(MoreCollectors.toList()); return this; } diff --git a/server/sonar-server/src/main/java/org/sonar/server/notification/ws/AddAction.java b/server/sonar-server/src/main/java/org/sonar/server/notification/ws/AddAction.java index 4fac5363b70..49ae0dda651 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/notification/ws/AddAction.java +++ b/server/sonar-server/src/main/java/org/sonar/server/notification/ws/AddAction.java @@ -39,7 +39,6 @@ import org.sonar.server.notification.NotificationUpdater; import org.sonar.server.notification.email.EmailNotificationChannel; import org.sonar.server.user.UserSession; import org.sonar.server.ws.KeyExamples; -import org.sonarqube.ws.client.notifications.AddRequest; import static java.util.Optional.empty; import static org.sonar.core.util.Protobuf.setNullable; @@ -172,4 +171,48 @@ public class AddAction implements NotificationsWsAction { return add; } + + private static class AddRequest { + + private String channel; + private String login; + private String project; + private String type; + + public AddRequest setChannel(String channel) { + this.channel = channel; + return this; + } + + public String getChannel() { + return channel; + } + + public AddRequest setLogin(String login) { + this.login = login; + return this; + } + + public String getLogin() { + return login; + } + + public AddRequest setProject(String project) { + this.project = project; + return this; + } + + public String getProject() { + return project; + } + + public AddRequest setType(String type) { + this.type = type; + return this; + } + + public String getType() { + return type; + } + } } diff --git a/server/sonar-server/src/main/java/org/sonar/server/notification/ws/RemoveAction.java b/server/sonar-server/src/main/java/org/sonar/server/notification/ws/RemoveAction.java index b8cd0a79ed2..d866cf20543 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/notification/ws/RemoveAction.java +++ b/server/sonar-server/src/main/java/org/sonar/server/notification/ws/RemoveAction.java @@ -39,7 +39,6 @@ import org.sonar.server.notification.NotificationUpdater; import org.sonar.server.notification.email.EmailNotificationChannel; import org.sonar.server.user.UserSession; import org.sonar.server.ws.KeyExamples; -import org.sonarqube.ws.client.notifications.RemoveRequest; import static java.util.Optional.empty; import static org.sonar.core.util.Protobuf.setNullable; @@ -170,4 +169,48 @@ public class RemoveAction implements NotificationsWsAction { return remove; } + + static class RemoveRequest { + + private String channel; + private String login; + private String project; + private String type; + + public RemoveRequest setChannel(String channel) { + this.channel = channel; + return this; + } + + public String getChannel() { + return channel; + } + + public RemoveRequest setLogin(String login) { + this.login = login; + return this; + } + + public String getLogin() { + return login; + } + + public RemoveRequest setProject(String project) { + this.project = project; + return this; + } + + public String getProject() { + return project; + } + + public RemoveRequest setType(String type) { + this.type = type; + return this; + } + + public String getType() { + return type; + } + } } diff --git a/server/sonar-server/src/main/java/org/sonar/server/permission/ws/PermissionsWsModule.java b/server/sonar-server/src/main/java/org/sonar/server/permission/ws/PermissionsWsModule.java index f32b3f49a6e..9407c73b4e4 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/permission/ws/PermissionsWsModule.java +++ b/server/sonar-server/src/main/java/org/sonar/server/permission/ws/PermissionsWsModule.java @@ -31,7 +31,6 @@ import org.sonar.server.permission.ws.template.RemoveGroupFromTemplateAction; import org.sonar.server.permission.ws.template.RemoveProjectCreatorFromTemplateAction; import org.sonar.server.permission.ws.template.RemoveUserFromTemplateAction; import org.sonar.server.permission.ws.template.SearchTemplatesAction; -import org.sonar.server.permission.ws.template.SearchTemplatesDataLoader; import org.sonar.server.permission.ws.template.SetDefaultTemplateAction; import org.sonar.server.permission.ws.template.TemplateGroupsAction; import org.sonar.server.permission.ws.template.TemplateUsersAction; @@ -67,8 +66,6 @@ public class PermissionsWsModule extends Module { TemplateGroupsAction.class, BulkApplyTemplateAction.class, // utility classes - SearchProjectPermissionsDataLoader.class, - SearchTemplatesDataLoader.class, PermissionWsSupport.class); } } diff --git a/server/sonar-server/src/main/java/org/sonar/server/permission/ws/SearchProjectPermissionsAction.java b/server/sonar-server/src/main/java/org/sonar/server/permission/ws/SearchProjectPermissionsAction.java index 2eb7531c944..dea8bfc6f22 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/permission/ws/SearchProjectPermissionsAction.java +++ b/server/sonar-server/src/main/java/org/sonar/server/permission/ws/SearchProjectPermissionsAction.java @@ -19,9 +19,16 @@ */ package org.sonar.server.permission.ws; +import java.util.List; import java.util.Locale; import java.util.Optional; + +import com.google.common.collect.Collections2; +import com.google.common.collect.Lists; +import com.google.common.collect.Table; +import com.google.common.collect.TreeBasedTable; import org.sonar.api.i18n.I18n; +import org.sonar.api.resources.ResourceType; import org.sonar.api.resources.ResourceTypes; import org.sonar.api.server.ws.Request; import org.sonar.api.server.ws.Response; @@ -32,6 +39,8 @@ import org.sonar.core.permission.ProjectPermissions; import org.sonar.db.DbClient; import org.sonar.db.DbSession; import org.sonar.db.component.ComponentDto; +import org.sonar.db.component.ComponentQuery; +import org.sonar.db.permission.CountPerProjectPermission; import org.sonar.server.permission.PermissionPrivilegeChecker; import org.sonar.server.permission.ProjectId; import org.sonar.server.user.UserSession; @@ -39,11 +48,16 @@ import org.sonarqube.ws.Common; import org.sonarqube.ws.Permissions.Permission; import org.sonarqube.ws.Permissions.SearchProjectPermissionsWsResponse; import org.sonarqube.ws.Permissions.SearchProjectPermissionsWsResponse.Project; -import org.sonarqube.ws.client.permission.SearchProjectPermissionsRequest; +import javax.annotation.CheckForNull; +import javax.annotation.Nullable; + +import static java.util.Collections.singletonList; +import static org.sonar.api.utils.Paging.forPageIndex; import static org.sonar.server.permission.ws.PermissionRequestValidator.validateQualifier; import static org.sonar.server.permission.ws.PermissionsWsParametersBuilder.createProjectParameters; import static org.sonar.server.permission.ws.ProjectWsRef.newOptionalWsProjectRef; +import static org.sonar.server.permission.ws.SearchProjectPermissionsData.newBuilder; import static org.sonar.server.ws.WsParameterBuilder.createRootQualifierParameter; import static org.sonar.server.ws.WsParameterBuilder.QualifierParameterContext.newQualifierParameterContext; import static org.sonar.server.ws.WsUtils.writeProtobuf; @@ -59,17 +73,17 @@ public class SearchProjectPermissionsAction implements PermissionsWsAction { private final UserSession userSession; private final I18n i18n; private final ResourceTypes resourceTypes; - private final SearchProjectPermissionsDataLoader dataLoader; private final PermissionWsSupport wsSupport; + private final String[] rootQualifiers; public SearchProjectPermissionsAction(DbClient dbClient, UserSession userSession, I18n i18n, ResourceTypes resourceTypes, - SearchProjectPermissionsDataLoader dataLoader, PermissionWsSupport wsSupport) { + PermissionWsSupport wsSupport) { this.dbClient = dbClient; this.userSession = userSession; this.i18n = i18n; this.resourceTypes = resourceTypes; - this.dataLoader = dataLoader; this.wsSupport = wsSupport; + this.rootQualifiers = Collections2.transform(resourceTypes.getRoots(), ResourceType::getQualifier).toArray(new String[resourceTypes.getRoots().size()]); } @Override @@ -108,7 +122,7 @@ public class SearchProjectPermissionsAction implements PermissionsWsAction { try (DbSession dbSession = dbClient.openSession(false)) { checkAuthorized(dbSession, request); validateQualifier(request.getQualifier(), resourceTypes); - SearchProjectPermissionsData data = dataLoader.load(dbSession, request); + SearchProjectPermissionsData data = load(dbSession, request); return buildResponse(data); } } @@ -182,4 +196,140 @@ public class SearchProjectPermissionsAction implements PermissionsWsAction { private String i18nName(String permissionKey) { return i18n.message(Locale.ENGLISH, PROPERTY_PREFIX + permissionKey, permissionKey); } + + private SearchProjectPermissionsData load(DbSession dbSession, SearchProjectPermissionsRequest request) { + SearchProjectPermissionsData.Builder data = newBuilder(); + int countRootComponents = countRootComponents(dbSession, request); + List rootComponents = searchRootComponents(dbSession, request, paging(request, countRootComponents)); + List rootComponentIds = Lists.transform(rootComponents, ComponentDto::getId); + + data.rootComponents(rootComponents) + .paging(paging(request, countRootComponents)) + .userCountByProjectIdAndPermission(userCountByRootComponentIdAndPermission(dbSession, rootComponentIds)) + .groupCountByProjectIdAndPermission(groupCountByRootComponentIdAndPermission(dbSession, rootComponentIds)); + + return data.build(); + } + + private static Paging paging(SearchProjectPermissionsRequest request, int total) { + return forPageIndex(request.getPage()) + .withPageSize(request.getPageSize()) + .andTotal(total); + } + + private int countRootComponents(DbSession dbSession, SearchProjectPermissionsRequest request) { + return dbClient.componentDao().countByQuery(dbSession, toDbQuery(request)); + } + + private List searchRootComponents(DbSession dbSession, SearchProjectPermissionsRequest request, Paging paging) { + com.google.common.base.Optional project = newOptionalWsProjectRef(request.getProjectId(), request.getProjectKey()); + + if (project.isPresent()) { + return singletonList(wsSupport.getRootComponentOrModule(dbSession, project.get())); + } + + return dbClient.componentDao().selectByQuery(dbSession, toDbQuery(request), paging.offset(), paging.pageSize()); + } + + private ComponentQuery toDbQuery(SearchProjectPermissionsRequest wsRequest) { + return ComponentQuery.builder() + .setQualifiers(qualifiers(wsRequest.getQualifier())) + .setNameOrKeyQuery(wsRequest.getQuery()) + .build(); + } + + private String[] qualifiers(@Nullable String requestQualifier) { + return requestQualifier == null + ? rootQualifiers + : (new String[] {requestQualifier}); + } + + private Table userCountByRootComponentIdAndPermission(DbSession dbSession, List rootComponentIds) { + final Table userCountByRootComponentIdAndPermission = TreeBasedTable.create(); + + dbClient.userPermissionDao().countUsersByProjectPermission(dbSession, rootComponentIds).forEach( + row -> userCountByRootComponentIdAndPermission.put(row.getComponentId(), row.getPermission(), row.getCount())); + + return userCountByRootComponentIdAndPermission; + } + + private Table groupCountByRootComponentIdAndPermission(DbSession dbSession, List rootComponentIds) { + final Table userCountByRootComponentIdAndPermission = TreeBasedTable.create(); + + dbClient.groupPermissionDao().groupsCountByComponentIdAndPermission(dbSession, rootComponentIds, context -> { + CountPerProjectPermission row = (CountPerProjectPermission) context.getResultObject(); + userCountByRootComponentIdAndPermission.put(row.getComponentId(), row.getPermission(), row.getCount()); + }); + + return userCountByRootComponentIdAndPermission; + } + + private static class SearchProjectPermissionsRequest { + private String projectId; + private String projectKey; + private String qualifier; + private Integer page; + private Integer pageSize; + private String query; + + @CheckForNull + public String getProjectId() { + return projectId; + } + + public SearchProjectPermissionsRequest setProjectId(@Nullable String projectId) { + this.projectId = projectId; + return this; + } + + @CheckForNull + public String getProjectKey() { + return projectKey; + } + + public SearchProjectPermissionsRequest setProjectKey(@Nullable String projectKey) { + this.projectKey = projectKey; + return this; + } + + @CheckForNull + public Integer getPage() { + return page; + } + + public SearchProjectPermissionsRequest setPage(int page) { + this.page = page; + return this; + } + + @CheckForNull + public Integer getPageSize() { + return pageSize; + } + + public SearchProjectPermissionsRequest setPageSize(int pageSize) { + this.pageSize = pageSize; + return this; + } + + @CheckForNull + public String getQuery() { + return query; + } + + public SearchProjectPermissionsRequest setQuery(@Nullable String query) { + this.query = query; + return this; + } + + @CheckForNull + public String getQualifier() { + return qualifier; + } + + public SearchProjectPermissionsRequest setQualifier(@Nullable String qualifier) { + this.qualifier = qualifier; + return this; + } + } } diff --git a/server/sonar-server/src/main/java/org/sonar/server/permission/ws/SearchProjectPermissionsDataLoader.java b/server/sonar-server/src/main/java/org/sonar/server/permission/ws/SearchProjectPermissionsDataLoader.java deleted file mode 100644 index 973144fcd19..00000000000 --- a/server/sonar-server/src/main/java/org/sonar/server/permission/ws/SearchProjectPermissionsDataLoader.java +++ /dev/null @@ -1,121 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2017 SonarSource SA - * mailto:info 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.permission.ws; - -import com.google.common.base.Optional; -import com.google.common.collect.Collections2; -import com.google.common.collect.Lists; -import com.google.common.collect.Table; -import com.google.common.collect.TreeBasedTable; -import java.util.List; -import javax.annotation.Nullable; -import org.sonar.api.resources.ResourceType; -import org.sonar.api.resources.ResourceTypes; -import org.sonar.api.utils.Paging; -import org.sonar.db.DbClient; -import org.sonar.db.DbSession; -import org.sonar.db.component.ComponentDto; -import org.sonar.db.component.ComponentQuery; -import org.sonar.db.permission.CountPerProjectPermission; -import org.sonarqube.ws.client.permission.SearchProjectPermissionsRequest; - -import static java.util.Collections.singletonList; -import static org.sonar.api.utils.Paging.forPageIndex; -import static org.sonar.server.permission.ws.ProjectWsRef.newOptionalWsProjectRef; -import static org.sonar.server.permission.ws.SearchProjectPermissionsData.newBuilder; - -public class SearchProjectPermissionsDataLoader { - private final DbClient dbClient; - private final PermissionWsSupport wsSupport; - private final String[] rootQualifiers; - - public SearchProjectPermissionsDataLoader(DbClient dbClient, PermissionWsSupport wsSupport, ResourceTypes resourceTypes) { - this.dbClient = dbClient; - this.wsSupport = wsSupport; - this.rootQualifiers = Collections2.transform(resourceTypes.getRoots(), ResourceType::getQualifier).toArray(new String[resourceTypes.getRoots().size()]); - } - - SearchProjectPermissionsData load(DbSession dbSession, SearchProjectPermissionsRequest request) { - SearchProjectPermissionsData.Builder data = newBuilder(); - int countRootComponents = countRootComponents(dbSession, request); - List rootComponents = searchRootComponents(dbSession, request, paging(request, countRootComponents)); - List rootComponentIds = Lists.transform(rootComponents, ComponentDto::getId); - - data.rootComponents(rootComponents) - .paging(paging(request, countRootComponents)) - .userCountByProjectIdAndPermission(userCountByRootComponentIdAndPermission(dbSession, rootComponentIds)) - .groupCountByProjectIdAndPermission(groupCountByRootComponentIdAndPermission(dbSession, rootComponentIds)); - - return data.build(); - } - - private static Paging paging(SearchProjectPermissionsRequest request, int total) { - return forPageIndex(request.getPage()) - .withPageSize(request.getPageSize()) - .andTotal(total); - } - - private int countRootComponents(DbSession dbSession, SearchProjectPermissionsRequest request) { - return dbClient.componentDao().countByQuery(dbSession, toDbQuery(request)); - } - - private List searchRootComponents(DbSession dbSession, SearchProjectPermissionsRequest request, Paging paging) { - Optional project = newOptionalWsProjectRef(request.getProjectId(), request.getProjectKey()); - - if (project.isPresent()) { - return singletonList(wsSupport.getRootComponentOrModule(dbSession, project.get())); - } - - return dbClient.componentDao().selectByQuery(dbSession, toDbQuery(request), paging.offset(), paging.pageSize()); - } - - private ComponentQuery toDbQuery(SearchProjectPermissionsRequest wsRequest) { - return ComponentQuery.builder() - .setQualifiers(qualifiers(wsRequest.getQualifier())) - .setNameOrKeyQuery(wsRequest.getQuery()) - .build(); - } - - private String[] qualifiers(@Nullable String requestQualifier) { - return requestQualifier == null - ? rootQualifiers - : (new String[] {requestQualifier}); - } - - private Table userCountByRootComponentIdAndPermission(DbSession dbSession, List rootComponentIds) { - final Table userCountByRootComponentIdAndPermission = TreeBasedTable.create(); - - dbClient.userPermissionDao().countUsersByProjectPermission(dbSession, rootComponentIds).forEach( - row -> userCountByRootComponentIdAndPermission.put(row.getComponentId(), row.getPermission(), row.getCount())); - - return userCountByRootComponentIdAndPermission; - } - - private Table groupCountByRootComponentIdAndPermission(DbSession dbSession, List rootComponentIds) { - final Table userCountByRootComponentIdAndPermission = TreeBasedTable.create(); - - dbClient.groupPermissionDao().groupsCountByComponentIdAndPermission(dbSession, rootComponentIds, context -> { - CountPerProjectPermission row = (CountPerProjectPermission) context.getResultObject(); - userCountByRootComponentIdAndPermission.put(row.getComponentId(), row.getPermission(), row.getCount()); - }); - - return userCountByRootComponentIdAndPermission; - } -} diff --git a/server/sonar-server/src/main/java/org/sonar/server/permission/ws/template/AddProjectCreatorToTemplateAction.java b/server/sonar-server/src/main/java/org/sonar/server/permission/ws/template/AddProjectCreatorToTemplateAction.java index 0d4956088e2..2c8d5e1705c 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/permission/ws/template/AddProjectCreatorToTemplateAction.java +++ b/server/sonar-server/src/main/java/org/sonar/server/permission/ws/template/AddProjectCreatorToTemplateAction.java @@ -31,8 +31,11 @@ import org.sonar.db.permission.template.PermissionTemplateDto; import org.sonar.server.permission.ws.PermissionWsSupport; import org.sonar.server.permission.ws.PermissionsWsAction; import org.sonar.server.user.UserSession; -import org.sonarqube.ws.client.permission.AddProjectCreatorToTemplateRequest; +import javax.annotation.CheckForNull; +import javax.annotation.Nullable; + +import static java.util.Objects.requireNonNull; import static org.sonar.server.permission.PermissionPrivilegeChecker.checkGlobalAdmin; import static org.sonar.server.permission.ws.PermissionRequestValidator.validateProjectPermission; import static org.sonar.server.permission.ws.PermissionsWsParametersBuilder.createProjectPermissionParameter; @@ -119,4 +122,76 @@ public class AddProjectCreatorToTemplateAction implements PermissionsWsAction { dbClient.permissionTemplateCharacteristicDao().update(dbSession, targetTemplatePermission); dbSession.commit(); } + + private static class AddProjectCreatorToTemplateRequest { + private final String templateId; + private final String organization; + private final String templateName; + private final String permission; + + private AddProjectCreatorToTemplateRequest(Builder builder) { + this.templateId = builder.templateId; + this.organization = builder.organization; + this.templateName = builder.templateName; + this.permission = requireNonNull(builder.permission); + } + + @CheckForNull + public String getTemplateId() { + return templateId; + } + + @CheckForNull + public String getOrganization() { + return organization; + } + + @CheckForNull + public String getTemplateName() { + return templateName; + } + + public String getPermission() { + return permission; + } + + public static Builder builder() { + return new Builder(); + } + } + + private static class Builder { + private String templateId; + private String organization; + private String templateName; + private String permission; + + private Builder() { + // enforce method constructor + } + + public Builder setTemplateId(@Nullable String templateId) { + this.templateId = templateId; + return this; + } + + public Builder setOrganization(@Nullable String s) { + this.organization = s; + return this; + } + + public Builder setTemplateName(@Nullable String templateName) { + this.templateName = templateName; + return this; + } + + public Builder setPermission(@Nullable String permission) { + this.permission = permission; + return this; + } + + public AddProjectCreatorToTemplateRequest build() { + return new AddProjectCreatorToTemplateRequest(this); + } + } } diff --git a/server/sonar-server/src/main/java/org/sonar/server/permission/ws/template/AddUserToTemplateAction.java b/server/sonar-server/src/main/java/org/sonar/server/permission/ws/template/AddUserToTemplateAction.java index 5c38b5a5ab7..d40e26891f1 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/permission/ws/template/AddUserToTemplateAction.java +++ b/server/sonar-server/src/main/java/org/sonar/server/permission/ws/template/AddUserToTemplateAction.java @@ -32,8 +32,11 @@ import org.sonar.server.permission.UserId; import org.sonar.server.permission.ws.PermissionWsSupport; import org.sonar.server.permission.ws.PermissionsWsAction; import org.sonar.server.user.UserSession; -import org.sonarqube.ws.client.permission.AddUserToTemplateRequest; +import javax.annotation.CheckForNull; +import javax.annotation.Nullable; + +import static java.util.Objects.requireNonNull; import static org.sonar.server.permission.PermissionPrivilegeChecker.checkGlobalAdmin; import static org.sonar.server.permission.ws.PermissionsWsParametersBuilder.createProjectPermissionParameter; import static org.sonar.server.permission.ws.PermissionsWsParametersBuilder.createTemplateParameters; @@ -110,4 +113,60 @@ public class AddUserToTemplateAction implements PermissionsWsAction { List usersWithPermission = dbClient.permissionTemplateDao().selectUserLoginsByQueryAndTemplate(dbSession, permissionQuery, templateId); return usersWithPermission.stream().anyMatch(s -> s.equals(userLogin)); } + + private static class AddUserToTemplateRequest { + private String login; + private String permission; + private String templateId; + private String organization; + private String templateName; + + public String getLogin() { + return login; + } + + public AddUserToTemplateRequest setLogin(String login) { + this.login = requireNonNull(login); + return this; + } + + public String getPermission() { + return permission; + } + + public AddUserToTemplateRequest setPermission(String permission) { + this.permission = requireNonNull(permission); + return this; + } + + @CheckForNull + public String getTemplateId() { + return templateId; + } + + public AddUserToTemplateRequest setTemplateId(@Nullable String templateId) { + this.templateId = templateId; + return this; + } + + @CheckForNull + public String getTemplateName() { + return templateName; + } + + public AddUserToTemplateRequest setTemplateName(@Nullable String templateName) { + this.templateName = templateName; + return this; + } + + @CheckForNull + public String getOrganization() { + return organization; + } + + public AddUserToTemplateRequest setOrganization(@Nullable String s) { + this.organization = s; + return this; + } + } } diff --git a/server/sonar-server/src/main/java/org/sonar/server/permission/ws/template/ApplyTemplateAction.java b/server/sonar-server/src/main/java/org/sonar/server/permission/ws/template/ApplyTemplateAction.java index 655d3a866f5..7997867e9e7 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/permission/ws/template/ApplyTemplateAction.java +++ b/server/sonar-server/src/main/java/org/sonar/server/permission/ws/template/ApplyTemplateAction.java @@ -31,7 +31,9 @@ import org.sonar.server.permission.PermissionTemplateService; import org.sonar.server.permission.ws.PermissionWsSupport; import org.sonar.server.permission.ws.PermissionsWsAction; import org.sonar.server.user.UserSession; -import org.sonarqube.ws.client.permission.ApplyTemplateRequest; + +import javax.annotation.CheckForNull; +import javax.annotation.Nullable; import static org.sonar.server.permission.PermissionPrivilegeChecker.checkGlobalAdmin; import static org.sonar.server.permission.ws.PermissionsWsParametersBuilder.createProjectParameters; @@ -99,4 +101,61 @@ public class ApplyTemplateAction implements PermissionsWsAction { permissionTemplateService.applyAndCommit(dbSession, template, Collections.singletonList(project)); } } + + private static class ApplyTemplateRequest { + private String projectId; + private String projectKey; + private String templateId; + private String organization; + private String templateName; + + @CheckForNull + public String getProjectId() { + return projectId; + } + + public ApplyTemplateRequest setProjectId(@Nullable String projectId) { + this.projectId = projectId; + return this; + } + + @CheckForNull + public String getProjectKey() { + return projectKey; + } + + public ApplyTemplateRequest setProjectKey(@Nullable String projectKey) { + this.projectKey = projectKey; + return this; + } + + @CheckForNull + public String getTemplateId() { + return templateId; + } + + public ApplyTemplateRequest setTemplateId(@Nullable String templateId) { + this.templateId = templateId; + return this; + } + + @CheckForNull + public String getOrganization() { + return organization; + } + + public ApplyTemplateRequest setOrganization(@Nullable String s) { + this.organization = s; + return this; + } + @CheckForNull + public String getTemplateName() { + return templateName; + } + + public ApplyTemplateRequest setTemplateName(@Nullable String templateName) { + this.templateName = templateName; + return this; + } + } } diff --git a/server/sonar-server/src/main/java/org/sonar/server/permission/ws/template/BulkApplyTemplateAction.java b/server/sonar-server/src/main/java/org/sonar/server/permission/ws/template/BulkApplyTemplateAction.java index e2f82dfc576..413fed5ead1 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/permission/ws/template/BulkApplyTemplateAction.java +++ b/server/sonar-server/src/main/java/org/sonar/server/permission/ws/template/BulkApplyTemplateAction.java @@ -39,8 +39,12 @@ import org.sonar.server.permission.ws.PermissionWsSupport; import org.sonar.server.permission.ws.PermissionsWsAction; import org.sonar.server.project.Visibility; import org.sonar.server.user.UserSession; -import org.sonarqube.ws.client.permission.BulkApplyTemplateRequest; +import javax.annotation.CheckForNull; +import javax.annotation.Nullable; + +import static java.util.Collections.singleton; +import static java.util.Objects.requireNonNull; import static org.sonar.api.utils.DateUtils.parseDateOrDateTime; import static org.sonar.core.util.Protobuf.setNullable; import static org.sonar.server.permission.PermissionPrivilegeChecker.checkGlobalAdmin; @@ -181,4 +185,103 @@ public class BulkApplyTemplateAction implements PermissionsWsAction { return query.build(); } + private static class BulkApplyTemplateRequest { + private String templateId; + private String organization; + private String templateName; + private String query; + private Collection qualifiers = singleton(Qualifiers.PROJECT); + private String visibility; + private String analyzedBefore; + private boolean onProvisionedOnly = false; + private Collection projects; + + @CheckForNull + public String getTemplateId() { + return templateId; + } + + public BulkApplyTemplateRequest setTemplateId(@Nullable String templateId) { + this.templateId = templateId; + return this; + } + + @CheckForNull + public String getOrganization() { + return organization; + } + + public BulkApplyTemplateRequest setOrganization(@Nullable String s) { + this.organization = s; + return this; + } + + @CheckForNull + public String getTemplateName() { + return templateName; + } + + public BulkApplyTemplateRequest setTemplateName(@Nullable String templateName) { + this.templateName = templateName; + return this; + } + + @CheckForNull + public String getQuery() { + return query; + } + + public BulkApplyTemplateRequest setQuery(@Nullable String query) { + this.query = query; + return this; + } + + public Collection getQualifiers() { + return qualifiers; + } + + public BulkApplyTemplateRequest setQualifiers(Collection qualifiers) { + this.qualifiers = requireNonNull(qualifiers); + return this; + } + + @CheckForNull + public String getVisibility() { + return visibility; + } + + public BulkApplyTemplateRequest setVisibility(@Nullable String visibility) { + this.visibility = visibility; + return this; + } + + @CheckForNull + public String getAnalyzedBefore() { + return analyzedBefore; + } + + public BulkApplyTemplateRequest setAnalyzedBefore(@Nullable String analyzedBefore) { + this.analyzedBefore = analyzedBefore; + return this; + } + + public boolean isOnProvisionedOnly() { + return onProvisionedOnly; + } + + public BulkApplyTemplateRequest setOnProvisionedOnly(boolean onProvisionedOnly) { + this.onProvisionedOnly = onProvisionedOnly; + return this; + } + + @CheckForNull + public Collection getProjects() { + return projects; + } + + public BulkApplyTemplateRequest setProjects(@Nullable Collection projects) { + this.projects = projects; + return this; + } + } } diff --git a/server/sonar-server/src/main/java/org/sonar/server/permission/ws/template/CreateTemplateAction.java b/server/sonar-server/src/main/java/org/sonar/server/permission/ws/template/CreateTemplateAction.java index 216cec4e230..0e6f0f70153 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/permission/ws/template/CreateTemplateAction.java +++ b/server/sonar-server/src/main/java/org/sonar/server/permission/ws/template/CreateTemplateAction.java @@ -34,9 +34,12 @@ import org.sonar.server.permission.ws.PermissionsWsAction; import org.sonar.server.user.UserSession; import org.sonarqube.ws.Permissions.CreateTemplateWsResponse; import org.sonarqube.ws.Permissions.PermissionTemplate; -import org.sonarqube.ws.client.permission.CreateTemplateRequest; + +import javax.annotation.CheckForNull; +import javax.annotation.Nullable; import static java.lang.String.format; +import static java.util.Objects.requireNonNull; import static org.sonar.server.permission.PermissionPrivilegeChecker.checkGlobalAdmin; import static org.sonar.server.permission.ws.PermissionRequestValidator.MSG_TEMPLATE_WITH_SAME_NAME; import static org.sonar.server.permission.ws.PermissionRequestValidator.validateProjectPattern; @@ -139,4 +142,50 @@ public class CreateTemplateAction implements PermissionsWsAction { dbSession.commit(); return template; } + + private static class CreateTemplateRequest { + private String description; + private String name; + private String projectKeyPattern; + private String organization; + + @CheckForNull + public String getDescription() { + return description; + } + + public CreateTemplateRequest setDescription(@Nullable String description) { + this.description = description; + return this; + } + + public String getName() { + return name; + } + + public CreateTemplateRequest setName(String name) { + this.name = requireNonNull(name); + return this; + } + + @CheckForNull + public String getProjectKeyPattern() { + return projectKeyPattern; + } + + public CreateTemplateRequest setProjectKeyPattern(@Nullable String projectKeyPattern) { + this.projectKeyPattern = projectKeyPattern; + return this; + } + + @CheckForNull + public String getOrganization() { + return organization; + } + + public CreateTemplateRequest setOrganization(@Nullable String s) { + this.organization = s; + return this; + } + } } diff --git a/server/sonar-server/src/main/java/org/sonar/server/permission/ws/template/DeleteTemplateAction.java b/server/sonar-server/src/main/java/org/sonar/server/permission/ws/template/DeleteTemplateAction.java index 821364c7fe0..ddcc6a46db4 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/permission/ws/template/DeleteTemplateAction.java +++ b/server/sonar-server/src/main/java/org/sonar/server/permission/ws/template/DeleteTemplateAction.java @@ -29,7 +29,9 @@ import org.sonar.db.permission.template.PermissionTemplateDto; import org.sonar.server.permission.ws.PermissionWsSupport; import org.sonar.server.permission.ws.PermissionsWsAction; import org.sonar.server.user.UserSession; -import org.sonarqube.ws.client.permission.DeleteTemplateRequest; + +import javax.annotation.CheckForNull; +import javax.annotation.Nullable; import static org.sonar.server.permission.PermissionPrivilegeChecker.checkGlobalAdmin; import static org.sonar.server.permission.ws.PermissionsWsParametersBuilder.createTemplateParameters; @@ -124,4 +126,39 @@ public class DeleteTemplateAction implements PermissionsWsAction { "It is not possible to delete the default permission template for views")); } + private static class DeleteTemplateRequest { + private String templateId; + private String organization; + private String templateName; + + @CheckForNull + public String getTemplateId() { + return templateId; + } + + public DeleteTemplateRequest setTemplateId(@Nullable String templateId) { + this.templateId = templateId; + return this; + } + + @CheckForNull + public String getOrganization() { + return organization; + } + + public DeleteTemplateRequest setOrganization(@Nullable String s) { + this.organization = s; + return this; + } + + @CheckForNull + public String getTemplateName() { + return templateName; + } + + public DeleteTemplateRequest setTemplateName(@Nullable String templateName) { + this.templateName = templateName; + return this; + } + } } diff --git a/server/sonar-server/src/main/java/org/sonar/server/permission/ws/template/RemoveProjectCreatorFromTemplateAction.java b/server/sonar-server/src/main/java/org/sonar/server/permission/ws/template/RemoveProjectCreatorFromTemplateAction.java index 2ff3728cb0b..111b14d69c9 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/permission/ws/template/RemoveProjectCreatorFromTemplateAction.java +++ b/server/sonar-server/src/main/java/org/sonar/server/permission/ws/template/RemoveProjectCreatorFromTemplateAction.java @@ -31,8 +31,11 @@ import org.sonar.db.permission.template.PermissionTemplateDto; import org.sonar.server.permission.ws.PermissionWsSupport; import org.sonar.server.permission.ws.PermissionsWsAction; import org.sonar.server.user.UserSession; -import org.sonarqube.ws.client.permission.RemoveProjectCreatorFromTemplateRequest; +import javax.annotation.CheckForNull; +import javax.annotation.Nullable; + +import static java.util.Objects.requireNonNull; import static org.sonar.server.permission.PermissionPrivilegeChecker.checkGlobalAdmin; import static org.sonar.server.permission.ws.PermissionRequestValidator.validateProjectPermission; import static org.sonar.server.permission.ws.PermissionsWsParametersBuilder.createProjectPermissionParameter; @@ -104,4 +107,76 @@ public class RemoveProjectCreatorFromTemplateAction implements PermissionsWsActi dbClient.permissionTemplateCharacteristicDao().update(dbSession, targetTemplatePermission); dbSession.commit(); } + + private static class RemoveProjectCreatorFromTemplateRequest { + private final String templateId; + private final String organization; + private final String templateName; + private final String permission; + + private RemoveProjectCreatorFromTemplateRequest(Builder builder) { + this.templateId = builder.templateId; + this.organization = builder.organization; + this.templateName = builder.templateName; + this.permission = requireNonNull(builder.permission); + } + + @CheckForNull + public String getTemplateId() { + return templateId; + } + + @CheckForNull + public String getOrganization() { + return organization; + } + + @CheckForNull + public String getTemplateName() { + return templateName; + } + + public String getPermission() { + return permission; + } + + public static Builder builder() { + return new Builder(); + } + } + + public static class Builder { + private String templateId; + private String organization; + private String templateName; + private String permission; + + private Builder() { + // enforce method constructor + } + + public Builder setTemplateId(@Nullable String templateId) { + this.templateId = templateId; + return this; + } + + public Builder setOrganization(@Nullable String s) { + this.organization = s; + return this; + } + + public Builder setTemplateName(@Nullable String templateName) { + this.templateName = templateName; + return this; + } + + public Builder setPermission(@Nullable String permission) { + this.permission = permission; + return this; + } + + public RemoveProjectCreatorFromTemplateRequest build() { + return new RemoveProjectCreatorFromTemplateRequest(this); + } + } } diff --git a/server/sonar-server/src/main/java/org/sonar/server/permission/ws/template/RemoveUserFromTemplateAction.java b/server/sonar-server/src/main/java/org/sonar/server/permission/ws/template/RemoveUserFromTemplateAction.java index f91d243ae2c..75ad5a2d3e9 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/permission/ws/template/RemoveUserFromTemplateAction.java +++ b/server/sonar-server/src/main/java/org/sonar/server/permission/ws/template/RemoveUserFromTemplateAction.java @@ -29,8 +29,11 @@ import org.sonar.server.permission.UserId; import org.sonar.server.permission.ws.PermissionWsSupport; import org.sonar.server.permission.ws.PermissionsWsAction; import org.sonar.server.user.UserSession; -import org.sonarqube.ws.client.permission.RemoveUserFromTemplateRequest; +import javax.annotation.CheckForNull; +import javax.annotation.Nullable; + +import static java.util.Objects.requireNonNull; import static org.sonar.server.permission.PermissionPrivilegeChecker.checkGlobalAdmin; import static org.sonar.server.permission.ws.PermissionRequestValidator.validateProjectPermission; import static org.sonar.server.permission.ws.PermissionsWsParametersBuilder.createProjectPermissionParameter; @@ -99,4 +102,60 @@ public class RemoveUserFromTemplateAction implements PermissionsWsAction { dbSession.commit(); } } + + private static class RemoveUserFromTemplateRequest { + private String login; + private String permission; + private String templateId; + private String organization; + private String templateName; + + public String getLogin() { + return login; + } + + public RemoveUserFromTemplateRequest setLogin(String login) { + this.login = requireNonNull(login); + return this; + } + + public String getPermission() { + return permission; + } + + public RemoveUserFromTemplateRequest setPermission(String permission) { + this.permission = requireNonNull(permission); + return this; + } + + @CheckForNull + public String getTemplateId() { + return templateId; + } + + public RemoveUserFromTemplateRequest setTemplateId(@Nullable String templateId) { + this.templateId = templateId; + return this; + } + + @CheckForNull + public String getOrganization() { + return organization; + } + + public RemoveUserFromTemplateRequest setOrganization(@Nullable String s) { + this.organization = s; + return this; + } + + @CheckForNull + public String getTemplateName() { + return templateName; + } + + public RemoveUserFromTemplateRequest setTemplateName(@Nullable String templateName) { + this.templateName = templateName; + return this; + } + } } diff --git a/server/sonar-server/src/main/java/org/sonar/server/permission/ws/template/SearchTemplatesAction.java b/server/sonar-server/src/main/java/org/sonar/server/permission/ws/template/SearchTemplatesAction.java index 29e68967dd0..b7568c127e3 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/permission/ws/template/SearchTemplatesAction.java +++ b/server/sonar-server/src/main/java/org/sonar/server/permission/ws/template/SearchTemplatesAction.java @@ -19,7 +19,12 @@ */ package org.sonar.server.permission.ws.template; +import java.util.List; import java.util.Locale; + +import com.google.common.collect.Lists; +import com.google.common.collect.Table; +import com.google.common.collect.TreeBasedTable; import org.sonar.api.i18n.I18n; import org.sonar.api.resources.Qualifiers; import org.sonar.api.server.ws.Request; @@ -29,7 +34,10 @@ import org.sonar.api.server.ws.WebService.Param; import org.sonar.core.permission.ProjectPermissions; import org.sonar.db.DbClient; import org.sonar.db.DbSession; +import org.sonar.db.organization.DefaultTemplates; import org.sonar.db.organization.OrganizationDto; +import org.sonar.db.permission.template.CountByTemplateAndPermissionDto; +import org.sonar.db.permission.template.PermissionTemplateCharacteristicDto; import org.sonar.db.permission.template.PermissionTemplateDto; import org.sonar.server.permission.ws.PermissionWsSupport; import org.sonar.server.permission.ws.PermissionsWsAction; @@ -39,12 +47,16 @@ import org.sonarqube.ws.Permissions.Permission; import org.sonarqube.ws.Permissions.PermissionTemplate; import org.sonarqube.ws.Permissions.SearchTemplatesWsResponse; import org.sonarqube.ws.Permissions.SearchTemplatesWsResponse.TemplateIdQualifier; -import org.sonarqube.ws.client.permission.SearchTemplatesRequest; + +import javax.annotation.CheckForNull; +import javax.annotation.Nullable; import static org.sonar.api.utils.DateUtils.formatDateTime; import static org.sonar.core.util.Protobuf.setNullable; import static org.sonar.server.permission.PermissionPrivilegeChecker.checkGlobalAdmin; import static org.sonar.server.permission.ws.PermissionsWsParametersBuilder.createOrganizationParameter; +import static org.sonar.server.permission.ws.template.SearchTemplatesData.builder; +import static org.sonar.server.ws.WsUtils.checkFoundWithOptional; import static org.sonar.server.ws.WsUtils.writeProtobuf; import static org.sonarqube.ws.client.permission.PermissionsWsParameters.PARAM_ORGANIZATION; @@ -56,14 +68,14 @@ public class SearchTemplatesAction implements PermissionsWsAction { private final UserSession userSession; private final I18n i18n; private final PermissionWsSupport support; - private final SearchTemplatesDataLoader dataLoader; + private final DefaultTemplatesResolver defaultTemplatesResolver; - public SearchTemplatesAction(DbClient dbClient, UserSession userSession, I18n i18n, PermissionWsSupport support, SearchTemplatesDataLoader dataLoader) { + public SearchTemplatesAction(DbClient dbClient, UserSession userSession, I18n i18n, PermissionWsSupport support, DefaultTemplatesResolver defaultTemplatesResolver) { this.dbClient = dbClient; this.userSession = userSession; this.i18n = i18n; this.support = support; - this.dataLoader = dataLoader; + this.defaultTemplatesResolver = defaultTemplatesResolver; } @Override @@ -88,7 +100,7 @@ public class SearchTemplatesAction implements PermissionsWsAction { .setQuery(wsRequest.param(Param.TEXT_QUERY)); checkGlobalAdmin(userSession, request.getOrganizationUuid()); - SearchTemplatesWsResponse searchTemplatesWsResponse = buildResponse(dataLoader.load(dbSession, request)); + SearchTemplatesWsResponse searchTemplatesWsResponse = buildResponse(load(dbSession, request)); writeProtobuf(searchTemplatesWsResponse, wsRequest, wsResponse); } } @@ -164,4 +176,84 @@ public class SearchTemplatesAction implements PermissionsWsAction { private String i18nName(String permissionKey) { return i18n.message(Locale.ENGLISH, PROPERTY_PREFIX + permissionKey, permissionKey); } + + private SearchTemplatesData load(DbSession dbSession, SearchTemplatesRequest request) { + SearchTemplatesData.Builder data = builder(); + List templates = searchTemplates(dbSession, request); + List templateIds = Lists.transform(templates, PermissionTemplateDto::getId); + + DefaultTemplates defaultTemplates = checkFoundWithOptional( + dbClient.organizationDao().getDefaultTemplates(dbSession, request.getOrganizationUuid()), + "No Default templates for organization with uuid '%s'", request.getOrganizationUuid()); + DefaultTemplatesResolver.ResolvedDefaultTemplates resolvedDefaultTemplates = defaultTemplatesResolver.resolve(defaultTemplates); + + data.templates(templates) + .defaultTemplates(resolvedDefaultTemplates) + .userCountByTemplateIdAndPermission(userCountByTemplateIdAndPermission(dbSession, templateIds)) + .groupCountByTemplateIdAndPermission(groupCountByTemplateIdAndPermission(dbSession, templateIds)) + .withProjectCreatorByTemplateIdAndPermission(withProjectCreatorsByTemplateIdAndPermission(dbSession, templateIds)); + + return data.build(); + } + + private List searchTemplates(DbSession dbSession, SearchTemplatesRequest request) { + return dbClient.permissionTemplateDao().selectAll(dbSession, request.getOrganizationUuid(), request.getQuery()); + } + + private Table userCountByTemplateIdAndPermission(DbSession dbSession, List templateIds) { + final Table userCountByTemplateIdAndPermission = TreeBasedTable.create(); + + dbClient.permissionTemplateDao().usersCountByTemplateIdAndPermission(dbSession, templateIds, context -> { + CountByTemplateAndPermissionDto row = context.getResultObject(); + userCountByTemplateIdAndPermission.put(row.getTemplateId(), row.getPermission(), row.getCount()); + }); + + return userCountByTemplateIdAndPermission; + } + + private Table groupCountByTemplateIdAndPermission(DbSession dbSession, List templateIds) { + final Table userCountByTemplateIdAndPermission = TreeBasedTable.create(); + + dbClient.permissionTemplateDao().groupsCountByTemplateIdAndPermission(dbSession, templateIds, context -> { + CountByTemplateAndPermissionDto row = context.getResultObject(); + userCountByTemplateIdAndPermission.put(row.getTemplateId(), row.getPermission(), row.getCount()); + }); + + return userCountByTemplateIdAndPermission; + } + + private Table withProjectCreatorsByTemplateIdAndPermission(DbSession dbSession, List templateIds) { + final Table templatePermissionsByTemplateIdAndPermission = TreeBasedTable.create(); + + List templatePermissions = dbClient.permissionTemplateCharacteristicDao().selectByTemplateIds(dbSession, templateIds); + templatePermissions.stream() + .forEach(templatePermission -> templatePermissionsByTemplateIdAndPermission.put(templatePermission.getTemplateId(), templatePermission.getPermission(), + templatePermission.getWithProjectCreator())); + + return templatePermissionsByTemplateIdAndPermission; + } + + private static class SearchTemplatesRequest { + private String query; + private String organizationUuid; + + @CheckForNull + public String getQuery() { + return query; + } + + public SearchTemplatesRequest setQuery(@Nullable String query) { + this.query = query; + return this; + } + + public String getOrganizationUuid() { + return organizationUuid; + } + + public SearchTemplatesRequest setOrganizationUuid(String s) { + this.organizationUuid = s; + return this; + } + } } diff --git a/server/sonar-server/src/main/java/org/sonar/server/permission/ws/template/SearchTemplatesDataLoader.java b/server/sonar-server/src/main/java/org/sonar/server/permission/ws/template/SearchTemplatesDataLoader.java deleted file mode 100644 index c95aa7f3132..00000000000 --- a/server/sonar-server/src/main/java/org/sonar/server/permission/ws/template/SearchTemplatesDataLoader.java +++ /dev/null @@ -1,102 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2017 SonarSource SA - * mailto:info 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.permission.ws.template; - -import com.google.common.collect.Lists; -import com.google.common.collect.Table; -import com.google.common.collect.TreeBasedTable; -import java.util.List; -import org.sonar.db.DbClient; -import org.sonar.db.DbSession; -import org.sonar.db.organization.DefaultTemplates; -import org.sonar.db.permission.template.CountByTemplateAndPermissionDto; -import org.sonar.db.permission.template.PermissionTemplateCharacteristicDto; -import org.sonar.db.permission.template.PermissionTemplateDto; -import org.sonar.server.permission.ws.template.DefaultTemplatesResolver.ResolvedDefaultTemplates; -import org.sonarqube.ws.client.permission.SearchTemplatesRequest; - -import static org.sonar.server.permission.ws.template.SearchTemplatesData.builder; -import static org.sonar.server.ws.WsUtils.checkFoundWithOptional; - -public class SearchTemplatesDataLoader { - private final DbClient dbClient; - private final DefaultTemplatesResolver defaultTemplatesResolver; - - public SearchTemplatesDataLoader(DbClient dbClient, DefaultTemplatesResolver defaultTemplatesResolver) { - this.dbClient = dbClient; - this.defaultTemplatesResolver = defaultTemplatesResolver; - } - - public SearchTemplatesData load(DbSession dbSession, SearchTemplatesRequest request) { - SearchTemplatesData.Builder data = builder(); - List templates = searchTemplates(dbSession, request); - List templateIds = Lists.transform(templates, PermissionTemplateDto::getId); - - DefaultTemplates defaultTemplates = checkFoundWithOptional( - dbClient.organizationDao().getDefaultTemplates(dbSession, request.getOrganizationUuid()), - "No Default templates for organization with uuid '%s'", request.getOrganizationUuid()); - ResolvedDefaultTemplates resolvedDefaultTemplates = defaultTemplatesResolver.resolve(defaultTemplates); - - data.templates(templates) - .defaultTemplates(resolvedDefaultTemplates) - .userCountByTemplateIdAndPermission(userCountByTemplateIdAndPermission(dbSession, templateIds)) - .groupCountByTemplateIdAndPermission(groupCountByTemplateIdAndPermission(dbSession, templateIds)) - .withProjectCreatorByTemplateIdAndPermission(withProjectCreatorsByTemplateIdAndPermission(dbSession, templateIds)); - - return data.build(); - } - - private List searchTemplates(DbSession dbSession, SearchTemplatesRequest request) { - return dbClient.permissionTemplateDao().selectAll(dbSession, request.getOrganizationUuid(), request.getQuery()); - } - - private Table userCountByTemplateIdAndPermission(DbSession dbSession, List templateIds) { - final Table userCountByTemplateIdAndPermission = TreeBasedTable.create(); - - dbClient.permissionTemplateDao().usersCountByTemplateIdAndPermission(dbSession, templateIds, context -> { - CountByTemplateAndPermissionDto row = context.getResultObject(); - userCountByTemplateIdAndPermission.put(row.getTemplateId(), row.getPermission(), row.getCount()); - }); - - return userCountByTemplateIdAndPermission; - } - - private Table groupCountByTemplateIdAndPermission(DbSession dbSession, List templateIds) { - final Table userCountByTemplateIdAndPermission = TreeBasedTable.create(); - - dbClient.permissionTemplateDao().groupsCountByTemplateIdAndPermission(dbSession, templateIds, context -> { - CountByTemplateAndPermissionDto row = context.getResultObject(); - userCountByTemplateIdAndPermission.put(row.getTemplateId(), row.getPermission(), row.getCount()); - }); - - return userCountByTemplateIdAndPermission; - } - - private Table withProjectCreatorsByTemplateIdAndPermission(DbSession dbSession, List templateIds) { - final Table templatePermissionsByTemplateIdAndPermission = TreeBasedTable.create(); - - List templatePermissions = dbClient.permissionTemplateCharacteristicDao().selectByTemplateIds(dbSession, templateIds); - templatePermissions.stream() - .forEach(templatePermission -> templatePermissionsByTemplateIdAndPermission.put(templatePermission.getTemplateId(), templatePermission.getPermission(), - templatePermission.getWithProjectCreator())); - - return templatePermissionsByTemplateIdAndPermission; - } -} diff --git a/server/sonar-server/src/main/java/org/sonar/server/permission/ws/template/SetDefaultTemplateAction.java b/server/sonar-server/src/main/java/org/sonar/server/permission/ws/template/SetDefaultTemplateAction.java index ea9ed0b4e71..e2c4fe436b3 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/permission/ws/template/SetDefaultTemplateAction.java +++ b/server/sonar-server/src/main/java/org/sonar/server/permission/ws/template/SetDefaultTemplateAction.java @@ -33,7 +33,9 @@ import org.sonar.db.permission.template.PermissionTemplateDto; import org.sonar.server.permission.ws.PermissionWsSupport; import org.sonar.server.permission.ws.PermissionsWsAction; import org.sonar.server.user.UserSession; -import org.sonarqube.ws.client.permission.SetDefaultTemplateRequest; + +import javax.annotation.CheckForNull; +import javax.annotation.Nullable; import static org.sonar.server.permission.PermissionPrivilegeChecker.checkGlobalAdmin; import static org.sonar.server.permission.ws.PermissionRequestValidator.validateQualifier; @@ -121,4 +123,51 @@ public class SetDefaultTemplateAction implements PermissionsWsAction { } organizationDao.setDefaultTemplates(dbSession, organizationUuid, defaultTemplates); } + + private static class SetDefaultTemplateRequest { + private String qualifier; + private String templateId; + private String organization; + private String templateName; + + @CheckForNull + public String getQualifier() { + return qualifier; + } + + public SetDefaultTemplateRequest setQualifier(@Nullable String qualifier) { + this.qualifier = qualifier; + return this; + } + + @CheckForNull + public String getTemplateId() { + return templateId; + } + + public SetDefaultTemplateRequest setTemplateId(@Nullable String templateId) { + this.templateId = templateId; + return this; + } + + @CheckForNull + public String getOrganization() { + return organization; + } + + public SetDefaultTemplateRequest setOrganization(@Nullable String s) { + this.organization = s; + return this; + } + + @CheckForNull + public String getTemplateName() { + return templateName; + } + + public SetDefaultTemplateRequest setTemplateName(@Nullable String templateName) { + this.templateName = templateName; + return this; + } + } } diff --git a/server/sonar-server/src/main/java/org/sonar/server/permission/ws/template/UpdateTemplateAction.java b/server/sonar-server/src/main/java/org/sonar/server/permission/ws/template/UpdateTemplateAction.java index 94f59901b1e..d81067fa176 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/permission/ws/template/UpdateTemplateAction.java +++ b/server/sonar-server/src/main/java/org/sonar/server/permission/ws/template/UpdateTemplateAction.java @@ -20,6 +20,7 @@ package org.sonar.server.permission.ws.template; import java.util.Date; +import javax.annotation.CheckForNull; import javax.annotation.Nullable; import org.sonar.api.server.ws.Request; import org.sonar.api.server.ws.Response; @@ -33,10 +34,10 @@ import org.sonar.server.permission.ws.PermissionsWsAction; import org.sonar.server.user.UserSession; import org.sonarqube.ws.Permissions.PermissionTemplate; import org.sonarqube.ws.Permissions.UpdateTemplateWsResponse; -import org.sonarqube.ws.client.permission.UpdateTemplateRequest; import static com.google.common.base.MoreObjects.firstNonNull; import static java.lang.String.format; +import static java.util.Objects.requireNonNull; import static org.sonar.server.permission.PermissionPrivilegeChecker.checkGlobalAdmin; import static org.sonar.server.permission.ws.PermissionRequestValidator.MSG_TEMPLATE_WITH_SAME_NAME; import static org.sonar.server.permission.ws.PermissionRequestValidator.validateProjectPattern; @@ -149,4 +150,50 @@ public class UpdateTemplateAction implements PermissionsWsAction { checkRequest(permissionTemplateWithSameName == null || permissionTemplateWithSameName.getId() == id, format(MSG_TEMPLATE_WITH_SAME_NAME, name)); } + + private static class UpdateTemplateRequest { + private String id; + private String description; + private String name; + private String projectKeyPattern; + + public String getId() { + return id; + } + + public UpdateTemplateRequest setId(String id) { + this.id = requireNonNull(id); + return this; + } + + @CheckForNull + public String getDescription() { + return description; + } + + public UpdateTemplateRequest setDescription(@Nullable String description) { + this.description = description; + return this; + } + + @CheckForNull + public String getName() { + return name; + } + + public UpdateTemplateRequest setName(@Nullable String name) { + this.name = name; + return this; + } + + @CheckForNull + public String getProjectKeyPattern() { + return projectKeyPattern; + } + + public UpdateTemplateRequest setProjectKeyPattern(@Nullable String projectKeyPattern) { + this.projectKeyPattern = projectKeyPattern; + return this; + } + } } diff --git a/server/sonar-server/src/main/java/org/sonar/server/project/ws/BulkDeleteAction.java b/server/sonar-server/src/main/java/org/sonar/server/project/ws/BulkDeleteAction.java index a220e876149..151ef69393f 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/project/ws/BulkDeleteAction.java +++ b/server/sonar-server/src/main/java/org/sonar/server/project/ws/BulkDeleteAction.java @@ -31,7 +31,6 @@ import org.sonar.db.permission.OrganizationPermission; import org.sonar.server.component.ComponentCleanerService; import org.sonar.server.project.Visibility; import org.sonar.server.user.UserSession; -import org.sonarqube.ws.client.project.SearchRequest; import static org.sonar.api.resources.Qualifiers.APP; import static org.sonar.api.resources.Qualifiers.PROJECT; diff --git a/server/sonar-server/src/main/java/org/sonar/server/project/ws/BulkUpdateKeyAction.java b/server/sonar-server/src/main/java/org/sonar/server/project/ws/BulkUpdateKeyAction.java index d2a8cc844eb..5602de9845a 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/project/ws/BulkUpdateKeyAction.java +++ b/server/sonar-server/src/main/java/org/sonar/server/project/ws/BulkUpdateKeyAction.java @@ -36,8 +36,11 @@ import org.sonar.server.component.ComponentFinder.ParamNames; import org.sonar.server.component.ComponentService; import org.sonar.server.user.UserSession; import org.sonarqube.ws.Projects.BulkUpdateKeyWsResponse; -import org.sonarqube.ws.client.project.BulkUpdateKeyRequest; +import javax.annotation.CheckForNull; +import javax.annotation.Nullable; + +import static com.google.common.base.Preconditions.checkArgument; import static org.sonar.core.util.Uuids.UUID_EXAMPLE_01; import static org.sonar.db.component.ComponentKeyUpdaterDao.checkIsProjectOrModule; import static org.sonar.server.ws.WsUtils.checkRequest; @@ -184,4 +187,89 @@ public class BulkUpdateKeyAction implements ProjectsWsAction { .setDryRun(request.mandatoryParamAsBoolean(PARAM_DRY_RUN)) .build(); } + + private static class BulkUpdateKeyRequest { + private final String id; + private final String key; + private final String from; + private final String to; + private final boolean dryRun; + + public BulkUpdateKeyRequest(Builder builder) { + this.id = builder.id; + this.key = builder.key; + this.from = builder.from; + this.to = builder.to; + this.dryRun = builder.dryRun; + } + + @CheckForNull + public String getId() { + return id; + } + + @CheckForNull + public String getKey() { + return key; + } + + public String getFrom() { + return from; + } + + public String getTo() { + return to; + } + + public boolean isDryRun() { + return dryRun; + } + + public static Builder builder() { + return new Builder(); + } + } + + public static class Builder { + private String id; + private String key; + private String from; + private String to; + private boolean dryRun; + + private Builder() { + // enforce method constructor + } + + public Builder setId(@Nullable String id) { + this.id = id; + return this; + } + + public Builder setKey(@Nullable String key) { + this.key = key; + return this; + } + + public Builder setFrom(String from) { + this.from = from; + return this; + } + + public Builder setTo(String to) { + this.to = to; + return this; + } + + public Builder setDryRun(boolean dryRun) { + this.dryRun = dryRun; + return this; + } + + public BulkUpdateKeyRequest build() { + checkArgument(from != null && !from.isEmpty(), "The string to match must not be empty"); + checkArgument(to != null && !to.isEmpty(), "The string replacement must not be empty"); + return new BulkUpdateKeyRequest(this); + } + } } diff --git a/server/sonar-server/src/main/java/org/sonar/server/project/ws/CreateAction.java b/server/sonar-server/src/main/java/org/sonar/server/project/ws/CreateAction.java index b643a9ab5c8..4a66c029c4a 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/project/ws/CreateAction.java +++ b/server/sonar-server/src/main/java/org/sonar/server/project/ws/CreateAction.java @@ -31,7 +31,9 @@ import org.sonar.server.component.ComponentUpdater; import org.sonar.server.project.Visibility; import org.sonar.server.user.UserSession; import org.sonarqube.ws.Projects.CreateWsResponse; -import org.sonarqube.ws.client.project.CreateRequest; + +import javax.annotation.CheckForNull; +import javax.annotation.Nullable; import static org.sonar.api.resources.Qualifiers.PROJECT; import static org.sonar.core.component.ComponentKeys.MAX_COMPONENT_KEY_LENGTH; @@ -152,4 +154,91 @@ public class CreateAction implements ProjectsWsAction { .build(); } + static class CreateRequest { + + private final String organization; + private final String key; + private final String name; + private final String branch; + @CheckForNull + private final String visibility; + + private CreateRequest(Builder builder) { + this.organization = builder.organization; + this.key = builder.key; + this.name = builder.name; + this.branch = builder.branch; + this.visibility = builder.visibility; + } + + @CheckForNull + public String getOrganization() { + return organization; + } + + @CheckForNull + public String getKey() { + return key; + } + + @CheckForNull + public String getName() { + return name; + } + + @CheckForNull + public String getBranch() { + return branch; + } + + @CheckForNull + public String getVisibility() { + return visibility; + } + + public static Builder builder() { + return new Builder(); + } + } + + static class Builder { + private String organization; + private String key; + private String name; + private String branch; + @CheckForNull + private String visibility; + + private Builder() { + } + + public Builder setOrganization(@Nullable String organization) { + this.organization = organization; + return this; + } + + public Builder setKey(@Nullable String key) { + this.key = key; + return this; + } + + public Builder setName(@Nullable String name) { + this.name = name; + return this; + } + + public Builder setBranch(@Nullable String branch) { + this.branch = branch; + return this; + } + + public Builder setVisibility(@Nullable String visibility) { + this.visibility = visibility; + return this; + } + + public CreateRequest build() { + return new CreateRequest(this); + } + } } diff --git a/server/sonar-server/src/main/java/org/sonar/server/project/ws/ProjectsWsModule.java b/server/sonar-server/src/main/java/org/sonar/server/project/ws/ProjectsWsModule.java index 48ce49927e7..e74a2e7c837 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/project/ws/ProjectsWsModule.java +++ b/server/sonar-server/src/main/java/org/sonar/server/project/ws/ProjectsWsModule.java @@ -36,7 +36,6 @@ public class ProjectsWsModule extends Module { GhostsAction.class, ProvisionedAction.class, SearchMyProjectsAction.class, - SearchMyProjectsDataLoader.class, SearchAction.class, UpdateVisibilityAction.class); } diff --git a/server/sonar-server/src/main/java/org/sonar/server/project/ws/SearchAction.java b/server/sonar-server/src/main/java/org/sonar/server/project/ws/SearchAction.java index 9ef198b33b2..5f38d12164f 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/project/ws/SearchAction.java +++ b/server/sonar-server/src/main/java/org/sonar/server/project/ws/SearchAction.java @@ -40,7 +40,6 @@ import org.sonar.db.permission.OrganizationPermission; import org.sonar.server.project.Visibility; import org.sonar.server.user.UserSession; import org.sonarqube.ws.Projects.SearchWsResponse; -import org.sonarqube.ws.client.project.SearchRequest; import static com.google.common.base.Preconditions.checkArgument; import static org.sonar.api.resources.Qualifiers.APP; diff --git a/server/sonar-server/src/main/java/org/sonar/server/project/ws/SearchMyProjectsAction.java b/server/sonar-server/src/main/java/org/sonar/server/project/ws/SearchMyProjectsAction.java index 95aabe985bd..37867d57e77 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/project/ws/SearchMyProjectsAction.java +++ b/server/sonar-server/src/main/java/org/sonar/server/project/ws/SearchMyProjectsAction.java @@ -19,37 +19,53 @@ */ package org.sonar.server.project.ws; +import java.util.List; import java.util.function.Function; + +import com.google.common.annotations.VisibleForTesting; +import com.google.common.collect.ImmutableSet; +import com.google.common.collect.Lists; +import org.sonar.api.measures.CoreMetrics; +import org.sonar.api.resources.Qualifiers; import org.sonar.api.server.ws.Change; import org.sonar.api.server.ws.Request; import org.sonar.api.server.ws.Response; import org.sonar.api.server.ws.WebService; import org.sonar.api.server.ws.WebService.Param; +import org.sonar.api.web.UserRole; import org.sonar.db.DbClient; import org.sonar.db.DbSession; import org.sonar.db.component.ComponentDto; import org.sonar.db.component.ComponentLinkDto; +import org.sonar.db.component.ComponentQuery; +import org.sonar.db.component.SnapshotDto; +import org.sonar.db.measure.MeasureDto; +import org.sonar.db.measure.MeasureQuery; +import org.sonar.db.metric.MetricDto; import org.sonar.server.user.UserSession; import org.sonarqube.ws.Projects.SearchMyProjectsWsResponse; import org.sonarqube.ws.Projects.SearchMyProjectsWsResponse.Link; import org.sonarqube.ws.Projects.SearchMyProjectsWsResponse.Project; -import org.sonarqube.ws.client.project.SearchMyProjectsRequest; + +import javax.annotation.CheckForNull; +import javax.annotation.Nullable; import static com.google.common.base.Strings.emptyToNull; import static com.google.common.base.Strings.isNullOrEmpty; +import static java.util.Objects.requireNonNull; +import static org.sonar.api.utils.Paging.offset; import static org.sonar.core.util.Protobuf.setNullable; +import static org.sonar.server.project.ws.SearchMyProjectsData.builder; import static org.sonar.server.ws.WsUtils.writeProtobuf; public class SearchMyProjectsAction implements ProjectsWsAction { private static final int MAX_SIZE = 500; private final DbClient dbClient; - private final SearchMyProjectsDataLoader dataLoader; private final UserSession userSession; - public SearchMyProjectsAction(DbClient dbClient, SearchMyProjectsDataLoader dataLoader, UserSession userSession) { + public SearchMyProjectsAction(DbClient dbClient, UserSession userSession) { this.dbClient = dbClient; - this.dataLoader = dataLoader; this.userSession = userSession; } @@ -76,7 +92,7 @@ public class SearchMyProjectsAction implements ProjectsWsAction { checkAuthenticated(); try (DbSession dbSession = dbClient.openSession(false)) { - SearchMyProjectsData data = dataLoader.load(dbSession, request); + SearchMyProjectsData data = load(dbSession, request); return buildResponse(request, data); } } @@ -153,4 +169,99 @@ public class SearchMyProjectsAction implements ProjectsWsAction { return link.build(); } } + + SearchMyProjectsData load(DbSession dbSession, SearchMyProjectsRequest request) { + SearchMyProjectsData.Builder data = builder(); + ProjectsResult searchResult = searchProjects(dbSession, request); + List projects = searchResult.projects; + List projectUuids = Lists.transform(projects, ComponentDto::projectUuid); + List projectLinks = dbClient.componentLinkDao().selectByComponentUuids(dbSession, projectUuids); + List snapshots = dbClient.snapshotDao().selectLastAnalysesByRootComponentUuids(dbSession, projectUuids); + MetricDto gateStatusMetric = dbClient.metricDao().selectOrFailByKey(dbSession, CoreMetrics.ALERT_STATUS_KEY); + MeasureQuery measureQuery = MeasureQuery.builder() + .setProjectUuids(projectUuids) + .setMetricId(gateStatusMetric.getId()) + .build(); + List qualityGates = dbClient.measureDao().selectByQuery(dbSession, measureQuery); + + data.setProjects(projects) + .setProjectLinks(projectLinks) + .setSnapshots(snapshots) + .setQualityGates(qualityGates) + .setTotalNbOfProjects(searchResult.total); + + return data.build(); + } + + @VisibleForTesting + ProjectsResult searchProjects(DbSession dbSession, SearchMyProjectsRequest request) { + int userId = requireNonNull(userSession.getUserId(), "Current user must be authenticated"); + + List componentIds = dbClient.roleDao().selectComponentIdsByPermissionAndUserId(dbSession, UserRole.ADMIN, userId); + ComponentQuery dbQuery = ComponentQuery.builder() + .setQualifiers(Qualifiers.PROJECT) + .setComponentIds(ImmutableSet.copyOf(componentIds)) + .build(); + + return new ProjectsResult( + dbClient.componentDao().selectByQuery(dbSession, dbQuery, offset(request.getPage(), request.getPageSize()), request.getPageSize()), + dbClient.componentDao().countByQuery(dbSession, dbQuery)); + } + + private static class ProjectsResult { + private final List projects; + private final int total; + + private ProjectsResult(List projects, int total) { + this.projects = projects; + this.total = total; + } + } + + private static class SearchMyProjectsRequest { + private final Integer page; + private final Integer pageSize; + + private SearchMyProjectsRequest(Builder builder) { + this.page = builder.page; + this.pageSize = builder.pageSize; + } + + @CheckForNull + public Integer getPage() { + return page; + } + + @CheckForNull + public Integer getPageSize() { + return pageSize; + } + + public static Builder builder() { + return new Builder(); + } + } + + private static class Builder { + private Integer page; + private Integer pageSize; + + private Builder() { + // enforce method constructor + } + + public Builder setPage(@Nullable Integer page) { + this.page = page; + return this; + } + + public Builder setPageSize(@Nullable Integer pageSize) { + this.pageSize = pageSize; + return this; + } + + public SearchMyProjectsRequest build() { + return new SearchMyProjectsRequest(this); + } + } } diff --git a/server/sonar-server/src/main/java/org/sonar/server/project/ws/SearchMyProjectsDataLoader.java b/server/sonar-server/src/main/java/org/sonar/server/project/ws/SearchMyProjectsDataLoader.java deleted file mode 100644 index be0e6630dda..00000000000 --- a/server/sonar-server/src/main/java/org/sonar/server/project/ws/SearchMyProjectsDataLoader.java +++ /dev/null @@ -1,102 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2017 SonarSource SA - * mailto:info 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.project.ws; - -import com.google.common.annotations.VisibleForTesting; -import com.google.common.collect.ImmutableSet; -import com.google.common.collect.Lists; -import java.util.List; -import org.sonar.api.measures.CoreMetrics; -import org.sonar.api.resources.Qualifiers; -import org.sonar.api.web.UserRole; -import org.sonar.db.DbClient; -import org.sonar.db.DbSession; -import org.sonar.db.component.ComponentDto; -import org.sonar.db.component.ComponentLinkDto; -import org.sonar.db.component.ComponentQuery; -import org.sonar.db.component.SnapshotDto; -import org.sonar.db.measure.MeasureDto; -import org.sonar.db.measure.MeasureQuery; -import org.sonar.db.metric.MetricDto; -import org.sonar.server.user.UserSession; -import org.sonarqube.ws.client.project.SearchMyProjectsRequest; - -import static java.util.Objects.requireNonNull; -import static org.sonar.api.utils.Paging.offset; -import static org.sonar.server.project.ws.SearchMyProjectsData.builder; - -public class SearchMyProjectsDataLoader { - private final UserSession userSession; - private final DbClient dbClient; - - public SearchMyProjectsDataLoader(UserSession userSession, DbClient dbClient) { - this.userSession = userSession; - this.dbClient = dbClient; - } - - SearchMyProjectsData load(DbSession dbSession, SearchMyProjectsRequest request) { - SearchMyProjectsData.Builder data = builder(); - ProjectsResult searchResult = searchProjects(dbSession, request); - List projects = searchResult.projects; - List projectUuids = Lists.transform(projects, ComponentDto::projectUuid); - List projectLinks = dbClient.componentLinkDao().selectByComponentUuids(dbSession, projectUuids); - List snapshots = dbClient.snapshotDao().selectLastAnalysesByRootComponentUuids(dbSession, projectUuids); - MetricDto gateStatusMetric = dbClient.metricDao().selectOrFailByKey(dbSession, CoreMetrics.ALERT_STATUS_KEY); - MeasureQuery measureQuery = MeasureQuery.builder() - .setProjectUuids(projectUuids) - .setMetricId(gateStatusMetric.getId()) - .build(); - List qualityGates = dbClient.measureDao().selectByQuery(dbSession, measureQuery); - - data.setProjects(projects) - .setProjectLinks(projectLinks) - .setSnapshots(snapshots) - .setQualityGates(qualityGates) - .setTotalNbOfProjects(searchResult.total); - - return data.build(); - } - - @VisibleForTesting - ProjectsResult searchProjects(DbSession dbSession, SearchMyProjectsRequest request) { - int userId = requireNonNull(userSession.getUserId(), "Current user must be authenticated"); - - List componentIds = dbClient.roleDao().selectComponentIdsByPermissionAndUserId(dbSession, UserRole.ADMIN, userId); - ComponentQuery dbQuery = ComponentQuery.builder() - .setQualifiers(Qualifiers.PROJECT) - .setComponentIds(ImmutableSet.copyOf(componentIds)) - .build(); - - return new ProjectsResult( - dbClient.componentDao().selectByQuery(dbSession, dbQuery, offset(request.getPage(), request.getPageSize()), request.getPageSize()), - dbClient.componentDao().countByQuery(dbSession, dbQuery)); - } - - private static class ProjectsResult { - private final List projects; - private final int total; - - private ProjectsResult(List projects, int total) { - this.projects = projects; - this.total = total; - } - } - -} diff --git a/server/sonar-server/src/main/java/org/sonar/server/project/ws/SearchRequest.java b/server/sonar-server/src/main/java/org/sonar/server/project/ws/SearchRequest.java new file mode 100644 index 00000000000..a725c86b253 --- /dev/null +++ b/server/sonar-server/src/main/java/org/sonar/server/project/ws/SearchRequest.java @@ -0,0 +1,179 @@ +/* + * SonarQube + * Copyright (C) 2009-2017 SonarSource SA + * mailto:info 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.project.ws; + +import java.util.List; +import javax.annotation.CheckForNull; +import javax.annotation.Nullable; +import org.sonar.api.resources.Qualifiers; + +import static com.google.common.base.Preconditions.checkArgument; +import static java.util.Collections.singletonList; +import static java.util.Objects.requireNonNull; +import static org.sonarqube.ws.client.project.ProjectsWsParameters.MAX_PAGE_SIZE; + +class SearchRequest { + + private final String organization; + private final String query; + private final List qualifiers; + private final String visibility; + private final Integer page; + private final Integer pageSize; + private final String analyzedBefore; + private final boolean onProvisionedOnly; + private final List projects; + private final List projectIds; + + public SearchRequest(Builder builder) { + this.organization = builder.organization; + this.query = builder.query; + this.qualifiers = builder.qualifiers; + this.visibility = builder.visibility; + this.page = builder.page; + this.pageSize = builder.pageSize; + this.analyzedBefore = builder.analyzedBefore; + this.onProvisionedOnly = builder.onProvisionedOnly; + this.projects = builder.projects; + this.projectIds = builder.projectIds; + } + + @CheckForNull + public String getOrganization() { + return organization; + } + + public List getQualifiers() { + return qualifiers; + } + + @CheckForNull + public Integer getPage() { + return page; + } + + @CheckForNull + public Integer getPageSize() { + return pageSize; + } + + @CheckForNull + public String getQuery() { + return query; + } + + @CheckForNull + public String getVisibility() { + return visibility; + } + + @CheckForNull + public String getAnalyzedBefore() { + return analyzedBefore; + } + + public boolean isOnProvisionedOnly() { + return onProvisionedOnly; + } + + @CheckForNull + public List getProjects() { + return projects; + } + + @CheckForNull + public List getProjectIds() { + return projectIds; + } + + public static Builder builder() { + return new Builder(); + } + + public static class Builder { + private String organization; + private List qualifiers = singletonList(Qualifiers.PROJECT); + private Integer page; + private Integer pageSize; + private String query; + private String visibility; + private String analyzedBefore; + private boolean onProvisionedOnly = false; + private List projects; + private List projectIds; + + public Builder setOrganization(@Nullable String organization) { + this.organization = organization; + return this; + } + + public Builder setQualifiers(List qualifiers) { + this.qualifiers = requireNonNull(qualifiers, "Qualifiers cannot be null"); + return this; + } + + public Builder setPage(@Nullable Integer page) { + this.page = page; + return this; + } + + public Builder setPageSize(@Nullable Integer pageSize) { + this.pageSize = pageSize; + return this; + } + + public Builder setQuery(@Nullable String query) { + this.query = query; + return this; + } + + public Builder setVisibility(@Nullable String visibility) { + this.visibility = visibility; + return this; + } + + public Builder setAnalyzedBefore(@Nullable String lastAnalysisBefore) { + this.analyzedBefore = lastAnalysisBefore; + return this; + } + + public Builder setOnProvisionedOnly(boolean onProvisionedOnly) { + this.onProvisionedOnly = onProvisionedOnly; + return this; + } + + public Builder setProjects(@Nullable List projects) { + this.projects = projects; + return this; + } + + public Builder setProjectIds(@Nullable List projectIds) { + this.projectIds = projectIds; + return this; + } + + public SearchRequest build() { + checkArgument(projects==null || !projects.isEmpty(), "Project key list must not be empty"); + checkArgument(projectIds==null || !projectIds.isEmpty(), "Project id list must not be empty"); + checkArgument(pageSize == null || pageSize <= MAX_PAGE_SIZE, "Page size must not be greater than %s", MAX_PAGE_SIZE); + return new SearchRequest(this); + } + } +} diff --git a/server/sonar-server/src/main/java/org/sonar/server/project/ws/UpdateKeyAction.java b/server/sonar-server/src/main/java/org/sonar/server/project/ws/UpdateKeyAction.java index 49e79a01085..92d636dd97c 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/project/ws/UpdateKeyAction.java +++ b/server/sonar-server/src/main/java/org/sonar/server/project/ws/UpdateKeyAction.java @@ -30,8 +30,11 @@ import org.sonar.db.component.ComponentDto; import org.sonar.server.component.ComponentFinder; import org.sonar.server.component.ComponentFinder.ParamNames; import org.sonar.server.component.ComponentService; -import org.sonarqube.ws.client.project.UpdateKeyRequest; +import javax.annotation.CheckForNull; +import javax.annotation.Nullable; + +import static com.google.common.base.Preconditions.checkArgument; import static org.sonar.core.util.Uuids.UUID_EXAMPLE_01; import static org.sonarqube.ws.client.project.ProjectsWsParameters.ACTION_UPDATE_KEY; import static org.sonarqube.ws.client.project.ProjectsWsParameters.PARAM_FROM; @@ -111,4 +114,64 @@ public class UpdateKeyAction implements ProjectsWsAction { .setNewKey(request.mandatoryParam(PARAM_TO)) .build(); } + + private static class UpdateKeyRequest { + private final String id; + private final String key; + private final String newKey; + + public UpdateKeyRequest(Builder builder) { + this.id = builder.id; + this.key = builder.key; + this.newKey = builder.newKey; + } + + @CheckForNull + public String getId() { + return id; + } + + @CheckForNull + public String getKey() { + return key; + } + + public String getNewKey() { + return newKey; + } + + public static Builder builder() { + return new Builder(); + } + } + + private static class Builder { + private String id; + private String key; + private String newKey; + + private Builder() { + // enforce method constructor + } + + public Builder setId(@Nullable String id) { + this.id = id; + return this; + } + + public Builder setKey(@Nullable String key) { + this.key = key; + return this; + } + + public Builder setNewKey(String newKey) { + this.newKey = newKey; + return this; + } + + public UpdateKeyRequest build() { + checkArgument(newKey != null && !newKey.isEmpty(), "The new key must not be empty"); + return new UpdateKeyRequest(this); + } + } } diff --git a/server/sonar-server/src/main/java/org/sonar/server/projectanalysis/ws/CreateEventAction.java b/server/sonar-server/src/main/java/org/sonar/server/projectanalysis/ws/CreateEventAction.java index 0fd7c05bfa6..2128a1f32ec 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/projectanalysis/ws/CreateEventAction.java +++ b/server/sonar-server/src/main/java/org/sonar/server/projectanalysis/ws/CreateEventAction.java @@ -42,7 +42,6 @@ import org.sonar.server.exceptions.NotFoundException; import org.sonar.server.user.UserSession; import org.sonarqube.ws.ProjectAnalyses.CreateEventResponse; import org.sonarqube.ws.ProjectAnalyses.Event; -import org.sonarqube.ws.client.projectanalysis.CreateEventRequest; import org.sonarqube.ws.client.projectanalysis.EventCategory; import static com.google.common.base.Preconditions.checkArgument; @@ -219,4 +218,65 @@ public class CreateEventAction implements ProjectAnalysesWsAction { throw new IllegalStateException("Event category not handled: " + request.getCategory()); } } + + private static class CreateEventRequest { + private final String analysis; + private final EventCategory category; + private final String name; + + private CreateEventRequest(Builder builder) { + analysis = builder.analysis; + category = builder.category; + name = builder.name; + } + + public String getAnalysis() { + return analysis; + } + + public EventCategory getCategory() { + return category; + } + + public String getName() { + return name; + } + + public static Builder builder() { + return new Builder(); + } + } + + private static class Builder { + private String analysis; + private EventCategory category = EventCategory.OTHER; + private String name; + + private Builder() { + // enforce static factory method + } + + public Builder setAnalysis(String analysis) { + this.analysis = analysis; + return this; + } + + public Builder setCategory(EventCategory category) { + this.category = category; + return this; + } + + public Builder setName(String name) { + this.name = name; + return this; + } + + public CreateEventRequest build() { + checkArgument(analysis != null, "Analysis key is required"); + checkArgument(category != null, "Category is required"); + checkArgument(name != null, "Name is required"); + + return new CreateEventRequest(this); + } + } } diff --git a/server/sonar-server/src/main/java/org/sonar/server/projectanalysis/ws/DeleteAction.java b/server/sonar-server/src/main/java/org/sonar/server/projectanalysis/ws/DeleteAction.java index 713572437be..e7a66a3dc5b 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/projectanalysis/ws/DeleteAction.java +++ b/server/sonar-server/src/main/java/org/sonar/server/projectanalysis/ws/DeleteAction.java @@ -19,9 +19,6 @@ */ package org.sonar.server.projectanalysis.ws; -import java.util.function.Consumer; -import java.util.function.Function; -import java.util.stream.Stream; import org.sonar.api.server.ws.Request; import org.sonar.api.server.ws.Response; import org.sonar.api.server.ws.WebService; @@ -32,7 +29,6 @@ import org.sonar.db.DbSession; import org.sonar.db.component.SnapshotDto; import org.sonar.server.exceptions.NotFoundException; import org.sonar.server.user.UserSession; -import org.sonarqube.ws.client.projectanalysis.DeleteRequest; import static com.google.common.base.Preconditions.checkArgument; import static java.lang.String.format; @@ -69,33 +65,21 @@ public class DeleteAction implements ProjectAnalysesWsAction { @Override public void handle(Request request, Response response) throws Exception { - Stream.of(request) - .map(toWsRequest()) - .forEach(deleteAnalysis()); + String analysisParam = request.mandatoryParam(PARAM_ANALYSIS); - response.noContent(); - - } - - private static Function toWsRequest() { - return request -> new DeleteRequest(request.mandatoryParam(PARAM_ANALYSIS)); - } - - private Consumer deleteAnalysis() { - return request -> { - try (DbSession dbSession = dbClient.openSession(false)) { - SnapshotDto analysis = dbClient.snapshotDao().selectByUuid(dbSession, request.getAnalysis()) - .orElseThrow(() -> analysisNotFoundException(request.getAnalysis())); - if (STATUS_UNPROCESSED.equals(analysis.getStatus())) { - throw analysisNotFoundException(request.getAnalysis()); - } - userSession.checkComponentUuidPermission(UserRole.ADMIN, analysis.getComponentUuid()); - checkArgument(!analysis.getLast(), "The last analysis '%s' cannot be deleted", request.getAnalysis()); - analysis.setStatus(STATUS_UNPROCESSED); - dbClient.snapshotDao().update(dbSession, analysis); - dbSession.commit(); + try (DbSession dbSession = dbClient.openSession(false)) { + SnapshotDto analysis = dbClient.snapshotDao().selectByUuid(dbSession, analysisParam) + .orElseThrow(() -> analysisNotFoundException(analysisParam)); + if (STATUS_UNPROCESSED.equals(analysis.getStatus())) { + throw analysisNotFoundException(analysisParam); } - }; + userSession.checkComponentUuidPermission(UserRole.ADMIN, analysis.getComponentUuid()); + checkArgument(!analysis.getLast(), "The last analysis '%s' cannot be deleted", analysisParam); + analysis.setStatus(STATUS_UNPROCESSED); + dbClient.snapshotDao().update(dbSession, analysis); + dbSession.commit(); + } + response.noContent(); } private static NotFoundException analysisNotFoundException(String analysis) { diff --git a/server/sonar-server/src/main/java/org/sonar/server/projectanalysis/ws/DeleteEventAction.java b/server/sonar-server/src/main/java/org/sonar/server/projectanalysis/ws/DeleteEventAction.java index efd3a2b312c..087ff98fc1e 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/projectanalysis/ws/DeleteEventAction.java +++ b/server/sonar-server/src/main/java/org/sonar/server/projectanalysis/ws/DeleteEventAction.java @@ -32,7 +32,6 @@ import org.sonar.db.component.SnapshotDto; import org.sonar.db.event.EventDto; import org.sonar.server.exceptions.NotFoundException; import org.sonar.server.user.UserSession; -import org.sonarqube.ws.client.projectanalysis.DeleteEventRequest; import static com.google.common.base.Preconditions.checkArgument; import static java.lang.String.format; @@ -73,18 +72,14 @@ public class DeleteEventAction implements ProjectAnalysesWsAction { @Override public void handle(Request request, Response response) throws Exception { - DeleteEventRequest deleteEventRequest = toDeleteEventRequest(request); - doHandle(deleteEventRequest); - response.noContent(); - } - - private void doHandle(DeleteEventRequest request) { + String eventP = request.mandatoryParam(PARAM_EVENT); try (DbSession dbSession = dbClient.openSession(false)) { - Stream.of(getEvent(dbSession, request.getEvent())) - .peek(checkPermissions()) - .peek(checkModifiable()) - .forEach(event -> deleteEvent(dbSession, event)); + Stream.of(getEvent(dbSession, eventP)) + .peek(checkPermissions()) + .peek(checkModifiable()) + .forEach(event -> deleteEvent(dbSession, event)); } + response.noContent(); } private EventDto getEvent(DbSession dbSession, String event) { @@ -107,8 +102,4 @@ public class DeleteEventAction implements ProjectAnalysesWsAction { private Consumer checkPermissions() { return event -> userSession.checkComponentUuidPermission(UserRole.ADMIN, event.getComponentUuid()); } - - private static DeleteEventRequest toDeleteEventRequest(Request httpRequest) { - return new DeleteEventRequest(httpRequest.mandatoryParam(PARAM_EVENT)); - } } diff --git a/server/sonar-server/src/main/java/org/sonar/server/projectanalysis/ws/SearchAction.java b/server/sonar-server/src/main/java/org/sonar/server/projectanalysis/ws/SearchAction.java index 8729785236d..20438481202 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/projectanalysis/ws/SearchAction.java +++ b/server/sonar-server/src/main/java/org/sonar/server/projectanalysis/ws/SearchAction.java @@ -41,7 +41,6 @@ import org.sonar.server.user.UserSession; import org.sonar.server.ws.KeyExamples; import org.sonarqube.ws.ProjectAnalyses; import org.sonarqube.ws.client.projectanalysis.EventCategory; -import org.sonarqube.ws.client.projectanalysis.SearchRequest; import static com.google.common.base.Preconditions.checkArgument; import static org.sonar.api.utils.DateUtils.parseEndingDateOrDateTime; @@ -57,7 +56,7 @@ import static org.sonarqube.ws.client.projectanalysis.ProjectAnalysesWsParameter import static org.sonarqube.ws.client.projectanalysis.ProjectAnalysesWsParameters.PARAM_FROM; import static org.sonarqube.ws.client.projectanalysis.ProjectAnalysesWsParameters.PARAM_PROJECT; import static org.sonarqube.ws.client.projectanalysis.ProjectAnalysesWsParameters.PARAM_TO; -import static org.sonarqube.ws.client.projectanalysis.SearchRequest.DEFAULT_PAGE_SIZE; +import static org.sonar.server.projectanalysis.ws.SearchRequest.DEFAULT_PAGE_SIZE; public class SearchAction implements ProjectAnalysesWsAction { private static final Set ALLOWED_QUALIFIERS = ImmutableSet.of(Qualifiers.PROJECT, Qualifiers.APP, Qualifiers.VIEW); diff --git a/server/sonar-server/src/main/java/org/sonar/server/projectanalysis/ws/SearchData.java b/server/sonar-server/src/main/java/org/sonar/server/projectanalysis/ws/SearchData.java index 233a59ca2c9..5d198211356 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/projectanalysis/ws/SearchData.java +++ b/server/sonar-server/src/main/java/org/sonar/server/projectanalysis/ws/SearchData.java @@ -29,7 +29,6 @@ import org.sonar.db.DbSession; import org.sonar.db.component.ComponentDto; import org.sonar.db.component.SnapshotDto; import org.sonar.db.event.EventDto; -import org.sonarqube.ws.client.projectanalysis.SearchRequest; import static java.util.Objects.requireNonNull; diff --git a/server/sonar-server/src/main/java/org/sonar/server/projectanalysis/ws/SearchRequest.java b/server/sonar-server/src/main/java/org/sonar/server/projectanalysis/ws/SearchRequest.java new file mode 100644 index 00000000000..d55ce270bdc --- /dev/null +++ b/server/sonar-server/src/main/java/org/sonar/server/projectanalysis/ws/SearchRequest.java @@ -0,0 +1,142 @@ +/* + * SonarQube + * Copyright (C) 2009-2017 SonarSource SA + * mailto:info 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.projectanalysis.ws; + +import org.sonarqube.ws.client.projectanalysis.EventCategory; + +import javax.annotation.CheckForNull; +import javax.annotation.Nullable; + +import static com.google.common.base.Preconditions.checkArgument; +import static java.util.Objects.requireNonNull; + +class SearchRequest { + static final int DEFAULT_PAGE_SIZE = 100; + static final int MAX_SIZE = 500; + + private final String project; + private final String branch; + private final EventCategory category; + private final int page; + private final int pageSize; + private final String from; + private final String to; + + private SearchRequest(Builder builder) { + this.project = builder.project; + this.branch= builder.branch; + this.category = builder.category; + this.page = builder.page; + this.pageSize = builder.pageSize; + this.from = builder.from; + this.to = builder.to; + } + + public String getProject() { + return project; + } + + @CheckForNull + public String getBranch() { + return branch; + } + + @CheckForNull + public EventCategory getCategory() { + return category; + } + + public int getPage() { + return page; + } + + public int getPageSize() { + return pageSize; + } + + @CheckForNull + public String getFrom() { + return from; + } + + @CheckForNull + public String getTo() { + return to; + } + + public static Builder builder() { + return new Builder(); + } + + public static class Builder { + private String project; + private String branch; + private EventCategory category; + private int page = 1; + private int pageSize = DEFAULT_PAGE_SIZE; + private String from; + private String to; + + private Builder() { + // enforce static factory method + } + + public Builder setProject(String project) { + this.project = project; + return this; + } + + public Builder setBranch(@Nullable String branch) { + this.branch = branch; + return this; + } + + public Builder setCategory(@Nullable EventCategory category) { + this.category = category; + return this; + } + + public Builder setPage(int page) { + this.page = page; + return this; + } + + public Builder setPageSize(int pageSize) { + this.pageSize = pageSize; + return this; + } + + public Builder setFrom(@Nullable String from) { + this.from = from; + return this; + } + + public Builder setTo(@Nullable String to) { + this.to = to; + return this; + } + + public SearchRequest build() { + requireNonNull(project, "Project is required"); + checkArgument(pageSize <= MAX_SIZE, "Page size must be lower than or equal to " + MAX_SIZE); + return new SearchRequest(this); + } + } +} diff --git a/server/sonar-server/src/main/java/org/sonar/server/projectanalysis/ws/UpdateEventAction.java b/server/sonar-server/src/main/java/org/sonar/server/projectanalysis/ws/UpdateEventAction.java index e065f851b42..45164cb841e 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/projectanalysis/ws/UpdateEventAction.java +++ b/server/sonar-server/src/main/java/org/sonar/server/projectanalysis/ws/UpdateEventAction.java @@ -38,10 +38,12 @@ import org.sonar.server.user.UserSession; import org.sonarqube.ws.ProjectAnalyses.Event; import org.sonarqube.ws.ProjectAnalyses.UpdateEventResponse; import org.sonarqube.ws.client.projectanalysis.EventCategory; -import org.sonarqube.ws.client.projectanalysis.UpdateEventRequest; + +import javax.annotation.CheckForNull; import static com.google.common.base.Preconditions.checkArgument; import static java.lang.String.format; +import static java.util.Objects.requireNonNull; import static org.apache.commons.lang.StringUtils.isNotBlank; import static org.sonar.core.util.Protobuf.setNullable; import static org.sonar.server.projectanalysis.ws.EventValidator.checkModifiable; @@ -189,4 +191,23 @@ public class UpdateEventAction implements ProjectAnalysesWsAction { request.mandatoryParam(PARAM_EVENT), request.param(PARAM_NAME)); } + + private static class UpdateEventRequest { + private final String event; + private final String name; + + public UpdateEventRequest(String event, String name) { + this.event = requireNonNull(event, "Event key is required"); + this.name = requireNonNull(name, "Name is required"); + } + + public String getEvent() { + return event; + } + + @CheckForNull + public String getName() { + return name; + } + } } diff --git a/server/sonar-server/src/main/java/org/sonar/server/projectlink/ws/CreateAction.java b/server/sonar-server/src/main/java/org/sonar/server/projectlink/ws/CreateAction.java index 11f7a31009f..cc174920fd9 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/projectlink/ws/CreateAction.java +++ b/server/sonar-server/src/main/java/org/sonar/server/projectlink/ws/CreateAction.java @@ -31,7 +31,6 @@ import org.sonar.server.component.ComponentFinder; import org.sonar.server.user.UserSession; import org.sonarqube.ws.ProjectLinks; import org.sonarqube.ws.ProjectLinks.CreateWsResponse; -import org.sonarqube.ws.client.projectlinks.CreateRequest; import static org.sonar.core.util.Slug.slugify; import static org.sonar.core.util.Uuids.UUID_EXAMPLE_01; @@ -147,4 +146,48 @@ public class CreateAction implements ProjectLinksWsAction { String slugified = slugify(name); return slugified.substring(0, Math.min(slugified.length(), LINK_TYPE_MAX_LENGTH)); } + + private static class CreateRequest { + + private String name; + private String projectId; + private String projectKey; + private String url; + + public CreateRequest setName(String name) { + this.name = name; + return this; + } + + public String getName() { + return name; + } + + public CreateRequest setProjectId(String projectId) { + this.projectId = projectId; + return this; + } + + public String getProjectId() { + return projectId; + } + + public CreateRequest setProjectKey(String projectKey) { + this.projectKey = projectKey; + return this; + } + + public String getProjectKey() { + return projectKey; + } + + public CreateRequest setUrl(String url) { + this.url = url; + return this; + } + + public String getUrl() { + return url; + } + } } diff --git a/server/sonar-server/src/main/java/org/sonar/server/projectlink/ws/DeleteAction.java b/server/sonar-server/src/main/java/org/sonar/server/projectlink/ws/DeleteAction.java index 243aac6040c..05c90cb6530 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/projectlink/ws/DeleteAction.java +++ b/server/sonar-server/src/main/java/org/sonar/server/projectlink/ws/DeleteAction.java @@ -28,7 +28,6 @@ import org.sonar.db.DbSession; import org.sonar.db.component.ComponentLinkDto; import org.sonar.server.user.UserSession; import org.sonar.server.ws.WsUtils; -import org.sonarqube.ws.client.projectlinks.DeleteRequest; import static org.sonar.db.component.ComponentLinkDto.PROVIDED_TYPES; import static org.sonar.server.projectlink.ws.ProjectLinksWsParameters.ACTION_DELETE; @@ -61,19 +60,13 @@ public class DeleteAction implements ProjectLinksWsAction { @Override public void handle(Request request, Response response) throws Exception { - DeleteRequest deleteWsRequest = toDeleteWsRequest(request); - doHandle(deleteWsRequest); + doHandle(request.mandatoryParam(PARAM_ID)); response.noContent(); } - private static DeleteRequest toDeleteWsRequest(Request request) { - return new DeleteRequest() - .setId(request.mandatoryParam(PARAM_ID)); - } - - private void doHandle(DeleteRequest request) { + private void doHandle(String idParam) { try (DbSession dbSession = dbClient.openSession(false)) { - long id = Long.parseLong(request.getId()); + long id = Long.parseLong(idParam); ComponentLinkDto link = dbClient.componentLinkDao().selectById(dbSession, id); link = WsUtils.checkFound(link, "Link with id '%s' not found", id); diff --git a/server/sonar-server/src/main/java/org/sonar/server/projectlink/ws/SearchAction.java b/server/sonar-server/src/main/java/org/sonar/server/projectlink/ws/SearchAction.java index 0410d9c3f01..2a0a5644f77 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/projectlink/ws/SearchAction.java +++ b/server/sonar-server/src/main/java/org/sonar/server/projectlink/ws/SearchAction.java @@ -33,7 +33,6 @@ import org.sonar.server.component.ComponentFinder; import org.sonar.server.user.UserSession; import org.sonarqube.ws.ProjectLinks.Link; import org.sonarqube.ws.ProjectLinks.SearchWsResponse; -import org.sonarqube.ws.client.projectlinks.SearchRequest; import static org.sonar.core.util.Protobuf.setNullable; import static org.sonar.core.util.Uuids.UUID_EXAMPLE_01; @@ -134,4 +133,28 @@ public class SearchAction implements ProjectLinksWsAction { .setProjectId(request.param(PARAM_PROJECT_ID)) .setProjectKey(request.param(PARAM_PROJECT_KEY)); } + + private static class SearchRequest { + + private String projectId; + private String projectKey; + + public SearchRequest setProjectId(String projectId) { + this.projectId = projectId; + return this; + } + + public String getProjectId() { + return projectId; + } + + public SearchRequest setProjectKey(String projectKey) { + this.projectKey = projectKey; + return this; + } + + public String getProjectKey() { + return projectKey; + } + } } diff --git a/server/sonar-server/src/main/java/org/sonar/server/qualityprofile/ws/CreateAction.java b/server/sonar-server/src/main/java/org/sonar/server/qualityprofile/ws/CreateAction.java index c179b663a56..35f87da20b4 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/qualityprofile/ws/CreateAction.java +++ b/server/sonar-server/src/main/java/org/sonar/server/qualityprofile/ws/CreateAction.java @@ -37,8 +37,10 @@ import org.sonar.server.qualityprofile.QProfileResult; import org.sonar.server.qualityprofile.index.ActiveRuleIndexer; import org.sonar.server.user.UserSession; import org.sonarqube.ws.Qualityprofiles.CreateWsResponse; -import org.sonarqube.ws.client.qualityprofile.CreateRequest; +import javax.annotation.Nullable; + +import static com.google.common.base.Preconditions.checkArgument; import static org.sonar.db.permission.OrganizationPermission.ADMINISTER_QUALITY_PROFILES; import static org.sonar.server.qualityprofile.ws.QProfileWsSupport.createOrganizationParam; import static org.sonar.server.util.LanguageParamUtils.getLanguageKeys; @@ -139,7 +141,7 @@ public class CreateAction implements QProfileWsAction { } private static CreateRequest toRequest(Request request, OrganizationDto organization) { - CreateRequest.Builder builder = CreateRequest.builder() + Builder builder = CreateRequest.builder() .setOrganizationKey(organization.getKey()) .setLanguage(request.mandatoryParam(PARAM_LANGUAGE)) .setName(request.mandatoryParam(PARAM_NAME)); @@ -168,4 +170,65 @@ public class CreateAction implements QProfileWsAction { private static String getBackupParamName(String importerKey) { return String.format(PARAM_BACKUP_FORMAT, importerKey); } + + private static class CreateRequest { + + private final String name; + private final String language; + private final String organizationKey; + + private CreateRequest(Builder builder) { + this.name = builder.name; + this.language = builder.language; + this.organizationKey = builder.organizationKey; + } + + public String getLanguage() { + return language; + } + + public String getName() { + return name; + } + + public String getOrganizationKey() { + return organizationKey; + } + + public static Builder builder() { + return new Builder(); + } + } + + private static class Builder { + private String language; + private String name; + private String organizationKey; + + private Builder() { + // enforce factory method use + } + + public Builder setLanguage(@Nullable String language) { + this.language = language; + return this; + } + + public Builder setName(@Nullable String profileName) { + this.name = profileName; + return this; + } + + public Builder setOrganizationKey(@Nullable String organizationKey) { + this.organizationKey = organizationKey; + return this; + } + + public CreateRequest build() { + checkArgument(language != null && !language.isEmpty(), "Language is mandatory and must not be empty."); + checkArgument(name != null && !name.isEmpty(), "Profile name is mandatory and must not be empty."); + checkArgument(organizationKey == null || !organizationKey.isEmpty(), "Organization key may be either null or not empty. Empty organization key is invalid."); + return new CreateRequest(this); + } + } } diff --git a/server/sonar-server/src/main/java/org/sonar/server/qualityprofile/ws/SearchAction.java b/server/sonar-server/src/main/java/org/sonar/server/qualityprofile/ws/SearchAction.java index 892096abe07..cd83b7f721f 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/qualityprofile/ws/SearchAction.java +++ b/server/sonar-server/src/main/java/org/sonar/server/qualityprofile/ws/SearchAction.java @@ -52,7 +52,6 @@ import org.sonar.server.user.UserSession; import org.sonar.server.util.LanguageParamUtils; import org.sonarqube.ws.Qualityprofiles.SearchWsResponse; import org.sonarqube.ws.Qualityprofiles.SearchWsResponse.QualityProfile; -import org.sonarqube.ws.client.qualityprofile.SearchRequest; import static com.google.common.base.Preconditions.checkState; import static java.lang.String.format; @@ -319,4 +318,59 @@ public class SearchAction implements QProfileWsAction { } } + private static class SearchRequest { + private String organizationKey; + private boolean defaults; + private String language; + private String qualityProfile; + private String projectKey; + + public String getOrganizationKey() { + return organizationKey; + } + + public SearchRequest setOrganizationKey(String organizationKey) { + this.organizationKey = organizationKey; + return this; + } + + public boolean getDefaults() { + return defaults; + } + + public SearchRequest setDefaults(boolean defaults) { + this.defaults = defaults; + return this; + } + + @CheckForNull + public String getLanguage() { + return language; + } + + public SearchRequest setLanguage(@Nullable String language) { + this.language = language; + return this; + } + + @CheckForNull + public String getQualityProfile() { + return qualityProfile; + } + + public SearchRequest setQualityProfile(@Nullable String qualityProfile) { + this.qualityProfile = qualityProfile; + return this; + } + + @CheckForNull + public String getProjectKey() { + return projectKey; + } + + public SearchRequest setProjectKey(@Nullable String projectKey) { + this.projectKey = projectKey; + return this; + } + } } diff --git a/server/sonar-server/src/main/java/org/sonar/server/qualityprofile/ws/SearchGroupsAction.java b/server/sonar-server/src/main/java/org/sonar/server/qualityprofile/ws/SearchGroupsAction.java index 32fb6e74e6b..dc2349efa8e 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/qualityprofile/ws/SearchGroupsAction.java +++ b/server/sonar-server/src/main/java/org/sonar/server/qualityprofile/ws/SearchGroupsAction.java @@ -38,7 +38,6 @@ import org.sonar.db.qualityprofile.SearchGroupsQuery; import org.sonar.db.user.GroupDto; import org.sonarqube.ws.Common; import org.sonarqube.ws.Qualityprofiles; -import org.sonarqube.ws.client.qualityprofile.SearchUsersRequest; import static org.sonar.api.server.ws.WebService.Param.PAGE; import static org.sonar.api.server.ws.WebService.Param.PAGE_SIZE; diff --git a/server/sonar-server/src/main/java/org/sonar/server/qualityprofile/ws/SearchUsersAction.java b/server/sonar-server/src/main/java/org/sonar/server/qualityprofile/ws/SearchUsersAction.java index c0ab8247722..66dc3f4a1f6 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/qualityprofile/ws/SearchUsersAction.java +++ b/server/sonar-server/src/main/java/org/sonar/server/qualityprofile/ws/SearchUsersAction.java @@ -39,7 +39,6 @@ import org.sonar.db.user.UserDto; import org.sonar.server.issue.ws.AvatarResolver; import org.sonarqube.ws.Common; import org.sonarqube.ws.Qualityprofiles.SearchUsersResponse; -import org.sonarqube.ws.client.qualityprofile.SearchUsersRequest; import static com.google.common.base.Strings.emptyToNull; import static org.sonar.api.server.ws.WebService.Param.PAGE; diff --git a/server/sonar-server/src/main/java/org/sonar/server/qualityprofile/ws/SearchUsersRequest.java b/server/sonar-server/src/main/java/org/sonar/server/qualityprofile/ws/SearchUsersRequest.java new file mode 100644 index 00000000000..c606c887672 --- /dev/null +++ b/server/sonar-server/src/main/java/org/sonar/server/qualityprofile/ws/SearchUsersRequest.java @@ -0,0 +1,127 @@ +/* + * SonarQube + * Copyright (C) 2009-2017 SonarSource SA + * mailto:info 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.qualityprofile.ws; + +import javax.annotation.CheckForNull; +import javax.annotation.Nullable; + +class SearchUsersRequest { + + private String organization; + private String qualityProfile; + private String language; + private String selected; + private String query; + private Integer page; + private Integer pageSize; + + private SearchUsersRequest(Builder builder) { + this.organization = builder.organization; + this.qualityProfile = builder.qualityProfile; + this.language = builder.language; + this.selected = builder.selected; + this.query = builder.query; + this.page = builder.page; + this.pageSize = builder.pageSize; + } + + @CheckForNull + public String getOrganization() { + return organization; + } + + public String getQualityProfile() { + return qualityProfile; + } + + public String getLanguage() { + return language; + } + + @CheckForNull + public String getQuery() { + return query; + } + + public String getSelected() { + return selected; + } + + public Integer getPage() { + return page; + } + + public Integer getPageSize() { + return pageSize; + } + + public static Builder builder() { + return new Builder(); + } + + public static class Builder { + private String organization; + private String qualityProfile; + private String language; + private String selected; + private String query; + private Integer page; + private Integer pageSize; + + public Builder setOrganization(@Nullable String organization) { + this.organization = organization; + return this; + } + + public Builder setQualityProfile(String qualityProfile) { + this.qualityProfile = qualityProfile; + return this; + } + + public Builder setLanguage(String language) { + this.language = language; + return this; + } + + public Builder setSelected(String selected) { + this.selected = selected; + return this; + } + + public Builder setQuery(@Nullable String query) { + this.query = query; + return this; + } + + public Builder setPage(Integer page) { + this.page = page; + return this; + } + + public Builder setPageSize(Integer pageSize) { + this.pageSize = pageSize; + return this; + } + + public SearchUsersRequest build() { + return new SearchUsersRequest(this); + } + } +} diff --git a/server/sonar-server/src/main/java/org/sonar/server/rule/ws/SearchAction.java b/server/sonar-server/src/main/java/org/sonar/server/rule/ws/SearchAction.java index 348f30b5652..a4486cbbd9f 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/rule/ws/SearchAction.java +++ b/server/sonar-server/src/main/java/org/sonar/server/rule/ws/SearchAction.java @@ -58,7 +58,6 @@ import org.sonar.server.rule.index.RuleIndexDefinition; import org.sonar.server.rule.index.RuleQuery; import org.sonarqube.ws.Common; import org.sonarqube.ws.Rules.SearchResponse; -import org.sonarqube.ws.client.rules.SearchRequest; import static java.lang.String.format; import static org.sonar.api.server.ws.WebService.Param.ASCENDING; @@ -448,27 +447,18 @@ public class SearchAction implements RulesWsAction { } private static SearchRequest toSearchWsRequest(Request request) { + request.mandatoryParamAsBoolean(ASCENDING); return new SearchRequest() - .setActivation("" + request.paramAsBoolean(PARAM_ACTIVATION)) .setActiveSeverities(request.paramAsStrings(PARAM_ACTIVE_SEVERITIES)) - .setAsc("" + request.mandatoryParamAsBoolean(ASCENDING)) - .setAvailableSince(request.param(PARAM_AVAILABLE_SINCE)) .setF(request.paramAsStrings(FIELDS)) .setFacets(request.paramAsStrings(FACETS)) - .setInheritance(request.paramAsStrings(PARAM_INHERITANCE)) - .setIsTemplate("" + request.paramAsBoolean(PARAM_IS_TEMPLATE)) .setLanguages(request.paramAsStrings(PARAM_LANGUAGES)) .setP("" + request.mandatoryParamAsInt(PAGE)) .setPs("" + request.mandatoryParamAsInt(PAGE_SIZE)) - .setQ(request.param(TEXT_QUERY)) - .setQprofile(request.param(PARAM_QPROFILE)) .setRepositories(request.paramAsStrings(PARAM_REPOSITORIES)) - .setRuleKey(request.param(PARAM_RULE_KEY)) - .setS(request.param(SORT)) .setSeverities(request.paramAsStrings(PARAM_SEVERITIES)) .setStatuses(request.paramAsStrings(PARAM_STATUSES)) .setTags(request.paramAsStrings(PARAM_TAGS)) - .setTemplateKey(request.param(PARAM_TEMPLATE_KEY)) .setTypes(request.paramAsStrings(PARAM_TYPES)); } @@ -539,4 +529,117 @@ public class SearchAction implements RulesWsAction { } } + private static class SearchRequest { + + private List activeSeverities; + private List f; + private List facets; + private List languages; + private String p; + private String ps; + private List repositories; + private List severities; + private List statuses; + private List tags; + private List types; + + private SearchRequest setActiveSeverities(List activeSeverities) { + this.activeSeverities = activeSeverities; + return this; + } + + private List getActiveSeverities() { + return activeSeverities; + } + + private SearchRequest setF(List f) { + this.f = f; + return this; + } + + private List getF() { + return f; + } + + private SearchRequest setFacets(List facets) { + this.facets = facets; + return this; + } + + private List getFacets() { + return facets; + } + + private SearchRequest setLanguages(List languages) { + this.languages = languages; + return this; + } + + private List getLanguages() { + return languages; + } + + private SearchRequest setP(String p) { + this.p = p; + return this; + } + + private String getP() { + return p; + } + + private SearchRequest setPs(String ps) { + this.ps = ps; + return this; + } + + private String getPs() { + return ps; + } + + private SearchRequest setRepositories(List repositories) { + this.repositories = repositories; + return this; + } + + private List getRepositories() { + return repositories; + } + + private SearchRequest setSeverities(List severities) { + this.severities = severities; + return this; + } + + private List getSeverities() { + return severities; + } + + private SearchRequest setStatuses(List statuses) { + this.statuses = statuses; + return this; + } + + private List getStatuses() { + return statuses; + } + + private SearchRequest setTags(List tags) { + this.tags = tags; + return this; + } + + private List getTags() { + return tags; + } + + private SearchRequest setTypes(List types) { + this.types = types; + return this; + } + + private List getTypes() { + return types; + } + } } diff --git a/server/sonar-server/src/main/java/org/sonar/server/setting/ws/ListDefinitionsAction.java b/server/sonar-server/src/main/java/org/sonar/server/setting/ws/ListDefinitionsAction.java index 35d78cc6c27..9e91afe3cd3 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/setting/ws/ListDefinitionsAction.java +++ b/server/sonar-server/src/main/java/org/sonar/server/setting/ws/ListDefinitionsAction.java @@ -34,7 +34,6 @@ import org.sonar.server.component.ComponentFinder; import org.sonar.server.user.UserSession; import org.sonarqube.ws.Settings; import org.sonarqube.ws.Settings.ListDefinitionsWsResponse; -import org.sonarqube.ws.client.settings.ListDefinitionsRequest; import static com.google.common.base.Strings.emptyToNull; import static java.util.Comparator.comparing; @@ -161,4 +160,27 @@ public class ListDefinitionsAction implements SettingsWsAction { .build(); } + private static class ListDefinitionsRequest { + + private String branch; + private String component; + + public ListDefinitionsRequest setBranch(String branch) { + this.branch = branch; + return this; + } + + public String getBranch() { + return branch; + } + + public ListDefinitionsRequest setComponent(String component) { + this.component = component; + return this; + } + + public String getComponent() { + return component; + } + } } diff --git a/server/sonar-server/src/main/java/org/sonar/server/setting/ws/ResetAction.java b/server/sonar-server/src/main/java/org/sonar/server/setting/ws/ResetAction.java index 27f89a4fc85..b8854c487a2 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/setting/ws/ResetAction.java +++ b/server/sonar-server/src/main/java/org/sonar/server/setting/ws/ResetAction.java @@ -36,7 +36,6 @@ import org.sonar.db.component.ComponentDto; import org.sonar.server.component.ComponentFinder; import org.sonar.server.setting.ws.SettingValidations.SettingData; import org.sonar.server.user.UserSession; -import org.sonarqube.ws.client.settings.ResetRequest; import static java.util.Collections.emptyList; import static org.sonar.server.ws.KeyExamples.KEY_BRANCH_EXAMPLE_001; @@ -146,4 +145,38 @@ public class ResetAction implements SettingsWsAction { userSession.checkIsSystemAdministrator(); } } + + private static class ResetRequest { + + private String branch; + private String component; + private List keys; + + public ResetRequest setBranch(String branch) { + this.branch = branch; + return this; + } + + public String getBranch() { + return branch; + } + + public ResetRequest setComponent(String component) { + this.component = component; + return this; + } + + public String getComponent() { + return component; + } + + public ResetRequest setKeys(List keys) { + this.keys = keys; + return this; + } + + public List getKeys() { + return keys; + } + } } diff --git a/server/sonar-server/src/main/java/org/sonar/server/setting/ws/SetAction.java b/server/sonar-server/src/main/java/org/sonar/server/setting/ws/SetAction.java index 8eb5a128a42..b652a39dbcc 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/setting/ws/SetAction.java +++ b/server/sonar-server/src/main/java/org/sonar/server/setting/ws/SetAction.java @@ -54,10 +54,10 @@ import org.sonar.server.exceptions.BadRequestException; import org.sonar.server.platform.SettingsChangeNotifier; import org.sonar.server.setting.ws.SettingValidations.SettingData; import org.sonar.server.user.UserSession; -import org.sonarqube.ws.client.settings.SetRequest; import static com.google.common.base.Preconditions.checkArgument; import static java.lang.String.format; +import static org.apache.commons.lang.StringUtils.isNotEmpty; import static org.sonar.server.ws.KeyExamples.KEY_PROJECT_EXAMPLE_001; import static org.sonar.server.ws.WsUtils.checkRequest; import static org.sonar.server.setting.ws.SettingsWsParameters.PARAM_BRANCH; @@ -282,13 +282,17 @@ public class SetAction implements SettingsWsAction { } private static SetRequest toWsRequest(Request request) { - return new SetRequest() + SetRequest set = new SetRequest() .setKey(request.mandatoryParam(PARAM_KEY)) .setValue(request.param(PARAM_VALUE)) .setValues(request.multiParam(PARAM_VALUES)) .setFieldValues(request.multiParam(PARAM_FIELD_VALUES)) .setComponent(request.param(PARAM_COMPONENT)) .setBranch(request.param(PARAM_BRANCH)); + checkArgument(isNotEmpty(set.getKey()), "Setting key is mandatory and must not be empty"); + checkArgument(set.getValues() != null, "Setting values must not be null"); + checkArgument(set.getFieldValues() != null, "Setting fields values must not be null"); + return set; } private static Map readOneFieldValues(String json, String key) { @@ -338,4 +342,68 @@ public class SetAction implements SettingsWsAction { this.value = value; } } + + private static class SetRequest { + + private String branch; + private String component; + private List fieldValues; + private String key; + private String value; + private List values; + + public SetRequest setBranch(String branch) { + this.branch = branch; + return this; + } + + public String getBranch() { + return branch; + } + + public SetRequest setComponent(String component) { + this.component = component; + return this; + } + + public String getComponent() { + return component; + } + + public SetRequest setFieldValues(List fieldValues) { + this.fieldValues = fieldValues; + return this; + } + + public List getFieldValues() { + return fieldValues; + } + + public SetRequest setKey(String key) { + this.key = key; + return this; + } + + public String getKey() { + return key; + } + + public SetRequest setValue(String value) { + this.value = value; + return this; + } + + public String getValue() { + return value; + } + + public SetRequest setValues(List values) { + this.values = values; + return this; + } + + public List getValues() { + return values; + } + } } diff --git a/server/sonar-server/src/main/java/org/sonar/server/setting/ws/ValuesAction.java b/server/sonar-server/src/main/java/org/sonar/server/setting/ws/ValuesAction.java index 5c50aeed676..e98c1df0462 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/setting/ws/ValuesAction.java +++ b/server/sonar-server/src/main/java/org/sonar/server/setting/ws/ValuesAction.java @@ -42,7 +42,6 @@ import org.sonar.server.component.ComponentFinder; import org.sonar.server.user.UserSession; import org.sonarqube.ws.Settings; import org.sonarqube.ws.Settings.ValuesWsResponse; -import org.sonarqube.ws.client.settings.ValuesRequest; import static java.lang.String.format; import static java.util.stream.Stream.concat; @@ -139,7 +138,7 @@ public class ValuesAction implements SettingsWsAction { private Set loadKeys(ValuesRequest valuesRequest) { List keys = valuesRequest.getKeys(); - return keys.isEmpty() ? concat(propertyDefinitions.getAll().stream().map(PropertyDefinition::key), SERVER_SETTING_KEYS.stream()).collect(Collectors.toSet()) + return keys == null || keys.isEmpty() ? concat(propertyDefinitions.getAll().stream().map(PropertyDefinition::key), SERVER_SETTING_KEYS.stream()).collect(Collectors.toSet()) : ImmutableSet.copyOf(keys); } @@ -290,4 +289,37 @@ public class ValuesAction implements SettingsWsAction { } } + private static class ValuesRequest { + + private String branch; + private String component; + private List keys; + + public ValuesRequest setBranch(String branch) { + this.branch = branch; + return this; + } + + public String getBranch() { + return branch; + } + + public ValuesRequest setComponent(String component) { + this.component = component; + return this; + } + + public String getComponent() { + return component; + } + + public ValuesRequest setKeys(List keys) { + this.keys = keys; + return this; + } + + public List getKeys() { + return keys; + } + } } diff --git a/server/sonar-server/src/main/java/org/sonar/server/user/ws/CreateAction.java b/server/sonar-server/src/main/java/org/sonar/server/user/ws/CreateAction.java index df3409fd416..626d03fe998 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/user/ws/CreateAction.java +++ b/server/sonar-server/src/main/java/org/sonar/server/user/ws/CreateAction.java @@ -33,9 +33,14 @@ import org.sonar.server.user.NewUser; import org.sonar.server.user.UserSession; import org.sonar.server.user.UserUpdater; import org.sonarqube.ws.Users.CreateWsResponse; -import org.sonarqube.ws.client.user.CreateRequest; +import javax.annotation.CheckForNull; +import javax.annotation.Nullable; + +import static com.google.common.base.Preconditions.checkArgument; import static com.google.common.base.Strings.emptyToNull; +import static com.google.common.base.Strings.isNullOrEmpty; +import static java.util.Collections.emptyList; import static org.sonar.core.util.Protobuf.setNullable; import static org.sonar.server.user.ExternalIdentity.SQ_AUTHORITY; import static org.sonar.server.user.UserUpdater.EMAIL_MAX_LENGTH; @@ -167,4 +172,104 @@ public class CreateAction implements UsersWsAction { List oldScmAccounts = request.paramAsStrings(PARAM_SCM_ACCOUNTS); return oldScmAccounts != null ? oldScmAccounts : Collections.emptyList(); } + + static class CreateRequest { + + private final String login; + private final String password; + private final String name; + private final String email; + private final List scmAccounts; + private final boolean local; + + private CreateRequest(Builder builder) { + this.login = builder.login; + this.password = builder.password; + this.name = builder.name; + this.email = builder.email; + this.scmAccounts = builder.scmAccounts; + this.local = builder.local; + } + + public String getLogin() { + return login; + } + + @CheckForNull + public String getPassword() { + return password; + } + + public String getName() { + return name; + } + + @CheckForNull + public String getEmail() { + return email; + } + + public List getScmAccounts() { + return scmAccounts; + } + + public boolean isLocal() { + return local; + } + + public static Builder builder() { + return new Builder(); + } + } + + static class Builder { + private String login; + private String password; + private String name; + private String email; + private List scmAccounts = emptyList(); + private boolean local = true; + + private Builder() { + // enforce factory method use + } + + public Builder setLogin(String login) { + this.login = login; + return this; + } + + public Builder setPassword(@Nullable String password) { + this.password = password; + return this; + } + + public Builder setName(String name) { + this.name = name; + return this; + } + + public Builder setEmail(@Nullable String email) { + this.email = email; + return this; + } + + public Builder setScmAccounts(List scmAccounts) { + this.scmAccounts = scmAccounts; + return this; + } + + public Builder setLocal(boolean local) { + this.local = local; + return this; + } + + public CreateRequest build() { + checkArgument(!isNullOrEmpty(login), "Login is mandatory and must not be empty"); + checkArgument(!isNullOrEmpty(name), "Name is mandatory and must not be empty"); + checkArgument(!local || !isNullOrEmpty(password), "Password is mandatory and must not be empty"); + checkArgument(local || isNullOrEmpty(password), "Password should only be set on local user"); + return new CreateRequest(this); + } + } } diff --git a/server/sonar-server/src/main/java/org/sonar/server/user/ws/GroupsAction.java b/server/sonar-server/src/main/java/org/sonar/server/user/ws/GroupsAction.java index e12438d042d..944d5385951 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/user/ws/GroupsAction.java +++ b/server/sonar-server/src/main/java/org/sonar/server/user/ws/GroupsAction.java @@ -21,6 +21,7 @@ package org.sonar.server.user.ws; import java.util.List; import java.util.Optional; +import javax.annotation.CheckForNull; import javax.annotation.Nullable; import org.sonar.api.server.ws.Change; import org.sonar.api.server.ws.Request; @@ -43,9 +44,9 @@ import org.sonar.server.user.UserSession; import org.sonar.server.usergroups.DefaultGroupFinder; import org.sonarqube.ws.Users.GroupsWsResponse; import org.sonarqube.ws.Users.GroupsWsResponse.Group; -import org.sonarqube.ws.client.user.GroupsRequest; import static com.google.common.base.Preconditions.checkArgument; +import static com.google.common.base.Strings.isNullOrEmpty; import static org.sonar.api.server.ws.WebService.Param.PAGE; import static org.sonar.api.server.ws.WebService.Param.PAGE_SIZE; import static org.sonar.api.server.ws.WebService.Param.SELECTED; @@ -179,4 +180,103 @@ public class GroupsAction implements UsersWsAction { return groupBuilder.build(); } + private static class GroupsRequest { + + private final String login; + private final String organization; + private final String query; + private final String selected; + private final Integer page; + private final Integer pageSize; + + private GroupsRequest(Builder builder) { + this.login = builder.login; + this.organization = builder.organization; + this.query = builder.query; + this.selected = builder.selected; + this.page = builder.page; + this.pageSize = builder.pageSize; + } + + public String getLogin() { + return login; + } + + @CheckForNull + public String getOrganization() { + return organization; + } + + @CheckForNull + public String getQuery() { + return query; + } + + @CheckForNull + public String getSelected() { + return selected; + } + + @CheckForNull + public Integer getPage() { + return page; + } + + @CheckForNull + public Integer getPageSize() { + return pageSize; + } + + public static Builder builder() { + return new Builder(); + } + } + + private static class Builder { + private String login; + private String organization; + private String query; + private String selected; + private Integer page; + private Integer pageSize; + + private Builder() { + // enforce factory method use + } + + public Builder setLogin(String login) { + this.login = login; + return this; + } + + public Builder setOrganization(@Nullable String organization) { + this.organization = organization; + return this; + } + + public Builder setQuery(@Nullable String query) { + this.query = query; + return this; + } + + public Builder setSelected(@Nullable String selected) { + this.selected = selected; + return this; + } + + public Builder setPage(@Nullable Integer page) { + this.page = page; + return this; + } + + public Builder setPageSize(@Nullable Integer pageSize) { + this.pageSize = pageSize; + return this; + } + + public GroupsRequest build() { + checkArgument(!isNullOrEmpty(login), "Login is mandatory and must not be empty"); + return new GroupsRequest(this); + } + } } diff --git a/server/sonar-server/src/main/java/org/sonar/server/user/ws/SearchAction.java b/server/sonar-server/src/main/java/org/sonar/server/user/ws/SearchAction.java index f10ba7f7378..58e0233aa29 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/user/ws/SearchAction.java +++ b/server/sonar-server/src/main/java/org/sonar/server/user/ws/SearchAction.java @@ -20,10 +20,13 @@ package org.sonar.server.user.ws; import com.google.common.collect.Multimap; + +import java.util.ArrayList; import java.util.Collection; import java.util.List; import java.util.Map; import java.util.function.Function; +import javax.annotation.CheckForNull; import javax.annotation.Nullable; import org.sonar.api.server.ws.Change; import org.sonar.api.server.ws.Request; @@ -42,7 +45,6 @@ import org.sonar.server.user.index.UserIndex; import org.sonar.server.user.index.UserQuery; import org.sonarqube.ws.Users; import org.sonarqube.ws.Users.SearchWsResponse; -import org.sonarqube.ws.client.user.SearchRequest; import static com.google.common.base.MoreObjects.firstNonNull; import static com.google.common.base.Preconditions.checkArgument; @@ -188,4 +190,76 @@ public class SearchAction implements UsersWsAction { .build(); } + private static class SearchRequest { + + private final Integer page; + private final Integer pageSize; + private final String query; + private final List possibleFields; + + private SearchRequest(Builder builder) { + this.page = builder.page; + this.pageSize = builder.pageSize; + this.query = builder.query; + this.possibleFields = builder.additionalFields; + } + + @CheckForNull + public Integer getPage() { + return page; + } + + @CheckForNull + public Integer getPageSize() { + return pageSize; + } + + @CheckForNull + public String getQuery() { + return query; + } + + public List getPossibleFields() { + return possibleFields; + } + + public static Builder builder() { + return new Builder(); + } + } + + private static class Builder { + private Integer page; + private Integer pageSize; + private String query; + private List additionalFields = new ArrayList<>(); + + private Builder() { + // enforce factory method use + } + + public Builder setPage(@Nullable Integer page) { + this.page = page; + return this; + } + + public Builder setPageSize(@Nullable Integer pageSize) { + this.pageSize = pageSize; + return this; + } + + public Builder setQuery(@Nullable String query) { + this.query = query; + return this; + } + + public Builder setPossibleFields(List possibleFields) { + this.additionalFields = possibleFields; + return this; + } + + public SearchRequest build() { + return new SearchRequest(this); + } + } } diff --git a/server/sonar-server/src/main/java/org/sonar/server/user/ws/UpdateAction.java b/server/sonar-server/src/main/java/org/sonar/server/user/ws/UpdateAction.java index bfe70c52004..5bf910b169f 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/user/ws/UpdateAction.java +++ b/server/sonar-server/src/main/java/org/sonar/server/user/ws/UpdateAction.java @@ -34,9 +34,14 @@ import org.sonar.db.user.UserDto; import org.sonar.server.user.UpdateUser; import org.sonar.server.user.UserSession; import org.sonar.server.user.UserUpdater; -import org.sonarqube.ws.client.user.UpdateRequest; +import javax.annotation.CheckForNull; +import javax.annotation.Nullable; + +import static com.google.common.base.Preconditions.checkArgument; import static com.google.common.base.Strings.emptyToNull; +import static com.google.common.base.Strings.isNullOrEmpty; +import static java.util.Collections.emptyList; import static java.util.Collections.singletonList; import static org.sonar.server.user.UserUpdater.EMAIL_MAX_LENGTH; import static org.sonar.server.user.UserUpdater.LOGIN_MAX_LENGTH; @@ -155,4 +160,77 @@ public class UpdateAction implements UsersWsAction { List oldScmAccounts = request.paramAsStrings(PARAM_SCM_ACCOUNTS); return oldScmAccounts != null ? oldScmAccounts : new ArrayList<>(); } + + private static class UpdateRequest { + + private final String login; + private final String name; + private final String email; + private final List scmAccounts; + + private UpdateRequest(Builder builder) { + this.login = builder.login; + this.name = builder.name; + this.email = builder.email; + this.scmAccounts = builder.scmAccounts; + } + + public String getLogin() { + return login; + } + + @CheckForNull + public String getName() { + return name; + } + + @CheckForNull + public String getEmail() { + return email; + } + + public List getScmAccounts() { + return scmAccounts; + } + + public static Builder builder() { + return new Builder(); + } + } + + private static class Builder { + private String login; + private String name; + private String email; + private List scmAccounts = emptyList(); + + private Builder() { + // enforce factory method use + } + + public Builder setLogin(String login) { + this.login = login; + return this; + } + + public Builder setName(@Nullable String name) { + this.name = name; + return this; + } + + public Builder setEmail(@Nullable String email) { + this.email = email; + return this; + } + + public Builder setScmAccounts(List scmAccounts) { + this.scmAccounts = scmAccounts; + return this; + } + + public UpdateRequest build() { + checkArgument(!isNullOrEmpty(login), "Login is mandatory and must not be empty"); + return new UpdateRequest(this); + } + } } diff --git a/server/sonar-server/src/main/java/org/sonar/server/usertoken/ws/GenerateAction.java b/server/sonar-server/src/main/java/org/sonar/server/usertoken/ws/GenerateAction.java index 02973e250cb..1a980db0856 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/usertoken/ws/GenerateAction.java +++ b/server/sonar-server/src/main/java/org/sonar/server/usertoken/ws/GenerateAction.java @@ -33,7 +33,6 @@ import org.sonar.server.user.UserSession; import org.sonar.server.usertoken.TokenGenerator; import org.sonarqube.ws.UserTokens; import org.sonarqube.ws.UserTokens.GenerateWsResponse; -import org.sonarqube.ws.client.usertokens.GenerateRequest; import static java.net.HttpURLConnection.HTTP_INTERNAL_ERROR; import static org.sonar.server.user.AbstractUserSession.insufficientPrivilegesException; @@ -155,4 +154,28 @@ public class GenerateAction implements UserTokensWsAction { .setToken(token) .build(); } + + private static class GenerateRequest { + + private String login; + private String name; + + public GenerateRequest setLogin(String login) { + this.login = login; + return this; + } + + public String getLogin() { + return login; + } + + public GenerateRequest setName(String name) { + this.name = name; + return this; + } + + public String getName() { + return name; + } + } } diff --git a/server/sonar-server/src/main/java/org/sonar/server/usertoken/ws/RevokeAction.java b/server/sonar-server/src/main/java/org/sonar/server/usertoken/ws/RevokeAction.java index fe828f6b411..c73673ada17 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/usertoken/ws/RevokeAction.java +++ b/server/sonar-server/src/main/java/org/sonar/server/usertoken/ws/RevokeAction.java @@ -25,7 +25,6 @@ import org.sonar.api.server.ws.WebService; import org.sonar.db.DbClient; import org.sonar.db.DbSession; import org.sonar.server.user.UserSession; -import org.sonarqube.ws.client.usertokens.RevokeRequest; import static org.sonar.server.usertoken.ws.UserTokensWsParameters.ACTION_REVOKE; import static org.sonar.server.usertoken.ws.UserTokensWsParameters.PARAM_LOGIN; @@ -61,26 +60,18 @@ public class RevokeAction implements UserTokensWsAction { @Override public void handle(Request request, Response response) throws Exception { - doHandle(toRevokeRequest(request)); - response.noContent(); - } + String login = request.param(PARAM_LOGIN); + if (login == null) { + login = userSession.getLogin(); + } + String name = request.mandatoryParam(PARAM_NAME); - private void doHandle(RevokeRequest request) { - TokenPermissionsValidator.validate(userSession, request.getLogin()); + TokenPermissionsValidator.validate(userSession, login); try (DbSession dbSession = dbClient.openSession(false)) { - dbClient.userTokenDao().deleteByLoginAndName(dbSession, request.getLogin(), request.getName()); + dbClient.userTokenDao().deleteByLoginAndName(dbSession, login, name); dbSession.commit(); } - } - - private RevokeRequest toRevokeRequest(Request request) { - RevokeRequest RevokeRequest = new RevokeRequest() - .setLogin(request.param(PARAM_LOGIN)) - .setName(request.mandatoryParam(PARAM_NAME)); - if (RevokeRequest.getLogin() == null) { - RevokeRequest.setLogin(userSession.getLogin()); - } - return RevokeRequest; + response.noContent(); } } diff --git a/server/sonar-server/src/main/java/org/sonar/server/usertoken/ws/SearchAction.java b/server/sonar-server/src/main/java/org/sonar/server/usertoken/ws/SearchAction.java index e946788bfae..a2472b49432 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/usertoken/ws/SearchAction.java +++ b/server/sonar-server/src/main/java/org/sonar/server/usertoken/ws/SearchAction.java @@ -29,7 +29,6 @@ import org.sonar.db.DbSession; import org.sonar.db.user.UserTokenDto; import org.sonar.server.user.UserSession; import org.sonarqube.ws.UserTokens.SearchWsResponse; -import org.sonarqube.ws.client.usertokens.SearchRequest; import static org.sonar.api.utils.DateUtils.formatDateTime; import static org.sonar.server.ws.WsUtils.checkFound; @@ -63,29 +62,24 @@ public class SearchAction implements UserTokensWsAction { @Override public void handle(Request request, Response response) throws Exception { - SearchWsResponse searchWsResponse = doHandle(toSearchRequest(request)); + String login = request.param(PARAM_LOGIN); + if (login == null) { + login = userSession.getLogin(); + } + SearchWsResponse searchWsResponse = doHandle(login); writeProtobuf(searchWsResponse, request, response); } - private SearchWsResponse doHandle(SearchRequest request) { - TokenPermissionsValidator.validate(userSession, request.getLogin()); + private SearchWsResponse doHandle(String login) { + TokenPermissionsValidator.validate(userSession, login); try (DbSession dbSession = dbClient.openSession(false)) { - String login = request.getLogin(); checkLoginExists(dbSession, login); List userTokens = dbClient.userTokenDao().selectByLogin(dbSession, login); return buildResponse(login, userTokens); } } - private SearchRequest toSearchRequest(Request request) { - SearchRequest SearchRequest = new SearchRequest().setLogin(request.param(PARAM_LOGIN)); - if (SearchRequest.getLogin() == null) { - SearchRequest.setLogin(userSession.getLogin()); - } - return SearchRequest; - } - private static SearchWsResponse buildResponse(String login, List userTokensDto) { SearchWsResponse.Builder searchWsResponse = SearchWsResponse.newBuilder(); SearchWsResponse.UserToken.Builder userTokenBuilder = SearchWsResponse.UserToken.newBuilder(); diff --git a/server/sonar-server/src/test/java/org/sonar/server/component/ws/SearchActionTest.java b/server/sonar-server/src/test/java/org/sonar/server/component/ws/SearchActionTest.java index 2a94d9e999d..a23bc3338c2 100644 --- a/server/sonar-server/src/test/java/org/sonar/server/component/ws/SearchActionTest.java +++ b/server/sonar-server/src/test/java/org/sonar/server/component/ws/SearchActionTest.java @@ -53,7 +53,7 @@ import org.sonar.server.ws.WsActionTester; import org.sonarqube.ws.MediaTypes; import org.sonarqube.ws.Components.Component; import org.sonarqube.ws.Components.SearchWsResponse; -import org.sonarqube.ws.client.component.SearchRequest; +import org.sonar.server.component.ws.SearchAction.SearchRequest; import static java.util.Arrays.asList; import static java.util.Collections.emptySet; diff --git a/server/sonar-server/src/test/java/org/sonar/server/component/ws/SearchProjectsActionTest.java b/server/sonar-server/src/test/java/org/sonar/server/component/ws/SearchProjectsActionTest.java index 2f2a6d1ac9e..77ba51d4a7e 100644 --- a/server/sonar-server/src/test/java/org/sonar/server/component/ws/SearchProjectsActionTest.java +++ b/server/sonar-server/src/test/java/org/sonar/server/component/ws/SearchProjectsActionTest.java @@ -46,6 +46,8 @@ import org.sonar.db.measure.MeasureDto; import org.sonar.db.metric.MetricDto; import org.sonar.db.organization.OrganizationDto; import org.sonar.db.property.PropertyDto; +import org.sonar.server.component.ws.SearchProjectsAction.RequestBuilder; +import org.sonar.server.component.ws.SearchProjectsAction.SearchProjectsRequest; import org.sonar.server.es.EsTester; import org.sonar.server.measure.index.ProjectMeasuresIndex; import org.sonar.server.measure.index.ProjectMeasuresIndexDefinition; @@ -59,7 +61,6 @@ import org.sonar.server.ws.WsActionTester; import org.sonarqube.ws.Common; import org.sonarqube.ws.Components.Component; import org.sonarqube.ws.Components.SearchProjectsWsResponse; -import org.sonarqube.ws.client.component.SearchProjectsRequest; import static java.util.Arrays.asList; import static java.util.Collections.singletonList; @@ -134,7 +135,7 @@ public class SearchProjectsActionTest { private WsActionTester ws = new WsActionTester( new SearchProjectsAction(dbClient, index, userSession)); - private SearchProjectsRequest.Builder request = SearchProjectsRequest.builder(); + private RequestBuilder request = SearchProjectsRequest.builder(); @Test public void verify_definition() { @@ -1111,7 +1112,7 @@ public class SearchProjectsActionTest { call(request.setPageSize(501)); } - private SearchProjectsWsResponse call(SearchProjectsRequest.Builder requestBuilder) { + private SearchProjectsWsResponse call(RequestBuilder requestBuilder) { SearchProjectsRequest wsRequest = requestBuilder.build(); TestRequest httpRequest = ws.newRequest(); ofNullable(wsRequest.getOrganization()).ifPresent(organization -> httpRequest.setParam(PARAM_ORGANIZATION, organization)); diff --git a/server/sonar-server/src/test/java/org/sonar/server/issue/IssueQueryFactoryTest.java b/server/sonar-server/src/test/java/org/sonar/server/issue/IssueQueryFactoryTest.java index 9ac942c58b5..bae47d6a5e9 100644 --- a/server/sonar-server/src/test/java/org/sonar/server/issue/IssueQueryFactoryTest.java +++ b/server/sonar-server/src/test/java/org/sonar/server/issue/IssueQueryFactoryTest.java @@ -35,7 +35,6 @@ import org.sonar.db.component.SnapshotDto; import org.sonar.db.organization.OrganizationDto; import org.sonar.server.exceptions.BadRequestException; import org.sonar.server.tester.UserSessionRule; -import org.sonarqube.ws.client.issue.SearchRequest; import static java.util.Arrays.asList; import static java.util.Collections.singletonList; diff --git a/server/sonar-server/src/test/java/org/sonar/server/issue/ws/BulkChangeActionTest.java b/server/sonar-server/src/test/java/org/sonar/server/issue/ws/BulkChangeActionTest.java index a88c1f70004..dfb147d3728 100644 --- a/server/sonar-server/src/test/java/org/sonar/server/issue/ws/BulkChangeActionTest.java +++ b/server/sonar-server/src/test/java/org/sonar/server/issue/ws/BulkChangeActionTest.java @@ -25,6 +25,7 @@ import java.util.Date; import java.util.List; import java.util.stream.Collectors; import java.util.stream.IntStream; +import javax.annotation.CheckForNull; import javax.annotation.Nullable; import org.junit.Before; import org.junit.Rule; @@ -67,10 +68,12 @@ import org.sonar.server.tester.UserSessionRule; import org.sonar.server.ws.TestRequest; import org.sonar.server.ws.WsActionTester; import org.sonarqube.ws.Issues.BulkChangeWsResponse; -import org.sonarqube.ws.client.issue.BulkChangeRequest; +import static com.google.common.base.Preconditions.checkArgument; +import static com.google.common.collect.Lists.newArrayList; import static java.util.Arrays.asList; import static java.util.Collections.singletonList; +import static java.util.Objects.requireNonNull; import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.tuple; import static org.mockito.Matchers.eq; @@ -145,7 +148,7 @@ public class BulkChangeActionTest { setUserProjectPermissions(USER, ISSUE_ADMIN); IssueDto issueDto = db.issues().insertIssue(newUnresolvedIssue().setType(BUG)); - BulkChangeWsResponse response = call(BulkChangeRequest.builder() + BulkChangeWsResponse response = call(builder() .setIssues(singletonList(issueDto.getKey())) .setSetType(RuleType.CODE_SMELL.name()) .build()); @@ -163,7 +166,7 @@ public class BulkChangeActionTest { setUserProjectPermissions(USER, ISSUE_ADMIN); IssueDto issueDto = db.issues().insertIssue(newUnresolvedIssue().setSeverity(MAJOR)); - BulkChangeWsResponse response = call(BulkChangeRequest.builder() + BulkChangeWsResponse response = call(builder() .setIssues(singletonList(issueDto.getKey())) .setSetSeverity(MINOR) .build()); @@ -181,7 +184,7 @@ public class BulkChangeActionTest { setUserProjectPermissions(USER, ISSUE_ADMIN); IssueDto issueDto = db.issues().insertIssue(newUnresolvedIssue().setTags(asList("tag1", "tag2"))); - BulkChangeWsResponse response = call(BulkChangeRequest.builder() + BulkChangeWsResponse response = call(builder() .setIssues(singletonList(issueDto.getKey())) .setAddTags(singletonList("tag3")) .build()); @@ -199,7 +202,7 @@ public class BulkChangeActionTest { setUserProjectPermissions(USER); IssueDto issueDto = db.issues().insertIssue(newUnresolvedIssue().setAssignee("arthur")); - BulkChangeWsResponse response = call(BulkChangeRequest.builder() + BulkChangeWsResponse response = call(builder() .setIssues(singletonList(issueDto.getKey())) .setAssign("") .build()); @@ -217,7 +220,7 @@ public class BulkChangeActionTest { setUserProjectPermissions(USER); IssueDto issueDto = db.issues().insertIssue(newUnresolvedIssue().setType(BUG)); - BulkChangeWsResponse response = call(BulkChangeRequest.builder() + BulkChangeWsResponse response = call(builder() .setIssues(singletonList(issueDto.getKey())) .setDoTransition("confirm") .setComment("type was badly defined") @@ -241,7 +244,7 @@ public class BulkChangeActionTest { IssueDto issue2 = db.issues().insertIssue(newUnresolvedIssue().setAssignee(userToAssign.getLogin())).setType(BUG).setSeverity(MAJOR); IssueDto issue3 = db.issues().insertIssue(newUnresolvedIssue().setAssignee(null)).setType(VULNERABILITY).setSeverity(MAJOR); - BulkChangeWsResponse response = call(BulkChangeRequest.builder() + BulkChangeWsResponse response = call(builder() .setIssues(asList(issue1.getKey(), issue2.getKey(), issue3.getKey())) .setAssign(userToAssign.getLogin()) .setSetSeverity(MINOR) @@ -264,7 +267,7 @@ public class BulkChangeActionTest { setUserProjectPermissions(USER); IssueDto issueDto = db.issues().insertIssue(newUnresolvedIssue().setType(BUG)); - BulkChangeWsResponse response = call(BulkChangeRequest.builder() + BulkChangeWsResponse response = call(builder() .setIssues(singletonList(issueDto.getKey())) .setDoTransition("confirm") .setSendNotifications(true) @@ -294,7 +297,7 @@ public class BulkChangeActionTest { ComponentDto fileOnBranch = db.components().insertComponent(newFileDto(branch)); IssueDto issueDto = db.issues().insertIssue(newUnresolvedIssue(rule, fileOnBranch, branch).setType(BUG)); - BulkChangeWsResponse response = call(BulkChangeRequest.builder() + BulkChangeWsResponse response = call(builder() .setIssues(singletonList(issueDto.getKey())) .setDoTransition("confirm") .setSendNotifications(true) @@ -323,7 +326,7 @@ public class BulkChangeActionTest { IssueDto issue3 = db.issues().insertIssue(newUnresolvedIssue().setType(VULNERABILITY)); ArgumentCaptor issueChangeNotificationCaptor = ArgumentCaptor.forClass(IssueChangeNotification.class); - BulkChangeWsResponse response = call(BulkChangeRequest.builder() + BulkChangeWsResponse response = call(builder() .setIssues(asList(issue1.getKey(), issue2.getKey(), issue3.getKey())) .setSetType(RuleType.BUG.name()) .setSendNotifications(true) @@ -345,7 +348,7 @@ public class BulkChangeActionTest { IssueDto issue2 = db.issues().insertIssue(newResolvedIssue().setType(BUG)); IssueDto issue3 = db.issues().insertIssue(newResolvedIssue().setType(BUG)); - BulkChangeWsResponse response = call(BulkChangeRequest.builder() + BulkChangeWsResponse response = call(builder() .setIssues(asList(issue1.getKey(), issue2.getKey(), issue3.getKey())) .setSetType(VULNERABILITY.name()) .build()); @@ -369,7 +372,7 @@ public class BulkChangeActionTest { IssueDto issue2 = db.issues().insertIssue(newUnresolvedIssue().setType(VULNERABILITY)); IssueDto issue3 = db.issues().insertIssue(newUnresolvedIssue().setType(VULNERABILITY)); - BulkChangeWsResponse response = call(BulkChangeRequest.builder() + BulkChangeWsResponse response = call(builder() .setIssues(asList(issue1.getKey(), issue2.getKey(), issue3.getKey())) .setSetType(VULNERABILITY.name()) .build()); @@ -393,7 +396,7 @@ public class BulkChangeActionTest { IssueDto issue2 = db.issues().insertIssue(newUnresolvedIssue().setType(VULNERABILITY)); IssueDto issue3 = db.issues().insertIssue(newUnresolvedIssue().setType(VULNERABILITY)); - BulkChangeWsResponse response = call(BulkChangeRequest.builder() + BulkChangeWsResponse response = call(builder() .setIssues(asList(issue1.getKey(), issue2.getKey(), issue3.getKey())) .setSetType(VULNERABILITY.name()) .setComment("test") @@ -417,7 +420,7 @@ public class BulkChangeActionTest { IssueDto notAuthorizedIssue1 = db.issues().insertIssue(newUnresolvedIssue(rule, anotherFile, anotherProject).setType(BUG)); IssueDto notAuthorizedIssue2 = db.issues().insertIssue(newUnresolvedIssue(rule, anotherFile, anotherProject).setType(BUG)); - BulkChangeWsResponse response = call(BulkChangeRequest.builder() + BulkChangeWsResponse response = call(builder() .setIssues(asList(authorizedIssue.getKey(), notAuthorizedIssue1.getKey(), notAuthorizedIssue2.getKey())) .setSetType(VULNERABILITY.name()) .build()); @@ -445,7 +448,7 @@ public class BulkChangeActionTest { IssueDto notAuthorizedIssue1 = db.issues().insertIssue(newUnresolvedIssue(rule, anotherFile, anotherProject).setType(BUG)); IssueDto notAuthorizedIssue2 = db.issues().insertIssue(newUnresolvedIssue(rule, anotherFile, anotherProject).setType(BUG)); - BulkChangeWsResponse response = call(BulkChangeRequest.builder() + BulkChangeWsResponse response = call(builder() .setIssues(asList(authorizedIssue1.getKey(), notAuthorizedIssue1.getKey(), notAuthorizedIssue2.getKey())) .setSetType(VULNERABILITY.name()) .build()); @@ -471,7 +474,7 @@ public class BulkChangeActionTest { IssueDto notAuthorizedIssue1 = db.issues().insertIssue(newUnresolvedIssue(rule, anotherFile, anotherProject).setSeverity(MAJOR)); IssueDto notAuthorizedIssue2 = db.issues().insertIssue(newUnresolvedIssue(rule, anotherFile, anotherProject).setSeverity(MAJOR)); - BulkChangeWsResponse response = call(BulkChangeRequest.builder() + BulkChangeWsResponse response = call(builder() .setIssues(asList(authorizedIssue1.getKey(), notAuthorizedIssue1.getKey(), notAuthorizedIssue2.getKey())) .setSetSeverity(MINOR) .build()); @@ -492,7 +495,7 @@ public class BulkChangeActionTest { expectedException.expectMessage("At least one action must be provided"); expectedException.expect(IllegalArgumentException.class); - call(BulkChangeRequest.builder() + call(builder() .setIssues(singletonList(issueDto.getKey())) .setComment("type was badly defined") .build()); @@ -504,7 +507,7 @@ public class BulkChangeActionTest { expectedException.expectMessage("Number of issues is limited to 500"); expectedException.expect(IllegalArgumentException.class); - call(BulkChangeRequest.builder() + call(builder() .setIssues(IntStream.range(0, 510).mapToObj(String::valueOf).collect(Collectors.toList())) .setSetSeverity(MINOR) .build()); @@ -514,7 +517,7 @@ public class BulkChangeActionTest { public void fail_when_not_authenticated() throws Exception { expectedException.expect(UnauthorizedException.class); - call(BulkChangeRequest.builder().setIssues(singletonList("ABCD")).build()); + call(builder().setIssues(singletonList("ABCD")).build()); } @Test @@ -607,4 +610,137 @@ public class BulkChangeActionTest { actions.add(new org.sonar.server.issue.CommentAction(issueFieldsSetter)); } + private static class BulkChangeRequest { + + private final List issues; + private final String assign; + private final String setSeverity; + private final String setType; + private final String doTransition; + private final List addTags; + private final List removeTags; + private final String comment; + private final Boolean sendNotifications; + + private BulkChangeRequest(Builder builder) { + this.issues = builder.issues; + this.assign = builder.assign; + this.setSeverity = builder.setSeverity; + this.setType = builder.setType; + this.doTransition = builder.doTransition; + this.addTags = builder.addTags; + this.removeTags = builder.removeTags; + this.comment = builder.comment; + this.sendNotifications = builder.sendNotifications; + } + + public List getIssues() { + return issues; + } + + @CheckForNull + public String getAssign() { + return assign; + } + + @CheckForNull + public String getSetSeverity() { + return setSeverity; + } + + @CheckForNull + public String getSetType() { + return setType; + } + + @CheckForNull + public String getDoTransition() { + return doTransition; + } + + public List getAddTags() { + return addTags; + } + + public List getRemoveTags() { + return removeTags; + } + + @CheckForNull + public String getComment() { + return comment; + } + + @CheckForNull + public Boolean getSendNotifications() { + return sendNotifications; + } + + } + + public static Builder builder() { + return new Builder(); + } + + public static class Builder { + private List issues; + private String assign; + private String setSeverity; + private String setType; + private String doTransition; + private List addTags = newArrayList(); + private List removeTags = newArrayList(); + private String comment; + private Boolean sendNotifications; + + public Builder setIssues(List issues) { + this.issues = issues; + return this; + } + + public Builder setAssign(@Nullable String assign) { + this.assign = assign; + return this; + } + + public Builder setSetSeverity(@Nullable String setSeverity) { + this.setSeverity = setSeverity; + return this; + } + + public Builder setSetType(@Nullable String setType) { + this.setType = setType; + return this; + } + + public Builder setDoTransition(@Nullable String doTransition) { + this.doTransition = doTransition; + return this; + } + + public Builder setAddTags(List addTags) { + this.addTags = requireNonNull(addTags); + return this; + } + + public Builder setRemoveTags(List removeTags) { + this.removeTags = requireNonNull(removeTags); + return this; + } + + public Builder setComment(@Nullable String comment) { + this.comment = comment; + return this; + } + + public Builder setSendNotifications(@Nullable Boolean sendNotifications) { + this.sendNotifications = sendNotifications; + return this; + } + + public BulkChangeRequest build() { + checkArgument(issues != null && !issues.isEmpty(), "Issue keys must be provided"); + return new BulkChangeRequest(this); + } + } } diff --git a/server/sonar-server/src/test/java/org/sonar/server/issue/ws/ComponentTagsActionTest.java b/server/sonar-server/src/test/java/org/sonar/server/issue/ws/ComponentTagsActionTest.java index b020c4426fc..23261f4ee3f 100644 --- a/server/sonar-server/src/test/java/org/sonar/server/issue/ws/ComponentTagsActionTest.java +++ b/server/sonar-server/src/test/java/org/sonar/server/issue/ws/ComponentTagsActionTest.java @@ -31,7 +31,7 @@ import org.sonar.server.issue.IssueQueryFactory; import org.sonar.server.issue.index.IssueIndex; import org.sonar.server.ws.TestResponse; import org.sonar.server.ws.WsActionTester; -import org.sonarqube.ws.client.issue.SearchRequest; +import org.sonar.server.issue.SearchRequest; import static org.assertj.core.api.Assertions.assertThat; import static org.mockito.Matchers.any; diff --git a/server/sonar-server/src/test/java/org/sonar/server/measure/ws/ComponentTreeActionTest.java b/server/sonar-server/src/test/java/org/sonar/server/measure/ws/ComponentTreeActionTest.java index 32bc30d6a31..c5ab5886cda 100644 --- a/server/sonar-server/src/test/java/org/sonar/server/measure/ws/ComponentTreeActionTest.java +++ b/server/sonar-server/src/test/java/org/sonar/server/measure/ws/ComponentTreeActionTest.java @@ -112,7 +112,7 @@ public class ComponentTreeActionTest { private WsActionTester ws = new WsActionTester( new ComponentTreeAction( - new ComponentTreeDataLoader(dbClient, new ComponentFinder(dbClient, resourceTypes), userSession, resourceTypes), + dbClient, new ComponentFinder(dbClient, resourceTypes), userSession, i18n, resourceTypes)); @Test diff --git a/server/sonar-server/src/test/java/org/sonar/server/measure/ws/ComponentTreeSortTest.java b/server/sonar-server/src/test/java/org/sonar/server/measure/ws/ComponentTreeSortTest.java index 379f7747237..839a9c05864 100644 --- a/server/sonar-server/src/test/java/org/sonar/server/measure/ws/ComponentTreeSortTest.java +++ b/server/sonar-server/src/test/java/org/sonar/server/measure/ws/ComponentTreeSortTest.java @@ -32,7 +32,6 @@ import org.sonar.core.util.Uuids; import org.sonar.db.component.ComponentDto; import org.sonar.db.measure.MeasureDto; import org.sonar.db.metric.MetricDto; -import org.sonarqube.ws.client.measure.ComponentTreeRequest; import static com.google.common.collect.Lists.newArrayList; import static java.util.Collections.singletonList; diff --git a/server/sonar-server/src/test/java/org/sonar/server/measure/ws/MeasuresWsModuleTest.java b/server/sonar-server/src/test/java/org/sonar/server/measure/ws/MeasuresWsModuleTest.java index 9f0343ecdfe..33f45d2f2ab 100644 --- a/server/sonar-server/src/test/java/org/sonar/server/measure/ws/MeasuresWsModuleTest.java +++ b/server/sonar-server/src/test/java/org/sonar/server/measure/ws/MeasuresWsModuleTest.java @@ -29,6 +29,6 @@ public class MeasuresWsModuleTest { public void verify_count_of_added_components() { ComponentContainer container = new ComponentContainer(); new MeasuresWsModule().configure(container); - assertThat(container.size()).isEqualTo(6 + 2); + assertThat(container.size()).isEqualTo(5 + 2); } } diff --git a/server/sonar-server/src/test/java/org/sonar/server/measure/ws/MeasuresWsTest.java b/server/sonar-server/src/test/java/org/sonar/server/measure/ws/MeasuresWsTest.java index a649929c8d4..7c6913c2ec3 100644 --- a/server/sonar-server/src/test/java/org/sonar/server/measure/ws/MeasuresWsTest.java +++ b/server/sonar-server/src/test/java/org/sonar/server/measure/ws/MeasuresWsTest.java @@ -31,7 +31,7 @@ import org.sonar.server.ws.WsTester; public class MeasuresWsTest { WsTester ws = new WsTester( new MeasuresWs( - new ComponentTreeAction(mock(ComponentTreeDataLoader.class), mock(I18n.class), mock(ResourceTypes.class)))); + new ComponentAction(null, null, null))); @Test public void define_ws() { diff --git a/server/sonar-server/src/test/java/org/sonar/server/measure/ws/SearchHistoryActionTest.java b/server/sonar-server/src/test/java/org/sonar/server/measure/ws/SearchHistoryActionTest.java index 73ae00a32b7..f778f3fdac0 100644 --- a/server/sonar-server/src/test/java/org/sonar/server/measure/ws/SearchHistoryActionTest.java +++ b/server/sonar-server/src/test/java/org/sonar/server/measure/ws/SearchHistoryActionTest.java @@ -43,6 +43,8 @@ import org.sonar.db.organization.OrganizationDto; import org.sonar.server.component.TestComponentFinder; import org.sonar.server.exceptions.ForbiddenException; import org.sonar.server.exceptions.NotFoundException; +import org.sonar.server.measure.ws.SearchHistoryAction.Builder; +import org.sonar.server.measure.ws.SearchHistoryAction.SearchHistoryRequest; import org.sonar.server.tester.UserSessionRule; import org.sonar.server.ws.TestRequest; import org.sonar.server.ws.WsActionTester; @@ -50,7 +52,6 @@ import org.sonarqube.ws.Common.Paging; import org.sonarqube.ws.Measures.SearchHistoryResponse; import org.sonarqube.ws.Measures.SearchHistoryResponse.HistoryMeasure; import org.sonarqube.ws.Measures.SearchHistoryResponse.HistoryValue; -import org.sonarqube.ws.client.measure.SearchHistoryRequest; import static com.google.common.collect.Lists.newArrayList; import static java.lang.Double.parseDouble; @@ -94,7 +95,7 @@ public class SearchHistoryActionTest { private MetricDto complexityMetric; private MetricDto nclocMetric; private MetricDto newViolationMetric; - private SearchHistoryRequest.Builder wsRequest; + private Builder wsRequest; @Before public void setUp() { diff --git a/server/sonar-server/src/test/java/org/sonar/server/notification/ws/AddActionTest.java b/server/sonar-server/src/test/java/org/sonar/server/notification/ws/AddActionTest.java index 95558a89bcb..26314b1c9c6 100644 --- a/server/sonar-server/src/test/java/org/sonar/server/notification/ws/AddActionTest.java +++ b/server/sonar-server/src/test/java/org/sonar/server/notification/ws/AddActionTest.java @@ -19,6 +19,7 @@ */ package org.sonar.server.notification.ws; +import javax.annotation.Nullable; import org.junit.Before; import org.junit.Rule; import org.junit.Test; @@ -42,7 +43,6 @@ import org.sonar.server.tester.UserSessionRule; import org.sonar.server.ws.TestRequest; import org.sonar.server.ws.TestResponse; import org.sonar.server.ws.WsActionTester; -import org.sonarqube.ws.client.notifications.AddRequest; import static java.lang.String.format; import static java.net.HttpURLConnection.HTTP_NO_CONTENT; @@ -82,8 +82,6 @@ public class AddActionTest { private AddAction underTest; private WsActionTester ws; - private AddRequest request = new AddRequest().setType(NOTIF_MY_NEW_ISSUES); - @Before public void setUp() { NotificationDispatcherMetadata metadata1 = NotificationDispatcherMetadata.create(NOTIF_MY_NEW_ISSUES) @@ -107,14 +105,14 @@ public class AddActionTest { @Test public void add_to_email_channel_by_default() { - call(request); + call(NOTIF_MY_NEW_ISSUES, null, null, null); db.notifications().assertExists(defaultChannel.getKey(), NOTIF_MY_NEW_ISSUES, userSession.getUserId(), null); } @Test public void add_to_a_specific_channel() { - call(request.setType(NOTIF_NEW_QUALITY_GATE_STATUS).setChannel(twitterChannel.getKey())); + call(NOTIF_NEW_QUALITY_GATE_STATUS, twitterChannel.getKey(), null, null); db.notifications().assertExists(twitterChannel.getKey(), NOTIF_NEW_QUALITY_GATE_STATUS, userSession.getUserId(), null); } @@ -124,7 +122,7 @@ public class AddActionTest { ComponentDto project = db.components().insertPrivateProject(); userSession.addProjectPermission(UserRole.USER, project); - call(request.setProject(project.getDbKey())); + call(NOTIF_MY_NEW_ISSUES, null, project.getDbKey(), null); db.notifications().assertExists(defaultChannel.getKey(), NOTIF_MY_NEW_ISSUES, userSession.getUserId(), project); } @@ -133,7 +131,7 @@ public class AddActionTest { public void add_notification_on_public_project() { ComponentDto project = db.components().insertPublicProject(); userSession.registerComponents(project); - call(request.setProject(project.getDbKey())); + call(NOTIF_MY_NEW_ISSUES, null, project.getDbKey(), null); db.notifications().assertExists(defaultChannel.getKey(), NOTIF_MY_NEW_ISSUES, userSession.getUserId(), project); } @@ -142,9 +140,9 @@ public class AddActionTest { public void add_a_global_notification_when_a_project_one_exists() { ComponentDto project = db.components().insertPrivateProject(); userSession.addProjectPermission(UserRole.USER, project); - call(request.setProject(project.getDbKey())); + call(NOTIF_MY_NEW_ISSUES, null, project.getDbKey(), null); - call(request.setProject(null)); + call(NOTIF_MY_NEW_ISSUES, null, null, null); db.notifications().assertExists(defaultChannel.getKey(), NOTIF_MY_NEW_ISSUES, userSession.getUserId(), project); db.notifications().assertExists(defaultChannel.getKey(), NOTIF_MY_NEW_ISSUES, userSession.getUserId(), null); @@ -153,10 +151,10 @@ public class AddActionTest { @Test public void add_a_notification_on_private_project_when_a_global_one_exists() { ComponentDto project = db.components().insertPrivateProject(); - call(request); + call(NOTIF_MY_NEW_ISSUES, null, null, null); userSession.addProjectPermission(UserRole.USER, project); - call(request.setProject(project.getDbKey())); + call(NOTIF_MY_NEW_ISSUES, null, project.getDbKey(), null); db.notifications().assertExists(defaultChannel.getKey(), NOTIF_MY_NEW_ISSUES, userSession.getUserId(), project); db.notifications().assertExists(defaultChannel.getKey(), NOTIF_MY_NEW_ISSUES, userSession.getUserId(), null); @@ -167,9 +165,9 @@ public class AddActionTest { public void add_a_notification_on_public_project_when_a_global_one_exists() { ComponentDto project = db.components().insertPublicProject(); userSession.registerComponents(project); - call(request); + call(NOTIF_MY_NEW_ISSUES, null, null, null); - call(request.setProject(project.getDbKey())); + call(NOTIF_MY_NEW_ISSUES, null, project.getDbKey(), null); db.notifications().assertExists(defaultChannel.getKey(), NOTIF_MY_NEW_ISSUES, userSession.getUserId(), project); db.notifications().assertExists(defaultChannel.getKey(), NOTIF_MY_NEW_ISSUES, userSession.getUserId(), null); @@ -177,7 +175,7 @@ public class AddActionTest { @Test public void http_no_content() { - TestResponse result = call(request); + TestResponse result = call(NOTIF_MY_NEW_ISSUES, null, null, null); assertThat(result.getStatus()).isEqualTo(HTTP_NO_CONTENT); } @@ -186,7 +184,7 @@ public class AddActionTest { public void add_a_notification_to_a_user_as_system_administrator() { userSession.logIn().setSystemAdministrator(); - call(request.setLogin(user.getLogin())); + call(NOTIF_MY_NEW_ISSUES, null, null, user.getLogin()); db.notifications().assertExists(defaultChannel.getKey(), NOTIF_MY_NEW_ISSUES, user.getId(), null); } @@ -198,7 +196,7 @@ public class AddActionTest { expectedException.expect(NotFoundException.class); expectedException.expectMessage("User 'LOGIN 404' not found"); - call(request.setLogin("LOGIN 404")); + call(NOTIF_MY_NEW_ISSUES, null, null, "LOGIN 404"); } @Test @@ -207,24 +205,24 @@ public class AddActionTest { expectedException.expect(ForbiddenException.class); - call(request.setLogin(user.getLogin())); + call(NOTIF_MY_NEW_ISSUES, null, null, user.getLogin()); } @Test public void fail_when_notification_already_exists() { - call(request); + call(NOTIF_MY_NEW_ISSUES, null, null, null); expectedException.expect(IllegalArgumentException.class); expectedException.expectMessage("Notification already added"); - call(request); + call(NOTIF_MY_NEW_ISSUES, null, null, null); } @Test public void fail_when_unknown_channel() { expectedException.expect(IllegalArgumentException.class); - call(request.setChannel("Channel42")); + call(NOTIF_MY_NEW_ISSUES, "Channel42", null, null); } @Test @@ -232,7 +230,7 @@ public class AddActionTest { expectedException.expect(BadRequestException.class); expectedException.expectMessage("Value of parameter 'type' (Dispatcher42) must be one of: [Dispatcher1, Dispatcher2, Dispatcher3]"); - call(request.setType("Dispatcher42")); + call("Dispatcher42", null, null, null); } @Test @@ -243,7 +241,7 @@ public class AddActionTest { expectedException.expect(BadRequestException.class); expectedException.expectMessage("Value of parameter 'type' (Dispatcher42) must be one of: [Dispatcher1, Dispatcher3]"); - call(request.setType("Dispatcher42").setProject(project.getDbKey())); + call("Dispatcher42", null, project.getDbKey(), null); } @Test @@ -253,7 +251,7 @@ public class AddActionTest { expectedException.expect(BadRequestException.class); expectedException.expectMessage("Value of parameter 'type' (Dispatcher42) must be one of: [Dispatcher1, Dispatcher3]"); - call(request.setType("Dispatcher42").setProject(project.getDbKey())); + call("Dispatcher42", null, project.getDbKey(), null); } @Test @@ -267,7 +265,7 @@ public class AddActionTest { public void fail_when_project_is_unknown() { expectedException.expect(NotFoundException.class); - call(request.setProject("Project-42")); + call(NOTIF_MY_NEW_ISSUES, null, "Project-42", null); } @Test @@ -277,7 +275,7 @@ public class AddActionTest { expectedException.expect(BadRequestException.class); expectedException.expectMessage("Component 'VIEW_1' must be a project"); - call(request.setProject("VIEW_1")); + call(NOTIF_MY_NEW_ISSUES, null, "VIEW_1", null); } @Test @@ -286,7 +284,7 @@ public class AddActionTest { expectedException.expect(UnauthorizedException.class); - call(request); + call(NOTIF_MY_NEW_ISSUES, null, null, null); } @Test @@ -297,7 +295,7 @@ public class AddActionTest { expectedException.expect(NotFoundException.class); expectedException.expectMessage(format("Component key '%s' not found", branch.getDbKey())); - call(request.setProject(branch.getDbKey())); + call(NOTIF_MY_NEW_ISSUES, null, branch.getDbKey(), null); } @Test @@ -307,17 +305,15 @@ public class AddActionTest { expectedException.expect(ForbiddenException.class); - call(request - .setProject(project.getDbKey()) - .setLogin(userSession.getLogin())); + call(NOTIF_MY_NEW_ISSUES, null, project.getDbKey(), userSession.getLogin()); } - private TestResponse call(AddRequest add) { + private TestResponse call(String type, @Nullable String channel, @Nullable String project, @Nullable String login) { TestRequest request = ws.newRequest(); - request.setParam(PARAM_TYPE, add.getType()); - setNullable(add.getChannel(), channel -> request.setParam(PARAM_CHANNEL, channel)); - setNullable(add.getProject(), project -> request.setParam(PARAM_PROJECT, project)); - setNullable(add.getLogin(), login -> request.setParam(PARAM_LOGIN, login)); + request.setParam(PARAM_TYPE, type); + setNullable(channel, channel1 -> request.setParam(PARAM_CHANNEL, channel1)); + setNullable(project, project1 -> request.setParam(PARAM_PROJECT, project1)); + setNullable(login, login1 -> request.setParam(PARAM_LOGIN, login1)); return request.execute(); } diff --git a/server/sonar-server/src/test/java/org/sonar/server/notification/ws/RemoveActionTest.java b/server/sonar-server/src/test/java/org/sonar/server/notification/ws/RemoveActionTest.java index 2b975075980..7289356e956 100644 --- a/server/sonar-server/src/test/java/org/sonar/server/notification/ws/RemoveActionTest.java +++ b/server/sonar-server/src/test/java/org/sonar/server/notification/ws/RemoveActionTest.java @@ -38,11 +38,11 @@ import org.sonar.server.exceptions.UnauthorizedException; import org.sonar.server.notification.NotificationCenter; import org.sonar.server.notification.NotificationDispatcherMetadata; import org.sonar.server.notification.NotificationUpdater; +import org.sonar.server.notification.ws.RemoveAction.RemoveRequest; import org.sonar.server.tester.UserSessionRule; import org.sonar.server.ws.TestRequest; import org.sonar.server.ws.TestResponse; import org.sonar.server.ws.WsActionTester; -import org.sonarqube.ws.client.notifications.RemoveRequest; import static java.lang.String.format; import static java.net.HttpURLConnection.HTTP_NO_CONTENT; diff --git a/server/sonar-server/src/test/java/org/sonar/server/organization/ws/SearchMembersActionTest.java b/server/sonar-server/src/test/java/org/sonar/server/organization/ws/SearchMembersActionTest.java index 695869c6d48..51c8ccd0209 100644 --- a/server/sonar-server/src/test/java/org/sonar/server/organization/ws/SearchMembersActionTest.java +++ b/server/sonar-server/src/test/java/org/sonar/server/organization/ws/SearchMembersActionTest.java @@ -21,6 +21,8 @@ package org.sonar.server.organization.ws; import java.util.stream.IntStream; +import javax.annotation.CheckForNull; +import javax.annotation.Nullable; import org.junit.Rule; import org.junit.Test; import org.junit.rules.ExpectedException; @@ -48,7 +50,6 @@ import org.sonar.server.ws.WsActionTester; import org.sonarqube.ws.Common.Paging; import org.sonarqube.ws.Organizations.SearchMembersWsResponse; import org.sonarqube.ws.Organizations.User; -import org.sonarqube.ws.client.organization.SearchMembersRequest; import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.tuple; @@ -329,4 +330,62 @@ public class SearchMembersActionTest { return wsRequest.executeProtobuf(SearchMembersWsResponse.class); } + + private static class SearchMembersRequest { + private String organization; + private String selected; + private String query; + private Integer page; + private Integer pageSize; + + @CheckForNull + public String getOrganization() { + return organization; + } + + public SearchMembersRequest setOrganization(@Nullable String organization) { + this.organization = organization; + return this; + } + + @CheckForNull + public String getSelected() { + return selected; + } + + public SearchMembersRequest setSelected(@Nullable String selected) { + this.selected = selected; + return this; + } + + @CheckForNull + public String getQuery() { + return query; + } + + public SearchMembersRequest setQuery(@Nullable String query) { + this.query = query; + return this; + } + + @CheckForNull + public Integer getPage() { + return page; + } + + public SearchMembersRequest setPage(@Nullable Integer page) { + this.page = page; + return this; + } + + @CheckForNull + public Integer getPageSize() { + return pageSize; + } + + public SearchMembersRequest setPageSize(@Nullable Integer pageSize) { + this.pageSize = pageSize; + return this; + } + } } diff --git a/server/sonar-server/src/test/java/org/sonar/server/permission/ws/PermissionsWsModuleTest.java b/server/sonar-server/src/test/java/org/sonar/server/permission/ws/PermissionsWsModuleTest.java index 83fa929ce57..f409cfcc7bb 100644 --- a/server/sonar-server/src/test/java/org/sonar/server/permission/ws/PermissionsWsModuleTest.java +++ b/server/sonar-server/src/test/java/org/sonar/server/permission/ws/PermissionsWsModuleTest.java @@ -30,6 +30,6 @@ public class PermissionsWsModuleTest { public void verify_count_of_added_components() { ComponentContainer container = new ComponentContainer(); new PermissionsWsModule().configure(container); - assertThat(container.size()).isEqualTo(COMPONENTS_IN_EMPTY_COMPONENT_CONTAINER + 27); + assertThat(container.size()).isEqualTo(COMPONENTS_IN_EMPTY_COMPONENT_CONTAINER + 25); } } diff --git a/server/sonar-server/src/test/java/org/sonar/server/permission/ws/SearchProjectPermissionsActionTest.java b/server/sonar-server/src/test/java/org/sonar/server/permission/ws/SearchProjectPermissionsActionTest.java index 58605ca8d24..894a575adad 100644 --- a/server/sonar-server/src/test/java/org/sonar/server/permission/ws/SearchProjectPermissionsActionTest.java +++ b/server/sonar-server/src/test/java/org/sonar/server/permission/ws/SearchProjectPermissionsActionTest.java @@ -66,8 +66,7 @@ public class SearchProjectPermissionsActionTest extends BasePermissionWsTest dbEvents = dbClient.eventDao().selectByComponentUuid(dbSession, analysis.getComponentUuid()); assertThat(dbEvents).hasSize(1); @@ -133,13 +128,9 @@ public class CreateEventActionTest { public void create_event_as_project_admin() { ComponentDto project = newPrivateProjectDto(db.getDefaultOrganization(), "P1"); SnapshotDto analysis = db.components().insertProjectAndSnapshot(project); - CreateEventRequest.Builder request = CreateEventRequest.builder() - .setAnalysis(analysis.getUuid()) - .setCategory(VERSION) - .setName("5.6.3"); logInAsProjectAdministrator(project); - CreateEventResponse result = call(request); + CreateEventResponse result = call(VERSION.name(), "5.6.3", analysis.getUuid()); assertThat(result.getEvent().getKey()).isNotEmpty(); } @@ -148,13 +139,9 @@ public class CreateEventActionTest { public void create_version_event() { ComponentDto project = ComponentTesting.newPrivateProjectDto(db.organizations().insert()); SnapshotDto analysis = db.components().insertProjectAndSnapshot(project); - CreateEventRequest.Builder request = CreateEventRequest.builder() - .setAnalysis(analysis.getUuid()) - .setCategory(VERSION) - .setName("5.6.3"); logInAsProjectAdministrator(project); - call(request); + call(VERSION.name(), "5.6.3", analysis.getUuid()); Optional newAnalysis = dbClient.snapshotDao().selectByUuid(dbSession, analysis.getUuid()); assertThat(newAnalysis.get().getVersion()).isEqualTo("5.6.3"); @@ -164,12 +151,9 @@ public class CreateEventActionTest { public void create_other_event_with_ws_response() { ComponentDto project = ComponentTesting.newPrivateProjectDto(db.organizations().insert()); SnapshotDto analysis = db.components().insertProjectAndSnapshot(project); - CreateEventRequest.Builder request = CreateEventRequest.builder() - .setAnalysis(analysis.getUuid()) - .setName("Project Import"); logInAsProjectAdministrator(project); - CreateEventResponse result = call(request); + CreateEventResponse result = call(OTHER.name(), "Project Import", analysis.getUuid()); SnapshotDto newAnalysis = dbClient.snapshotDao().selectByUuid(dbSession, analysis.getUuid()).get(); assertThat(analysis.getVersion()).isEqualTo(newAnalysis.getVersion()); @@ -185,13 +169,9 @@ public class CreateEventActionTest { public void create_event_without_description() { ComponentDto project = ComponentTesting.newPrivateProjectDto(db.getDefaultOrganization()); SnapshotDto analysis = db.components().insertProjectAndSnapshot(project); - CreateEventRequest.Builder request = CreateEventRequest.builder() - .setAnalysis(analysis.getUuid()) - .setCategory(OTHER) - .setName("Project Import"); logInAsProjectAdministrator(project); - CreateEventResponse result = call(request); + CreateEventResponse result = call(OTHER.name(), "Project Import", analysis.getUuid()); ProjectAnalyses.Event event = result.getEvent(); assertThat(event.getKey()).isNotEmpty(); @@ -202,13 +182,9 @@ public class CreateEventActionTest { public void create_event_on_application() { ComponentDto application = ComponentTesting.newApplication(db.getDefaultOrganization()); SnapshotDto analysis = db.components().insertProjectAndSnapshot(application); - CreateEventRequest.Builder request = CreateEventRequest.builder() - .setAnalysis(analysis.getUuid()) - .setCategory(OTHER) - .setName("Application Event"); logInAsProjectAdministrator(application); - CreateEventResponse result = call(request); + CreateEventResponse result = call(OTHER.name(), "Application Event", analysis.getUuid()); ProjectAnalyses.Event event = result.getEvent(); assertThat(event.getName()).isEqualTo("Application Event"); @@ -218,20 +194,12 @@ public class CreateEventActionTest { public void create_2_version_events_on_same_project() { ComponentDto project = ComponentTesting.newPrivateProjectDto(db.organizations().insert()); SnapshotDto firstAnalysis = db.components().insertProjectAndSnapshot(project); - CreateEventRequest.Builder firstRequest = CreateEventRequest.builder() - .setAnalysis(firstAnalysis.getUuid()) - .setCategory(VERSION) - .setName("5.6.3"); SnapshotDto secondAnalysis = dbClient.snapshotDao().insert(dbSession, newAnalysis(project)); db.commit(); - CreateEventRequest.Builder secondRequest = CreateEventRequest.builder() - .setAnalysis(secondAnalysis.getUuid()) - .setCategory(VERSION) - .setName("6.3"); logInAsProjectAdministrator(project); - call(firstRequest); - call(secondRequest); + call(VERSION.name(), "5.6.3", firstAnalysis.getUuid()); + call(VERSION.name(), "6.3", secondAnalysis.getUuid()); List events = dbClient.eventDao().selectByComponentUuid(dbSession, project.uuid()); assertThat(events).hasSize(2); @@ -241,13 +209,12 @@ public class CreateEventActionTest { public void fail_if_not_blank_name() { ComponentDto project = ComponentTesting.newPrivateProjectDto(db.organizations().insert()); SnapshotDto analysis = db.components().insertProjectAndSnapshot(project); - CreateEventRequest.Builder request = CreateEventRequest.builder().setAnalysis(analysis.getUuid()).setName(" "); logInAsProjectAdministrator(project); expectedException.expect(IllegalArgumentException.class); expectedException.expectMessage("A non empty name is required"); - call(request); + call(OTHER.name(), " ", analysis.getUuid()); } @Test @@ -257,46 +224,33 @@ public class CreateEventActionTest { expectedException.expect(NotFoundException.class); expectedException.expectMessage("Analysis 'A42' is not found"); - CreateEventRequest.Builder request = CreateEventRequest.builder() - .setAnalysis("A42") - .setCategory(OTHER) - .setName("Project Import"); - - call(request); + call(OTHER.name(), "Project Import", "A42"); } @Test public void fail_if_2_version_events_on_the_same_analysis() { ComponentDto project = ComponentTesting.newPrivateProjectDto(db.getDefaultOrganization()); SnapshotDto analysis = db.components().insertProjectAndSnapshot(project); - CreateEventRequest.Builder request = CreateEventRequest.builder() - .setAnalysis(analysis.getUuid()) - .setCategory(VERSION) - .setName("5.6.3"); logInAsProjectAdministrator(project); - call(request); + call(VERSION.name(), "5.6.3", analysis.getUuid()); expectedException.expect(IllegalArgumentException.class); expectedException.expectMessage("A version event already exists on analysis '" + analysis.getUuid() + "'"); - call(request.setName("6.3")); + call(VERSION.name(), "6.3", analysis.getUuid()); } @Test public void fail_if_2_other_events_on_same_analysis_with_same_name() { ComponentDto project = ComponentTesting.newPrivateProjectDto(db.organizations().insert()); SnapshotDto analysis = db.components().insertProjectAndSnapshot(project); - CreateEventRequest.Builder request = CreateEventRequest.builder() - .setAnalysis(analysis.getUuid()) - .setCategory(OTHER) - .setName("Project Import"); logInAsProjectAdministrator(project); - call(request); + call(OTHER.name(), "Project Import", analysis.getUuid()); expectedException.expect(IllegalArgumentException.class); expectedException.expectMessage("An 'Other' event with the same name already exists on analysis '" + analysis.getUuid() + "'"); - call(request.setName("Project Import")); + call(OTHER.name(), "Project Import", analysis.getUuid()); } @Test @@ -317,32 +271,24 @@ public class CreateEventActionTest { public void fail_if_create_on_view() { ComponentDto view = newView(db.organizations().insert()); SnapshotDto analysis = db.components().insertViewAndSnapshot(view); - CreateEventRequest.Builder request = CreateEventRequest.builder() - .setAnalysis(analysis.getUuid()) - .setCategory(OTHER) - .setName("View Event"); logInAsProjectAdministrator(view); expectedException.expect(IllegalArgumentException.class); expectedException.expectMessage("An event must be created on a project or an application"); - call(request); + call(OTHER.name(), "View Event", analysis.getUuid()); } @Test public void fail_if_create_version_event_on_application() { ComponentDto application = newApplication(db.organizations().insert()); SnapshotDto analysis = db.components().insertViewAndSnapshot(application); - CreateEventRequest.Builder request = CreateEventRequest.builder() - .setAnalysis(analysis.getUuid()) - .setCategory(VERSION) - .setName("5.6.3"); logInAsProjectAdministrator(application); expectedException.expect(IllegalArgumentException.class); expectedException.expectMessage("A version event must be created on a project"); - call(request); + call(VERSION.name(), "5.6.3", analysis.getUuid()); } @Test @@ -350,30 +296,22 @@ public class CreateEventActionTest { userSession.logIn(); SnapshotDto analysis = dbClient.snapshotDao().insert(dbSession, newSnapshot().setUuid("A1")); db.commit(); - CreateEventRequest.Builder request = CreateEventRequest.builder() - .setAnalysis(analysis.getUuid()) - .setCategory(VERSION) - .setName("5.6.3"); expectedException.expect(IllegalStateException.class); expectedException.expectMessage("Project of analysis 'A1' is not found"); - call(request); + call(VERSION.name(), "5.6.3", analysis.getUuid()); } @Test public void throw_ForbiddenException_if_not_project_administrator() { SnapshotDto analysis = db.components().insertProjectAndSnapshot(newPrivateProjectDto(db.organizations().insert(), "P1")); - CreateEventRequest.Builder request = CreateEventRequest.builder() - .setAnalysis(analysis.getUuid()) - .setCategory(VERSION) - .setName("5.6.3"); userSession.logIn(); expectedException.expect(ForbiddenException.class); expectedException.expectMessage("Insufficient privileges"); - call(request); + call(VERSION.name(), "5.6.3", analysis.getUuid()); } @Test @@ -389,14 +327,13 @@ public class CreateEventActionTest { userSession.logIn().addProjectPermission(UserRole.ADMIN, project); } - private CreateEventResponse call(CreateEventRequest.Builder requestBuilder) { - CreateEventRequest request = requestBuilder.build(); + private CreateEventResponse call(String categoryName, String name, String analysis) { TestRequest httpRequest = ws.newRequest() .setMethod(POST.name()); - httpRequest.setParam(PARAM_CATEGORY, request.getCategory().name()) - .setParam(PARAM_NAME, request.getName()) - .setParam(PARAM_ANALYSIS, request.getAnalysis()); + httpRequest.setParam(PARAM_CATEGORY, categoryName) + .setParam(PARAM_NAME, name) + .setParam(PARAM_ANALYSIS, analysis); return httpRequest.executeProtobuf(CreateEventResponse.class); } diff --git a/server/sonar-server/src/test/java/org/sonar/server/projectanalysis/ws/SearchActionTest.java b/server/sonar-server/src/test/java/org/sonar/server/projectanalysis/ws/SearchActionTest.java index 4d5954ce0fe..703d093398c 100644 --- a/server/sonar-server/src/test/java/org/sonar/server/projectanalysis/ws/SearchActionTest.java +++ b/server/sonar-server/src/test/java/org/sonar/server/projectanalysis/ws/SearchActionTest.java @@ -48,7 +48,6 @@ import org.sonarqube.ws.ProjectAnalyses.Analysis; import org.sonarqube.ws.ProjectAnalyses.Event; import org.sonarqube.ws.ProjectAnalyses.SearchResponse; import org.sonarqube.ws.client.projectanalysis.EventCategory; -import org.sonarqube.ws.client.projectanalysis.SearchRequest; import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.tuple; diff --git a/server/sonar-server/src/test/java/org/sonar/server/user/ws/CreateActionTest.java b/server/sonar-server/src/test/java/org/sonar/server/user/ws/CreateActionTest.java index 5de4d8d7e56..25d50b30a30 100644 --- a/server/sonar-server/src/test/java/org/sonar/server/user/ws/CreateActionTest.java +++ b/server/sonar-server/src/test/java/org/sonar/server/user/ws/CreateActionTest.java @@ -47,12 +47,12 @@ import org.sonar.server.user.index.UserDoc; import org.sonar.server.user.index.UserIndex; import org.sonar.server.user.index.UserIndexDefinition; import org.sonar.server.user.index.UserIndexer; +import org.sonar.server.user.ws.CreateAction.CreateRequest; import org.sonar.server.usergroups.DefaultGroupFinder; import org.sonar.server.ws.TestRequest; import org.sonar.server.ws.WsActionTester; import org.sonarqube.ws.Users.CreateWsResponse; import org.sonarqube.ws.Users.CreateWsResponse.User; -import org.sonarqube.ws.client.user.CreateRequest; import static java.util.Collections.singletonList; import static org.assertj.core.api.Assertions.assertThat; diff --git a/sonar-ws/src/main/java/org/sonarqube/ws/client/measure/SearchRequest.java b/sonar-ws/src/main/java/org/sonarqube/ws/client/measure/SearchRequest.java index 61b5e774110..5c8cc2bec0e 100644 --- a/sonar-ws/src/main/java/org/sonarqube/ws/client/measure/SearchRequest.java +++ b/sonar-ws/src/main/java/org/sonarqube/ws/client/measure/SearchRequest.java @@ -24,7 +24,7 @@ import java.util.List; import static com.google.common.base.Preconditions.checkArgument; public class SearchRequest { - public static final int MAX_NB_PROJECTS = 100; + private static final int MAX_NB_PROJECTS = 100; private final List metricKeys; private final List projectKeys; diff --git a/sonar-ws/src/main/java/org/sonarqube/ws/client/settings/SettingsService.java b/sonar-ws/src/main/java/org/sonarqube/ws/client/settings/SettingsService.java index a353e7dfb2f..9d3f046dee6 100644 --- a/sonar-ws/src/main/java/org/sonarqube/ws/client/settings/SettingsService.java +++ b/sonar-ws/src/main/java/org/sonarqube/ws/client/settings/SettingsService.java @@ -126,10 +126,10 @@ public class SettingsService extends BaseService { new PostRequest(path("set")) .setParam("branch", request.getBranch()) .setParam("component", request.getComponent()) - .setParam("fieldValues", request.getFieldValues() == null ? null : request.getFieldValues().stream().collect(Collectors.joining(","))) + .setParam("fieldValues", request.getFieldValues() == null ? null : request.getFieldValues()) .setParam("key", request.getKey()) .setParam("value", request.getValue()) - .setParam("values", request.getValues() == null ? null : request.getValues().stream().collect(Collectors.joining(","))) + .setParam("values", request.getValues() == null ? null : request.getValues()) .setMediaType(MediaTypes.JSON) ).content(); } diff --git a/sonar-ws/src/main/java/org/sonarqube/ws/client/users/ChangePasswordRequest.java b/sonar-ws/src/main/java/org/sonarqube/ws/client/users/ChangePasswordRequest.java deleted file mode 100644 index fe370e42bff..00000000000 --- a/sonar-ws/src/main/java/org/sonarqube/ws/client/users/ChangePasswordRequest.java +++ /dev/null @@ -1,75 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2017 SonarSource SA - * mailto:info 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.sonarqube.ws.client.users; - -import java.util.List; -import javax.annotation.Generated; - -/** - * This is part of the internal API. - * This is a POST request. - * @see Further information about this action online (including a response example) - * @since 5.2 - */ -@Generated("sonar-ws-generator") -public class ChangePasswordRequest { - - private String login; - private String password; - private String previousPassword; - - /** - * This is a mandatory parameter. - * Example value: "myuser" - */ - public ChangePasswordRequest setLogin(String login) { - this.login = login; - return this; - } - - public String getLogin() { - return login; - } - - /** - * This is a mandatory parameter. - * Example value: "mypassword" - */ - public ChangePasswordRequest setPassword(String password) { - this.password = password; - return this; - } - - public String getPassword() { - return password; - } - - /** - * Example value: "oldpassword" - */ - public ChangePasswordRequest setPreviousPassword(String previousPassword) { - this.previousPassword = previousPassword; - return this; - } - - public String getPreviousPassword() { - return previousPassword; - } -} diff --git a/sonar-ws/src/main/java/org/sonarqube/ws/client/users/CreateRequest.java b/sonar-ws/src/main/java/org/sonarqube/ws/client/users/CreateRequest.java deleted file mode 100644 index 7852c6846c8..00000000000 --- a/sonar-ws/src/main/java/org/sonarqube/ws/client/users/CreateRequest.java +++ /dev/null @@ -1,135 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2017 SonarSource SA - * mailto:info 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.sonarqube.ws.client.users; - -import java.util.List; -import javax.annotation.Generated; - -/** - * This is part of the internal API. - * This is a POST request. - * @see Further information about this action online (including a response example) - * @since 3.7 - */ -@Generated("sonar-ws-generator") -public class CreateRequest { - - private String email; - private String local; - private String login; - private String name; - private String password; - private String scmAccount; - private String scmAccounts; - - /** - * Example value: "myname@email.com" - */ - public CreateRequest setEmail(String email) { - this.email = email; - return this; - } - - public String getEmail() { - return email; - } - - /** - * Possible values: - *
    - *
  • "true"
  • - *
  • "false"
  • - *
  • "yes"
  • - *
  • "no"
  • - *
- */ - public CreateRequest setLocal(String local) { - this.local = local; - return this; - } - - public String getLocal() { - return local; - } - - /** - * This is a mandatory parameter. - * Example value: "myuser" - */ - public CreateRequest setLogin(String login) { - this.login = login; - return this; - } - - public String getLogin() { - return login; - } - - /** - * This is a mandatory parameter. - * Example value: "My Name" - */ - public CreateRequest setName(String name) { - this.name = name; - return this; - } - - public String getName() { - return name; - } - - /** - * Example value: "mypassword" - */ - public CreateRequest setPassword(String password) { - this.password = password; - return this; - } - - public String getPassword() { - return password; - } - - /** - * Example value: "scmAccount=firstValue&scmAccount=secondValue&scmAccount=thirdValue" - */ - public CreateRequest setScmAccount(String scmAccount) { - this.scmAccount = scmAccount; - return this; - } - - public String getScmAccount() { - return scmAccount; - } - - /** - * Example value: "myscmaccount1,myscmaccount2" - * @deprecated since 6.1 - */ - @Deprecated - public CreateRequest setScmAccounts(String scmAccounts) { - this.scmAccounts = scmAccounts; - return this; - } - - public String getScmAccounts() { - return scmAccounts; - } -} diff --git a/sonar-ws/src/main/java/org/sonarqube/ws/client/users/DeactivateRequest.java b/sonar-ws/src/main/java/org/sonarqube/ws/client/users/DeactivateRequest.java deleted file mode 100644 index cf8906d82ce..00000000000 --- a/sonar-ws/src/main/java/org/sonarqube/ws/client/users/DeactivateRequest.java +++ /dev/null @@ -1,48 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2017 SonarSource SA - * mailto:info 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.sonarqube.ws.client.users; - -import java.util.List; -import javax.annotation.Generated; - -/** - * This is part of the internal API. - * This is a POST request. - * @see Further information about this action online (including a response example) - * @since 3.7 - */ -@Generated("sonar-ws-generator") -public class DeactivateRequest { - - private String login; - - /** - * This is a mandatory parameter. - * Example value: "myuser" - */ - public DeactivateRequest setLogin(String login) { - this.login = login; - return this; - } - - public String getLogin() { - return login; - } -} diff --git a/sonar-ws/src/main/java/org/sonarqube/ws/client/users/GroupsRequest.java b/sonar-ws/src/main/java/org/sonarqube/ws/client/users/GroupsRequest.java deleted file mode 100644 index 8db1e4e3133..00000000000 --- a/sonar-ws/src/main/java/org/sonarqube/ws/client/users/GroupsRequest.java +++ /dev/null @@ -1,119 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2017 SonarSource SA - * mailto:info 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.sonarqube.ws.client.users; - -import java.util.List; -import javax.annotation.Generated; - -/** - * This is part of the internal API. - * This is a POST request. - * @see Further information about this action online (including a response example) - * @since 5.2 - */ -@Generated("sonar-ws-generator") -public class GroupsRequest { - - private String login; - private String organization; - private String p; - private String ps; - private String q; - private String selected; - - /** - * This is a mandatory parameter. - * Example value: "admin" - */ - public GroupsRequest setLogin(String login) { - this.login = login; - return this; - } - - public String getLogin() { - return login; - } - - /** - * This is part of the internal API. - * Example value: "my-org" - */ - public GroupsRequest setOrganization(String organization) { - this.organization = organization; - return this; - } - - public String getOrganization() { - return organization; - } - - /** - * Example value: "42" - */ - public GroupsRequest setP(String p) { - this.p = p; - return this; - } - - public String getP() { - return p; - } - - /** - * Example value: "20" - */ - public GroupsRequest setPs(String ps) { - this.ps = ps; - return this; - } - - public String getPs() { - return ps; - } - - /** - * Example value: "users" - */ - public GroupsRequest setQ(String q) { - this.q = q; - return this; - } - - public String getQ() { - return q; - } - - /** - * Possible values: - *
    - *
  • "all"
  • - *
  • "deselected"
  • - *
  • "selected"
  • - *
- */ - public GroupsRequest setSelected(String selected) { - this.selected = selected; - return this; - } - - public String getSelected() { - return selected; - } -} diff --git a/sonar-ws/src/main/java/org/sonarqube/ws/client/users/SearchRequest.java b/sonar-ws/src/main/java/org/sonarqube/ws/client/users/SearchRequest.java deleted file mode 100644 index f7b7967d1bc..00000000000 --- a/sonar-ws/src/main/java/org/sonarqube/ws/client/users/SearchRequest.java +++ /dev/null @@ -1,98 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2017 SonarSource SA - * mailto:info 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.sonarqube.ws.client.users; - -import java.util.List; -import javax.annotation.Generated; - -/** - * This is part of the internal API. - * This is a POST request. - * @see Further information about this action online (including a response example) - * @since 3.6 - */ -@Generated("sonar-ws-generator") -public class SearchRequest { - - private List f; - private String p; - private String ps; - private String q; - - /** - * Possible values: - *
    - *
  • "name"
  • - *
  • "email"
  • - *
  • "avatart"
  • - *
  • "scmAccounts"
  • - *
  • "groups"
  • - *
  • "active"
  • - *
  • "local"
  • - *
  • "externalIdentity"
  • - *
  • "externalProvider"
  • - *
- * @deprecated since 5.4 - */ - @Deprecated - public SearchRequest setF(List f) { - this.f = f; - return this; - } - - public List getF() { - return f; - } - - /** - * Example value: "42" - */ - public SearchRequest setP(String p) { - this.p = p; - return this; - } - - public String getP() { - return p; - } - - /** - * Example value: "20" - */ - public SearchRequest setPs(String ps) { - this.ps = ps; - return this; - } - - public String getPs() { - return ps; - } - - /** - */ - public SearchRequest setQ(String q) { - this.q = q; - return this; - } - - public String getQ() { - return q; - } -} diff --git a/sonar-ws/src/main/java/org/sonarqube/ws/client/users/UpdateRequest.java b/sonar-ws/src/main/java/org/sonarqube/ws/client/users/UpdateRequest.java deleted file mode 100644 index 672f3c89be7..00000000000 --- a/sonar-ws/src/main/java/org/sonarqube/ws/client/users/UpdateRequest.java +++ /dev/null @@ -1,102 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2017 SonarSource SA - * mailto:info 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.sonarqube.ws.client.users; - -import java.util.List; -import javax.annotation.Generated; - -/** - * This is part of the internal API. - * This is a POST request. - * @see Further information about this action online (including a response example) - * @since 3.7 - */ -@Generated("sonar-ws-generator") -public class UpdateRequest { - - private String email; - private String login; - private String name; - private String scmAccount; - private String scmAccounts; - - /** - * Example value: "myname@email.com" - */ - public UpdateRequest setEmail(String email) { - this.email = email; - return this; - } - - public String getEmail() { - return email; - } - - /** - * This is a mandatory parameter. - * Example value: "myuser" - */ - public UpdateRequest setLogin(String login) { - this.login = login; - return this; - } - - public String getLogin() { - return login; - } - - /** - * Example value: "My Name" - */ - public UpdateRequest setName(String name) { - this.name = name; - return this; - } - - public String getName() { - return name; - } - - /** - * Example value: "scmAccount=firstValue&scmAccount=secondValue&scmAccount=thirdValue" - */ - public UpdateRequest setScmAccount(String scmAccount) { - this.scmAccount = scmAccount; - return this; - } - - public String getScmAccount() { - return scmAccount; - } - - /** - * Example value: "myscmaccount1,myscmaccount2" - * @deprecated since 6.1 - */ - @Deprecated - public UpdateRequest setScmAccounts(String scmAccounts) { - this.scmAccounts = scmAccounts; - return this; - } - - public String getScmAccounts() { - return scmAccounts; - } -} diff --git a/sonar-ws/src/main/java/org/sonarqube/ws/client/users/UsersService.java b/sonar-ws/src/main/java/org/sonarqube/ws/client/users/UsersService.java deleted file mode 100644 index f456762369b..00000000000 --- a/sonar-ws/src/main/java/org/sonarqube/ws/client/users/UsersService.java +++ /dev/null @@ -1,191 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2017 SonarSource SA - * mailto:info 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.sonarqube.ws.client.users; - -import java.util.stream.Collectors; -import javax.annotation.Generated; -import org.sonarqube.ws.MediaTypes; -import org.sonarqube.ws.client.BaseService; -import org.sonarqube.ws.client.GetRequest; -import org.sonarqube.ws.client.PostRequest; -import org.sonarqube.ws.client.WsConnector; -import org.sonarqube.ws.Users.CreateWsResponse; -import org.sonarqube.ws.Users.CurrentWsResponse; -import org.sonarqube.ws.Users.GroupsWsResponse; -import org.sonarqube.ws.Users.IdentityProvidersWsResponse; -import org.sonarqube.ws.Users.SearchWsResponse; - -/** - * @see Further information about this web service online - */ -@Generated("sonar-ws-generator") -public class UsersService extends BaseService { - - public UsersService(WsConnector wsConnector) { - super(wsConnector, "api/users"); - } - - /** - * - * This is part of the internal API. - * This is a POST request. - * @see Further information about this action online (including a response example) - * @since 5.2 - */ - public void changePassword(ChangePasswordRequest request) { - call( - new PostRequest(path("change_password")) - .setParam("login", request.getLogin()) - .setParam("password", request.getPassword()) - .setParam("previousPassword", request.getPreviousPassword()) - .setMediaType(MediaTypes.JSON) - ).content(); - } - - /** - * - * This is part of the internal API. - * This is a POST request. - * @see Further information about this action online (including a response example) - * @since 3.7 - */ - public void create(CreateRequest request) { - call( - new PostRequest(path("create")) - .setParam("email", request.getEmail()) - .setParam("local", request.getLocal()) - .setParam("login", request.getLogin()) - .setParam("name", request.getName()) - .setParam("password", request.getPassword()) - .setParam("scmAccount", request.getScmAccount()) - .setParam("scmAccounts", request.getScmAccounts()), - CreateWsResponse.parser()); - } - - /** - * - * This is part of the internal API. - * This is a GET request. - * @see Further information about this action online (including a response example) - * @since 5.2 - */ - public CurrentWsResponse current() { - return call( - new GetRequest(path("current")), - CurrentWsResponse.parser()); - } - - /** - * - * This is part of the internal API. - * This is a POST request. - * @see Further information about this action online (including a response example) - * @since 3.7 - */ - public String deactivate(DeactivateRequest request) { - return call( - new PostRequest(path("deactivate")) - .setParam("login", request.getLogin()) - .setMediaType(MediaTypes.JSON) - ).content(); - } - - /** - * - * This is part of the internal API. - * This is a GET request. - * @see Further information about this action online (including a response example) - * @since 5.2 - */ - public GroupsWsResponse groups(GroupsRequest request) { - return call( - new GetRequest(path("groups")) - .setParam("login", request.getLogin()) - .setParam("organization", request.getOrganization()) - .setParam("p", request.getP()) - .setParam("ps", request.getPs()) - .setParam("q", request.getQ()) - .setParam("selected", request.getSelected()), - GroupsWsResponse.parser()); - } - - /** - * - * This is part of the internal API. - * This is a GET request. - * @see Further information about this action online (including a response example) - * @since 5.5 - */ - public IdentityProvidersWsResponse identityProviders() { - return call( - new GetRequest(path("identity_providers")), - IdentityProvidersWsResponse.parser()); - } - - /** - * - * This is part of the internal API. - * This is a GET request. - * @see Further information about this action online (including a response example) - * @since 3.6 - */ - public SearchWsResponse search(SearchRequest request) { - return call( - new GetRequest(path("search")) - .setParam("f", request.getF() == null ? null : request.getF().stream().collect(Collectors.joining(","))) - .setParam("p", request.getP()) - .setParam("ps", request.getPs()) - .setParam("q", request.getQ()), - SearchWsResponse.parser()); - } - - /** - * - * This is part of the internal API. - * This is a POST request. - * @see Further information about this action online (including a response example) - * @since 6.5 - */ - public void skipOnboardingTutorial() { - call( - new PostRequest(path("skip_onboarding_tutorial")) - .setMediaType(MediaTypes.JSON) - ).content(); - } - - /** - * - * This is part of the internal API. - * This is a POST request. - * @see Further information about this action online (including a response example) - * @since 3.7 - */ - public String update(UpdateRequest request) { - return call( - new PostRequest(path("update")) - .setParam("email", request.getEmail()) - .setParam("login", request.getLogin()) - .setParam("name", request.getName()) - .setParam("scmAccount", request.getScmAccount()) - .setParam("scmAccounts", request.getScmAccounts()) - .setMediaType(MediaTypes.JSON) - ).content(); - } -} diff --git a/sonar-ws/src/main/java/org/sonarqube/ws/client/users/package-info.java b/sonar-ws/src/main/java/org/sonarqube/ws/client/users/package-info.java deleted file mode 100644 index 90f68b1a6d2..00000000000 --- a/sonar-ws/src/main/java/org/sonarqube/ws/client/users/package-info.java +++ /dev/null @@ -1,26 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2017 SonarSource SA - * mailto:info 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. - */ -@ParametersAreNonnullByDefault -@Generated("sonar-ws-generator") -package org.sonarqube.ws.client.users; - -import javax.annotation.ParametersAreNonnullByDefault; -import javax.annotation.Generated; - -- 2.39.5