Search in sources :

Example 1 with MetadataSearchResponse

use of io.cdap.cdap.proto.metadata.MetadataSearchResponse 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);
}
Also used : MetadataSearchResponse(io.cdap.cdap.proto.metadata.MetadataSearchResponse) ImmutablePair(io.cdap.cdap.common.utils.ImmutablePair) MetadataDirective(io.cdap.cdap.spi.metadata.MetadataDirective) NamespaceId(io.cdap.cdap.proto.id.NamespaceId) Inject(com.google.inject.Inject) HashMap(java.util.HashMap) USER(io.cdap.cdap.api.metadata.MetadataScope.USER) MetadataChange(io.cdap.cdap.spi.metadata.MetadataChange) MetadataStorage(io.cdap.cdap.spi.metadata.MetadataStorage) HashSet(java.util.HashSet) TAG(io.cdap.cdap.spi.metadata.MetadataKind.TAG) ScopedNameOfKind(io.cdap.cdap.spi.metadata.ScopedNameOfKind) Metadata(io.cdap.cdap.spi.metadata.Metadata) Map(java.util.Map) SearchRequest(io.cdap.cdap.spi.metadata.SearchRequest) MetadataEntity(io.cdap.cdap.api.metadata.MetadataEntity) MetadataMutation(io.cdap.cdap.spi.metadata.MetadataMutation) Read(io.cdap.cdap.spi.metadata.Read) EnumSet(java.util.EnumSet) Sorting(io.cdap.cdap.spi.metadata.Sorting) SortInfo(io.cdap.cdap.data2.metadata.dataset.SortInfo) TransactionSystemClient(org.apache.tephra.TransactionSystemClient) PROPERTY(io.cdap.cdap.spi.metadata.MetadataKind.PROPERTY) ImmutableMap(com.google.common.collect.ImmutableMap) Cursor(io.cdap.cdap.common.metadata.Cursor) SYSTEM(io.cdap.cdap.api.metadata.MetadataScope.SYSTEM) Set(java.util.Set) SearchResponse(io.cdap.cdap.spi.metadata.SearchResponse) IOException(java.io.IOException) MetadataKind(io.cdap.cdap.spi.metadata.MetadataKind) ScopedName(io.cdap.cdap.spi.metadata.ScopedName) Maps(com.google.common.collect.Maps) Collectors(java.util.stream.Collectors) Sets(com.google.common.collect.Sets) List(java.util.List) EntityScope(io.cdap.cdap.proto.EntityScope) MetadataScope(io.cdap.cdap.api.metadata.MetadataScope) Named(com.google.inject.name.Named) Constants(io.cdap.cdap.common.conf.Constants) VisibleForTesting(com.google.common.annotations.VisibleForTesting) DatasetDefinition(io.cdap.cdap.api.dataset.DatasetDefinition) MetadataRecord(io.cdap.cdap.spi.metadata.MetadataRecord) MutationOptions(io.cdap.cdap.spi.metadata.MutationOptions) MetadataDataset(io.cdap.cdap.data2.metadata.dataset.MetadataDataset) Collections(java.util.Collections) HashSet(java.util.HashSet) EnumSet(java.util.EnumSet) Set(java.util.Set) Metadata(io.cdap.cdap.spi.metadata.Metadata) Cursor(io.cdap.cdap.common.metadata.Cursor) MetadataRecord(io.cdap.cdap.spi.metadata.MetadataRecord) MetadataScope(io.cdap.cdap.api.metadata.MetadataScope) MetadataSearchResponse(io.cdap.cdap.proto.metadata.MetadataSearchResponse) Sorting(io.cdap.cdap.spi.metadata.Sorting) SortInfo(io.cdap.cdap.data2.metadata.dataset.SortInfo) MetadataSearchResponse(io.cdap.cdap.proto.metadata.MetadataSearchResponse) SearchResponse(io.cdap.cdap.spi.metadata.SearchResponse) NamespaceId(io.cdap.cdap.proto.id.NamespaceId)

Example 2 with MetadataSearchResponse

use of io.cdap.cdap.proto.metadata.MetadataSearchResponse in project cdap by caskdata.

the class SearchHelper method search.

