use of io.pravega.controller.server.rest.generated.model.StreamsList in project pravega by pravega.
the class StreamMetaDataAuthFocusedTests method testListStreamsReturnsAllWhenUserHasWildCardAccess.
@Test
public void testListStreamsReturnsAllWhenUserHasWildCardAccess() {
// Arrange
String resourceURI = getURI() + "v1/scopes/myscope/streams";
Map<String, StreamConfiguration> streamsList = ImmutableMap.of("stream1", this.aStreamConfig(), "stream2", this.aStreamConfig(), "stream3", this.aStreamConfig());
when(mockControllerService.listStreamsInScope(eq("myscope"), anyLong())).thenReturn(CompletableFuture.completedFuture(streamsList));
// Act
Response response = this.invocationBuilder(resourceURI, USER_PRIVILEGED, DEFAULT_PASSWORD).buildGet().invoke();
StreamsList listedStreams = response.readEntity(StreamsList.class);
// Assert
assertEquals(HTTP_STATUS_OK, response.getStatus());
assertEquals(3, listedStreams.getStreams().size());
response.close();
}
use of io.pravega.controller.server.rest.generated.model.StreamsList in project pravega by pravega.
the class StreamMetaDataAuthFocusedTests method testListStreamsReturnsEmptyListWhenUserHasNoStreamsAssigned.
// endregion
// region Streams listing tests
@Test
public void testListStreamsReturnsEmptyListWhenUserHasNoStreamsAssigned() {
// Arrange
String resourceURI = getURI() + "v1/scopes/myscope/streams";
Map<String, StreamConfiguration> streamsList = ImmutableMap.of("stream1", this.aStreamConfig(), "stream2", this.aStreamConfig());
when(mockControllerService.listStreamsInScope(eq("myscope"), anyLong())).thenReturn(CompletableFuture.completedFuture(streamsList));
// Act
Response response = this.invocationBuilder(resourceURI, USER_ACCESS_TO_SCOPES_BUT_NOSTREAMS, DEFAULT_PASSWORD).buildGet().invoke();
StreamsList listedStreams = response.readEntity(StreamsList.class);
// Assert
assertEquals(HTTP_STATUS_OK, response.getStatus());
Assert.assertTrue(listedStreams.getStreams().isEmpty());
response.close();
}
use of io.pravega.controller.server.rest.generated.model.StreamsList in project pravega by pravega.
the class StreamMetaDataAuthFocusedTests method testListStreamsReturnsAllStreamsWhenUserHasWildcardOnScope.
@Test
public void testListStreamsReturnsAllStreamsWhenUserHasWildcardOnScope() {
// Arrange
String resourceURI = getURI() + "v1/scopes/myscope/streams";
Map<String, StreamConfiguration> streamsList = ImmutableMap.of("stream1", this.aStreamConfig(), "stream2", this.aStreamConfig(), "stream3", this.aStreamConfig());
when(mockControllerService.listStreamsInScope(eq("myscope"), anyLong())).thenReturn(CompletableFuture.completedFuture(streamsList));
// Act
Response response = this.invocationBuilder(resourceURI, USER_ACCESS_TO_SCOPES_READ_ALLSTREAMS, DEFAULT_PASSWORD).buildGet().invoke();
StreamsList listedStreams = response.readEntity(StreamsList.class);
// Assert
assertEquals(HTTP_STATUS_OK, response.getStatus());
assertEquals(3, listedStreams.getStreams().size());
response.close();
}
use of io.pravega.controller.server.rest.generated.model.StreamsList in project pravega by pravega.
the class StreamMetaDataTests method testListStreams.
/**
* Test for listStreams REST API.
*
* @throws ExecutionException
* @throws InterruptedException
*/
@Test(timeout = 30000)
public void testListStreams() throws ExecutionException, InterruptedException {
final String resourceURI = getURI() + "v1/scopes/scope1/streams";
final StreamConfiguration streamConfiguration1 = StreamConfiguration.builder().scalingPolicy(ScalingPolicy.byEventRate(100, 2, 2)).retentionPolicy(RetentionPolicy.byTime(Duration.ofMillis(123L))).build();
final StreamConfiguration streamConfiguration2 = StreamConfiguration.builder().scalingPolicy(ScalingPolicy.byEventRate(100, 2, 2)).retentionPolicy(RetentionPolicy.byTime(Duration.ofMillis(123L))).build();
// Test to list streams.
Map<String, StreamConfiguration> streamsList = ImmutableMap.of(stream1, streamConfiguration1, stream2, streamConfiguration2);
when(mockControllerService.listStreamsInScope(eq("scope1"), anyLong())).thenReturn(CompletableFuture.completedFuture(streamsList));
Response response = addAuthHeaders(client.target(resourceURI).request()).buildGet().invoke();
assertEquals("List Streams response code", 200, response.getStatus());
assertTrue(response.bufferEntity());
final StreamsList streamsList1 = response.readEntity(StreamsList.class);
assertEquals("List count", streamsList1.getStreams().size(), 2);
assertEquals("List element", streamsList1.getStreams().get(0).getStreamName(), "stream1");
assertEquals("List element", streamsList1.getStreams().get(1).getStreamName(), "stream2");
response.close();
// Test for list streams for invalid scope.
final CompletableFuture<Map<String, StreamConfiguration>> completableFuture1 = new CompletableFuture<>();
completableFuture1.completeExceptionally(StoreException.create(StoreException.Type.DATA_NOT_FOUND, "scope1"));
when(mockControllerService.listStreamsInScope(eq("scope1"), anyLong())).thenReturn(completableFuture1);
response = addAuthHeaders(client.target(resourceURI).request()).buildGet().invoke();
assertEquals("List Streams response code", 404, response.getStatus());
response.close();
// Test for list streams failure.
final CompletableFuture<Map<String, StreamConfiguration>> completableFuture = new CompletableFuture<>();
completableFuture.completeExceptionally(new Exception());
when(mockControllerService.listStreamsInScope(eq("scope1"), anyLong())).thenReturn(completableFuture);
response = addAuthHeaders(client.target(resourceURI).request()).buildGet().invoke();
assertEquals("List Streams response code", 500, response.getStatus());
response.close();
// Test for filtering streams.
final StreamConfiguration streamConfiguration3 = StreamConfiguration.builder().scalingPolicy(ScalingPolicy.fixed(1)).build();
Map<String, StreamConfiguration> allStreamsList = ImmutableMap.of(stream1, streamConfiguration1, stream2, streamConfiguration2, NameUtils.getInternalNameForStream("stream3"), streamConfiguration3);
when(mockControllerService.listStreamsInScope(eq("scope1"), anyLong())).thenReturn(CompletableFuture.completedFuture(allStreamsList));
response = addAuthHeaders(client.target(resourceURI).request()).buildGet().invoke();
assertEquals("List Streams response code", 200, response.getStatus());
assertTrue(response.bufferEntity());
StreamsList streamsListResp = response.readEntity(StreamsList.class);
assertEquals("List count", 2, streamsListResp.getStreams().size());
assertEquals("List element", "stream1", streamsListResp.getStreams().get(0).getStreamName());
assertEquals("List element", "stream2", streamsListResp.getStreams().get(1).getStreamName());
response.close();
response = addAuthHeaders(client.target(resourceURI).queryParam("filter_type", "showInternalStreams").request()).buildGet().invoke();
assertEquals("List Streams response code", 200, response.getStatus());
assertTrue(response.bufferEntity());
streamsListResp = response.readEntity(StreamsList.class);
assertEquals("List count", 1, streamsListResp.getStreams().size());
assertEquals("List element", NameUtils.getInternalNameForStream("stream3"), streamsListResp.getStreams().get(0).getStreamName());
response.close();
// Test for tags
final StreamConfiguration streamConfigurationForTags = StreamConfiguration.builder().scalingPolicy(ScalingPolicy.byEventRate(100, 2, 2)).retentionPolicy(RetentionPolicy.byTime(Duration.ofMillis(123L))).tag("testTag").build();
List<String> tagStream = new ArrayList<>();
tagStream.add("streamForTags");
ImmutablePair<List<String>, String> tagPair = new ImmutablePair<>(tagStream, "");
ImmutablePair<List<String>, String> emptyPair = new ImmutablePair<>(Collections.emptyList(), "");
when(mockControllerService.listStreamsForTag(eq("scope1"), eq("testTag"), anyString(), anyLong())).thenReturn(CompletableFuture.completedFuture(tagPair)).thenReturn(CompletableFuture.completedFuture(emptyPair));
when(mockControllerService.getStream(eq("scope1"), eq("streamForTags"), anyLong())).thenReturn(CompletableFuture.completedFuture(streamConfigurationForTags));
response = addAuthHeaders(client.target(resourceURI).queryParam("filter_type", "tag").queryParam("filter_value", "testTag").request()).buildGet().invoke();
assertEquals("List Streams response code", 200, response.getStatus());
assertTrue(response.bufferEntity());
final StreamsList streamsListForTags = response.readEntity(StreamsList.class);
assertEquals("List count", streamsListForTags.getStreams().size(), 1);
assertEquals("List element", streamsListForTags.getStreams().get(0).getStreamName(), "streamForTags");
response.close();
final CompletableFuture<Pair<List<String>, String>> completableFutureForTag = new CompletableFuture<>();
completableFutureForTag.completeExceptionally(StoreException.create(StoreException.Type.DATA_NOT_FOUND, "scope1"));
when(mockControllerService.listStreamsForTag(eq("scope1"), eq("testTag"), anyString(), anyLong())).thenReturn(completableFutureForTag);
response = addAuthHeaders(client.target(resourceURI).queryParam("filter_type", "tag").queryParam("filter_value", "testTag").request()).buildGet().invoke();
assertEquals("List Streams response code", 404, response.getStatus());
response.close();
final CompletableFuture<Pair<List<String>, String>> completableFutureForTag1 = new CompletableFuture<>();
completableFutureForTag1.completeExceptionally(new Exception());
when(mockControllerService.listStreamsForTag(eq("scope1"), eq("testTag"), anyString(), anyLong())).thenReturn(completableFutureForTag1);
response = addAuthHeaders(client.target(resourceURI).queryParam("filter_type", "tag").queryParam("filter_value", "testTag").request()).buildGet().invoke();
assertEquals("List Streams response code", 500, response.getStatus());
response.close();
// Test to list large number of streams.
streamsList = new HashMap<>();
for (int i = 0; i < 50000; i++) {
streamsList.put("stream" + i, streamConfiguration1);
}
when(mockControllerService.listStreamsInScope(eq("scope1"), anyLong())).thenReturn(CompletableFuture.completedFuture(streamsList));
response = addAuthHeaders(client.target(resourceURI).request()).buildGet().invoke();
assertEquals("List Streams response code", 200, response.getStatus());
assertTrue(response.bufferEntity());
final StreamsList streamsList2 = response.readEntity(StreamsList.class);
assertEquals("List count", 50000, streamsList2.getStreams().size());
response.close();
}
use of io.pravega.controller.server.rest.generated.model.StreamsList in project pravega by pravega.
the class StreamMetadataResourceImpl method listStreams.
/**
* Implementation of listStreams REST API.
*
* @param scopeName The scope name of stream.
* @param securityContext The security for API access.
* @param asyncResponse AsyncResponse provides means for asynchronous server side response processing.
*/
@Override
public void listStreams(final String scopeName, final String filterType, final String filterValue, final SecurityContext securityContext, final AsyncResponse asyncResponse) {
long traceId = LoggerHelpers.traceEnter(log, "listStreams");
long requestId = requestIdGenerator.nextLong();
final Principal principal;
final List<String> authHeader = getAuthorizationHeader();
try {
principal = restAuthHelper.authenticate(authHeader);
restAuthHelper.authorize(authHeader, authorizationResource.ofStreamsInScope(scopeName), principal, READ);
} catch (AuthException e) {
log.warn(requestId, "List streams for {} failed due to authentication failure.", scopeName);
asyncResponse.resume(Response.status(Status.fromStatusCode(e.getResponseCode())).build());
LoggerHelpers.traceLeave(log, "listStreams", traceId);
return;
}
boolean showOnlyInternalStreams = filterType != null && filterType.equals("showInternalStreams");
boolean showStreamsWithTag = filterType != null && filterType.equals("tag");
String tag;
if (showStreamsWithTag && filterValue != null) {
tag = filterValue;
List<Stream> streams = new ArrayList<>();
String finalTag = tag;
localController.listStreamsForTag(scopeName, tag).collectRemaining(streams::add).thenCompose(v -> {
List<CompletableFuture<ImmutablePair<Stream, StreamConfiguration>>> streamConfigFutureList = streams.stream().filter(stream -> {
boolean isAuthorized = false;
try {
isAuthorized = restAuthHelper.isAuthorized(authHeader, authorizationResource.ofStreamInScope(scopeName, stream.getStreamName()), principal, READ);
} catch (AuthException e) {
log.warn(requestId, "List Streams with tag {} for scope {} failed due to authentication failure.", finalTag, scopeName);
// Ignore. This exception occurs under abnormal circumstances and not to determine
// whether the user is authorized. In case it does occur, we assume that the user
// is unauthorized.
}
return isAuthorized;
}).map(stream -> localController.getStreamConfiguration(scopeName, stream.getStreamName()).thenApply(config -> new ImmutablePair<>(stream, config))).collect(Collectors.toList());
return Futures.allOfWithResults(streamConfigFutureList);
}).thenApply(streamConfigPairs -> {
StreamsList responseStreams = new StreamsList();
responseStreams.setStreams(new ArrayList<>());
streamConfigPairs.forEach(pair -> responseStreams.addStreamsItem(ModelHelper.encodeStreamResponse(pair.left.getScope(), pair.left.getStreamName(), pair.right)));
log.info(requestId, "Successfully fetched streams for scope: {} with tag: {}", scopeName, finalTag);
return Response.status(Status.OK).entity(responseStreams).build();
}).exceptionally(exception -> {
if (exception.getCause() instanceof StoreException.DataNotFoundException || exception instanceof StoreException.DataNotFoundException) {
log.warn(requestId, "Scope name: {} not found", scopeName);
return Response.status(Status.NOT_FOUND).build();
} else {
log.warn(requestId, "listStreams for {} with tag {} failed with exception: {}", scopeName, finalTag, exception);
return Response.status(Status.INTERNAL_SERVER_ERROR).build();
}
}).thenApply(asyncResponse::resume).thenAccept(x -> LoggerHelpers.traceLeave(log, "listStreams", traceId));
} else {
controllerService.listStreamsInScope(scopeName, requestId).thenApply(streamsList -> {
StreamsList streams = new StreamsList();
streams.setStreams(new ArrayList<>());
streamsList.forEach((stream, config) -> {
try {
if (restAuthHelper.isAuthorized(authHeader, authorizationResource.ofStreamInScope(scopeName, stream), principal, READ)) {
// otherwise display the regular user created streams.
if (!showOnlyInternalStreams ^ stream.startsWith(INTERNAL_NAME_PREFIX)) {
streams.addStreamsItem(ModelHelper.encodeStreamResponse(scopeName, stream, config));
}
}
} catch (AuthException e) {
log.warn(requestId, "Read internal streams for scope {} failed due to authentication failure.", scopeName);
// Ignore. This exception occurs under abnormal circumstances and not to determine
// whether the user is authorized. In case it does occur, we assume that the user
// is unauthorized.
}
});
log.info(requestId, "Successfully fetched streams for scope: {}", scopeName);
return Response.status(Status.OK).entity(streams).build();
}).exceptionally(exception -> {
if (exception.getCause() instanceof StoreException.DataNotFoundException || exception instanceof StoreException.DataNotFoundException) {
log.warn(requestId, "Scope name: {} not found", scopeName);
return Response.status(Status.NOT_FOUND).build();
} else {
log.warn(requestId, "listStreams for {} failed with exception: {}", scopeName, exception);
return Response.status(Status.INTERNAL_SERVER_ERROR).build();
}
}).thenApply(asyncResponse::resume).thenAccept(x -> LoggerHelpers.traceLeave(log, "listStreams", traceId));
}
}
Aggregations