use of co.cask.cdap.proto.metadata.MetadataSearchResponse in project cdap by caskdata.
the class DefaultMetadataAdmin method filterAuthorizedSearchResult.
/**
* Filter a list of {@link MetadataSearchResultRecord} that ensures the logged-in user has a privilege on
*
* @param results the {@link MetadataSearchResponse} to filter
* @return filtered {@link MetadataSearchResponse}
*/
private MetadataSearchResponse filterAuthorizedSearchResult(MetadataSearchResponse results) throws Exception {
Principal principal = authenticationContext.getPrincipal();
final Predicate<EntityId> filter = authorizationEnforcer.createFilter(principal);
return new MetadataSearchResponse(results.getSort(), results.getOffset(), results.getLimit(), results.getNumCursors(), results.getTotal(), ImmutableSet.copyOf(Iterables.filter(results.getResults(), new com.google.common.base.Predicate<MetadataSearchResultRecord>() {
@Override
public boolean apply(MetadataSearchResultRecord metadataSearchResultRecord) {
return filter.apply(metadataSearchResultRecord.getEntityId());
}
})), results.getCursors(), results.isShowHidden(), results.getEntityScope());
}
use of co.cask.cdap.proto.metadata.MetadataSearchResponse in project cdap by caskdata.
the class DefaultMetadataStore method search.
private MetadataSearchResponse search(Set<MetadataScope> scopes, String namespaceId, String searchQuery, Set<EntityTypeSimpleName> types, SortInfo sortInfo, int offset, int limit, int numCursors, String cursor, boolean showHidden, Set<EntityScope> entityScope) throws BadRequestException {
if (offset < 0) {
throw new IllegalArgumentException("offset must not be negative");
}
if (limit < 0) {
throw new IllegalArgumentException("limit must not be negative");
}
List<MetadataEntry> results = new LinkedList<>();
List<String> cursors = new LinkedList<>();
for (MetadataScope scope : scopes) {
SearchResults searchResults = getSearchResults(scope, namespaceId, searchQuery, types, sortInfo, offset, limit, numCursors, cursor, showHidden, entityScope);
results.addAll(searchResults.getResults());
cursors.addAll(searchResults.getCursors());
}
// sort if required
Set<NamespacedEntityId> sortedEntities = getSortedEntities(results, sortInfo);
int total = sortedEntities.size();
// pagination is not performed at the dataset level, because:
// 1. scoring is needed for DEFAULT sort info. So perform it here for now.
// 2. Even when using custom sorting, we need to remove elements from the beginning to the offset and the cursors
// at the end
// TODO: Figure out how all of this can be done server (HBase) side
int startIndex = Math.min(offset, sortedEntities.size());
// Account for overflow
int endIndex = (int) Math.min(Integer.MAX_VALUE, (long) offset + limit);
endIndex = Math.min(endIndex, sortedEntities.size());
// add 1 to maxIndex because end index is exclusive
sortedEntities = new LinkedHashSet<>(ImmutableList.copyOf(sortedEntities).subList(startIndex, endIndex));
// Fetch metadata for entities in the result list
// Note: since the fetch is happening in a different transaction, the metadata for entities may have been
// removed. It is okay not to have metadata for some results in case this happens.
Map<NamespacedEntityId, Metadata> systemMetadata = fetchMetadata(sortedEntities, MetadataScope.SYSTEM);
Map<NamespacedEntityId, Metadata> userMetadata = fetchMetadata(sortedEntities, MetadataScope.USER);
return new MetadataSearchResponse(sortInfo.getSortBy() + " " + sortInfo.getSortOrder(), offset, limit, numCursors, total, addMetadataToEntities(sortedEntities, systemMetadata, userMetadata), cursors, showHidden, entityScope);
}
use of co.cask.cdap.proto.metadata.MetadataSearchResponse in project cdap by caskdata.
the class MetadataHttpHandlerTestRun method testSearchResultPaginationWithTargetType.
@Test
public void testSearchResultPaginationWithTargetType() throws Exception {
// note that the ordering of the entity creations and the sort param used in this test case matter, in order to
// reproduce the scenario that caused the issue CDAP-7881
NamespaceId namespace = new NamespaceId("pagination_with_target_type");
namespaceClient.create(new NamespaceMeta.Builder().setName(namespace).build());
StreamId stream1 = namespace.stream("text1");
StreamId stream2 = namespace.stream("text2");
DatasetId trackerDataset = namespace.dataset("_auditLog");
DatasetId mydataset = namespace.dataset("mydataset");
// the creation order below will determine how we see the entities in search result sorted by entity creation time
// in ascending order
datasetClient.create(trackerDataset, new DatasetInstanceConfiguration(Table.class.getName(), Collections.<String, String>emptyMap()));
datasetClient.create(mydataset, new DatasetInstanceConfiguration(Table.class.getName(), Collections.<String, String>emptyMap()));
// create entities so system metadata is annotated
streamClient.create(stream1);
streamClient.create(stream2);
// do sorting with creation time here since the testSearchResultPagination does with entity name
// the sorted result order _auditLog mydataset text2 text1 (ascending: creation from earliest time)
String sort = AbstractSystemMetadataWriter.CREATION_TIME_KEY + " " + SortInfo.SortOrder.ASC;
// offset 1, limit 2, 2 cursors, should return 2nd result, with 0 cursors since we don't have enough data
// set showHidden to true which will show the trackerDataset but will not be in search response since its not stream
MetadataSearchResponse searchResponse = searchMetadata(namespace, "*", ImmutableSet.of(EntityTypeSimpleName.STREAM), sort, 1, 2, 2, null, true);
List<MetadataSearchResultRecord> expectedResults = ImmutableList.of(new MetadataSearchResultRecord(stream2));
List<String> expectedCursors = ImmutableList.of();
Assert.assertEquals(expectedResults, new ArrayList<>(searchResponse.getResults()));
Assert.assertEquals(expectedCursors, searchResponse.getCursors());
// offset 1, limit 2, 2 cursors, should return just the dataset created above other than trackerDataset even
// though it was created before since showHidden is false and it should not affect pagination
searchResponse = searchMetadata(namespace, "*", ImmutableSet.of(EntityTypeSimpleName.DATASET), sort, 0, 2, 2, null);
expectedResults = ImmutableList.of(new MetadataSearchResultRecord(mydataset));
expectedCursors = ImmutableList.of();
Assert.assertEquals(expectedResults, new ArrayList<>(searchResponse.getResults()));
Assert.assertEquals(expectedCursors, searchResponse.getCursors());
}
use of co.cask.cdap.proto.metadata.MetadataSearchResponse in project cdap by caskdata.
the class MetadataHttpHandlerTestRun method searchMetadata.
/**
* strips metadata from search results
*/
@Override
protected MetadataSearchResponse searchMetadata(NamespaceId namespaceId, String query, Set<EntityTypeSimpleName> targets, @Nullable String sort, int offset, int limit, int numCursors, @Nullable String cursor, boolean showHidden) throws Exception {
MetadataSearchResponse searchResponse = super.searchMetadata(namespaceId, query, targets, sort, offset, limit, numCursors, cursor, showHidden);
Set<MetadataSearchResultRecord> transformed = new LinkedHashSet<>();
for (MetadataSearchResultRecord result : searchResponse.getResults()) {
transformed.add(new MetadataSearchResultRecord(result.getEntityId()));
}
return new MetadataSearchResponse(searchResponse.getSort(), searchResponse.getOffset(), searchResponse.getLimit(), searchResponse.getNumCursors(), searchResponse.getTotal(), transformed, searchResponse.getCursors(), searchResponse.isShowHidden(), searchResponse.getEntityScope());
}
use of co.cask.cdap.proto.metadata.MetadataSearchResponse in project cdap by caskdata.
the class SearchMetadataCommand method perform.
@Override
public void perform(Arguments arguments, PrintStream output) throws Exception {
String searchQuery = arguments.get(ArgumentName.SEARCH_QUERY.toString());
String type = arguments.getOptional(ArgumentName.TARGET_TYPE.toString());
MetadataSearchResponse metadataSearchResponse = metadataClient.searchMetadata(cliConfig.getCurrentNamespace(), searchQuery, parseTargetType(type));
Set<MetadataSearchResultRecord> searchResults = metadataSearchResponse.getResults();
Table table = Table.builder().setHeader("Entity").setRows(Lists.newArrayList(searchResults), new RowMaker<MetadataSearchResultRecord>() {
@Override
public List<?> makeRow(MetadataSearchResultRecord searchResult) {
return Lists.newArrayList(searchResult.getEntityId().toString());
}
}).build();
cliConfig.getTableRenderer().render(cliConfig, output, table);
}
Aggregations