use of com.yahoo.pulsar.broker.web.RestException in project pulsar by yahoo.
the class PersistentTopics method getReplicatorReference.
/**
* Get the Replicator object reference from the Topic reference
*/
private PersistentReplicator getReplicatorReference(String replName, PersistentTopic topic) {
try {
String remoteCluster = PersistentReplicator.getRemoteCluster(replName);
PersistentReplicator repl = topic.getPersistentReplicator(remoteCluster);
return checkNotNull(repl);
} catch (Exception e) {
throw new RestException(Status.NOT_FOUND, "Replicator not found");
}
}
use of com.yahoo.pulsar.broker.web.RestException in project pulsar by yahoo.
the class PersistentTopics method skipMessages.
@POST
@Path("/{property}/{cluster}/{namespace}/{destination}/subscription/{subName}/skip/{numMessages}")
@ApiOperation(value = "Skip messages on a topic subscription.")
@ApiResponses(value = { @ApiResponse(code = 403, message = "Don't have admin permission"), @ApiResponse(code = 404, message = "Topic or subscription does not exist") })
public void skipMessages(@PathParam("property") String property, @PathParam("cluster") String cluster, @PathParam("namespace") String namespace, @PathParam("destination") @Encoded String destination, @PathParam("subName") String subName, @PathParam("numMessages") int numMessages, @QueryParam("authoritative") @DefaultValue("false") boolean authoritative) {
destination = decode(destination);
DestinationName dn = DestinationName.get(domain(), property, cluster, namespace, destination);
PartitionedTopicMetadata partitionMetadata = getPartitionedTopicMetadata(property, cluster, namespace, destination, authoritative);
if (partitionMetadata.partitions > 0) {
throw new RestException(Status.METHOD_NOT_ALLOWED, "Skip messages on a partitioned topic is not allowed");
}
validateAdminOperationOnDestination(dn, authoritative);
PersistentTopic topic = getTopicReference(dn);
try {
if (subName.startsWith(topic.replicatorPrefix)) {
String remoteCluster = PersistentReplicator.getRemoteCluster(subName);
PersistentReplicator repl = topic.getPersistentReplicator(remoteCluster);
checkNotNull(repl);
repl.skipMessages(numMessages).get();
} else {
PersistentSubscription sub = topic.getPersistentSubscription(subName);
checkNotNull(sub);
sub.skipMessages(numMessages).get();
}
log.info("[{}] Skipped {} messages on {} {}", clientAppId(), numMessages, dn, subName);
} catch (NullPointerException npe) {
throw new RestException(Status.NOT_FOUND, "Subscription not found");
} catch (Exception exception) {
log.error("[{}] Failed to skip {} messages {} {}", clientAppId(), numMessages, dn, subName, exception);
throw new RestException(exception);
}
}
use of com.yahoo.pulsar.broker.web.RestException in project pulsar by yahoo.
the class PersistentTopics method expireMessages.
public void expireMessages(String property, String cluster, String namespace, String destination, String subName, int expireTimeInSeconds, boolean authoritative) {
DestinationName dn = DestinationName.get(domain(), property, cluster, namespace, destination);
PartitionedTopicMetadata partitionMetadata = getPartitionedTopicMetadata(property, cluster, namespace, destination, authoritative);
if (partitionMetadata.partitions > 0) {
// expire messages for each partition destination
try {
for (int i = 0; i < partitionMetadata.partitions; i++) {
pulsar().getAdminClient().persistentTopics().expireMessages(dn.getPartition(i).toString(), subName, expireTimeInSeconds);
}
} catch (Exception e) {
throw new RestException(e);
}
} else {
// validate ownership and redirect if current broker is not owner
validateAdminOperationOnDestination(dn, authoritative);
PersistentTopic topic = getTopicReference(dn);
try {
if (subName.startsWith(topic.replicatorPrefix)) {
String remoteCluster = PersistentReplicator.getRemoteCluster(subName);
PersistentReplicator repl = topic.getPersistentReplicator(remoteCluster);
checkNotNull(repl);
repl.expireMessages(expireTimeInSeconds);
} else {
PersistentSubscription sub = topic.getPersistentSubscription(subName);
checkNotNull(sub);
sub.expireMessages(expireTimeInSeconds);
}
log.info("[{}] Message expire started up to {} on {} {}", clientAppId(), expireTimeInSeconds, dn, subName);
} catch (NullPointerException npe) {
throw new RestException(Status.NOT_FOUND, "Subscription not found");
} catch (Exception exception) {
log.error("[{}] Failed to expire messages up to {} on {} with subscription {} {}", clientAppId(), expireTimeInSeconds, dn, subName, exception);
throw new RestException(exception);
}
}
}
use of com.yahoo.pulsar.broker.web.RestException in project pulsar by yahoo.
the class PersistentTopics method grantPermissionsOnDestination.
@POST
@Path("/{property}/{cluster}/{namespace}/{destination}/permissions/{role}")
@ApiOperation(value = "Grant a new permission to a role on a single destination.")
@ApiResponses(value = { @ApiResponse(code = 403, message = "Don't have admin permission"), @ApiResponse(code = 404, message = "Namespace doesn't exist"), @ApiResponse(code = 409, message = "Concurrent modification") })
public void grantPermissionsOnDestination(@PathParam("property") String property, @PathParam("cluster") String cluster, @PathParam("namespace") String namespace, @PathParam("destination") @Encoded String destination, @PathParam("role") String role, Set<AuthAction> actions) {
destination = decode(destination);
// This operation should be reading from zookeeper and it should be allowed without having admin privileges
validateAdminAccessOnProperty(property);
validatePoliciesReadOnlyAccess();
String destinationUri = DestinationName.get(domain(), property, cluster, namespace, destination).toString();
try {
Stat nodeStat = new Stat();
byte[] content = globalZk().getData(path("policies", property, cluster, namespace), null, nodeStat);
Policies policies = jsonMapper().readValue(content, Policies.class);
if (!policies.auth_policies.destination_auth.containsKey(destinationUri)) {
policies.auth_policies.destination_auth.put(destinationUri, new TreeMap<String, Set<AuthAction>>());
}
policies.auth_policies.destination_auth.get(destinationUri).put(role, actions);
// Write the new policies to zookeeper
globalZk().setData(path("policies", property, cluster, namespace), jsonMapper().writeValueAsBytes(policies), nodeStat.getVersion());
// invalidate the local cache to force update
policiesCache().invalidate(path("policies", property, cluster, namespace));
log.info("[{}] Successfully granted access for role {}: {} - destination {}", clientAppId(), role, actions, destinationUri);
} catch (KeeperException.NoNodeException e) {
log.warn("[{}] Failed to grant permissions on destination {}: Namespace does not exist", clientAppId(), destinationUri);
throw new RestException(Status.NOT_FOUND, "Namespace does not exist");
} catch (Exception e) {
log.error("[{}] Failed to grant permissions for destination {}", clientAppId(), destinationUri, e);
throw new RestException(e);
}
}
use of com.yahoo.pulsar.broker.web.RestException in project pulsar by yahoo.
the class NamespacesTest method testDeleteNamespaceWithBundles.
@Test
public void testDeleteNamespaceWithBundles() throws Exception {
URL localWebServiceUrl = new URL(pulsar.getWebServiceAddress());
String bundledNsLocal = "test-bundled-namespace-1";
BundlesData bundleData = new BundlesData(Lists.newArrayList("0x00000000", "0x80000000", "0xffffffff"));
createBundledTestNamespaces(this.testProperty, this.testLocalCluster, bundledNsLocal, bundleData);
final NamespaceName testNs = new NamespaceName(this.testProperty, this.testLocalCluster, bundledNsLocal);
com.yahoo.pulsar.client.admin.Namespaces namespacesAdmin = mock(com.yahoo.pulsar.client.admin.Namespaces.class);
doReturn(namespacesAdmin).when(admin).namespaces();
doReturn(null).when(nsSvc).getWebServiceUrl(Mockito.argThat(new Matcher<NamespaceBundle>() {
@Override
public void describeTo(Description description) {
}
@Override
public boolean matches(Object item) {
if (item instanceof NamespaceBundle) {
NamespaceBundle bundle = (NamespaceBundle) item;
return bundle.getNamespaceObject().equals(testNs);
}
return false;
}
@Override
public void _dont_implement_Matcher___instead_extend_BaseMatcher_() {
}
}), Mockito.anyBoolean(), Mockito.anyBoolean(), Mockito.anyBoolean());
doReturn(false).when(nsSvc).isServiceUnitOwned(Mockito.argThat(new Matcher<NamespaceBundle>() {
@Override
public void describeTo(Description description) {
}
@Override
public boolean matches(Object item) {
if (item instanceof NamespaceBundle) {
NamespaceBundle bundle = (NamespaceBundle) item;
return bundle.getNamespaceObject().equals(testNs);
}
return false;
}
@Override
public void _dont_implement_Matcher___instead_extend_BaseMatcher_() {
}
}));
doReturn(Optional.of(new NamespaceEphemeralData())).when(nsSvc).getOwner(Mockito.argThat(new Matcher<NamespaceBundle>() {
@Override
public void describeTo(Description description) {
}
@Override
public boolean matches(Object item) {
if (item instanceof NamespaceBundle) {
NamespaceBundle bundle = (NamespaceBundle) item;
return bundle.getNamespaceObject().equals(testNs);
}
return false;
}
@Override
public void _dont_implement_Matcher___instead_extend_BaseMatcher_() {
}
}));
doThrow(new PulsarAdminException.PreconditionFailedException(new ClientErrorException(Status.PRECONDITION_FAILED))).when(namespacesAdmin).deleteNamespaceBundle(Mockito.anyString(), Mockito.anyString());
try {
namespaces.deleteNamespaceBundle(testProperty, testLocalCluster, bundledNsLocal, "0x00000000_0x80000000", false);
fail("Should have failed");
} catch (RestException re) {
assertEquals(re.getResponse().getStatus(), Status.PRECONDITION_FAILED.getStatusCode());
}
try {
namespaces.deleteNamespace(testProperty, testLocalCluster, bundledNsLocal, false);
fail("Should have failed");
} catch (RestException re) {
assertEquals(re.getResponse().getStatus(), Status.PRECONDITION_FAILED.getStatusCode());
}
NamespaceBundles nsBundles = nsSvc.getNamespaceBundleFactory().getBundles(testNs, bundleData);
// make one bundle owned
doReturn(localWebServiceUrl).when(nsSvc).getWebServiceUrl(nsBundles.getBundles().get(0), false, true, false);
doReturn(true).when(nsSvc).isServiceUnitOwned(nsBundles.getBundles().get(0));
doNothing().when(namespacesAdmin).deleteNamespaceBundle(testProperty + "/" + testLocalCluster + "/" + bundledNsLocal, "0x00000000_0x80000000");
try {
namespaces.deleteNamespaceBundle(testProperty, testLocalCluster, bundledNsLocal, "0x80000000_0xffffffff", false);
fail("Should have failed");
} catch (RestException re) {
assertEquals(re.getResponse().getStatus(), Status.PRECONDITION_FAILED.getStatusCode());
}
try {
namespaces.deleteNamespace(testProperty, testLocalCluster, bundledNsLocal, false);
fail("should have failed");
} catch (RestException re) {
assertEquals(re.getResponse().getStatus(), Status.PRECONDITION_FAILED.getStatusCode());
}
// ensure all three bundles are owned by the local broker
for (NamespaceBundle bundle : nsBundles.getBundles()) {
doReturn(localWebServiceUrl).when(nsSvc).getWebServiceUrl(bundle, false, true, false);
doReturn(true).when(nsSvc).isServiceUnitOwned(bundle);
}
doNothing().when(namespacesAdmin).deleteNamespaceBundle(Mockito.anyString(), Mockito.anyString());
}
Aggregations