From b8198f32a6c687bdcdd37f4579b5678e0b372198 Mon Sep 17 00:00:00 2001 From: Malek-Ben-Anes Date: Tue, 25 Oct 2022 14:07:15 +0200 Subject: [PATCH] SONAR-17513 Deprecated legacy pagination parameters in APIs results --- .../qualityprofile/ws/ChangelogAction.java | 22 ++++- .../sonar/server/rule/ws/SearchAction.java | 10 +++ .../server/usergroups/ws/UsersAction.java | 11 +++ .../server/metric/ws/example-search.json | 8 +- .../qualityprofile/ws/changelog-example.json | 8 +- .../sonar/server/rule/ws/search-example.json | 8 +- .../server/usergroups/ws/users-example.json | 8 +- .../ws/ws/response_example-example.json | 89 ++++++++++++++++++- .../ws/ChangelogActionTest.java | 16 ++-- .../server/rule/ws/SearchActionTest.java | 40 +++++++++ .../server/usergroups/ws/UsersActionTest.java | 17 ++++ ...apply_paging_with_multiple_components.json | 7 +- .../apply_paging_with_one_component.json | 7 +- .../ignore_paging_with_one_component.json | 7 +- .../issue/ws/SearchActionTest/no_issue.json | 7 +- .../issue/ws/SearchActionTest/paging.json | 7 +- .../changelog_example.json | 43 +++++++++ .../filter_by_tags.json | 25 ++++-- .../get_note_as_markdown_and_html.json | 9 +- .../search_2_rules.json | 5 ++ .../search_2_rules_fields.json | 5 ++ .../search_active_rules.json | 9 +- ...th_default_and_overridden_debt_values.json | 11 ++- ...r_offset_and_overridden_constant_debt.json | 32 ++++--- ...ear_offset_and_overridden_linear_debt.json | 11 ++- .../search_no_rules.json | 5 ++ .../rule/ws/SearchActionTest/paging.json | 10 +++ sonar-ws/src/main/protobuf/ws-rules.proto | 8 +- 28 files changed, 391 insertions(+), 54 deletions(-) create mode 100644 server/sonar-webserver-webapi/src/test/resources/org/sonar/server/qualityprofile/ws/ChangelogActionTest/changelog_example.json create mode 100644 server/sonar-webserver-webapi/src/test/resources/org/sonar/server/rule/ws/SearchActionTest/paging.json diff --git a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/qualityprofile/ws/ChangelogAction.java b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/qualityprofile/ws/ChangelogAction.java index a47320dd6e4..776829ddc16 100644 --- a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/qualityprofile/ws/ChangelogAction.java +++ b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/qualityprofile/ws/ChangelogAction.java @@ -70,6 +70,9 @@ public class ChangelogAction implements QProfileWsAction { .setSince("5.2") .setDescription("Get the history of changes on a quality profile: rule activation/deactivation, change in parameters/severity. " + "Events are ordered by date in descending order (most recent first).") + .setChangelog( + new org.sonar.api.server.ws.Change("9.8", "response fields 'total', 's', 'ps' have been deprecated, please use 'paging' object instead"), + new org.sonar.api.server.ws.Change("9.8", "The field 'paging' has been added to the response")) .setHandler(this) .setResponseExample(getClass().getResource("changelog-example.json")); @@ -141,9 +144,12 @@ public class ChangelogAction implements QProfileWsAction { private static void writeResponse(JsonWriter json, int total, int page, int pageSize, List changelogs, Map usersByUuid, Map rulesByRuleUuids) { json.beginObject(); - json.prop("total", total); - json.prop(Param.PAGE, page); - json.prop(Param.PAGE_SIZE, pageSize); + writePaging(json, total, page, pageSize); + json.name("paging").beginObject() + .prop("pageIndex", page) + .prop("pageSize", pageSize) + .prop("total", total) + .endObject(); json.name("events").beginArray(); changelogs.forEach(change -> { JsonWriter changeWriter = json.beginObject(); @@ -178,6 +184,16 @@ public class ChangelogAction implements QProfileWsAction { json.endObject(); } + /** + * @deprecated since 9.8 - replaced by 'paging' object structure. + */ + @Deprecated(since = "9.8") + private static void writePaging(JsonWriter json, int total, int page, int pageSize) { + json.prop("total", total); + json.prop(Param.PAGE, page); + json.prop(Param.PAGE_SIZE, pageSize); + } + /** * @return non-null list of changes, by descending order of date */ diff --git a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/rule/ws/SearchAction.java b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/rule/ws/SearchAction.java index 016d1da1236..13ea8a5011b 100644 --- a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/rule/ws/SearchAction.java +++ b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/rule/ws/SearchAction.java @@ -138,6 +138,8 @@ public class SearchAction implements RulesWsAction { .addPagingParams(100, MAX_PAGE_SIZE) .setHandler(this) .setChangelog( + new Change("9.8", "response fields 'total', 's', 'ps' have been deprecated, please use 'paging' object instead"), + new Change("9.8", "The field 'paging' has been added to the response"), new Change("5.5", "The field 'effortToFixDescription' has been deprecated use 'gapDescription' instead"), new Change("5.5", "The field 'debtRemFnCoeff' has been deprecated use 'remFnGapMultiplier' instead"), new Change("5.5", "The field 'defaultDebtRemFnCoeff' has been deprecated use 'defaultRemFnGapMultiplier' instead"), @@ -202,6 +204,14 @@ public class SearchAction implements RulesWsAction { response.setTotal(searchResult.total); response.setP(context.getPage()); response.setPs(context.getLimit()); + response.setPaging(formatPaging(searchResult.total, context.getPage(), context.getLimit())); + } + + private static Common.Paging.Builder formatPaging(Long total, int pageIndex, int limit) { + return Common.Paging.newBuilder() + .setPageIndex(pageIndex) + .setPageSize(limit) + .setTotal(total.intValue()); } private void writeRules(DbSession dbSession, SearchResponse.Builder response, SearchResult result, SearchOptions context) { diff --git a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/usergroups/ws/UsersAction.java b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/usergroups/ws/UsersAction.java index 651230763c1..d51d675790f 100644 --- a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/usergroups/ws/UsersAction.java +++ b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/usergroups/ws/UsersAction.java @@ -68,6 +68,8 @@ public class UsersAction implements UserGroupsWsAction { .addSearchQuery("freddy", "names", "logins") .addPagingParams(25) .setChangelog( + new Change("9.8", "response fields 'total', 's', 'ps' have been deprecated, please use 'paging' object instead."), + new Change("9.8", "The field 'paging' has been added to the response."), new Change("8.4", "Parameter 'id' is deprecated. Format changes from integer to string. Use 'name' instead.")); defineGroupWsParameters(action); @@ -99,6 +101,11 @@ public class UsersAction implements UserGroupsWsAction { json.beginObject(); writeMembers(json, users); writePaging(json, paging); + json.name("paging").beginObject() + .prop("pageIndex", page) + .prop("pageSize", pageSize) + .prop("total", total) + .endObject(); json.endObject(); } } @@ -116,6 +123,10 @@ public class UsersAction implements UserGroupsWsAction { json.endArray(); } + /** + * @deprecated since 9.8 - replaced by 'paging' object structure. + */ + @Deprecated(since = "9.8") private static void writePaging(JsonWriter json, Paging paging) { json.prop(Param.PAGE, paging.pageIndex()) .prop(Param.PAGE_SIZE, paging.pageSize()) diff --git a/server/sonar-webserver-webapi/src/main/resources/org/sonar/server/metric/ws/example-search.json b/server/sonar-webserver-webapi/src/main/resources/org/sonar/server/metric/ws/example-search.json index a10a1d76c86..4de63316bb5 100644 --- a/server/sonar-webserver-webapi/src/main/resources/org/sonar/server/metric/ws/example-search.json +++ b/server/sonar-webserver-webapi/src/main/resources/org/sonar/server/metric/ws/example-search.json @@ -25,7 +25,9 @@ "custom": false } ], - "total": 2, - "p": 1, - "ps": 100 + "paging": { + "pageSize": 100, + "total": 2, + "pageIndex": 1 + } } diff --git a/server/sonar-webserver-webapi/src/main/resources/org/sonar/server/qualityprofile/ws/changelog-example.json b/server/sonar-webserver-webapi/src/main/resources/org/sonar/server/qualityprofile/ws/changelog-example.json index 49556046226..0bf3a77442e 100644 --- a/server/sonar-webserver-webapi/src/main/resources/org/sonar/server/qualityprofile/ws/changelog-example.json +++ b/server/sonar-webserver-webapi/src/main/resources/org/sonar/server/qualityprofile/ws/changelog-example.json @@ -1,7 +1,9 @@ { - "total": 3, - "ps": 10, - "p": 1, + "paging": { + "pageSize": 10, + "total": 3, + "pageIndex": 1 + }, "events": [ { "date" : "2015-02-23T17:58:39+0100", diff --git a/server/sonar-webserver-webapi/src/main/resources/org/sonar/server/rule/ws/search-example.json b/server/sonar-webserver-webapi/src/main/resources/org/sonar/server/rule/ws/search-example.json index cc1dfc76622..e2a94d52852 100644 --- a/server/sonar-webserver-webapi/src/main/resources/org/sonar/server/rule/ws/search-example.json +++ b/server/sonar-webserver-webapi/src/main/resources/org/sonar/server/rule/ws/search-example.json @@ -1,7 +1,9 @@ { - "total": 4, - "p": 1, - "ps": 3, + "paging": { + "pageSize": 3, + "total": 4, + "pageIndex": 1 + }, "rules": [ { "key": "squid:S1067", diff --git a/server/sonar-webserver-webapi/src/main/resources/org/sonar/server/usergroups/ws/users-example.json b/server/sonar-webserver-webapi/src/main/resources/org/sonar/server/usergroups/ws/users-example.json index d90046c4686..9b38c59393e 100644 --- a/server/sonar-webserver-webapi/src/main/resources/org/sonar/server/usergroups/ws/users-example.json +++ b/server/sonar-webserver-webapi/src/main/resources/org/sonar/server/usergroups/ws/users-example.json @@ -11,7 +11,9 @@ "selected": true } ], - "p":1, - "ps":25, - "total":2 + "paging": { + "pageIndex": 1, + "pageSize": 25, + "total": 2 + } } diff --git a/server/sonar-webserver-webapi/src/main/resources/org/sonar/server/ws/ws/response_example-example.json b/server/sonar-webserver-webapi/src/main/resources/org/sonar/server/ws/ws/response_example-example.json index 86a6548d865..46674b77634 100644 --- a/server/sonar-webserver-webapi/src/main/resources/org/sonar/server/ws/ws/response_example-example.json +++ b/server/sonar-webserver-webapi/src/main/resources/org/sonar/server/ws/ws/response_example-example.json @@ -1,4 +1,91 @@ { "format": "json", - "example": "{\n \"paging\": {\n \"pageIndex\": 1,\n \"pageSize\": 100,\n \"total\": 1\n },\n \"issues\": [\n {\n \"key\": \"01fc972e-2a3c-433e-bcae-0bd7f88f5123\",\n \"component\": \"com.github.kevinsawicki:http-request:com.github.kevinsawicki.http.HttpRequest\",\n \"project\": \"com.github.kevinsawicki:http-request\",\n \"rule\": \"checkstyle:com.puppycrawl.tools.checkstyle.checks.coding.MagicNumberCheck\",\n \"status\": \"RESOLVED\",\n \"resolution\": \"FALSE-POSITIVE\",\n \"severity\": \"MINOR\",\n \"message\": \"'3' is a magic number.\",\n \"line\": 530,\n \"textRange\": {\n \"startLine\": 81,\n \"endLine\": 81,\n \"startOffset\": 0,\n \"endOffset\": 134\n },\n \"author\": \"Developer 1\",\n \"debt\": \"2h1min\",\n \"creationDate\": \"2013-05-13T17:55:39+0200\",\n \"updateDate\": \"2013-05-13T17:55:39+0200\",\n \"tags\": [\"bug\"],\n \"comments\": [\n {\n \"key\": \"7d7c56f5-7b5a-41b9-87f8-36fa70caa5ba\",\n \"login\": \"john.smith\",\n \"htmlText\": \"Must be "final"!\",\n \"markdown\": \"Must be \\\"final\\\"!\",\n \"updatable\": false,\n \"createdAt\": \"2013-05-13T18:08:34+0200\"\n }\n ],\n \"attr\": {\n \"jira-issue-key\": \"SONAR-1234\"\n },\n \"transitions\": [\n \"unconfirm\",\n \"resolve\",\n \"falsepositive\"\n ],\n \"actions\": [\n \"comment\"\n ]\n }\n ],\n \"components\": [\n {\n \"key\": \"com.github.kevinsawicki:http-request:src/main/java/com/github/kevinsawicki/http/HttpRequest.java\",\n \"enabled\": true,\n \"qualifier\": \"FIL\",\n \"name\": \"HttpRequest.java\",\n \"longName\": \"src/main/java/com/github/kevinsawicki/http/HttpRequest.java\",\n \"path\": \"src/main/java/com/github/kevinsawicki/http/HttpRequest.java\"\n },\n {\n \"key\": \"com.github.kevinsawicki:http-request\",\n \"enabled\": true,\n \"qualifier\": \"TRK\",\n \"name\": \"http-request\",\n \"longName\": \"http-request\"\n }\n ],\n \"rules\": [\n {\n \"key\": \"checkstyle:com.puppycrawl.tools.checkstyle.checks.coding.MagicNumberCheck\",\n \"name\": \"Magic Number\",\n \"status\": \"READY\",\n \"lang\": \"java\",\n \"langName\": \"Java\"\n }\n ],\n \"users\": [\n {\n \"login\": \"admin\",\n \"name\": \"Administrator\",\n \"active\": true,\n \"email\": \"admin@sonarqube.org\"\n }\n ]\n\n}" + "example": { + "paging": { + "pageIndex": 1, + "pageSize": 100, + "total": 1 + }, + "issues": [ + { + "key": "01fc972e-2a3c-433e-bcae-0bd7f88f5123", + "component": "com.github.kevinsawicki:http-request:com.github.kevinsawicki.http.HttpRequest", + "project": "com.github.kevinsawicki:http-request", + "rule": "checkstyle:com.puppycrawl.tools.checkstyle.checks.coding.MagicNumberCheck", + "status": "RESOLVED", + "resolution": "FALSE-POSITIVE", + "severity": "MINOR", + "message": "'3' is a magic number.", + "line": 530, + "textRange": { + "startLine": 81, + "endLine": 81, + "startOffset": 0, + "endOffset": 134 + }, + "author": "Developer 1", + "debt": "2h1min", + "creationDate": "2013-05-13T17: 55: 39+0200", + "updateDate": "2013-05-13T17: 55: 39+0200", + "tags": [ + "bug" + ], + "comments": [ + { + "key": "7d7c56f5-7b5a-41b9-87f8-36fa70caa5ba", + "login": "john.smith", + "htmlText": "Must be "final"!", + "markdown": "Must be \"final\"!", + "updatable": false, + "createdAt": "2013-05-13T18: 08: 34+0200" + } + ], + "attr": { + "jira-issue-key": "SONAR-1234" + }, + "transitions": [ + "unconfirm", + "resolve", + "falsepositive" + ], + "actions": [ + "comment" + ] + } + ], + "components": [ + { + "key": "com.github.kevinsawicki:http-request:src/main/java/com/github/kevinsawicki/http/HttpRequest.java", + "enabled": true, + "qualifier": "FIL", + "name": "HttpRequest.java", + "longName": "src/main/java/com/github/kevinsawicki/http/HttpRequest.java", + "path": "src/main/java/com/github/kevinsawicki/http/HttpRequest.java" + }, + { + "key": "com.github.kevinsawicki:http-request", + "enabled": true, + "qualifier": "TRK", + "name": "http-request", + "longName": "http-request" + } + ], + "rules": [ + { + "key": "checkstyle:com.puppycrawl.tools.checkstyle.checks.coding.MagicNumberCheck", + "name": "Magic Number", + "status": "READY", + "lang": "java", + "langName": "Java" + } + ], + "users": [ + { + "login": "admin", + "name": "Administrator", + "active": true, + "email": "admin@sonarqube.org" + } + ] + } } diff --git a/server/sonar-webserver-webapi/src/test/java/org/sonar/server/qualityprofile/ws/ChangelogActionTest.java b/server/sonar-webserver-webapi/src/test/java/org/sonar/server/qualityprofile/ws/ChangelogActionTest.java index 46e70c7404b..b6836a27736 100644 --- a/server/sonar-webserver-webapi/src/test/java/org/sonar/server/qualityprofile/ws/ChangelogActionTest.java +++ b/server/sonar-webserver-webapi/src/test/java/org/sonar/server/qualityprofile/ws/ChangelogActionTest.java @@ -83,6 +83,11 @@ public class ChangelogActionTest { " \"total\": 1,\n" + " \"p\": 1,\n" + " \"ps\": 50,\n" + + " \"paging\": {\n" + + " \"pageIndex\": 1,\n" + + " \"pageSize\": 50,\n" + + " \"total\": 1\n" + + " }," + " \"events\": [\n" + " {\n" + " \"date\": \"" + DATE + "\",\n" + @@ -168,14 +173,13 @@ public class ChangelogActionTest { @Test public void changelog_empty() { QProfileDto qualityProfile = db.qualityProfiles().insert(); - String response = ws.newRequest() .setParam(PARAM_LANGUAGE, qualityProfile.getLanguage()) .setParam(PARAM_QUALITY_PROFILE, qualityProfile.getName()) .execute() .getInput(); - assertJson(response).isSimilarTo("{\"total\":0,\"p\":1,\"ps\":50,\"events\":[]}"); + assertJson(response).isSimilarTo("{\"total\":0,\"p\":1,\"ps\":50,\"paging\":{\"pageIndex\":1,\"pageSize\":50,\"total\":0},\"events\":[]}"); } @Test @@ -315,7 +319,7 @@ public class ChangelogActionTest { } @Test - public void example() { + public void changelog_example() { QProfileDto profile = db.qualityProfiles().insert(); String profileUuid = profile.getRulesProfileUuid(); @@ -343,15 +347,13 @@ public class ChangelogActionTest { .setChangeType(ActiveRuleChange.Type.ACTIVATED.name()) .setData(ImmutableMap.of("severity", "MAJOR", "param_format", "^[A-Z][a-zA-Z0-9]*$", "ruleUuid", rule3.getUuid()))); - String response = ws.newRequest() + ws.newRequest() .setMethod("GET") .setParam(PARAM_LANGUAGE, profile.getLanguage()) .setParam(PARAM_QUALITY_PROFILE, profile.getName()) .setParam("ps", "10") .execute() - .getInput(); - - assertJson(response).isSimilarTo(getClass().getResource("changelog-example.json")); + .assertJson(this.getClass(), "changelog_example.json"); } @Test diff --git a/server/sonar-webserver-webapi/src/test/java/org/sonar/server/rule/ws/SearchActionTest.java b/server/sonar-webserver-webapi/src/test/java/org/sonar/server/rule/ws/SearchActionTest.java index fc332643679..f2a7e1a94b5 100644 --- a/server/sonar-webserver-webapi/src/test/java/org/sonar/server/rule/ws/SearchActionTest.java +++ b/server/sonar-webserver-webapi/src/test/java/org/sonar/server/rule/ws/SearchActionTest.java @@ -161,6 +161,9 @@ public class SearchActionTest { assertThat(response.getTotal()).isZero(); assertThat(response.getP()).isOne(); + assertThat(response.getPaging().getTotal()).isZero(); + assertThat(response.getPaging().getPageIndex()).isOne(); + assertThat(response.getPaging().getPageSize()).isNotZero(); assertThat(response.getRulesCount()).isZero(); } @@ -541,6 +544,8 @@ public class SearchActionTest { .setParam("f", "langName") .executeProtobuf(SearchResponse.class); assertThat(result.getTotal()).isOne(); + assertThat(result.getPaging().getTotal()).isOne(); + assertThat(result.getPaging().getPageIndex()).isOne(); assertThat(result.getRulesCount()).isOne(); Rule searchedRule = result.getRules(0); @@ -564,6 +569,8 @@ public class SearchActionTest { .setParam("f", "debtRemFn,debtOverloaded,defaultDebtRemFn") .executeProtobuf(SearchResponse.class); assertThat(result.getTotal()).isOne(); + assertThat(result.getPaging().getTotal()).isOne(); + assertThat(result.getPaging().getPageIndex()).isOne(); assertThat(result.getRulesCount()).isOne(); Rule searchedRule = result.getRules(0); @@ -596,6 +603,8 @@ public class SearchActionTest { .setParam("f", "debtRemFn,debtOverloaded,defaultDebtRemFn") .executeProtobuf(SearchResponse.class); assertThat(result.getTotal()).isOne(); + assertThat(result.getPaging().getTotal()).isOne(); + assertThat(result.getPaging().getPageIndex()).isOne(); assertThat(result.getRulesCount()).isOne(); Rule searchedRule = result.getRules(0); @@ -628,6 +637,8 @@ public class SearchActionTest { .setParam("f", "debtRemFn,debtOverloaded,defaultDebtRemFn") .executeProtobuf(SearchResponse.class); assertThat(result.getTotal()).isOne(); + assertThat(result.getPaging().getTotal()).isOne(); + assertThat(result.getPaging().getPageIndex()).isOne(); assertThat(result.getRulesCount()).isOne(); Rule searchedRule = result.getRules(0); @@ -658,6 +669,8 @@ public class SearchActionTest { .setParam("is_template", "true") .executeProtobuf(SearchResponse.class); assertThat(result.getTotal()).isOne(); + assertThat(result.getPaging().getTotal()).isOne(); + assertThat(result.getPaging().getPageIndex()).isOne(); assertThat(result.getRulesCount()).isOne(); Rule searchedRule = result.getRules(0); @@ -680,6 +693,8 @@ public class SearchActionTest { .setParam("template_key", templateRule.getRepositoryKey() + ":" + templateRule.getRuleKey()) .executeProtobuf(SearchResponse.class); assertThat(result.getTotal()).isOne(); + assertThat(result.getPaging().getTotal()).isOne(); + assertThat(result.getPaging().getPageIndex()).isOne(); assertThat(result.getRulesCount()).isOne(); Rule searchedRule = result.getRules(0); @@ -696,6 +711,8 @@ public class SearchActionTest { SearchResponse result = ws.newRequest().executeProtobuf(SearchResponse.class); assertThat(result.getTotal()).isZero(); + assertThat(result.getPaging().getTotal()).isZero(); + assertThat(result.getPaging().getPageIndex()).isOne(); assertThat(result.getRulesCount()).isZero(); } @@ -713,6 +730,8 @@ public class SearchActionTest { .setParam("activation", "true") .executeProtobuf(SearchResponse.class); assertThat(result.getTotal()).isOne(); + assertThat(result.getPaging().getTotal()).isOne(); + assertThat(result.getPaging().getPageIndex()).isOne(); assertThat(result.getRulesCount()).isOne(); Rule searchedRule = result.getRules(0); @@ -756,6 +775,8 @@ public class SearchActionTest { .setParam("qprofile", profile.getKee()) .executeProtobuf(SearchResponse.class); assertThat(result.getTotal()).isOne(); + assertThat(result.getPaging().getTotal()).isOne(); + assertThat(result.getPaging().getPageIndex()).isOne(); assertThat(result.getRulesCount()).isOne(); assertThat(result.getActives()).isNotNull(); assertThat(result.getActives().getActives().get(rule.getKey().toString())).isNotNull(); @@ -811,6 +832,8 @@ public class SearchActionTest { .executeProtobuf(SearchResponse.class); assertThat(result.getTotal()).isOne(); + assertThat(result.getPaging().getTotal()).isOne(); + assertThat(result.getPaging().getPageIndex()).isOne(); assertThat(result.getRulesCount()).isOne(); assertThat(result.getActives()).isNotNull(); assertThat(result.getActives().getActives().get(rule.getKey().toString())).isNotNull(); @@ -949,6 +972,20 @@ public class SearchActionTest { tuple(rule3.getKey().toString(), rule3.getStatus().name())); } + @Test + public void paging() { + for (int i = 0; i < 12; i++) { + db.rules().insert(r -> r.setLanguage("java")); + } + indexRules(); + + ws.newRequest() + .setParam(WebService.Param.PAGE, "2") + .setParam(WebService.Param.PAGE_SIZE, "9") + .execute() + .assertJson(this.getClass(), "paging.json"); + } + @Test public void compare_to_another_profile() { QProfileDto profile = db.qualityProfiles().insert(p -> p.setLanguage(JAVA)); @@ -1009,11 +1046,14 @@ public class SearchActionTest { Rules.SearchResponse response = request.executeProtobuf(Rules.SearchResponse.class); assertThat(response.getP()).isOne(); + assertThat(response.getPaging().getPageIndex()).isOne(); + assertThat(response.getPaging().getPageSize()).isNotZero(); RuleKey[] expectedRuleKeys = stream(expectedRules).map(RuleDto::getKey).collect(MoreCollectors.toList()).toArray(new RuleKey[0]); assertThat(response.getRulesList()) .extracting(r -> RuleKey.parse(r.getKey())) .containsExactlyInAnyOrder(expectedRuleKeys); assertThat(response.getTotal()).isEqualTo(expectedRules.length); + assertThat(response.getPaging().getTotal()).isEqualTo(expectedRules.length); assertThat(response.getRulesCount()).isEqualTo(expectedRules.length); } diff --git a/server/sonar-webserver-webapi/src/test/java/org/sonar/server/usergroups/ws/UsersActionTest.java b/server/sonar-webserver-webapi/src/test/java/org/sonar/server/usergroups/ws/UsersActionTest.java index 3e6e408f79b..f08ac493e65 100644 --- a/server/sonar-webserver-webapi/src/test/java/org/sonar/server/usergroups/ws/UsersActionTest.java +++ b/server/sonar-webserver-webapi/src/test/java/org/sonar/server/usergroups/ws/UsersActionTest.java @@ -61,6 +61,8 @@ public class UsersActionTest { assertThat(wsDef.since()).isEqualTo("5.2"); assertThat(wsDef.isPost()).isFalse(); assertThat(wsDef.changelog()).extracting(Change::getVersion, Change::getDescription).containsOnly( + tuple("9.8", "response fields 'total', 's', 'ps' have been deprecated, please use 'paging' object instead."), + tuple("9.8", "The field 'paging' has been added to the response."), tuple("8.4", "Parameter 'id' is deprecated. Format changes from integer to string. Use 'name' instead.")); } @@ -104,6 +106,11 @@ public class UsersActionTest { assertJson(result).isSimilarTo("{\n" + " \"p\": 1,\n" + " \"total\": 0,\n" + + " \"paging\": {\n" + + " \"pageIndex\": 1,\n" + + " \"pageSize\": 25,\n" + + " \"total\": 0\n" + + " }," + " \"users\": []\n" + "}"); } @@ -232,6 +239,11 @@ public class UsersActionTest { " \"p\": 1,\n" + " \"ps\": 1,\n" + " \"total\": 2,\n" + + " \"paging\": {\n" + + " \"pageIndex\": 1,\n" + + " \"pageSize\": 1,\n" + + " \"total\": 2\n" + + " }," + " \"users\": [\n" + " {\"login\": \"ada\", \"name\": \"Ada Lovelace\", \"selected\": true}\n" + " ]\n" + @@ -247,6 +259,11 @@ public class UsersActionTest { " \"p\": 2,\n" + " \"ps\": 1,\n" + " \"total\": 2,\n" + + " \"paging\": {\n" + + " \"pageIndex\": 2,\n" + + " \"pageSize\": 1,\n" + + " \"total\": 2\n" + + " }," + " \"users\": [\n" + " {\"login\": \"grace\", \"name\": \"Grace Hopper\", \"selected\": false}\n" + " ]\n" + diff --git a/server/sonar-webserver-webapi/src/test/resources/org/sonar/server/issue/ws/SearchActionTest/apply_paging_with_multiple_components.json b/server/sonar-webserver-webapi/src/test/resources/org/sonar/server/issue/ws/SearchActionTest/apply_paging_with_multiple_components.json index 640bd4009d1..2629aa292a6 100644 --- a/server/sonar-webserver-webapi/src/test/resources/org/sonar/server/issue/ws/SearchActionTest/apply_paging_with_multiple_components.json +++ b/server/sonar-webserver-webapi/src/test/resources/org/sonar/server/issue/ws/SearchActionTest/apply_paging_with_multiple_components.json @@ -1,5 +1,10 @@ { "total": 501, "p": 1, - "ps": 100 + "ps": 100, + "paging": { + "pageIndex": 1, + "pageSize": 100, + "total": 501 + } } diff --git a/server/sonar-webserver-webapi/src/test/resources/org/sonar/server/issue/ws/SearchActionTest/apply_paging_with_one_component.json b/server/sonar-webserver-webapi/src/test/resources/org/sonar/server/issue/ws/SearchActionTest/apply_paging_with_one_component.json index 640bd4009d1..2629aa292a6 100644 --- a/server/sonar-webserver-webapi/src/test/resources/org/sonar/server/issue/ws/SearchActionTest/apply_paging_with_one_component.json +++ b/server/sonar-webserver-webapi/src/test/resources/org/sonar/server/issue/ws/SearchActionTest/apply_paging_with_one_component.json @@ -1,5 +1,10 @@ { "total": 501, "p": 1, - "ps": 100 + "ps": 100, + "paging": { + "pageIndex": 1, + "pageSize": 100, + "total": 501 + } } diff --git a/server/sonar-webserver-webapi/src/test/resources/org/sonar/server/issue/ws/SearchActionTest/ignore_paging_with_one_component.json b/server/sonar-webserver-webapi/src/test/resources/org/sonar/server/issue/ws/SearchActionTest/ignore_paging_with_one_component.json index 7da1192f599..87fc782db8b 100644 --- a/server/sonar-webserver-webapi/src/test/resources/org/sonar/server/issue/ws/SearchActionTest/ignore_paging_with_one_component.json +++ b/server/sonar-webserver-webapi/src/test/resources/org/sonar/server/issue/ws/SearchActionTest/ignore_paging_with_one_component.json @@ -1,5 +1,10 @@ { "total": 501, "p": 1, - "ps": 999999 + "ps": 999999, + "paging": { + "pageIndex": 1, + "pageSize": 999999, + "total": 501 + } } diff --git a/server/sonar-webserver-webapi/src/test/resources/org/sonar/server/issue/ws/SearchActionTest/no_issue.json b/server/sonar-webserver-webapi/src/test/resources/org/sonar/server/issue/ws/SearchActionTest/no_issue.json index ce8bbfbeeb7..5d7390f509e 100644 --- a/server/sonar-webserver-webapi/src/test/resources/org/sonar/server/issue/ws/SearchActionTest/no_issue.json +++ b/server/sonar-webserver-webapi/src/test/resources/org/sonar/server/issue/ws/SearchActionTest/no_issue.json @@ -1,4 +1,9 @@ { "total": 0, - "issues": [] + "issues": [], + "paging": { + "pageIndex": 1, + "pageSize": 100, + "total": 0 + } } diff --git a/server/sonar-webserver-webapi/src/test/resources/org/sonar/server/issue/ws/SearchActionTest/paging.json b/server/sonar-webserver-webapi/src/test/resources/org/sonar/server/issue/ws/SearchActionTest/paging.json index d16592f6408..e9042aabbe7 100644 --- a/server/sonar-webserver-webapi/src/test/resources/org/sonar/server/issue/ws/SearchActionTest/paging.json +++ b/server/sonar-webserver-webapi/src/test/resources/org/sonar/server/issue/ws/SearchActionTest/paging.json @@ -1,5 +1,10 @@ { "total": 12, "p": 2, - "ps": 9 + "ps": 9, + "paging": { + "pageIndex": 2, + "pageSize": 9, + "total": 12 + } } diff --git a/server/sonar-webserver-webapi/src/test/resources/org/sonar/server/qualityprofile/ws/ChangelogActionTest/changelog_example.json b/server/sonar-webserver-webapi/src/test/resources/org/sonar/server/qualityprofile/ws/ChangelogActionTest/changelog_example.json new file mode 100644 index 00000000000..c40c1bb7f32 --- /dev/null +++ b/server/sonar-webserver-webapi/src/test/resources/org/sonar/server/qualityprofile/ws/ChangelogActionTest/changelog_example.json @@ -0,0 +1,43 @@ +{ + "total": 3, + "ps": 10, + "p": 1, + "paging": { + "pageSize": 10, + "total": 3, + "pageIndex": 1 + }, + "events": [ + { + "date" : "2015-02-23T17:58:39+0100", + "action" : "ACTIVATED", + "authorLogin" : "anakin.skywalker", + "authorName" : "Anakin Skywalker", + "ruleKey" : "java:S2438", + "ruleName" : "\"Threads\" should not be used where \"Runnables\" are expected", + "params" : { + "severity" : "CRITICAL" + } + }, + { + "date" : "2015-02-23T17:58:18+0100", + "action" : "DEACTIVATED", + "authorLogin" : "padme.amidala", + "authorName" : "Padme Amidala", + "ruleKey" : "java:S2162", + "ruleName" : "\"equals\" methods should be symmetric and work for subclasses" + }, + { + "action" : "ACTIVATED", + "authorLogin" : "obiwan.kenobi", + "authorName" : "Obiwan Kenobi", + "ruleKey" : "java:S00101", + "ruleName" : "Class names should comply with a naming convention", + "date" : "2014-09-12T15:20:46+0200", + "params" : { + "severity" : "MAJOR", + "format" : "^[A-Z][a-zA-Z0-9]*$" + } + } + ] +} diff --git a/server/sonar-webserver-webapi/src/test/resources/org/sonar/server/rule/ws/SearchActionMediumTest/filter_by_tags.json b/server/sonar-webserver-webapi/src/test/resources/org/sonar/server/rule/ws/SearchActionMediumTest/filter_by_tags.json index e109ed28cc8..20697e5b8ec 100644 --- a/server/sonar-webserver-webapi/src/test/resources/org/sonar/server/rule/ws/SearchActionMediumTest/filter_by_tags.json +++ b/server/sonar-webserver-webapi/src/test/resources/org/sonar/server/rule/ws/SearchActionMediumTest/filter_by_tags.json @@ -1,11 +1,20 @@ -{"total": 1, "p": 1, "ps": 100, "rules": [ - { - "key": "xoo:x1", - "sysTags": ["tag1"], - "tags": [] - } -], -"facets": [ +{ + "total": 1, + "p": 1, + "ps": 100, + "paging": { + "pageIndex": 1, + "pageSize": 100, + "total": 1 + }, + "rules": [ + { + "key": "xoo:x1", + "sysTags": ["tag1"], + "tags": [] + } + ], + "facets": [ { "property": "tags", "values": [ diff --git a/server/sonar-webserver-webapi/src/test/resources/org/sonar/server/rule/ws/SearchActionMediumTest/get_note_as_markdown_and_html.json b/server/sonar-webserver-webapi/src/test/resources/org/sonar/server/rule/ws/SearchActionMediumTest/get_note_as_markdown_and_html.json index 68a29b47e65..fcee129b4b1 100644 --- a/server/sonar-webserver-webapi/src/test/resources/org/sonar/server/rule/ws/SearchActionMediumTest/get_note_as_markdown_and_html.json +++ b/server/sonar-webserver-webapi/src/test/resources/org/sonar/server/rule/ws/SearchActionMediumTest/get_note_as_markdown_and_html.json @@ -1,5 +1,12 @@ { - "total": 1, "p": 1, "ps": 100, + "total": 1, + "p": 1, + "ps": 100, + "paging": { + "pageIndex": 1, + "pageSize": 100, + "total": 1 + }, "rules": [ { "key": "xoo:x1", diff --git a/server/sonar-webserver-webapi/src/test/resources/org/sonar/server/rule/ws/SearchActionMediumTest/search_2_rules.json b/server/sonar-webserver-webapi/src/test/resources/org/sonar/server/rule/ws/SearchActionMediumTest/search_2_rules.json index 315359d66f9..cd8c7024d55 100644 --- a/server/sonar-webserver-webapi/src/test/resources/org/sonar/server/rule/ws/SearchActionMediumTest/search_2_rules.json +++ b/server/sonar-webserver-webapi/src/test/resources/org/sonar/server/rule/ws/SearchActionMediumTest/search_2_rules.json @@ -2,6 +2,11 @@ "total": 2, "p": 1, "ps": 100, + "paging": { + "pageIndex": 1, + "pageSize": 100, + "total": 2 + }, "rules": [ { "key": "xoo:x2", diff --git a/server/sonar-webserver-webapi/src/test/resources/org/sonar/server/rule/ws/SearchActionMediumTest/search_2_rules_fields.json b/server/sonar-webserver-webapi/src/test/resources/org/sonar/server/rule/ws/SearchActionMediumTest/search_2_rules_fields.json index 30c6468a86b..404203e522f 100644 --- a/server/sonar-webserver-webapi/src/test/resources/org/sonar/server/rule/ws/SearchActionMediumTest/search_2_rules_fields.json +++ b/server/sonar-webserver-webapi/src/test/resources/org/sonar/server/rule/ws/SearchActionMediumTest/search_2_rules_fields.json @@ -2,6 +2,11 @@ "total": 2, "p": 1, "ps": 100, + "paging": { + "pageIndex": 1, + "pageSize": 100, + "total": 2 + }, "rules": [ { "key": "xoo:x2", diff --git a/server/sonar-webserver-webapi/src/test/resources/org/sonar/server/rule/ws/SearchActionMediumTest/search_active_rules.json b/server/sonar-webserver-webapi/src/test/resources/org/sonar/server/rule/ws/SearchActionMediumTest/search_active_rules.json index 76e721d0b85..fdc460c739d 100644 --- a/server/sonar-webserver-webapi/src/test/resources/org/sonar/server/rule/ws/SearchActionMediumTest/search_active_rules.json +++ b/server/sonar-webserver-webapi/src/test/resources/org/sonar/server/rule/ws/SearchActionMediumTest/search_active_rules.json @@ -1,5 +1,12 @@ { - "total": 1, "p": 1, "ps": 100, + "total": 1, + "p": 1, + "ps": 100, + "paging": { + "pageIndex": 1, + "pageSize": 100, + "total": 2 + }, "rules": [ { "key": "xoo:x1" diff --git a/server/sonar-webserver-webapi/src/test/resources/org/sonar/server/rule/ws/SearchActionMediumTest/search_debt_rules_with_default_and_overridden_debt_values.json b/server/sonar-webserver-webapi/src/test/resources/org/sonar/server/rule/ws/SearchActionMediumTest/search_debt_rules_with_default_and_overridden_debt_values.json index ac69b2e9ea7..2fce4c1f7be 100644 --- a/server/sonar-webserver-webapi/src/test/resources/org/sonar/server/rule/ws/SearchActionMediumTest/search_debt_rules_with_default_and_overridden_debt_values.json +++ b/server/sonar-webserver-webapi/src/test/resources/org/sonar/server/rule/ws/SearchActionMediumTest/search_debt_rules_with_default_and_overridden_debt_values.json @@ -1,4 +1,13 @@ -{"total": 1, "p": 1, "ps": 100, "rules": [ +{ + "total": 1, + "p": 1, + "ps": 100, + "paging": { + "pageIndex": 1, + "pageSize": 100, + "total": 1 + }, + "rules": [ { "key": "xoo:x1", "remFnType": "LINEAR_OFFSET", diff --git a/server/sonar-webserver-webapi/src/test/resources/org/sonar/server/rule/ws/SearchActionMediumTest/search_debt_rules_with_default_linear_offset_and_overridden_constant_debt.json b/server/sonar-webserver-webapi/src/test/resources/org/sonar/server/rule/ws/SearchActionMediumTest/search_debt_rules_with_default_linear_offset_and_overridden_constant_debt.json index d744e2ed7da..435010e807c 100644 --- a/server/sonar-webserver-webapi/src/test/resources/org/sonar/server/rule/ws/SearchActionMediumTest/search_debt_rules_with_default_linear_offset_and_overridden_constant_debt.json +++ b/server/sonar-webserver-webapi/src/test/resources/org/sonar/server/rule/ws/SearchActionMediumTest/search_debt_rules_with_default_linear_offset_and_overridden_constant_debt.json @@ -1,11 +1,21 @@ -{"total": 1, "p": 1, "ps": 100, "rules": [ - { - "key": "xoo:x1", - "remFnType": "CONSTANT_ISSUE", - "remFnBaseEffort": "5min", - "debtOverloaded": true, - "defaultRemFnType": "LINEAR_OFFSET", - "defaultRemFnGapMultiplier": "1h", - "defaultRemFnBaseEffort": "15min" - } -]} +{ + "total": 1, + "p": 1, + "ps": 100, + "paging": { + "pageIndex": 1, + "pageSize": 100, + "total": 1 + }, + "rules": [ + { + "key": "xoo:x1", + "remFnType": "CONSTANT_ISSUE", + "remFnBaseEffort": "5min", + "debtOverloaded": true, + "defaultRemFnType": "LINEAR_OFFSET", + "defaultRemFnGapMultiplier": "1h", + "defaultRemFnBaseEffort": "15min" + } + ] +} diff --git a/server/sonar-webserver-webapi/src/test/resources/org/sonar/server/rule/ws/SearchActionMediumTest/search_debt_rules_with_default_linear_offset_and_overridden_linear_debt.json b/server/sonar-webserver-webapi/src/test/resources/org/sonar/server/rule/ws/SearchActionMediumTest/search_debt_rules_with_default_linear_offset_and_overridden_linear_debt.json index 27e1e453317..684826ba2a4 100644 --- a/server/sonar-webserver-webapi/src/test/resources/org/sonar/server/rule/ws/SearchActionMediumTest/search_debt_rules_with_default_linear_offset_and_overridden_linear_debt.json +++ b/server/sonar-webserver-webapi/src/test/resources/org/sonar/server/rule/ws/SearchActionMediumTest/search_debt_rules_with_default_linear_offset_and_overridden_linear_debt.json @@ -1,4 +1,13 @@ -{"total": 1, "p": 1, "ps": 100, "rules": [ +{ + "total": 1, + "p": 1, + "ps": 100, + "paging": { + "pageIndex": 1, + "pageSize": 100, + "total": 1 + }, + "rules": [ { "key": "xoo:x1", "remFnType": "LINEAR", diff --git a/server/sonar-webserver-webapi/src/test/resources/org/sonar/server/rule/ws/SearchActionMediumTest/search_no_rules.json b/server/sonar-webserver-webapi/src/test/resources/org/sonar/server/rule/ws/SearchActionMediumTest/search_no_rules.json index 0e7286cf282..f62d3435336 100644 --- a/server/sonar-webserver-webapi/src/test/resources/org/sonar/server/rule/ws/SearchActionMediumTest/search_no_rules.json +++ b/server/sonar-webserver-webapi/src/test/resources/org/sonar/server/rule/ws/SearchActionMediumTest/search_no_rules.json @@ -2,6 +2,11 @@ "total": 0, "p": 1, "ps": 100, + "paging": { + "pageIndex": 1, + "pageSize": 100, + "total": 99999 + }, "rules": [], "actives": {}, "qProfiles": {} diff --git a/server/sonar-webserver-webapi/src/test/resources/org/sonar/server/rule/ws/SearchActionTest/paging.json b/server/sonar-webserver-webapi/src/test/resources/org/sonar/server/rule/ws/SearchActionTest/paging.json new file mode 100644 index 00000000000..e9042aabbe7 --- /dev/null +++ b/server/sonar-webserver-webapi/src/test/resources/org/sonar/server/rule/ws/SearchActionTest/paging.json @@ -0,0 +1,10 @@ +{ + "total": 12, + "p": 2, + "ps": 9, + "paging": { + "pageIndex": 2, + "pageSize": 9, + "total": 12 + } +} diff --git a/sonar-ws/src/main/protobuf/ws-rules.proto b/sonar-ws/src/main/protobuf/ws-rules.proto index 7ec1c827f9f..96c6fb64797 100644 --- a/sonar-ws/src/main/protobuf/ws-rules.proto +++ b/sonar-ws/src/main/protobuf/ws-rules.proto @@ -41,13 +41,15 @@ message ListResponse { // WS api/rules/search message SearchResponse { - optional int64 total = 1; - optional int32 p = 2; - optional int64 ps = 3; + optional int64 total = 1 [deprecated=true]; + optional int32 p = 2 [deprecated=true]; + optional int64 ps = 3 [deprecated=true]; + repeated Rule rules = 4; optional Actives actives = 5; optional QProfiles qProfiles = 6; optional sonarqube.ws.commons.Facets facets = 7; + optional sonarqube.ws.commons.Paging paging = 8; } //WS api/rules/show -- 2.39.5