From dd7f7b94c710e1181009d0c6db80fb166b3e0683 Mon Sep 17 00:00:00 2001 From: yrizhkov Date: Fri, 7 May 2021 13:19:43 +0300 Subject: [PATCH 1/8] update dependencies --- build.gradle | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/build.gradle b/build.gradle index 824992e..e8295f9 100644 --- a/build.gradle +++ b/build.gradle @@ -1,9 +1,9 @@ buildscript { ext { - springBootVersion = '2.4.2' + springBootVersion = '2.4.5' springfoxVersion = '2.9.2' httpclientVersion = '4.5.12' - aerospikeClientVersion = findProperty('aerospikeClientVersion') ?:'5.0.2' + aerospikeClientVersion = findProperty('aerospikeClientVersion') ?:'5.1.0' } if (findProperty("aerospikeUseLocal")) { print("using Local repo") From 05a41aa19ef2a54e20e243f48c9865b5b4e050c6 Mon Sep 17 00:00:00 2001 From: yrizhkov Date: Fri, 7 May 2021 13:22:21 +0300 Subject: [PATCH 2/8] add useBoolBin configuration property --- .../aerospike/restclient/config/AerospikeClientConfig.java | 6 +++++- .../com/aerospike/restclient/util/AerospikeClientPool.java | 6 +++++- src/main/resources/application.properties | 6 ++++++ 3 files changed, 16 insertions(+), 2 deletions(-) diff --git a/src/main/java/com/aerospike/restclient/config/AerospikeClientConfig.java b/src/main/java/com/aerospike/restclient/config/AerospikeClientConfig.java index a4ceb21..9dd4865 100644 --- a/src/main/java/com/aerospike/restclient/config/AerospikeClientConfig.java +++ b/src/main/java/com/aerospike/restclient/config/AerospikeClientConfig.java @@ -47,6 +47,9 @@ public class AerospikeClientConfig { @Value("${aerospike.restclient.requireAuthentication:false}") boolean requireAuthentication; + @Value("${aerospike.restclient.useBoolBin:false}") + boolean useBoolBin; + @Autowired ClientPolicy policy; @@ -89,7 +92,8 @@ public AerospikeClientPool configAerospikeClientPool() { port, hostList, hostname, - defaultClient + defaultClient, + useBoolBin ); } } diff --git a/src/main/java/com/aerospike/restclient/util/AerospikeClientPool.java b/src/main/java/com/aerospike/restclient/util/AerospikeClientPool.java index 6d75a36..95b0926 100644 --- a/src/main/java/com/aerospike/restclient/util/AerospikeClientPool.java +++ b/src/main/java/com/aerospike/restclient/util/AerospikeClientPool.java @@ -18,6 +18,7 @@ import com.aerospike.client.AerospikeClient; import com.aerospike.client.Host; +import com.aerospike.client.Value; import com.aerospike.client.policy.ClientPolicy; import com.aerospike.restclient.domain.auth.AuthDetails; import com.google.common.cache.Cache; @@ -41,7 +42,8 @@ public class AerospikeClientPool { private final String hostname; public AerospikeClientPool(int poolSize, ClientPolicy clientPolicy, - int port, String hostList, String hostname, AerospikeClient defaultClient) { + int port, String hostList, String hostname, + AerospikeClient defaultClient, boolean useBoolBin) { this.clientPool = CacheBuilder.newBuilder().maximumSize(poolSize).build(); if (defaultClient != null) { this.clientPool.put(DEFAULT_CLIENT_KEY, defaultClient); @@ -51,6 +53,8 @@ public AerospikeClientPool(int poolSize, ClientPolicy clientPolicy, this.port = port; this.hostList = hostList; this.hostname = hostname; + + Value.UseBoolBin = useBoolBin; } public AerospikeClient getClient(AuthDetails authDetails) { diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties index 42069f3..3dd02e9 100644 --- a/src/main/resources/application.properties +++ b/src/main/resources/application.properties @@ -30,6 +30,12 @@ spring.main.banner-mode=off # Aerospike hosts to seed the cluster. # aerospike.restclient.hostlist=localhost:3000 +# Should client send boolean particle type for a boolean bin. If false, +# an integer particle type (1 or 0) is sent instead. Must be false for server +# versions less than 5.6 which do not support boolean bins. Can set to true for +# server 5.6+. +# aerospike.restclient.useBoolBin=false + # Server HTTP port. # server.port=8080 From 4e3a8f7a9913a7743773ebafd5e725bc8a9d6125 Mon Sep 17 00:00:00 2001 From: yrizhkov Date: Fri, 7 May 2021 13:23:57 +0300 Subject: [PATCH 3/8] use sha256 as a key --- .../java/com/aerospike/restclient/util/AerospikeClientPool.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/com/aerospike/restclient/util/AerospikeClientPool.java b/src/main/java/com/aerospike/restclient/util/AerospikeClientPool.java index 95b0926..fa7afcf 100644 --- a/src/main/java/com/aerospike/restclient/util/AerospikeClientPool.java +++ b/src/main/java/com/aerospike/restclient/util/AerospikeClientPool.java @@ -95,6 +95,6 @@ protected AerospikeClient getClient() { @SuppressWarnings("UnstableApiUsage") protected String buildPoolKey(AuthDetails authDetails) { - return Hashing.md5().hashBytes(authDetails.toString().getBytes()).toString(); + return Hashing.sha256().hashBytes(authDetails.toString().getBytes()).toString(); } } From 1e89e3e09f9e332cff94874aa9cfe83a0534c65e Mon Sep 17 00:00:00 2001 From: yrizhkov Date: Fri, 7 May 2021 13:27:55 +0300 Subject: [PATCH 4/8] remove obsolete Priority field from policies --- .../util/converters/PolicyValueConverter.java | 18 ++-- .../policyconverters/PolicyConverter.java | 102 +++++++++--------- .../converters/BasePolicyConverterTests.java | 25 ++--- .../converters/BatchPolicyConverterTests.java | 23 ++-- .../converters/PolicyConverterTests.java | 19 +--- .../converters/WritePolicyConverterTests.java | 23 ++-- 6 files changed, 82 insertions(+), 128 deletions(-) diff --git a/src/main/java/com/aerospike/restclient/util/converters/PolicyValueConverter.java b/src/main/java/com/aerospike/restclient/util/converters/PolicyValueConverter.java index 990465f..87a35d4 100644 --- a/src/main/java/com/aerospike/restclient/util/converters/PolicyValueConverter.java +++ b/src/main/java/com/aerospike/restclient/util/converters/PolicyValueConverter.java @@ -17,7 +17,12 @@ package com.aerospike.restclient.util.converters; import com.aerospike.client.exp.Expression; -import com.aerospike.client.policy.*; +import com.aerospike.client.policy.CommitLevel; +import com.aerospike.client.policy.GenerationPolicy; +import com.aerospike.client.policy.ReadModeAP; +import com.aerospike.client.policy.ReadModeSC; +import com.aerospike.client.policy.RecordExistsAction; +import com.aerospike.client.policy.Replica; import com.aerospike.client.query.PredExp; import com.aerospike.restclient.util.RestClientErrors; import com.aerospike.restclient.util.converters.exp.FilterExpParser; @@ -43,6 +48,7 @@ public static ReadModeSC getReadModeSC(String readModeSC) { } } + @SuppressWarnings("deprecation") public static PredExp[] getPredExp(String predExp) { try { return predExpParser.parse(predExp); @@ -63,14 +69,6 @@ public static boolean getCompress(String compress) { return getBoolValue(compress); } - public static Priority getPriority(String priority) { - try { - return Priority.valueOf(priority); - } catch (IllegalArgumentException e) { - throw new RestClientErrors.InvalidPolicyValueError("Invalid priority: " + priority); - } - } - public static Replica getReplica(String replica) { try { return Replica.valueOf(replica); @@ -104,7 +102,7 @@ public static RecordExistsAction getRecordExistsAction(String recordExistsAction } public static boolean getBoolValue(String testValue) { - return testValue.toLowerCase().equals("true"); + return testValue.equalsIgnoreCase("true"); } public static int getIntValue(String intString) { diff --git a/src/main/java/com/aerospike/restclient/util/converters/policyconverters/PolicyConverter.java b/src/main/java/com/aerospike/restclient/util/converters/policyconverters/PolicyConverter.java index b4b93cc..fd9e2fd 100644 --- a/src/main/java/com/aerospike/restclient/util/converters/policyconverters/PolicyConverter.java +++ b/src/main/java/com/aerospike/restclient/util/converters/policyconverters/PolicyConverter.java @@ -24,57 +24,53 @@ public class PolicyConverter { - public static Policy policyFromMap(Map policyMap) { - Policy policy = new Policy(); + public static Policy policyFromMap(Map policyMap) { + Policy policy = new Policy(); - if (policyMap.containsKey(AerospikeAPIConstants.TOTAL_TIMEOUT)) { - policy.totalTimeout = PolicyValueConverter.getIntValue( - policyMap.get(AerospikeAPIConstants.TOTAL_TIMEOUT)); - } - if (policyMap.containsKey(AerospikeAPIConstants.SOCKET_TIMEOUT)) { - policy.socketTimeout = PolicyValueConverter.getIntValue( - policyMap.get(AerospikeAPIConstants.SOCKET_TIMEOUT)); - } - if (policyMap.containsKey(AerospikeAPIConstants.SLEEP_BETWEEN_RETRIES)) { - policy.sleepBetweenRetries = PolicyValueConverter.getIntValue( - policyMap.get(AerospikeAPIConstants.SLEEP_BETWEEN_RETRIES)); - } - if (policyMap.containsKey(AerospikeAPIConstants.MAX_RETRIES)) { - policy.maxRetries = PolicyValueConverter.getIntValue( - policyMap.get(AerospikeAPIConstants.MAX_RETRIES)); - } - if (policyMap.containsKey(AerospikeAPIConstants.SEND_KEY)) { - policy.sendKey = PolicyValueConverter.getBoolValue( - policyMap.get(AerospikeAPIConstants.SEND_KEY)); - } - if (policyMap.containsKey(AerospikeAPIConstants.PRIORITY)) { - policy.priority = PolicyValueConverter.getPriority( - policyMap.get(AerospikeAPIConstants.PRIORITY)); - } - if (policyMap.containsKey(AerospikeAPIConstants.REPLICA)) { - policy.replica = PolicyValueConverter.getReplica( - policyMap.get(AerospikeAPIConstants.REPLICA)); - } - if (policyMap.containsKey(AerospikeAPIConstants.READ_MODE_AP)) { - policy.readModeAP = PolicyValueConverter.getReadModeAP( - policyMap.get(AerospikeAPIConstants.READ_MODE_AP)); - } - if (policyMap.containsKey(AerospikeAPIConstants.READ_MODE_SC)) { - policy.readModeSC = PolicyValueConverter.getReadModeSC( - policyMap.get(AerospikeAPIConstants.READ_MODE_SC)); - } - if (policyMap.containsKey(AerospikeAPIConstants.PRED_EXP)) { - policy.predExp = PolicyValueConverter.getPredExp( - policyMap.get(AerospikeAPIConstants.PRED_EXP)); - } - if (policyMap.containsKey(AerospikeAPIConstants.FILTER_EXP)) { - policy.filterExp = PolicyValueConverter.getFilterExp( - policyMap.get(AerospikeAPIConstants.FILTER_EXP)); - } - if (policyMap.containsKey(AerospikeAPIConstants.COMPRESS)) { - policy.compress = PolicyValueConverter.getCompress( - policyMap.get(AerospikeAPIConstants.COMPRESS)); - } - return policy; - } -} \ No newline at end of file + if (policyMap.containsKey(AerospikeAPIConstants.TOTAL_TIMEOUT)) { + policy.totalTimeout = PolicyValueConverter.getIntValue( + policyMap.get(AerospikeAPIConstants.TOTAL_TIMEOUT)); + } + if (policyMap.containsKey(AerospikeAPIConstants.SOCKET_TIMEOUT)) { + policy.socketTimeout = PolicyValueConverter.getIntValue( + policyMap.get(AerospikeAPIConstants.SOCKET_TIMEOUT)); + } + if (policyMap.containsKey(AerospikeAPIConstants.SLEEP_BETWEEN_RETRIES)) { + policy.sleepBetweenRetries = PolicyValueConverter.getIntValue( + policyMap.get(AerospikeAPIConstants.SLEEP_BETWEEN_RETRIES)); + } + if (policyMap.containsKey(AerospikeAPIConstants.MAX_RETRIES)) { + policy.maxRetries = PolicyValueConverter.getIntValue( + policyMap.get(AerospikeAPIConstants.MAX_RETRIES)); + } + if (policyMap.containsKey(AerospikeAPIConstants.SEND_KEY)) { + policy.sendKey = PolicyValueConverter.getBoolValue( + policyMap.get(AerospikeAPIConstants.SEND_KEY)); + } + if (policyMap.containsKey(AerospikeAPIConstants.REPLICA)) { + policy.replica = PolicyValueConverter.getReplica( + policyMap.get(AerospikeAPIConstants.REPLICA)); + } + if (policyMap.containsKey(AerospikeAPIConstants.READ_MODE_AP)) { + policy.readModeAP = PolicyValueConverter.getReadModeAP( + policyMap.get(AerospikeAPIConstants.READ_MODE_AP)); + } + if (policyMap.containsKey(AerospikeAPIConstants.READ_MODE_SC)) { + policy.readModeSC = PolicyValueConverter.getReadModeSC( + policyMap.get(AerospikeAPIConstants.READ_MODE_SC)); + } + if (policyMap.containsKey(AerospikeAPIConstants.PRED_EXP)) { + policy.predExp = PolicyValueConverter.getPredExp( + policyMap.get(AerospikeAPIConstants.PRED_EXP)); + } + if (policyMap.containsKey(AerospikeAPIConstants.FILTER_EXP)) { + policy.filterExp = PolicyValueConverter.getFilterExp( + policyMap.get(AerospikeAPIConstants.FILTER_EXP)); + } + if (policyMap.containsKey(AerospikeAPIConstants.COMPRESS)) { + policy.compress = PolicyValueConverter.getCompress( + policyMap.get(AerospikeAPIConstants.COMPRESS)); + } + return policy; + } +} diff --git a/src/test/java/com/aerospike/restclient/converters/BasePolicyConverterTests.java b/src/test/java/com/aerospike/restclient/converters/BasePolicyConverterTests.java index d8d83cb..75c7fdc 100644 --- a/src/test/java/com/aerospike/restclient/converters/BasePolicyConverterTests.java +++ b/src/test/java/com/aerospike/restclient/converters/BasePolicyConverterTests.java @@ -16,18 +16,16 @@ */ package com.aerospike.restclient.converters; -import java.util.HashMap; -import java.util.Map; - -import org.junit.Assert; -import org.junit.Before; -import org.junit.Test; - import com.aerospike.client.policy.Policy; -import com.aerospike.client.policy.Priority; import com.aerospike.client.policy.Replica; import com.aerospike.restclient.util.AerospikeAPIConstants; import com.aerospike.restclient.util.converters.policyconverters.PolicyConverter; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; + +import java.util.HashMap; +import java.util.Map; public class BasePolicyConverterTests { @@ -35,11 +33,9 @@ public class BasePolicyConverterTests { @Before public void setup() { - policyMap = new HashMap(); + policyMap = new HashMap<>(); } - - @Test public void testReplica() { policyMap.put(AerospikeAPIConstants.REPLICA, Replica.MASTER.toString()); @@ -47,13 +43,6 @@ public void testReplica() { Assert.assertEquals(policy.replica, Replica.MASTER); } - @Test - public void testPriority() { - policyMap.put(AerospikeAPIConstants.PRIORITY, Priority.MEDIUM.toString()); - Policy policy = PolicyConverter.policyFromMap(policyMap); - Assert.assertEquals(policy.priority, Priority.MEDIUM); - } - @Test public void testTotalTimeout() { policyMap.put(AerospikeAPIConstants.TOTAL_TIMEOUT, "333"); diff --git a/src/test/java/com/aerospike/restclient/converters/BatchPolicyConverterTests.java b/src/test/java/com/aerospike/restclient/converters/BatchPolicyConverterTests.java index e5b0a8a..86a960b 100644 --- a/src/test/java/com/aerospike/restclient/converters/BatchPolicyConverterTests.java +++ b/src/test/java/com/aerospike/restclient/converters/BatchPolicyConverterTests.java @@ -16,18 +16,16 @@ */ package com.aerospike.restclient.converters; -import java.util.HashMap; -import java.util.Map; - -import org.junit.Assert; -import org.junit.Before; -import org.junit.Test; - import com.aerospike.client.policy.BatchPolicy; -import com.aerospike.client.policy.Priority; import com.aerospike.client.policy.Replica; import com.aerospike.restclient.util.AerospikeAPIConstants; import com.aerospike.restclient.util.converters.policyconverters.BatchPolicyConverter; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; + +import java.util.HashMap; +import java.util.Map; public class BatchPolicyConverterTests { @@ -35,7 +33,7 @@ public class BatchPolicyConverterTests { @Before public void setup() { - policyMap = new HashMap(); + policyMap = new HashMap<>(); } @Test @@ -45,13 +43,6 @@ public void testReplica() { Assert.assertEquals(policy.replica, Replica.MASTER); } - @Test - public void testPriority() { - policyMap.put(AerospikeAPIConstants.PRIORITY, Priority.MEDIUM.toString()); - BatchPolicy policy = BatchPolicyConverter.batchPolicyFromMap(policyMap); - Assert.assertEquals(policy.priority, Priority.MEDIUM); - } - @Test public void testTotalTimeout() { policyMap.put(AerospikeAPIConstants.TOTAL_TIMEOUT, "333"); diff --git a/src/test/java/com/aerospike/restclient/converters/PolicyConverterTests.java b/src/test/java/com/aerospike/restclient/converters/PolicyConverterTests.java index 1e860ac..fc60f56 100644 --- a/src/test/java/com/aerospike/restclient/converters/PolicyConverterTests.java +++ b/src/test/java/com/aerospike/restclient/converters/PolicyConverterTests.java @@ -16,7 +16,10 @@ */ package com.aerospike.restclient.converters; -import com.aerospike.client.policy.*; +import com.aerospike.client.policy.CommitLevel; +import com.aerospike.client.policy.GenerationPolicy; +import com.aerospike.client.policy.RecordExistsAction; +import com.aerospike.client.policy.Replica; import com.aerospike.restclient.util.RestClientErrors.InvalidPolicyValueError; import com.aerospike.restclient.util.converters.PolicyValueConverter; import org.junit.Test; @@ -26,20 +29,6 @@ public class PolicyConverterTests { - - @Test - public void testPriority() { - assertEquals(Priority.HIGH, PolicyValueConverter.getPriority("HIGH")); - assertEquals(Priority.MEDIUM, PolicyValueConverter.getPriority("MEDIUM")); - assertEquals(Priority.LOW, PolicyValueConverter.getPriority("LOW")); - assertEquals(Priority.DEFAULT, PolicyValueConverter.getPriority("DEFAULT")); - } - - @Test(expected=InvalidPolicyValueError.class) - public void testInvalidPriority() { - PolicyValueConverter.getPriority("highest"); - } - @Test public void testReplica() { assertEquals(Replica.MASTER, PolicyValueConverter.getReplica("MASTER")); diff --git a/src/test/java/com/aerospike/restclient/converters/WritePolicyConverterTests.java b/src/test/java/com/aerospike/restclient/converters/WritePolicyConverterTests.java index a360b7d..6ed2427 100644 --- a/src/test/java/com/aerospike/restclient/converters/WritePolicyConverterTests.java +++ b/src/test/java/com/aerospike/restclient/converters/WritePolicyConverterTests.java @@ -16,21 +16,19 @@ */ package com.aerospike.restclient.converters; -import java.util.HashMap; -import java.util.Map; - -import org.junit.Assert; -import org.junit.Before; -import org.junit.Test; - import com.aerospike.client.policy.CommitLevel; import com.aerospike.client.policy.GenerationPolicy; -import com.aerospike.client.policy.Priority; import com.aerospike.client.policy.RecordExistsAction; import com.aerospike.client.policy.Replica; import com.aerospike.client.policy.WritePolicy; import com.aerospike.restclient.util.AerospikeAPIConstants; import com.aerospike.restclient.util.converters.policyconverters.WritePolicyConverter; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; + +import java.util.HashMap; +import java.util.Map; public class WritePolicyConverterTests { @@ -38,7 +36,7 @@ public class WritePolicyConverterTests { @Before public void setup() { - policyMap = new HashMap(); + policyMap = new HashMap<>(); } @Test @@ -48,13 +46,6 @@ public void testReplica() { Assert.assertEquals(policy.replica, Replica.MASTER); } - @Test - public void testPriority() { - policyMap.put(AerospikeAPIConstants.PRIORITY, Priority.MEDIUM.toString()); - WritePolicy policy = WritePolicyConverter.writePolicyFromMap(policyMap); - Assert.assertEquals(policy.priority, Priority.MEDIUM); - } - @Test public void testTotalTimeout() { policyMap.put(AerospikeAPIConstants.TOTAL_TIMEOUT, "333"); From d11998d7f504996e130f9085ef26b9b03385f676 Mon Sep 17 00:00:00 2001 From: yrizhkov Date: Fri, 7 May 2021 13:32:53 +0300 Subject: [PATCH 5/8] [CLIENT-1524] Support user quotas and statistics --- .../controllers/AdminController.java | 38 ++++- .../restclient/domain/RestClientRole.java | 142 ++++++++++++------ .../domain/RestClientRoleQuota.java | 33 ++++ .../restclient/handlers/AdminHandler.java | 9 +- .../service/AerospikeAdminService.java | 3 + .../service/AerospikeAdminServiceV1.java | 20 ++- 6 files changed, 191 insertions(+), 54 deletions(-) create mode 100644 src/main/java/com/aerospike/restclient/domain/RestClientRoleQuota.java diff --git a/src/main/java/com/aerospike/restclient/controllers/AdminController.java b/src/main/java/com/aerospike/restclient/controllers/AdminController.java index 34add8d..938bba4 100644 --- a/src/main/java/com/aerospike/restclient/controllers/AdminController.java +++ b/src/main/java/com/aerospike/restclient/controllers/AdminController.java @@ -20,14 +20,27 @@ import com.aerospike.restclient.domain.RestClientError; import com.aerospike.restclient.domain.RestClientPrivilege; import com.aerospike.restclient.domain.RestClientRole; +import com.aerospike.restclient.domain.RestClientRoleQuota; import com.aerospike.restclient.domain.RestClientUserModel; import com.aerospike.restclient.domain.auth.AuthDetails; import com.aerospike.restclient.service.AerospikeAdminService; import com.aerospike.restclient.util.HeaderHandler; -import io.swagger.annotations.*; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import io.swagger.annotations.ApiParam; +import io.swagger.annotations.ApiResponse; +import io.swagger.annotations.ApiResponses; +import io.swagger.annotations.Example; +import io.swagger.annotations.ExampleProperty; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.HttpStatus; -import org.springframework.web.bind.annotation.*; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestHeader; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestMethod; +import org.springframework.web.bind.annotation.ResponseStatus; +import org.springframework.web.bind.annotation.RestController; import javax.validation.Valid; import java.util.List; @@ -189,6 +202,27 @@ public void createRole(@ApiParam(required = true) @RequestBody RestClientRole rc adminService.createRole(authDetails, rcRole); } + @ApiResponses(value = { + @ApiResponse(code = 403, response = RestClientError.class, message = "Not authorized to create roles.", + examples = @Example(value = {@ExampleProperty(mediaType = "Example json", value = "{'inDoubt': false, 'message': 'A message' ")})), + @ApiResponse(code = 400, response = RestClientError.class, message = "Invalid role creation parameters", + examples = @Example(value = {@ExampleProperty(mediaType = "Example json", value = "{'inDoubt': false, 'message': 'A message' ")})), + @ApiResponse(code = 409, response = RestClientError.class, message = "Role already exists.", + examples = @Example(value = {@ExampleProperty(mediaType = "Example json", value = "{'inDoubt': false, 'message': 'A message' ")})) + }) + @ApiOperation(value = "Set maximum reads/writes per second limits for a role.", nickname = "setRoleQuotas") + @ResponseStatus(value = HttpStatus.ACCEPTED) + @RequestMapping(method = RequestMethod.POST, value = "/role/{name}/quota", + consumes = {"application/json", "application/msgpack"}, produces = {"application/json", "application/msgpack"}) + public void setRoleQuotas( + @ApiParam(value = "The name of the role to which quotas will be set.", required = true) @PathVariable(value = "name") String name, + @ApiParam(required = true) @RequestBody RestClientRoleQuota roleQuota, + @RequestHeader(value = "Authorization", required = false) String basicAuth) { + + AuthDetails authDetails = HeaderHandler.extractAuthDetails(basicAuth); + adminService.setRoleQuotas(authDetails, name, roleQuota); + } + @ApiResponses(value = { @ApiResponse(code = 403, response = RestClientError.class, message = "Not authorized to read role information", examples = @Example(value = {@ExampleProperty(mediaType = "Example json", value = "{'inDoubt': false, 'message': 'A message' ")})), diff --git a/src/main/java/com/aerospike/restclient/domain/RestClientRole.java b/src/main/java/com/aerospike/restclient/domain/RestClientRole.java index 8cfe25e..a18eb59 100644 --- a/src/main/java/com/aerospike/restclient/domain/RestClientRole.java +++ b/src/main/java/com/aerospike/restclient/domain/RestClientRole.java @@ -16,60 +16,104 @@ */ package com.aerospike.restclient.domain; -import java.util.List; -import java.util.stream.Collectors; - -import javax.validation.constraints.NotNull; - import com.aerospike.client.admin.Role; import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.annotation.JsonInclude.Include; - +import io.swagger.annotations.ApiModel; import io.swagger.annotations.ApiModelProperty; +import javax.validation.constraints.NotNull; +import java.util.List; +import java.util.stream.Collectors; + @JsonInclude(Include.NON_NULL) +@ApiModel(value = "RestClientRole") public class RestClientRole { - @NotNull - @ApiModelProperty(example="customRole") - String name; - - @NotNull - List privileges; - - public String getName() { - return this.name; - } - public List getPrivileges() { - return this.privileges; - } - - public void setName(String name) { - this.name = name; - } - public void setPrivileges(List privileges) { - this.privileges = privileges; - } - - /* - * Convert to Java Client role - */ - public Role toRole() { - Role role = new Role(); - role.name = name; - role.privileges = this.privileges.stream().map(elt -> elt.toPrivilege()).collect(Collectors.toList()); - - return role; - } - - public RestClientRole() { - } - - /* - * Constructor from Java Client Role - */ - public RestClientRole (Role role) { - name = role.name; - privileges = role.privileges.stream().map(elt -> new RestClientPrivilege(elt)).collect(Collectors.toList()); - } -} \ No newline at end of file + @NotNull + @ApiModelProperty(required = true, value = "Role name.", example = "customRole") + private String name; + + @NotNull + @ApiModelProperty(required = true, value = "List of assigned privileges.") + private List privileges; + + @ApiModelProperty(value = "List of allowable IP addresses.") + private List whitelist; + + @ApiModelProperty(value = "Maximum reads per second limit.") + private int readQuota; + + @ApiModelProperty(value = "Maximum writes per second limit.") + private int writeQuota; + + public String getName() { + return this.name; + } + + public void setName(String name) { + this.name = name; + } + + public List getPrivileges() { + return this.privileges; + } + + public void setPrivileges(List privileges) { + this.privileges = privileges; + } + + public List getWhitelist() { + return this.whitelist; + } + + public void setWhitelist(List whitelist) { + this.whitelist = whitelist; + } + + public int getReadQuota() { + return this.readQuota; + } + + public void setReadQuota(int readQuota) { + this.readQuota = readQuota; + } + + public int getWriteQuota() { + return this.writeQuota; + } + + public void setWriteQuota(int writeQuota) { + this.writeQuota = writeQuota; + } + + /* + * Convert to Java Client role + */ + public Role toRole() { + Role role = new Role(); + role.name = name; + role.privileges = this.privileges.stream() + .map(RestClientPrivilege::toPrivilege).collect(Collectors.toList()); + role.whitelist = whitelist; + role.readQuota = readQuota; + role.writeQuota = writeQuota; + + return role; + } + + public RestClientRole() { + } + + /* + * Constructor from Java Client Role + */ + public RestClientRole(Role role) { + name = role.name; + privileges = role.privileges.stream() + .map(RestClientPrivilege::new).collect(Collectors.toList()); + whitelist = role.whitelist; + readQuota = role.readQuota; + writeQuota = role.writeQuota; + } +} diff --git a/src/main/java/com/aerospike/restclient/domain/RestClientRoleQuota.java b/src/main/java/com/aerospike/restclient/domain/RestClientRoleQuota.java new file mode 100644 index 0000000..856ad85 --- /dev/null +++ b/src/main/java/com/aerospike/restclient/domain/RestClientRoleQuota.java @@ -0,0 +1,33 @@ +package com.aerospike.restclient.domain; + +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; + +@ApiModel(value = "RestClientRoleQuota") +public class RestClientRoleQuota { + + @ApiModelProperty(value = "Maximum reads per second limit.") + private int readQuota; + + @ApiModelProperty(value = "Maximum writes per second limit.") + private int writeQuota; + + public int getReadQuota() { + return this.readQuota; + } + + public void setReadQuota(int readQuota) { + this.readQuota = readQuota; + } + + public int getWriteQuota() { + return this.writeQuota; + } + + public void setWriteQuota(int writeQuota) { + this.writeQuota = writeQuota; + } + + public RestClientRoleQuota() { + } +} diff --git a/src/main/java/com/aerospike/restclient/handlers/AdminHandler.java b/src/main/java/com/aerospike/restclient/handlers/AdminHandler.java index 5bfe142..e2da406 100644 --- a/src/main/java/com/aerospike/restclient/handlers/AdminHandler.java +++ b/src/main/java/com/aerospike/restclient/handlers/AdminHandler.java @@ -70,8 +70,13 @@ public Role getRole(AdminPolicy policy, String roleName) { return client.queryRole(policy, roleName); } - public void createRole(AdminPolicy policy, String roleName, List privileges) { - client.createRole(policy, roleName, privileges); + public void createRole(AdminPolicy policy, String roleName, List privileges, + List whitelist, int readQuota, int writeQuota) { + client.createRole(policy, roleName, privileges, whitelist, readQuota, writeQuota); + } + + public void setRoleQuotas(AdminPolicy policy, String roleName, int readQuota, int writeQuota) { + client.setQuotas(policy, roleName, readQuota, writeQuota); } public void deleteRole(AdminPolicy policy, String roleName) { diff --git a/src/main/java/com/aerospike/restclient/service/AerospikeAdminService.java b/src/main/java/com/aerospike/restclient/service/AerospikeAdminService.java index 641b3b2..4a73d38 100644 --- a/src/main/java/com/aerospike/restclient/service/AerospikeAdminService.java +++ b/src/main/java/com/aerospike/restclient/service/AerospikeAdminService.java @@ -19,6 +19,7 @@ import com.aerospike.client.admin.User; import com.aerospike.restclient.domain.RestClientPrivilege; import com.aerospike.restclient.domain.RestClientRole; +import com.aerospike.restclient.domain.RestClientRoleQuota; import com.aerospike.restclient.domain.RestClientUserModel; import com.aerospike.restclient.domain.auth.AuthDetails; @@ -48,6 +49,8 @@ public interface AerospikeAdminService { public void createRole(AuthDetails authDetails, RestClientRole rcRole); + public void setRoleQuotas(AuthDetails authDetails, String roleName, RestClientRoleQuota roleQuota); + public RestClientRole getRole(AuthDetails authDetails, String roleName); public void dropRole(AuthDetails authDetails, String roleName); diff --git a/src/main/java/com/aerospike/restclient/service/AerospikeAdminServiceV1.java b/src/main/java/com/aerospike/restclient/service/AerospikeAdminServiceV1.java index a3c4ce4..1fc7210 100644 --- a/src/main/java/com/aerospike/restclient/service/AerospikeAdminServiceV1.java +++ b/src/main/java/com/aerospike/restclient/service/AerospikeAdminServiceV1.java @@ -21,6 +21,7 @@ import com.aerospike.client.admin.User; import com.aerospike.restclient.domain.RestClientPrivilege; import com.aerospike.restclient.domain.RestClientRole; +import com.aerospike.restclient.domain.RestClientRoleQuota; import com.aerospike.restclient.domain.RestClientUserModel; import com.aerospike.restclient.domain.auth.AuthDetails; import com.aerospike.restclient.handlers.AdminHandler; @@ -94,7 +95,24 @@ public List getRoles(AuthDetails authDetails) { @Override public void createRole(AuthDetails authDetails, RestClientRole rcRole) { Role asRole = rcRole.toRole(); - AdminHandler.create(clientPool.getClient(authDetails)).createRole(null, asRole.name, asRole.privileges); + AdminHandler.create(clientPool.getClient(authDetails)).createRole( + null, + asRole.name, + asRole.privileges, + asRole.whitelist, + asRole.readQuota, + asRole.writeQuota + ); + } + + @Override + public void setRoleQuotas(AuthDetails authDetails, String roleName, RestClientRoleQuota roleQuota) { + AdminHandler.create(clientPool.getClient(authDetails)).setRoleQuotas( + null, + roleName, + roleQuota.getReadQuota(), + roleQuota.getWriteQuota() + ); } @Override From 058b2fe66a1393126891a2641a9672226b09d564 Mon Sep 17 00:00:00 2001 From: yrizhkov Date: Fri, 7 May 2021 13:38:01 +0300 Subject: [PATCH 6/8] add Boolean type test --- .../restclient/RecordPostCorrectTests.java | 12 +++++++++++ .../restclient/RoleTestsCorrect.java | 21 +++++++------------ 2 files changed, 20 insertions(+), 13 deletions(-) diff --git a/src/test/java/com/aerospike/restclient/RecordPostCorrectTests.java b/src/test/java/com/aerospike/restclient/RecordPostCorrectTests.java index ba9319d..202245a 100644 --- a/src/test/java/com/aerospike/restclient/RecordPostCorrectTests.java +++ b/src/test/java/com/aerospike/restclient/RecordPostCorrectTests.java @@ -286,6 +286,18 @@ public void PostGeoJson() throws Exception { Record record = client.get(null, this.testKey); Assert.assertEquals(((Value.GeoJSONValue) record.bins.get("geo_json")).getObject(), geoStr); } + + @Test + public void PostBoolean() throws Exception { + Map binMap = new HashMap<>(); + + binMap.put("bool", true); + + postPerformer.perform(mockMVC, testEndpoint, binMap); + + Record record = client.get(null, this.testKey); + Assert.assertEquals((long) record.bins.get("bool"), 1L); + } } interface PostPerformer { diff --git a/src/test/java/com/aerospike/restclient/RoleTestsCorrect.java b/src/test/java/com/aerospike/restclient/RoleTestsCorrect.java index 1d37140..20fd6c0 100644 --- a/src/test/java/com/aerospike/restclient/RoleTestsCorrect.java +++ b/src/test/java/com/aerospike/restclient/RoleTestsCorrect.java @@ -24,6 +24,7 @@ import java.util.ArrayList; import java.util.Arrays; +import java.util.Collections; import java.util.List; import org.junit.After; @@ -62,14 +63,13 @@ @SpringBootTest public class RoleTestsCorrect { - @ClassRule public static final SpringClassRule springClassRule = new SpringClassRule(); @Rule public final SpringMethodRule springMethodRule = new SpringMethodRule(); - private RestRoleHandler handler; + private final RestRoleHandler handler; @Parameters public static Object[] getParams() { @@ -123,12 +123,12 @@ public void setup() throws InterruptedException { createdRole = new Role(); createdRole.name = TestRoleName; createdRole.privileges = createdPrivileges; - createdRoles = new ArrayList(); + createdRoles = new ArrayList<>(); try { client.createRole(null, TestRoleName, createdPrivileges); createdRoles.add(TestRoleName); - } catch (AerospikeException e) {} // If this fails, it probably means the role already exists, so it's fine. + } catch (AerospikeException ignore) {} // If this fails, it probably means the role already exists, so it's fine. // Give some time for the creation to propagate to all nodes Thread.sleep(1000); } @@ -138,12 +138,12 @@ public void tearDown() { for (String role: createdRoles) { try { client.dropRole(null, role); - } catch (AerospikeException e) {} + } catch (AerospikeException ignore) {} } try { //Replication of the user dropping is asynchronous, so wait for it to happen Thread.sleep(1000); - } catch (InterruptedException e) {} + } catch (InterruptedException ignore) {} } @Test @@ -186,7 +186,7 @@ public void createRole() throws Exception { crPrivilege.namespace = "test"; crPrivilege.setName = "rwu"; - testRole.privileges = Arrays.asList(crPrivilege); + testRole.privileges = Collections.singletonList(crPrivilege); createdRoles.add(testRole.name); handler.createRole(mockMVC, endpoint, new RestClientRole(testRole)); @@ -196,7 +196,6 @@ public void createRole() throws Exception { Role fetchedRole = client.queryRole(null, testRole.name); Assert.assertTrue(roleEquals(fetchedRole, testRole)); - } @Test @@ -266,11 +265,7 @@ private boolean PrivilegeEquals(Privilege priv1, Privilege priv2) { return false; } - if (priv1.code != priv2.code) { - return false; - } - - return true; + return priv1.code == priv2.code; } private boolean rcRolesListContainsRole(List rcRoles, Role role) { From 6d5201081d4533b4209134d8f70d8568755240cc Mon Sep 17 00:00:00 2001 From: yrizhkov Date: Sun, 9 May 2021 10:38:22 +0300 Subject: [PATCH 7/8] update swagger.json files --- .../sample-rest-stockapp/swagger/swagger.json | 175 ++++++++++++++---- docs/swagger.json | 175 ++++++++++++++---- 2 files changed, 270 insertions(+), 80 deletions(-) diff --git a/demos/sample-rest-stockapp/swagger/swagger.json b/demos/sample-rest-stockapp/swagger/swagger.json index 814d290..5d652b9 100644 --- a/demos/sample-rest-stockapp/swagger/swagger.json +++ b/demos/sample-rest-stockapp/swagger/swagger.json @@ -2,7 +2,7 @@ "swagger": "2.0", "info": { "description": "REST Interface for Aerospike Database.", - "version": "1.7.0", + "version": "1.8.0", "title": "Aerospike REST Client", "contact": { "name": "Aerospike, Inc.", @@ -420,6 +420,78 @@ "deprecated": false } }, + "/v1/admin/role/{name}/quota": { + "post": { + "tags": [ + "Admin Operations" + ], + "summary": "Set maximum reads/writes per second limits for a role.", + "operationId": "setRoleQuotas", + "consumes": [ + "application/json", + "application/msgpack" + ], + "produces": [ + "application/json", + "application/msgpack" + ], + "parameters": [ + { + "name": "Authorization", + "in": "header", + "description": "Authorization", + "required": false, + "type": "string" + }, + { + "name": "name", + "in": "path", + "description": "The name of the role to which quotas will be set.", + "required": true, + "type": "string" + }, + { + "in": "body", + "name": "roleQuota", + "description": "roleQuota", + "required": true, + "schema": { + "$ref": "#/definitions/RestClientRoleQuota" + } + } + ], + "responses": { + "202": { + "description": "Accepted" + }, + "400": { + "description": "Invalid role creation parameters", + "schema": { + "$ref": "#/definitions/RestClientError" + } + }, + "403": { + "description": "Not authorized to create roles.", + "schema": { + "$ref": "#/definitions/RestClientError" + } + }, + "409": { + "description": "Role already exists.", + "schema": { + "$ref": "#/definitions/RestClientError" + } + }, + "500": { + "description": "The REST Client encountered an error processing the request", + "schema": { + "$ref": "#/definitions/RestClientError" + } + } + }, + "deprecated": false + } + }, "/v1/admin/user": { "get": { "tags": [ @@ -5394,13 +5466,6 @@ "required": false, "type": "boolean" }, - { - "name": "failOnClusterChange", - "in": "query", - "description": "Terminate scan if cluster in migration state. Only used for server versions < 4.9.", - "required": false, - "type": "boolean" - }, { "name": "filterexp", "in": "query", @@ -5529,14 +5594,6 @@ "RANDOM" ] }, - { - "name": "scanPercent", - "in": "query", - "description": "Percent of data to scan. Valid integer range is 1 to 100.\nThis field is supported on server versions < 4.9.\nFor server versions >= 4.9, use maxRecords.", - "required": false, - "type": "integer", - "format": "int32" - }, { "name": "sendKey", "in": "query", @@ -5637,13 +5694,6 @@ "required": false, "type": "boolean" }, - { - "name": "failOnClusterChange", - "in": "query", - "description": "Terminate scan if cluster in migration state. Only used for server versions < 4.9.", - "required": false, - "type": "boolean" - }, { "name": "filterexp", "in": "query", @@ -5772,14 +5822,6 @@ "RANDOM" ] }, - { - "name": "scanPercent", - "in": "query", - "description": "Percent of data to scan. Valid integer range is 1 to 100.\nThis field is supported on server versions < 4.9.\nFor server versions >= 4.9, use maxRecords.", - "required": false, - "type": "integer", - "format": "int32" - }, { "name": "sendKey", "in": "query", @@ -6026,12 +6068,12 @@ } }, "key": { - "description": "Key to retrieve a record", + "description": "Key to retrieve a record.", "$ref": "#/definitions/Key" }, "readAllBins": { "type": "boolean", - "description": "Whether all bins should be returned with this record" + "description": "Whether all bins should be returned with this record." } }, "title": "BatchReadRequest" @@ -6039,14 +6081,10 @@ "Key": { "type": "object", "required": [ - "namespace" + "namespace", + "userKey" ], "properties": { - "digest": { - "type": "string", - "example": "AAAAAAAAAAAAAAAAAAAAAAAAAAA=", - "description": "URL safe base64 encoded key digest. Returned by the server on batch responses. May be provided by client." - }, "keytype": { "type": "string", "example": "STRING", @@ -6398,20 +6436,59 @@ }, "RestClientRole": { "type": "object", + "required": [ + "name", + "privileges" + ], "properties": { "name": { "type": "string", - "example": "customRole" + "example": "customRole", + "description": "Role name." }, "privileges": { "type": "array", + "description": "List of assigned privileges.", "items": { "$ref": "#/definitions/Privilege" } + }, + "readQuota": { + "type": "integer", + "format": "int32", + "description": "Maximum reads per second limit." + }, + "whitelist": { + "type": "array", + "description": "List of allowable IP addresses.", + "items": { + "type": "string" + } + }, + "writeQuota": { + "type": "integer", + "format": "int32", + "description": "Maximum writes per second limit." } }, "title": "RestClientRole" }, + "RestClientRoleQuota": { + "type": "object", + "properties": { + "readQuota": { + "type": "integer", + "format": "int32", + "description": "Maximum reads per second limit." + }, + "writeQuota": { + "type": "integer", + "format": "int32", + "description": "Maximum writes per second limit." + } + }, + "title": "RestClientRoleQuota" + }, "RestClientScanResponse": { "type": "object", "properties": { @@ -6465,14 +6542,32 @@ "User": { "type": "object", "properties": { + "connsInUse": { + "type": "integer", + "format": "int32" + }, "name": { "type": "string" }, + "readInfo": { + "type": "array", + "items": { + "type": "integer", + "format": "int32" + } + }, "roles": { "type": "array", "items": { "type": "string" } + }, + "writeInfo": { + "type": "array", + "items": { + "type": "integer", + "format": "int32" + } } }, "title": "User" diff --git a/docs/swagger.json b/docs/swagger.json index 3241ee4..bd6c9c8 100644 --- a/docs/swagger.json +++ b/docs/swagger.json @@ -2,7 +2,7 @@ "swagger": "2.0", "info": { "description": "REST Interface for Aerospike Database.", - "version": "1.7.0", + "version": "1.8.0", "title": "Aerospike REST Client", "contact": { "name": "Aerospike, Inc.", @@ -420,6 +420,78 @@ "deprecated": false } }, + "/v1/admin/role/{name}/quota": { + "post": { + "tags": [ + "Admin Operations" + ], + "summary": "Set maximum reads/writes per second limits for a role.", + "operationId": "setRoleQuotas", + "consumes": [ + "application/json", + "application/msgpack" + ], + "produces": [ + "application/json", + "application/msgpack" + ], + "parameters": [ + { + "name": "Authorization", + "in": "header", + "description": "Authorization", + "required": false, + "type": "string" + }, + { + "name": "name", + "in": "path", + "description": "The name of the role to which quotas will be set.", + "required": true, + "type": "string" + }, + { + "in": "body", + "name": "roleQuota", + "description": "roleQuota", + "required": true, + "schema": { + "$ref": "#/definitions/RestClientRoleQuota" + } + } + ], + "responses": { + "202": { + "description": "Accepted" + }, + "400": { + "description": "Invalid role creation parameters", + "schema": { + "$ref": "#/definitions/RestClientError" + } + }, + "403": { + "description": "Not authorized to create roles.", + "schema": { + "$ref": "#/definitions/RestClientError" + } + }, + "409": { + "description": "Role already exists.", + "schema": { + "$ref": "#/definitions/RestClientError" + } + }, + "500": { + "description": "The REST Client encountered an error processing the request", + "schema": { + "$ref": "#/definitions/RestClientError" + } + } + }, + "deprecated": false + } + }, "/v1/admin/user": { "get": { "tags": [ @@ -5394,13 +5466,6 @@ "required": false, "type": "boolean" }, - { - "name": "failOnClusterChange", - "in": "query", - "description": "Terminate scan if cluster in migration state. Only used for server versions < 4.9.", - "required": false, - "type": "boolean" - }, { "name": "filterexp", "in": "query", @@ -5529,14 +5594,6 @@ "RANDOM" ] }, - { - "name": "scanPercent", - "in": "query", - "description": "Percent of data to scan. Valid integer range is 1 to 100.\nThis field is supported on server versions < 4.9.\nFor server versions >= 4.9, use maxRecords.", - "required": false, - "type": "integer", - "format": "int32" - }, { "name": "sendKey", "in": "query", @@ -5637,13 +5694,6 @@ "required": false, "type": "boolean" }, - { - "name": "failOnClusterChange", - "in": "query", - "description": "Terminate scan if cluster in migration state. Only used for server versions < 4.9.", - "required": false, - "type": "boolean" - }, { "name": "filterexp", "in": "query", @@ -5772,14 +5822,6 @@ "RANDOM" ] }, - { - "name": "scanPercent", - "in": "query", - "description": "Percent of data to scan. Valid integer range is 1 to 100.\nThis field is supported on server versions < 4.9.\nFor server versions >= 4.9, use maxRecords.", - "required": false, - "type": "integer", - "format": "int32" - }, { "name": "sendKey", "in": "query", @@ -6026,12 +6068,12 @@ } }, "key": { - "description": "Key to retrieve a record", + "description": "Key to retrieve a record.", "$ref": "#/definitions/Key" }, "readAllBins": { "type": "boolean", - "description": "Whether all bins should be returned with this record" + "description": "Whether all bins should be returned with this record." } }, "title": "BatchReadRequest" @@ -6039,14 +6081,10 @@ "Key": { "type": "object", "required": [ - "namespace" + "namespace", + "userKey" ], "properties": { - "digest": { - "type": "string", - "example": "AAAAAAAAAAAAAAAAAAAAAAAAAAA=", - "description": "URL safe base64 encoded key digest. Returned by the server on batch responses. May be provided by client." - }, "keytype": { "type": "string", "example": "STRING", @@ -6398,20 +6436,59 @@ }, "RestClientRole": { "type": "object", + "required": [ + "name", + "privileges" + ], "properties": { "name": { "type": "string", - "example": "customRole" + "example": "customRole", + "description": "Role name." }, "privileges": { "type": "array", + "description": "List of assigned privileges.", "items": { "$ref": "#/definitions/Privilege" } + }, + "readQuota": { + "type": "integer", + "format": "int32", + "description": "Maximum reads per second limit." + }, + "whitelist": { + "type": "array", + "description": "List of allowable IP addresses.", + "items": { + "type": "string" + } + }, + "writeQuota": { + "type": "integer", + "format": "int32", + "description": "Maximum writes per second limit." } }, "title": "RestClientRole" }, + "RestClientRoleQuota": { + "type": "object", + "properties": { + "readQuota": { + "type": "integer", + "format": "int32", + "description": "Maximum reads per second limit." + }, + "writeQuota": { + "type": "integer", + "format": "int32", + "description": "Maximum writes per second limit." + } + }, + "title": "RestClientRoleQuota" + }, "RestClientScanResponse": { "type": "object", "properties": { @@ -6465,14 +6542,32 @@ "User": { "type": "object", "properties": { + "connsInUse": { + "type": "integer", + "format": "int32" + }, "name": { "type": "string" }, + "readInfo": { + "type": "array", + "items": { + "type": "integer", + "format": "int32" + } + }, "roles": { "type": "array", "items": { "type": "string" } + }, + "writeInfo": { + "type": "array", + "items": { + "type": "integer", + "format": "int32" + } } }, "title": "User" From 9419438ae01baf121d6a6bee2c84e61d5452fcd3 Mon Sep 17 00:00:00 2001 From: yrizhkov Date: Sun, 9 May 2021 10:38:49 +0300 Subject: [PATCH 8/8] v1.8.0 --- gradle.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle.properties b/gradle.properties index 33f6d65..ec61877 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,2 +1,2 @@ -appVersion=1.7.0 +appVersion=1.8.0 jarBaseName=as-rest-client