This is an automated email from the ASF dual-hosted git repository.
technoboy pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/pulsar.git
The following commit(s) were added to refs/heads/master by this push:
new c598974346a [improve][PIP] PIP-383: Support granting/revoking
permissions for multiple topics (#23355)
c598974346a is described below
commit c598974346a5df2bb328e679f49b6cb0b56ab84b
Author: Jiwei Guo <[email protected]>
AuthorDate: Tue Oct 8 19:22:31 2024 +0800
[improve][PIP] PIP-383: Support granting/revoking permissions for multiple
topics (#23355)
---
pip/pip-383.md | 144 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 144 insertions(+)
diff --git a/pip/pip-383.md b/pip/pip-383.md
new file mode 100644
index 00000000000..72f4e182ea7
--- /dev/null
+++ b/pip/pip-383.md
@@ -0,0 +1,144 @@
+# PIP-383: Support granting/revoking permissions for multiple topics
+
+## Background
+
+In AuthorizationProvider, the authorization interface
`grantPermissionAsync(TopicName topicName, Set<AuthAction> actions, String
role, String authDataJson)` currently only supports granting permissions to a
single topic at a time.
+When multiple topics need to be authorized under a namespace, the client makes
the calls to the authorization interface concurrently.
+Since the permissions information is stored in the namespace-level policies,
and multiple topics may be on different brokers, concurrent authorization
modification will cause concurrent modification exceptions.
+Therefore, supporting granting permissions for multiple topics is very
beneficial.
+
+
+## Motivation
+
+Supporting granting/revoking permissions for multiple topics,
+add `grantPermissionAsync(List<GrantTopicPermissionOptions> options)` and
`revokePermissionAsync(List<RevokeTopicPermissionOptions> options)` in
AuthorizationProvider.
+
+## Goals
+
+### In Scope
+
+- Add `grantPermissionAsync(List<GrantTopicPermissionOptions> options)` in
AuthorizationProvider.
+- Add `revokePermissionAsync(List<GrantTopicPermissionOptions> options)` in
AuthorizationProvider.
+
+## High-Level Design
+
+### Design & Implementation Details
+
+Add default method implementation in AuthorizationProvider
+```java
+
+public interface AuthorizationProvider extends Closeable {
+
+ default CompletableFuture<Void>
grantPermissionAsync(List<GrantTopicPermissionOptions> options) {
+ return FutureUtil.failedFuture(new IllegalStateException(
+ String.format("grantPermissionAsync is not supported by the
Authorization")));
+ }
+
+ default CompletableFuture<Void>
revokePermissionAsync(List<RevokeTopicPermissionOptions> options) {
+ return FutureUtil.failedFuture(new IllegalStateException(
+ String.format("revokePermissionAsync is not supported by the
Authorization")));
+ }
+}
+```
+
+```
+@Data
+@Builder
+public class GrantTopicPermissionOptions {
+
+ private final String topic;
+
+ private final String role;
+
+ private final Set<AuthAction> actions;
+}
+
+@Data
+@Builder
+public class RevokeTopicPermissionOptions {
+
+ private final String topic;
+
+ private final String role;
+}
+```
+
+Add namespace admin API.
+
+```java
+public interface Namespaces {
+
+ CompletableFuture<Void>
grantPermissionOnTopicsAsync(List<GrantTopicPermissionOptions> options);
+
+ void grantPermissionOnTopics(List<GrantTopicPermissionOptions> options)
throws PulsarAdminException;
+
+ CompletableFuture<Void>
revokePermissionOnTopicsAsync(List<RevokeTopicPermissionOptions> options);
+
+ void revokePermissionOnTopics(List<RevokeTopicPermissionOptions> options)
throws PulsarAdminException;
+}
+```
+
+Add namespace rest implementation in broker side.
+```java
+@POST
+@Path("/grantPermissions")
+public void grantPermissionOnTopics(@Suspended final AsyncResponse
asyncResponse,
+ List<GrantTopicPermissionOptions> options) {
+ internalGrantPermissionsAsync(options)
+ .thenAccept(__ ->
asyncResponse.resume(Response.noContent().build()))
+ .exceptionally(ex -> {
+ log.error("[{}] Failed to grant permissions {}",
+ clientAppId(), options, ex);
+ resumeAsyncResponseExceptionally(asyncResponse, ex);
+ return null;
+ });
+}
+
+@POST
+@Path("/revokePermissions")
+public void revokePermissionOnTopics(@Suspended final AsyncResponse
asyncResponse,
+ List<RevokeTopicPermissionOptions> options) {
+ internalRevokePermissionsAsync(options)
+ .thenAccept(__ ->
asyncResponse.resume(Response.noContent().build()))
+ .exceptionally(ex -> {
+ log.error("[{}] Failed to revoke permissions {}",
+ clientAppId(), options, ex);
+ resumeAsyncResponseExceptionally(asyncResponse, ex);
+ return null;
+ });
+}
+```
+
+so user can grant/revoke permissions to multi-topics like :
+```java
+public class TestAuthorization {
+
+ @Test
+ public void testGrantPermission() {
+ // grant permission for multi-topics
+ List<GrantPermissionOptions> grantPermissions = new ArrayList<>();
+
grantPermissions.add(GrantPermissionOptions.builder().topic("topic1").role("role1").actions(Set.of(AuthAction.produce)).build());
+
grantPermissions.add(GrantPermissionOptions.builder().topic("topic2").role("role2").actions(Set.of(AuthAction.consume)).build());
+ admin.namespaces().grantPermissionOnTopics(grantPermissions);
+ // revoke permission topics
+ List<RevokePermissionOptions> revokePermissions = new ArrayList<>();
+
revokePermissions.add(RevokePermissionOptions.builder().topic("topic1").role("role1").build());
+
revokePermissions.add(RevokePermissionOptions.builder().topic("topic2").role("role2").build());
+ admin.namespaces().revokePermissionOnTopics(revokePermissions);
+ }
+}
+
+```
+
+## Backward & Forward Compatibility
+
+
+
+## Alternatives
+
+## General Notes
+
+## Links
+
+* Mailing List discussion thread:
https://lists.apache.org/thread/6n2jdl9bsf1f6xz2orygz3kvxmy11ykh
+* Mailing List voting thread:
https://lists.apache.org/thread/qbyvs75r0d64h6jk8w1swr782l85b77h