private MetadataSearchResponse search(Set<MetadataScope> scopes, SearchRequest request) {
    List<MetadataEntry> results = new LinkedList<>();
    List<String> cursors = new LinkedList<>();
    for (MetadataScope scope : scopes) {
        SearchResults searchResults = execute(context -> context.getDataset(scope).search(request));
        results.addAll(searchResults.getResults());
        cursors.addAll(searchResults.getCursors());
    }
    int offset = request.getOffset();
    int limit = request.getLimit();
    SortInfo sortInfo = request.getSortInfo();
    // sort if required
    Set<MetadataEntity> 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(request.getOffset(), 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
    Set<MetadataEntity> subSortedEntities = 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.
    Set<MetadataSearchResultRecord> finalResults = execute(context -> addMetadataToEntities(subSortedEntities, fetchMetadata(context.getDataset(SYSTEM), subSortedEntities), fetchMetadata(context.getDataset(USER), subSortedEntities)));
    return new MetadataSearchResponse(sortInfo.getSortBy() + " " + sortInfo.getSortOrder(), offset, limit, request.getNumCursors(), total, finalResults, cursors, request.shouldShowHidden(), request.getEntityScopes());
}
Also used : LinkedHashSet(java.util.LinkedHashSet) MetadataEntity(io.cdap.cdap.api.metadata.MetadataEntity) MetadataSearchResponse(io.cdap.cdap.proto.metadata.MetadataSearchResponse) SearchResults(io.cdap.cdap.data2.metadata.dataset.SearchResults) LinkedList(java.util.LinkedList) SortInfo(io.cdap.cdap.data2.metadata.dataset.SortInfo) MetadataSearchResultRecord(io.cdap.cdap.proto.metadata.MetadataSearchResultRecord) MetadataEntry(io.cdap.cdap.data2.metadata.dataset.MetadataEntry) MetadataScope(io.cdap.cdap.api.metadata.MetadataScope)

Example 3 with MetadataSearchResponse

use of io.cdap.cdap.proto.metadata.MetadataSearchResponse in project cdap by caskdata.

the class MetadataHttpHandlerTestRun method testSystemScopeArtifacts.

@Test
public void testSystemScopeArtifacts() throws Exception {
    // add a system artifact. currently can't do this through the rest api (by design)
    // so bypass it and use the repository directly
    ArtifactId systemId = NamespaceId.SYSTEM.artifact("app", "1.0.0");
    File systemArtifact = createArtifactJarFile(AllProgramsApp.class, "app", "1.0.0", new Manifest());
    StandaloneTester tester = STANDALONE.get();
    tester.addSystemArtifact(systemId.getArtifact(), Id.Artifact.fromEntityId(systemId).getVersion(), systemArtifact, null);
    // wait until the system metadata has been processed
    Tasks.waitFor(false, () -> getProperties(systemId, MetadataScope.SYSTEM).isEmpty(), 10, TimeUnit.SECONDS);
    // verify that user metadata can be added for system-scope artifacts
    Map<String, String> userProperties = ImmutableMap.of("systemArtifactKey", "systemArtifactValue");
    Set<String> userTags = ImmutableSet.of();
    addProperties(systemId, userProperties);
    addTags(systemId, userTags);
    // verify that user and system metadata can be retrieved for system-scope artifacts
    Assert.assertEquals(ImmutableSet.of(new MetadataRecord(systemId, MetadataScope.USER, userProperties, userTags), new MetadataRecord(systemId, MetadataScope.SYSTEM, ImmutableMap.of(MetadataConstants.ENTITY_NAME_KEY, systemId.getEntityName()), ImmutableSet.of())), removeCreationTime(getMetadata(systemId.toMetadataEntity())));
    // verify that system scope artifacts can be returned by a search in the default namespace
    // with no target type
    MetadataSearchResponse response = searchMetadata(ImmutableList.of(NamespaceId.DEFAULT, NamespaceId.SYSTEM), "system*");
    MetadataEntity expectedEntity = systemId.toMetadataEntity();
    Set<MetadataEntity> actualEntities = new HashSet<>(extractMetadataEntities(response.getResults()));
    Assert.assertTrue(actualEntities.contains(expectedEntity));
    // with target type as artifact
    assertSearch(searchMetadata(ImmutableList.of(NamespaceId.DEFAULT, NamespaceId.SYSTEM), "system*", MetadataEntity.ARTIFACT), systemId);
    // verify that user metadata can be deleted for system-scope artifacts
    removeMetadata(systemId);
    Assert.assertEquals(ImmutableSet.of(new MetadataRecord(systemId, MetadataScope.USER, ImmutableMap.of(), ImmutableSet.of()), new MetadataRecord(systemId, MetadataScope.SYSTEM, ImmutableMap.of(MetadataConstants.ENTITY_NAME_KEY, systemId.getEntityName()), ImmutableSet.of())), removeCreationTime(getMetadata(systemId.toMetadataEntity())));
    artifactClient.delete(systemId);
}
Also used : StandaloneTester(io.cdap.cdap.StandaloneTester) MetadataEntity(io.cdap.cdap.api.metadata.MetadataEntity) ArtifactId(io.cdap.cdap.proto.id.ArtifactId) MetadataSearchResponse(io.cdap.cdap.proto.metadata.MetadataSearchResponse) Manifest(java.util.jar.Manifest) MetadataRecord(io.cdap.cdap.common.metadata.MetadataRecord) File(java.io.File) HashSet(java.util.HashSet) Test(org.junit.Test)

Example 4 with MetadataSearchResponse

use of io.cdap.cdap.proto.metadata.MetadataSearchResponse in project cdap by caskdata.

the class MetadataHttpHandlerTestRun method testCrossNamespaceSearchMetadata.

@Test
public void testCrossNamespaceSearchMetadata() throws Exception {
    NamespaceId namespace1 = new NamespaceId("ns1");
    namespaceClient.create(new NamespaceMeta.Builder().setName(namespace1).build());
    NamespaceId namespace2 = new NamespaceId("ns2");
    namespaceClient.create(new NamespaceMeta.Builder().setName(namespace2).build());
    try {
        appClient.deploy(namespace1, createAppJarFile(AllProgramsApp.class));
        appClient.deploy(namespace2, createAppJarFile(AllProgramsApp.class));
        // Add metadata to app
        Map<String, String> props = ImmutableMap.of("key1", "value1");
        Metadata meta = new Metadata(props, Collections.emptySet());
        ApplicationId app1Id = namespace1.app(AllProgramsApp.NAME);
        addProperties(app1Id, props);
        ApplicationId app2Id = namespace2.app(AllProgramsApp.NAME);
        addProperties(app2Id, props);
        MetadataSearchResponse results = super.searchMetadata(ImmutableList.of(), "value*", Collections.emptySet(), null, 0, 10, 0, null, false);
        Map<MetadataEntity, Metadata> expected = new HashMap<>();
        expected.put(app1Id.toMetadataEntity(), meta);
        expected.put(app2Id.toMetadataEntity(), meta);
        Map<MetadataEntity, Metadata> actual = new HashMap<>();
        for (MetadataSearchResultRecord record : results.getResults()) {
            actual.put(record.getMetadataEntity(), record.getMetadata().get(MetadataScope.USER));
        }
        Assert.assertEquals(expected, actual);
    } finally {
        namespaceClient.delete(namespace1);
        namespaceClient.delete(namespace2);
    }
}
Also used : MetadataEntity(io.cdap.cdap.api.metadata.MetadataEntity) HashMap(java.util.HashMap) Metadata(io.cdap.cdap.api.metadata.Metadata) MetadataSearchResponse(io.cdap.cdap.proto.metadata.MetadataSearchResponse) AllProgramsApp(io.cdap.cdap.client.app.AllProgramsApp) MetadataSearchResultRecord(io.cdap.cdap.proto.metadata.MetadataSearchResultRecord) NamespaceMeta(io.cdap.cdap.proto.NamespaceMeta) NamespaceId(io.cdap.cdap.proto.id.NamespaceId) ApplicationId(io.cdap.cdap.proto.id.ApplicationId) Test(org.junit.Test)

Example 5 with MetadataSearchResponse

use of io.cdap.cdap.proto.metadata.MetadataSearchResponse in project cdap by caskdata.

the class MetadataServiceMainTest method testMetadataService.

@Test
public void testMetadataService() throws Exception {
    Injector injector = getServiceMainInstance(MetadataServiceMain.class).getInjector();
    DatasetId datasetId = NamespaceId.DEFAULT.dataset("testds");
    // Create a dataset, a metadata should get published.
    DatasetFramework datasetFramework = injector.getInstance(DatasetFramework.class);
    long beforeCreation = System.currentTimeMillis();
    datasetFramework.addInstance(KeyValueTable.class.getName(), datasetId, DatasetProperties.EMPTY);
    // Query the metadata
    DiscoveryServiceClient discoveryServiceClient = injector.getInstance(DiscoveryServiceClient.class);
    Discoverable metadataEndpoint = new RandomEndpointStrategy(() -> discoveryServiceClient.discover(Constants.Service.METADATA_SERVICE)).pick(5, TimeUnit.SECONDS);
    Assert.assertNotNull(metadataEndpoint);
    // Try to query the metadata
    InetSocketAddress metadataAddr = metadataEndpoint.getSocketAddress();
    ConnectionConfig connConfig = ConnectionConfig.builder().setSSLEnabled(URIScheme.HTTPS.isMatch(metadataEndpoint)).setHostname(metadataAddr.getHostName()).setPort(metadataAddr.getPort()).build();
    MetadataClient metadataClient = new MetadataClient(ClientConfig.builder().setVerifySSLCert(false).setConnectionConfig(connConfig).build());
    MetadataSearchResponse response = metadataClient.searchMetadata(datasetId.getNamespaceId(), "*", (String) null);
    Set<MetadataSearchResultRecord> results = response.getResults();
    Assert.assertFalse(results.isEmpty());
    long creationTime = results.stream().filter(r -> datasetId.equals(r.getEntityId())).map(MetadataSearchResultRecord::getMetadata).map(metadata -> metadata.get(MetadataScope.SYSTEM).getProperties().get(MetadataConstants.CREATION_TIME_KEY)).map(Long::parseLong).findFirst().orElse(-1L);
    // The creation time should be between the beforeCreation time and the current time
    Assert.assertTrue(creationTime >= beforeCreation);
    Assert.assertTrue(creationTime <= System.currentTimeMillis());
}
Also used : MetadataSearchResponse(io.cdap.cdap.proto.metadata.MetadataSearchResponse) RandomEndpointStrategy(io.cdap.cdap.common.discovery.RandomEndpointStrategy) URIScheme(io.cdap.cdap.common.discovery.URIScheme) NamespaceId(io.cdap.cdap.proto.id.NamespaceId) DatasetFramework(io.cdap.cdap.data2.dataset2.DatasetFramework) Set(java.util.Set) Test(org.junit.Test) InetSocketAddress(java.net.InetSocketAddress) Injector(com.google.inject.Injector) DatasetProperties(io.cdap.cdap.api.dataset.DatasetProperties) TimeUnit(java.util.concurrent.TimeUnit) MetadataClient(io.cdap.cdap.client.MetadataClient) Discoverable(org.apache.twill.discovery.Discoverable) MetadataSearchResultRecord(io.cdap.cdap.proto.metadata.MetadataSearchResultRecord) DatasetId(io.cdap.cdap.proto.id.DatasetId) DiscoveryServiceClient(org.apache.twill.discovery.DiscoveryServiceClient) ClientConfig(io.cdap.cdap.client.config.ClientConfig) MetadataScope(io.cdap.cdap.api.metadata.MetadataScope) MetadataConstants(io.cdap.cdap.spi.metadata.MetadataConstants) ConnectionConfig(io.cdap.cdap.client.config.ConnectionConfig) Constants(io.cdap.cdap.common.conf.Constants) Assert(org.junit.Assert) KeyValueTable(io.cdap.cdap.api.dataset.lib.KeyValueTable) Discoverable(org.apache.twill.discovery.Discoverable) DiscoveryServiceClient(org.apache.twill.discovery.DiscoveryServiceClient) InetSocketAddress(java.net.InetSocketAddress) MetadataSearchResponse(io.cdap.cdap.proto.metadata.MetadataSearchResponse) DatasetId(io.cdap.cdap.proto.id.DatasetId) DatasetFramework(io.cdap.cdap.data2.dataset2.DatasetFramework) MetadataClient(io.cdap.cdap.client.MetadataClient) MetadataSearchResultRecord(io.cdap.cdap.proto.metadata.MetadataSearchResultRecord) Injector(com.google.inject.Injector) KeyValueTable(io.cdap.cdap.api.dataset.lib.KeyValueTable) ConnectionConfig(io.cdap.cdap.client.config.ConnectionConfig) RandomEndpointStrategy(io.cdap.cdap.common.discovery.RandomEndpointStrategy) Test(org.junit.Test)

Aggregations

MetadataSearchResponse (io.cdap.cdap.proto.metadata.MetadataSearchResponse)9 NamespaceId (io.cdap.cdap.proto.id.NamespaceId)5 MetadataSearchResultRecord (io.cdap.cdap.proto.metadata.MetadataSearchResultRecord)5 Test (org.junit.Test)5 MetadataEntity (io.cdap.cdap.api.metadata.MetadataEntity)4 MetadataScope (io.cdap.cdap.api.metadata.MetadataScope)3 NamespaceMeta (io.cdap.cdap.proto.NamespaceMeta)3 DatasetId (io.cdap.cdap.proto.id.DatasetId)3 VisibleForTesting (com.google.common.annotations.VisibleForTesting)2 Inject (com.google.inject.Inject)2 KeyValueTable (io.cdap.cdap.api.dataset.lib.KeyValueTable)2 MetadataClient (io.cdap.cdap.client.MetadataClient)2 Constants (io.cdap.cdap.common.conf.Constants)2 SortInfo (io.cdap.cdap.data2.metadata.dataset.SortInfo)2 DatasetInstanceConfiguration (io.cdap.cdap.proto.DatasetInstanceConfiguration)2 ApplicationId (io.cdap.cdap.proto.id.ApplicationId)2 HashMap (java.util.HashMap)2 HashSet (java.util.HashSet)2 Set (java.util.Set)2 Splitter (com.google.common.base.Splitter)1