use of com.yahoo.pulsar.common.naming.NamespaceBundle in project pulsar by yahoo.
the class Namespaces method splitNamespaceBundle.
@PUT
@Path("/{property}/{cluster}/{namespace}/{bundle}/split")
@ApiOperation(value = "Split a namespace bundle")
@ApiResponses(value = { @ApiResponse(code = 403, message = "Don't have admin permission") })
public void splitNamespaceBundle(@PathParam("property") String property, @PathParam("cluster") String cluster, @PathParam("namespace") String namespace, @PathParam("bundle") String bundleRange, @QueryParam("authoritative") @DefaultValue("false") boolean authoritative) {
log.info("[{}] Split namespace bundle {}/{}/{}/{}", clientAppId(), property, cluster, namespace, bundleRange);
validateSuperUserAccess();
Policies policies = getNamespacePolicies(property, cluster, namespace);
if (!cluster.equals(Namespaces.GLOBAL_CLUSTER)) {
validateClusterOwnership(cluster);
validateClusterForProperty(property, cluster);
}
NamespaceName fqnn = new NamespaceName(property, cluster, namespace);
validatePoliciesReadOnlyAccess();
NamespaceBundle nsBundle = validateNamespaceBundleOwnership(fqnn, policies.bundles, bundleRange, authoritative, true);
try {
pulsar().getNamespaceService().splitAndOwnBundle(nsBundle).get();
log.info("[{}] Successfully split namespace bundle {}", clientAppId(), nsBundle.toString());
} catch (Exception e) {
log.error("[{}] Failed to split namespace bundle {}/{}", clientAppId(), fqnn.toString(), bundleRange, e);
throw new RestException(e);
}
}
use of com.yahoo.pulsar.common.naming.NamespaceBundle in project pulsar by yahoo.
the class NamespaceBundleTest method testIncludes.
@Test
public void testIncludes() throws Exception {
DestinationName dn = DestinationName.get("persistent://pulsar/use/ns1/topic-1");
Long hashKey = factory.getLongHashCode(dn.toString());
Long upper = Math.max(hashKey + 1, NamespaceBundles.FULL_UPPER_BOUND);
BoundType upperType = upper.equals(NamespaceBundles.FULL_UPPER_BOUND) ? BoundType.CLOSED : BoundType.OPEN;
NamespaceBundle bundle = factory.getBundle(dn.getNamespaceObject(), Range.range(hashKey / 2, BoundType.CLOSED, upper, upperType));
assertTrue(bundle.includes(dn));
bundle = factory.getBundle(new NamespaceName("pulsar/use/ns1"), Range.range(upper, BoundType.CLOSED, NamespaceBundles.FULL_UPPER_BOUND, BoundType.CLOSED));
assertTrue(!bundle.includes(dn));
NamespaceBundle otherBundle = factory.getBundle(new NamespaceName("pulsar/use/ns2"), Range.range(0l, BoundType.CLOSED, 0x40000000L, BoundType.OPEN));
assertTrue(!otherBundle.includes(dn));
}
use of com.yahoo.pulsar.common.naming.NamespaceBundle in project pulsar by yahoo.
the class NamespaceBundleTest method testEquals.
@Test
public void testEquals() throws Exception {
NamespaceBundle bundle = factory.getBundle(new NamespaceName("pulsar/use/ns1"), Range.range(0l, BoundType.CLOSED, 0x40000000L, BoundType.OPEN));
NamespaceBundle bundle2 = factory.getBundle(new NamespaceName("pulsar/use/ns1"), Range.range(0x20000000l, BoundType.CLOSED, 0x40000000L, BoundType.OPEN));
assertTrue(!bundle.equals(bundle2));
NamespaceBundle bundle0 = factory.getBundle(new NamespaceName("pulsar/use/ns1"), Range.range(0l, BoundType.CLOSED, 0x40000000L, BoundType.OPEN));
assertTrue(bundle0.equals(bundle));
NamespaceBundle otherBundle = factory.getBundle(new NamespaceName("pulsar/use/ns2"), Range.range(0l, BoundType.CLOSED, 0x40000000L, BoundType.OPEN));
assertTrue(!otherBundle.equals(bundle));
}
use of com.yahoo.pulsar.common.naming.NamespaceBundle in project pulsar by yahoo.
the class NamespaceBundleTest method testGetBundle.
@Test
public void testGetBundle() throws Exception {
NamespaceBundle bundle = factory.getBundle(new NamespaceName("pulsar/use/ns1"), Range.range(0L, BoundType.CLOSED, 0xffffffffL, BoundType.CLOSED));
assertNotNull(bundle);
NamespaceBundle bundle2 = factory.getBundle(new NamespaceName("pulsar/use/ns1"), Range.range(0L, BoundType.CLOSED, 0xffffffffL, BoundType.CLOSED));
// Don't call equals and make sure those two are the same instance
assertEquals(bundle, bundle2);
}
use of com.yahoo.pulsar.common.naming.NamespaceBundle in project pulsar by yahoo.
the class BrokerClientIntegrationTest method testDisconnectClientWithoutClosingConnection.
/**
* Verifies unload namespace-bundle doesn't close shared connection used by other namespace-bundle.
* <pre>
* 1. after disabling broker fron loadbalancer
* 2. unload namespace-bundle "my-ns1" which disconnects client (producer/consumer) connected on that namespacebundle
* 3. but doesn't close the connection for namesapce-bundle "my-ns2" and clients are still connected
* 4. verifies unloaded "my-ns1" should not connected again with the broker as broker is disabled
* 5. unload "my-ns2" which closes the connection as broker doesn't have any more client connected on that connection
* 6. all namespace-bundles are in "connecting" state and waiting for available broker
* </pre>
*
* @throws Exception
*/
@Test
public void testDisconnectClientWithoutClosingConnection() throws Exception {
final String ns1 = "my-property/use/con-ns1";
final String ns2 = "my-property/use/con-ns2";
admin.namespaces().createNamespace(ns1);
admin.namespaces().createNamespace(ns2);
final String dn1 = "persistent://" + ns1 + "/my-topic";
final String dn2 = "persistent://" + ns2 + "/my-topic";
ConsumerImpl cons1 = (ConsumerImpl) pulsarClient.subscribe(dn1, "my-subscriber-name", new ConsumerConfiguration());
ProducerImpl prod1 = (ProducerImpl) pulsarClient.createProducer(dn1, new ProducerConfiguration());
ProducerImpl prod2 = (ProducerImpl) pulsarClient.createProducer(dn2, new ProducerConfiguration());
ConsumerImpl consumer1 = spy(cons1);
doAnswer(invocationOnMock -> cons1.getState()).when(consumer1).getState();
doAnswer(invocationOnMock -> cons1.getClientCnx()).when(consumer1).getClientCnx();
doAnswer(invocationOnMock -> cons1.cnx()).when(consumer1).cnx();
doAnswer(invocationOnMock -> {
cons1.connectionClosed((ClientCnx) invocationOnMock.getArguments()[0]);
return null;
}).when(consumer1).connectionClosed(anyObject());
ProducerImpl producer1 = spy(prod1);
doAnswer(invocationOnMock -> prod1.getState()).when(producer1).getState();
doAnswer(invocationOnMock -> prod1.getClientCnx()).when(producer1).getClientCnx();
doAnswer(invocationOnMock -> prod1.cnx()).when(producer1).cnx();
doAnswer(invocationOnMock -> {
prod1.connectionClosed((ClientCnx) invocationOnMock.getArguments()[0]);
return null;
}).when(producer1).connectionClosed(anyObject());
ProducerImpl producer2 = spy(prod2);
doAnswer(invocationOnMock -> prod2.getState()).when(producer2).getState();
doAnswer(invocationOnMock -> prod2.getClientCnx()).when(producer2).getClientCnx();
doAnswer(invocationOnMock -> prod2.cnx()).when(producer2).cnx();
doAnswer(invocationOnMock -> {
prod2.connectionClosed((ClientCnx) invocationOnMock.getArguments()[0]);
return null;
}).when(producer2).connectionClosed(anyObject());
ClientCnx clientCnx = producer1.getClientCnx();
Field pfield = ClientCnx.class.getDeclaredField("producers");
pfield.setAccessible(true);
Field cfield = ClientCnx.class.getDeclaredField("consumers");
cfield.setAccessible(true);
ConcurrentLongHashMap<ProducerImpl> producers = (ConcurrentLongHashMap<ProducerImpl>) pfield.get(clientCnx);
ConcurrentLongHashMap<ConsumerImpl> consumers = (ConcurrentLongHashMap<ConsumerImpl>) cfield.get(clientCnx);
producers.put(2, producers.get(0));
producers.put(3, producers.get(1));
consumers.put(1, consumers.get(0));
producers.put(0, producer1);
producers.put(1, producer2);
consumers.put(0, consumer1);
// disable this broker to avoid any new requests
pulsar.getLoadManager().disableBroker();
NamespaceBundle bundle1 = pulsar.getNamespaceService().getBundle(DestinationName.get(dn1));
NamespaceBundle bundle2 = pulsar.getNamespaceService().getBundle(DestinationName.get(dn2));
// unload ns-bundle:1
pulsar.getNamespaceService().unloadNamespaceBundle((NamespaceBundle) bundle1);
// let server send signal to close-connection and client close the connection
Thread.sleep(1000);
// [1] Verify: producer1 must get connectionClosed signal
verify(producer1, atLeastOnce()).connectionClosed(anyObject());
// [2] Verify: consumer1 must get connectionClosed signal
verify(consumer1, atLeastOnce()).connectionClosed(anyObject());
// [3] Verify: producer2 should have not received connectionClosed signal
verify(producer2, never()).connectionClosed(anyObject());
// sleep for sometime to let other disconnected producer and consumer connect again: but they should not get
// connected with same broker as that broker is already out from active-broker list
Thread.sleep(200);
// producer1 must not be able to connect again
assertTrue(prod1.getClientCnx() == null);
assertTrue(prod1.getState().equals(State.Connecting));
// consumer1 must not be able to connect again
assertTrue(cons1.getClientCnx() == null);
assertTrue(cons1.getState().equals(State.Connecting));
// producer2 must have live connection
assertTrue(prod2.getClientCnx() != null);
assertTrue(prod2.getState().equals(State.Ready));
// unload ns-bundle2 as well
pulsar.getNamespaceService().unloadNamespaceBundle((NamespaceBundle) bundle2);
verify(producer2, atLeastOnce()).connectionClosed(anyObject());
Thread.sleep(200);
// producer1 must not be able to connect again
assertTrue(prod1.getClientCnx() == null);
assertTrue(prod1.getState().equals(State.Connecting));
// consumer1 must not be able to connect again
assertTrue(cons1.getClientCnx() == null);
assertTrue(cons1.getState().equals(State.Connecting));
// producer2 must not be able to connect again
assertTrue(prod2.getClientCnx() == null);
assertTrue(prod2.getState().equals(State.Connecting));
producer1.close();
producer2.close();
consumer1.close();
prod1.close();
prod2.close();
cons1.close();
}
Aggregations