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.
Supporting granting/revoking permissions for multiple topics,
add grantPermissionAsync(List<GrantTopicPermissionOptions> options)
and revokePermissionAsync(List<RevokeTopicPermissionOptions> options)
in AuthorizationProvider.
- Add
grantPermissionAsync(List<GrantTopicPermissionOptions> options)
in AuthorizationProvider. - Add
revokePermissionAsync(List<GrantTopicPermissionOptions> options)
in AuthorizationProvider.
Add default method implementation in AuthorizationProvider
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.
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.
@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 :
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);
}
}
- Mailing List discussion thread: https://lists.apache.org/thread/6n2jdl9bsf1f6xz2orygz3kvxmy11ykh
- Mailing List voting thread: https://lists.apache.org/thread/qbyvs75r0d64h6jk8w1swr782l85b77h