use of io.cdap.cdap.api.metadata.MetadataScope in project cdap by caskdata.
the class Cursor method fromString.
public static Cursor fromString(String str) {
String[] parts = str.split(":", 9);
if (parts.length != 9) {
throw new IllegalArgumentException("Cursor must have exactly 9 components, but has only " + parts.length);
}
int offset = Integer.parseInt(parts[0]);
int limit = Integer.parseInt(parts[1]);
boolean showHidden = Boolean.parseBoolean(parts[2]);
MetadataScope scope = parts[3].isEmpty() ? null : MetadataScope.valueOf(parts[3]);
Set<String> namespaces = parts[4].isEmpty() ? null : ImmutableSet.copyOf(parts[4].split(","));
Set<String> types = parts[5].isEmpty() ? null : ImmutableSet.copyOf(parts[5].split(","));
String sorting = parts[6].isEmpty() ? null : parts[6];
String actual = parts[7];
String query = parts[8];
return new Cursor(offset, limit, showHidden, scope, namespaces, types, sorting, actual, query);
}
use of io.cdap.cdap.api.metadata.MetadataScope in project cdap by caskdata.
the class DatasetMetadataStorage method replaceInScope.
private MetadataDataset.Change replaceInScope(MetadataDatasetContext context, MetadataScope scope, MetadataEntity entity, Set<String> newTags, Map<String, String> newProperties, Map<ScopedNameOfKind, MetadataDirective> directives) {
MetadataDataset dataset = context.getDataset(scope);
MetadataDataset.Record before = dataset.getMetadata(entity);
if (newTags.isEmpty() && newProperties.isEmpty()) {
// this scope remains unchanged
return new MetadataDataset.Change(before, before);
}
Set<String> existingTags = before.getTags();
Set<String> tagsToKeepOrPreserve = directives.entrySet().stream().filter(entry -> entry.getKey().getScope() == scope && entry.getKey().getKind() == TAG && (entry.getValue() == MetadataDirective.KEEP || entry.getValue() == MetadataDirective.PRESERVE)).map(Map.Entry::getKey).map(ScopedName::getName).filter(existingTags::contains).collect(Collectors.toSet());
newTags = Sets.union(newTags, tagsToKeepOrPreserve);
Map<String, String> existingProperties = before.getProperties();
Map<String, String> propertiesToKeepOrPreserve = directives.entrySet().stream().filter(entry -> entry.getKey().getScope() == scope && entry.getKey().getKind() == PROPERTY).filter(entry -> existingProperties.containsKey(entry.getKey().getName())).filter(entry -> entry.getValue() == MetadataDirective.PRESERVE || entry.getValue() == MetadataDirective.KEEP && !newProperties.containsKey(entry.getKey().getName())).map(Map.Entry::getKey).map(ScopedName::getName).collect(Collectors.toMap(name -> name, existingProperties::get));
newProperties.putAll(propertiesToKeepOrPreserve);
Set<String> tagsToRemove = Sets.difference(before.getTags(), newTags);
Set<String> tagsToAdd = Sets.difference(newTags, before.getTags());
Set<String> propertiesToRemove = Sets.difference(before.getProperties().keySet(), newProperties.keySet());
@SuppressWarnings("ConstantConditions") Map<String, String> propertiesToAdd = Maps.filterEntries(newProperties, entry -> !entry.getValue().equals(existingProperties.get(entry.getKey())));
MetadataDataset.Record after = before;
if (!tagsToRemove.isEmpty()) {
after = dataset.removeTags(entity, tagsToRemove).getLatest();
}
if (!tagsToAdd.isEmpty()) {
after = dataset.addTags(entity, tagsToAdd).getLatest();
}
if (!propertiesToRemove.isEmpty()) {
after = dataset.removeProperties(entity, propertiesToRemove).getLatest();
}
if (!propertiesToAdd.isEmpty()) {
after = dataset.addProperties(entity, propertiesToAdd).getLatest();
}
return new MetadataDataset.Change(before, after);
}
use of io.cdap.cdap.api.metadata.MetadataScope in project cdap by caskdata.
the class DatasetMetadataStorage method remove.
private MetadataChange remove(MetadataDatasetContext context, MetadataMutation.Remove remove) {
MetadataEntity entity = remove.getEntity();
MetadataDataset.Change userChange, systemChange;
if (remove.getRemovals() != null) {
Set<String> userTagsToRemove = new HashSet<>();
Set<String> systemTagsToRemove = new HashSet<>();
Set<String> userPropertiesToRemove = new HashSet<>();
Set<String> systemPropertiesToRemove = new HashSet<>();
remove.getRemovals().forEach(removal -> (TAG == removal.getKind() ? USER == removal.getScope() ? userTagsToRemove : systemTagsToRemove : USER == removal.getScope() ? userPropertiesToRemove : systemPropertiesToRemove).add(removal.getName()));
userChange = removeInScope(context, USER, entity, userTagsToRemove, userPropertiesToRemove);
systemChange = removeInScope(context, SYSTEM, entity, systemTagsToRemove, systemPropertiesToRemove);
} else {
Set<MetadataScope> scopes = remove.getScopes();
Set<MetadataKind> kinds = remove.getKinds();
userChange = removeScope(context, USER, entity, scopes, kinds);
systemChange = removeScope(context, SYSTEM, entity, scopes, kinds);
}
return combineChanges(entity, userChange, systemChange);
}
use of io.cdap.cdap.api.metadata.MetadataScope in project cdap by caskdata.
the class DatasetMetadataStorage method search.
@Override
public SearchResponse search(SearchRequest request) {
Cursor cursor = request.getCursor() != null && !request.getCursor().isEmpty() ? Cursor.fromString(request.getCursor()) : null;
Set<String> namespaces = cursor == null ? request.getNamespaces() : cursor.getNamespaces();
ImmutablePair<NamespaceId, Set<EntityScope>> namespaceAndScopes = determineNamespaceAndScopes(namespaces);
CursorAndOffsetInfo cursorOffsetAndLimits = determineCursorOffsetAndLimits(request, cursor);
String query = cursor != null ? cursor.getQuery() : request.getQuery() == null || request.getQuery().isEmpty() ? "*" : request.getQuery();
Set<String> types = cursor != null ? cursor.getTypes() : request.getTypes();
types = types == null ? Collections.emptySet() : types;
Sorting sorting = cursor == null ? request.getSorting() : cursor.getSorting() == null ? null : Sorting.of(cursor.getSorting());
SortInfo sortInfo = sorting == null ? SortInfo.DEFAULT : new SortInfo(sorting.getKey(), SortInfo.SortOrder.valueOf(sorting.getOrder().name()));
boolean showHidden = cursor != null ? cursor.isShowHidden() : request.isShowHidden();
MetadataScope scope = cursor != null ? cursor.getScope() : request.getScope();
MetadataSearchResponse response = search(new io.cdap.cdap.data2.metadata.dataset.SearchRequest(namespaceAndScopes.getFirst(), query, types, sortInfo, cursorOffsetAndLimits.getOffsetToRequest(), cursorOffsetAndLimits.getLimitToRequest(), request.isCursorRequested() ? 1 : 0, cursorOffsetAndLimits.getCursor(), showHidden, namespaceAndScopes.getSecond()), scope);
// translate results back and limit them to at most what was requested (see above where we add 1)
int limitToRespond = cursorOffsetAndLimits.getLimitToRespond();
int offsetToRespond = cursorOffsetAndLimits.getOffsetToRespond();
List<MetadataRecord> results = response.getResults().stream().limit(limitToRespond).map(record -> {
Metadata metadata = Metadata.EMPTY;
for (Map.Entry<MetadataScope, io.cdap.cdap.api.metadata.Metadata> entry : record.getMetadata().entrySet()) {
Metadata toAdd = new Metadata(entry.getKey(), entry.getValue().getTags(), entry.getValue().getProperties());
metadata = mergeDisjointMetadata(metadata, toAdd);
}
return new MetadataRecord(record.getMetadataEntity(), metadata);
}).collect(Collectors.toList());
Cursor newCursor = null;
if (response.getCursors() != null && !response.getCursors().isEmpty()) {
String actualCursor = response.getCursors().get(0);
if (cursor != null) {
// the new cursor's offset is the previous cursor's offset plus the number of results
newCursor = new Cursor(cursor, cursor.getOffset() + results.size(), actualCursor);
} else {
newCursor = new Cursor(offsetToRespond + results.size(), limitToRespond, showHidden, scope, namespaces, types, sorting == null ? null : sorting.toString(), actualCursor, query);
}
}
// adjust the total results by the difference of requested offset and the true offset that we respond back
int totalResults = offsetToRespond - cursorOffsetAndLimits.getOffsetToRequest() + response.getTotal();
return new SearchResponse(request, newCursor == null ? null : newCursor.toString(), offsetToRespond, limitToRespond, totalResults, results);
}
use of io.cdap.cdap.api.metadata.MetadataScope in project cdap by caskdata.
the class DatasetMetadataStorage method readScope.
private MetadataDataset.Record readScope(MetadataDatasetContext context, MetadataScope scope, Read read) {
MetadataEntity entity = read.getEntity();
if (read.getSelection() == null && (!read.getScopes().contains(scope) || read.getKinds().isEmpty())) {
return new MetadataDataset.Record(entity);
}
Set<ScopedNameOfKind> selectionForScope = null;
if (read.getSelection() != null) {
// noinspection ConstantConditions
selectionForScope = Sets.filter(read.getSelection(), entry -> entry.getScope() == scope);
if (selectionForScope.isEmpty()) {
return new MetadataDataset.Record(entity);
}
}
// now we know we must read from the dataset
MetadataDataset dataset = context.getDataset(scope);
if (selectionForScope != null) {
// request is for a specific set of tags and properties
Set<String> tagsToRead = selectionForScope.stream().filter(entry -> TAG == entry.getKind()).map(ScopedName::getName).collect(Collectors.toSet());
Set<String> propertiesToRead = selectionForScope.stream().filter(entry -> PROPERTY == entry.getKind()).map(ScopedName::getName).collect(Collectors.toSet());
Set<String> tags = tagsToRead.isEmpty() ? Collections.emptySet() : Sets.intersection(tagsToRead, dataset.getTags(entity));
Map<String, String> properties = propertiesToRead.isEmpty() ? Collections.emptyMap() : Maps.filterKeys(dataset.getProperties(entity), propertiesToRead::contains);
return new MetadataDataset.Record(entity, properties, tags);
}
if (MetadataKind.ALL.equals(read.getKinds())) {
// all metadata kinds requested
return dataset.getMetadata(entity);
}
// exactly one kind is requested
MetadataKind requestKind = read.getKinds().iterator().next();
if (requestKind == TAG) {
return new MetadataDataset.Record(entity, Collections.emptyMap(), dataset.getTags(entity));
}
if (requestKind == PROPERTY) {
return new MetadataDataset.Record(entity, dataset.getProperties(entity), Collections.emptySet());
}
throw new IllegalStateException("Encountered metadata read request for unknown kind " + requestKind);
}
Aggregations