use of org.apache.pulsar.broker.PulsarServerException in project incubator-pulsar by apache.
the class NonPersistentTopics method getList.
@GET
@Path("/{property}/{cluster}/{namespace}")
@ApiOperation(value = "Get the list of non-persistent topics under a namespace.", response = String.class, responseContainer = "List")
@ApiResponses(value = { @ApiResponse(code = 403, message = "Don't have admin permission"), @ApiResponse(code = 404, message = "Namespace doesn't exist") })
public List<String> getList(@PathParam("property") String property, @PathParam("cluster") String cluster, @PathParam("namespace") String namespace) {
log.info("[{}] list of topics on namespace {}/{}/{}/{}", clientAppId(), property, cluster, namespace);
validateAdminAccessOnProperty(property);
Policies policies = getNamespacePolicies(property, cluster, namespace);
NamespaceName nsName = NamespaceName.get(property, cluster, namespace);
if (!cluster.equals(Constants.GLOBAL_CLUSTER)) {
validateClusterOwnership(cluster);
validateClusterForProperty(property, cluster);
} else {
// check cluster ownership for a given global namespace: redirect if peer-cluster owns it
validateGlobalNamespaceOwnership(nsName);
}
final List<CompletableFuture<List<String>>> futures = Lists.newArrayList();
final List<String> boundaries = policies.bundles.getBoundaries();
for (int i = 0; i < boundaries.size() - 1; i++) {
final String bundle = String.format("%s_%s", boundaries.get(i), boundaries.get(i + 1));
try {
futures.add(pulsar().getAdminClient().nonPersistentTopics().getListInBundleAsync(nsName.toString(), bundle));
} catch (PulsarServerException e) {
log.error(String.format("[%s] Failed to get list of topics under namespace %s/%s/%s/%s", clientAppId(), property, cluster, namespace, bundle), e);
throw new RestException(e);
}
}
final List<String> topics = Lists.newArrayList();
try {
FutureUtil.waitForAll(futures).get();
futures.forEach(topicListFuture -> {
try {
if (topicListFuture.isDone() && topicListFuture.get() != null) {
topics.addAll(topicListFuture.get());
}
} catch (InterruptedException | ExecutionException e) {
log.error(String.format("[%s] Failed to get list of topics under namespace %s/%s/%s", clientAppId(), property, cluster, namespace), e);
}
});
} catch (InterruptedException | ExecutionException e) {
log.error(String.format("[%s] Failed to get list of topics under namespace %s/%s/%s", clientAppId(), property, cluster, namespace), e);
throw new RestException(e instanceof ExecutionException ? e.getCause() : e);
}
return topics;
}
use of org.apache.pulsar.broker.PulsarServerException in project incubator-pulsar by apache.
the class PulsarAuthorizationProvider method canConsumeAsync.
/**
* Check if the specified role has permission to receive messages from the specified fully qualified topic
* name.
*
* @param topicName
* the fully qualified topic name associated with the topic.
* @param role
* the app id used to receive messages from the topic.
* @param subscription
* the subscription name defined by the client
*/
@Override
public CompletableFuture<Boolean> canConsumeAsync(TopicName topicName, String role, AuthenticationDataSource authenticationData, String subscription) {
CompletableFuture<Boolean> permissionFuture = new CompletableFuture<>();
try {
configCache.policiesCache().getAsync(POLICY_ROOT + topicName.getNamespace()).thenAccept(policies -> {
if (!policies.isPresent()) {
if (log.isDebugEnabled()) {
log.debug("Policies node couldn't be found for topic : {}", topicName);
}
} else {
if (isNotBlank(subscription) && !isSuperUser(role)) {
switch(policies.get().subscription_auth_mode) {
case Prefix:
if (!subscription.startsWith(role)) {
PulsarServerException ex = new PulsarServerException(String.format("Failed to create consumer - The subscription name needs to be prefixed by the authentication role, like %s-xxxx for topic: %s", role, topicName));
permissionFuture.completeExceptionally(ex);
return;
}
break;
default:
break;
}
}
}
checkAuthorization(topicName, role, AuthAction.consume).thenAccept(isAuthorized -> {
permissionFuture.complete(isAuthorized);
});
}).exceptionally(ex -> {
log.warn("Client with Role - {} failed to get permissions for topic - {}. {}", role, topicName, ex.getMessage());
permissionFuture.completeExceptionally(ex);
return null;
});
} catch (Exception e) {
log.warn("Client with Role - {} failed to get permissions for topic - {}. {}", role, topicName, e.getMessage());
permissionFuture.completeExceptionally(e);
}
return permissionFuture;
}
use of org.apache.pulsar.broker.PulsarServerException in project incubator-pulsar by apache.
the class ResourceQuotaCache method initZK.
/**
* Initialize the resource quota root node in ZooKeeper.
*/
public void initZK() throws PulsarServerException {
String zpath = ResourceQuotaCache.path(null);
ResourceQuota quota = this.readQuotaFromZnode(zpath);
if (!quota.isValid()) {
quota = ResourceQuotaCache.getInitialQuotaValue();
try {
this.saveQuotaToZnode(zpath, quota);
} catch (Exception e) {
throw new PulsarServerException(e);
}
}
}
use of org.apache.pulsar.broker.PulsarServerException in project incubator-pulsar by apache.
the class ProxyServer method start.
public void start() throws PulsarServerException {
log.info("Starting web socket proxy at port {}", conf.getWebServicePort());
try {
RequestLogHandler requestLogHandler = new RequestLogHandler();
Slf4jRequestLog requestLog = new Slf4jRequestLog();
requestLog.setExtended(true);
requestLog.setLogTimeZone(TimeZone.getDefault().getID());
requestLog.setLogLatency(true);
requestLogHandler.setRequestLog(requestLog);
handlers.add(0, new ContextHandlerCollection());
handlers.add(requestLogHandler);
ContextHandlerCollection contexts = new ContextHandlerCollection();
contexts.setHandlers(handlers.toArray(new Handler[handlers.size()]));
HandlerCollection handlerCollection = new HandlerCollection();
handlerCollection.setHandlers(new Handler[] { contexts, new DefaultHandler(), requestLogHandler });
server.setHandler(handlerCollection);
server.start();
} catch (Exception e) {
throw new PulsarServerException(e);
}
}
use of org.apache.pulsar.broker.PulsarServerException in project incubator-pulsar by apache.
the class Consumer method sendMessages.
/**
* Dispatch a list of entries to the consumer. <br/>
* <b>It is also responsible to release entries data and recycle entries object.</b>
*
* @return a promise that can be use to track when all the data has been written into the socket
*/
public SendMessageInfo sendMessages(final List<Entry> entries) {
final ChannelHandlerContext ctx = cnx.ctx();
final SendMessageInfo sentMessages = new SendMessageInfo();
final ChannelPromise writePromise = ctx.newPromise();
sentMessages.channelPromse = writePromise;
if (entries.isEmpty()) {
if (log.isDebugEnabled()) {
log.debug("[{}-{}] List of messages is empty, triggering write future immediately for consumerId {}", topicName, subscription, consumerId);
}
writePromise.setSuccess();
sentMessages.totalSentMessages = 0;
sentMessages.totalSentMessageBytes = 0;
return sentMessages;
}
try {
updatePermitsAndPendingAcks(entries, sentMessages);
} catch (PulsarServerException pe) {
log.warn("[{}] [{}] consumer doesn't support batch-message {}", subscription, consumerId, cnx.getRemoteEndpointProtocolVersion());
subscription.markTopicWithBatchMessagePublished();
sentMessages.totalSentMessages = 0;
sentMessages.totalSentMessageBytes = 0;
// disconnect consumer: it will update dispatcher's availablePermits and resend pendingAck-messages of this
// consumer to other consumer
disconnect();
return sentMessages;
}
ctx.channel().eventLoop().execute(() -> {
for (int i = 0; i < entries.size(); i++) {
Entry entry = entries.get(i);
PositionImpl pos = (PositionImpl) entry.getPosition();
MessageIdData.Builder messageIdBuilder = MessageIdData.newBuilder();
MessageIdData messageId = messageIdBuilder.setLedgerId(pos.getLedgerId()).setEntryId(pos.getEntryId()).build();
ByteBuf metadataAndPayload = entry.getDataBuffer();
// increment ref-count of data and release at the end of process: so, we can get chance to call entry.release
metadataAndPayload.retain();
// skip checksum by incrementing reader-index if consumer-client doesn't support checksum verification
if (cnx.getRemoteEndpointProtocolVersion() < ProtocolVersion.v11.getNumber()) {
Commands.skipChecksumIfPresent(metadataAndPayload);
}
if (log.isDebugEnabled()) {
log.debug("[{}-{}] Sending message to consumerId {}, entry id {}", topicName, subscription, consumerId, pos.getEntryId());
}
// We only want to pass the "real" promise on the last entry written
ChannelPromise promise = ctx.voidPromise();
if (i == (entries.size() - 1)) {
promise = writePromise;
}
ctx.write(Commands.newMessage(consumerId, messageId, metadataAndPayload), promise);
messageId.recycle();
messageIdBuilder.recycle();
entry.release();
}
ctx.flush();
});
return sentMessages;
}
Aggregations