forked from apache/pulsar
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[improve][PIP] PIP-383: Support granting/revoking permissions for mul…
…tiple topics (apache#23355)
- Loading branch information
1 parent
7a5166b
commit 89ddca6
Showing
1 changed file
with
144 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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 |