use of com.yahoo.pulsar.common.naming.NamespaceBundles in project pulsar by yahoo.
the class AdminApiTest method testNamespaceSplitBundle.
@Test
public void testNamespaceSplitBundle() throws Exception {
// Force to create a destination
final String namespace = "prop-xyz/use/ns1";
final String topicName = (new StringBuilder("persistent://")).append(namespace).append("/ds2").toString();
Producer producer = pulsarClient.createProducer(topicName);
producer.send("message".getBytes());
publishMessagesOnPersistentTopic(topicName, 0);
assertEquals(admin.persistentTopics().getList(namespace), Lists.newArrayList(topicName));
try {
admin.namespaces().splitNamespaceBundle(namespace, "0x00000000_0xffffffff");
} catch (Exception e) {
fail("split bundle shouldn't have thrown exception");
}
// bundle-factory cache must have updated split bundles
NamespaceBundles bundles = bundleFactory.getBundles(new NamespaceName(namespace));
String[] splitRange = { namespace + "/0x00000000_0x7fffffff", namespace + "/0x7fffffff_0xffffffff" };
for (int i = 0; i < bundles.getBundles().size(); i++) {
assertEquals(bundles.getBundles().get(i).toString(), splitRange[i]);
}
producer.close();
}
use of com.yahoo.pulsar.common.naming.NamespaceBundles in project pulsar by yahoo.
the class NamespaceServiceTest method testIsServiceUnitDisabled.
@Test
public void testIsServiceUnitDisabled() throws Exception {
OwnershipCache MockOwnershipCache = spy(pulsar.getNamespaceService().getOwnershipCache());
ManagedLedger ledger = mock(ManagedLedger.class);
when(ledger.getCursors()).thenReturn(Lists.newArrayList());
doNothing().when(MockOwnershipCache).disableOwnership(any(NamespaceBundle.class));
Field ownership = NamespaceService.class.getDeclaredField("ownershipCache");
ownership.setAccessible(true);
ownership.set(pulsar.getNamespaceService(), MockOwnershipCache);
NamespaceService namespaceService = pulsar.getNamespaceService();
NamespaceName nsname = new NamespaceName("pulsar/global/ns1");
DestinationName dn = DestinationName.get("persistent://pulsar/global/ns1/topic-1");
NamespaceBundles bundles = namespaceService.getNamespaceBundleFactory().getBundles(nsname);
NamespaceBundle originalBundle = bundles.findBundle(dn);
assertFalse(namespaceService.isNamespaceBundleDisabled(originalBundle));
}
use of com.yahoo.pulsar.common.naming.NamespaceBundles in project pulsar by yahoo.
the class NamespaceService method splitAndOwnBundle.
/**
* 1. split the given bundle into two bundles 2. assign ownership of both the bundles to current broker 3. update
* policies with newly created bundles into LocalZK 4. disable original bundle and refresh the cache
*
* @param bundle
* @return
* @throws Exception
*/
public CompletableFuture<Void> splitAndOwnBundle(NamespaceBundle bundle) throws Exception {
final CompletableFuture<Void> future = new CompletableFuture<>();
Pair<NamespaceBundles, List<NamespaceBundle>> splittedBundles = bundleFactory.splitBundles(bundle, 2);
if (splittedBundles != null) {
checkNotNull(splittedBundles.getLeft());
checkNotNull(splittedBundles.getRight());
checkArgument(splittedBundles.getRight().size() == 2, "bundle has to be split in two bundles");
NamespaceName nsname = bundle.getNamespaceObject();
try {
// take ownership of newly split bundles
for (NamespaceBundle sBundle : splittedBundles.getRight()) {
checkNotNull(ownershipCache.tryAcquiringOwnership(sBundle));
}
updateNamespaceBundles(nsname, splittedBundles.getLeft(), (rc, path, zkCtx, stat) -> pulsar.getOrderedExecutor().submit(safeRun(() -> {
if (rc == KeeperException.Code.OK.intValue()) {
// disable old bundle
try {
ownershipCache.disableOwnership(bundle);
// invalidate cache as zookeeper has new split
// namespace bundle
bundleFactory.invalidateBundleCache(nsname);
// update bundled_topic cache for load-report-generation
pulsar.getBrokerService().refreshTopicToStatsMaps(bundle);
loadManager.setLoadReportForceUpdateFlag();
future.complete(null);
} catch (Exception e) {
String msg1 = format("failed to disable bundle %s under namespace [%s] with error %s", nsname.toString(), bundle.toString(), e.getMessage());
LOG.warn(msg1, e);
future.completeExceptionally(new ServiceUnitNotReadyException(msg1));
}
} else {
String msg2 = format("failed to update namespace [%s] policies due to %s", nsname.toString(), KeeperException.create(KeeperException.Code.get(rc)).getMessage());
LOG.warn(msg2);
future.completeExceptionally(new ServiceUnitNotReadyException(msg2));
}
})));
} catch (Exception e) {
String msg = format("failed to aquire ownership of split bundle for namespace [%s], %s", nsname.toString(), e.getMessage());
LOG.warn(msg, e);
future.completeExceptionally(new ServiceUnitNotReadyException(msg));
}
} else {
String msg = format("bundle %s not found under namespace", bundle.toString());
future.completeExceptionally(new ServiceUnitNotReadyException(msg));
}
return future;
}
use of com.yahoo.pulsar.common.naming.NamespaceBundles in project pulsar by yahoo.
the class AdminResource method getNamespacePolicies.
protected Policies getNamespacePolicies(String property, String cluster, String namespace) {
try {
Policies policies = policiesCache().get(AdminResource.path("policies", property, cluster, namespace)).orElseThrow(() -> new RestException(Status.NOT_FOUND, "Namespace does not exist"));
// fetch bundles from LocalZK-policies
NamespaceBundles bundles = pulsar().getNamespaceService().getNamespaceBundleFactory().getBundles(new NamespaceName(property, cluster, namespace));
BundlesData bundleData = NamespaceBundleFactory.getBundlesData(bundles);
policies.bundles = bundleData != null ? bundleData : policies.bundles;
return policies;
} catch (RestException re) {
throw re;
} catch (Exception e) {
log.error("[{}] Failed to get namespace policies {}/{}/{}", clientAppId(), property, cluster, namespace, e);
throw new RestException(e);
}
}
use of com.yahoo.pulsar.common.naming.NamespaceBundles in project pulsar by yahoo.
the class Namespaces method unsubscribeNamespace.
@POST
@Path("/{property}/{cluster}/{namespace}/unsubscribe/{subscription}")
@ApiOperation(value = "Unsubscribes the given subscription on all destinations on a namespace.")
@ApiResponses(value = { @ApiResponse(code = 403, message = "Don't have admin permission"), @ApiResponse(code = 404, message = "Namespace does not exist") })
public void unsubscribeNamespace(@PathParam("property") String property, @PathParam("cluster") String cluster, @PathParam("namespace") String namespace, @PathParam("subscription") String subscription, @QueryParam("authoritative") @DefaultValue("false") boolean authoritative) {
validateAdminAccessOnProperty(property);
NamespaceName nsName = new NamespaceName(property, cluster, namespace);
try {
NamespaceBundles bundles = pulsar().getNamespaceService().getNamespaceBundleFactory().getBundles(nsName);
Exception exception = null;
for (NamespaceBundle nsBundle : bundles.getBundles()) {
try {
// check if the bundle is owned by any broker, if not then there are no subscriptions
if (pulsar().getNamespaceService().getOwner(nsBundle).isPresent()) {
// TODO: make this admin call asynchronous
pulsar().getAdminClient().namespaces().unsubscribeNamespaceBundle(nsName.toString(), nsBundle.getBundleRange(), subscription);
}
} catch (Exception e) {
if (exception == null) {
exception = e;
}
}
}
if (exception != null) {
if (exception instanceof PulsarAdminException) {
throw new RestException((PulsarAdminException) exception);
} else {
throw new RestException(exception.getCause());
}
}
} catch (WebApplicationException wae) {
throw wae;
} catch (Exception e) {
throw new RestException(e);
}
log.info("[{}] Successfully unsubscribed {} on all the bundles for namespace {}", clientAppId(), subscription, nsName.toString());
}
Aggregations