Search in sources :

Example 1 with ScanApplicationsRequest

use of io.cdap.cdap.app.store.ScanApplicationsRequest in project cdap by caskdata.

the class DefaultStoreTest method testScanApplicationsWithNamespace.

public void testScanApplicationsWithNamespace(Store store) {
    ApplicationSpecification appSpec = Specifications.from(new AllProgramsApp());
    int count = 100;
    for (int i = 0; i < count / 2; i++) {
        String appName = "test" + (2 * i);
        store.addApplication(new ApplicationId(NamespaceId.DEFAULT.getNamespace(), appName), appSpec);
        appName = "test" + (2 * i + 1);
        store.addApplication(new ApplicationId(NamespaceId.CDAP.getNamespace(), appName), appSpec);
    }
    List<ApplicationId> apps = new ArrayList<ApplicationId>();
    ScanApplicationsRequest request = ScanApplicationsRequest.builder().setNamespaceId(NamespaceId.CDAP).build();
    store.scanApplications(request, 20, (appId, spec) -> {
        apps.add(appId);
    });
    Assert.assertEquals(count / 2, apps.size());
    // Reverse
    List<ApplicationId> reverseApps = new ArrayList<>();
    request = ScanApplicationsRequest.builder().setNamespaceId(NamespaceId.CDAP).setSortOrder(SortOrder.DESC).build();
    store.scanApplications(request, 20, (appId, spec) -> reverseApps.add(appId));
    Assert.assertEquals(Lists.reverse(apps), reverseApps);
    // Second page
    int firstPageSize = 10;
    List<ApplicationId> restartApps = new ArrayList<>();
    request = ScanApplicationsRequest.builder().setNamespaceId(NamespaceId.CDAP).setScanFrom(apps.get(firstPageSize - 1)).build();
    store.scanApplications(request, 20, (appId, spec) -> restartApps.add(appId));
    Assert.assertEquals(apps.subList(firstPageSize, apps.size()), restartApps);
}
Also used : ScanApplicationsRequest(io.cdap.cdap.app.store.ScanApplicationsRequest) ApplicationSpecification(io.cdap.cdap.api.app.ApplicationSpecification) ArrayList(java.util.ArrayList) AllProgramsApp(io.cdap.cdap.AllProgramsApp) ApplicationId(io.cdap.cdap.proto.id.ApplicationId)

Example 2 with ScanApplicationsRequest

use of io.cdap.cdap.app.store.ScanApplicationsRequest in project cdap by caskdata.

the class DefaultStore method scanApplications.

@Override
public boolean scanApplications(ScanApplicationsRequest request, int txBatchSize, BiConsumer<ApplicationId, ApplicationSpecification> consumer) {
    AtomicReference<ScanApplicationsRequest> requestRef = new AtomicReference<>(request);
    AtomicReference<ApplicationId> lastKey = new AtomicReference<>();
    AtomicInteger currentLimit = new AtomicInteger(request.getLimit());
    while (currentLimit.get() > 0) {
        AtomicInteger count = new AtomicInteger();
        try {
            TransactionRunners.run(transactionRunner, context -> {
                getAppMetadataStore(context).scanApplications(requestRef.get(), entry -> {
                    lastKey.set(entry.getKey());
                    currentLimit.decrementAndGet();
                    consumer.accept(entry.getKey(), entry.getValue().getSpec());
                    return count.incrementAndGet() < txBatchSize && currentLimit.get() > 0;
                });
            });
        } catch (UnsupportedOperationException e) {
            if (requestRef.get().getSortOrder() != SortOrder.DESC || count.get() != 0) {
                throw e;
            }
            scanApplicationwWithReorder(requestRef.get(), txBatchSize, consumer);
        }
        if (lastKey.get() == null) {
            break;
        }
        ScanApplicationsRequest nextBatchRequest = ScanApplicationsRequest.builder(requestRef.get()).setScanFrom(lastKey.get()).setLimit(currentLimit.get()).build();
        requestRef.set(nextBatchRequest);
        lastKey.set(null);
    }
    return currentLimit.get() == 0;
}
Also used : ScanApplicationsRequest(io.cdap.cdap.app.store.ScanApplicationsRequest) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) AtomicReference(java.util.concurrent.atomic.AtomicReference) ApplicationId(io.cdap.cdap.proto.id.ApplicationId)

Example 3 with ScanApplicationsRequest

use of io.cdap.cdap.app.store.ScanApplicationsRequest in project cdap by caskdata.

the class AppLifecycleHttpHandler method getAllApps.

/**
 * Returns a list of applications associated with a namespace.
 */
@GET
@Path("/apps")
public void getAllApps(HttpRequest request, HttpResponder responder, @PathParam("namespace-id") String namespaceId, @QueryParam("artifactName") String artifactName, @QueryParam("artifactVersion") String artifactVersion, @QueryParam("pageToken") String pageToken, @QueryParam("pageSize") Integer pageSize, @QueryParam("orderBy") SortOrder orderBy, @QueryParam("nameFilter") String nameFilter) throws Exception {
    NamespaceId namespace = validateNamespace(namespaceId);
    Set<String> names = new HashSet<>();
    if (!Strings.isNullOrEmpty(artifactName)) {
        for (String name : Splitter.on(',').split(artifactName)) {
            names.add(name);
        }
    }
    if (Optional.ofNullable(pageSize).orElse(0) != 0) {
        JsonPaginatedListResponder.respond(GSON, responder, APP_LIST_PAGINATED_KEY, jsonListResponder -> {
            AtomicReference<ApplicationRecord> lastRecord = new AtomicReference<>(null);
            ScanApplicationsRequest scanRequest = getScanRequest(namespaceId, artifactVersion, pageToken, pageSize, orderBy, nameFilter, names);
            boolean pageLimitReached = applicationLifecycleService.scanApplications(scanRequest, appDetail -> {
                ApplicationRecord record = new ApplicationRecord(appDetail);
                jsonListResponder.send(record);
                lastRecord.set(record);
            });
            ApplicationRecord record = lastRecord.get();
            return !pageLimitReached || record == null ? null : record.getName() + EntityId.IDSTRING_PART_SEPARATOR + record.getAppVersion();
        });
    } else {
        ScanApplicationsRequest scanRequest = getScanRequest(namespaceId, artifactVersion, pageToken, null, orderBy, nameFilter, names);
        JsonWholeListResponder.respond(GSON, responder, jsonListResponder -> applicationLifecycleService.scanApplications(scanRequest, d -> jsonListResponder.send(new ApplicationRecord(d))));
    }
}
Also used : ScanApplicationsRequest(io.cdap.cdap.app.store.ScanApplicationsRequest) AuditDetail(io.cdap.cdap.common.security.AuditDetail) ApplicationDetail(io.cdap.cdap.proto.ApplicationDetail) Arrays(java.util.Arrays) GsonBuilder(com.google.gson.GsonBuilder) ScanApplicationsRequest(io.cdap.cdap.app.store.ScanApplicationsRequest) ArtifactSummary(io.cdap.cdap.api.artifact.ArtifactSummary) Map(java.util.Map) HeaderParam(javax.ws.rs.HeaderParam) ApplicationNotFoundException(io.cdap.cdap.common.ApplicationNotFoundException) ProgramTerminator(io.cdap.cdap.internal.app.deploy.ProgramTerminator) EnumSet(java.util.EnumSet) HttpRequest(io.netty.handler.codec.http.HttpRequest) BodyConsumer(io.cdap.http.BodyConsumer) Set(java.util.Set) Reader(java.io.Reader) FullHttpRequest(io.netty.handler.codec.http.FullHttpRequest) StandardCharsets(java.nio.charset.StandardCharsets) Id(io.cdap.cdap.common.id.Id) JsonArray(com.google.gson.JsonArray) ApplicationId(io.cdap.cdap.proto.id.ApplicationId) Singleton(com.google.inject.Singleton) Iterables(com.google.common.collect.Iterables) ByteArrayOutputStream(java.io.ByteArrayOutputStream) Location(org.apache.twill.filesystem.Location) GET(javax.ws.rs.GET) AccessEnforcer(io.cdap.cdap.security.spi.authorization.AccessEnforcer) UnauthorizedException(io.cdap.cdap.security.spi.authorization.UnauthorizedException) ArrayList(java.util.ArrayList) Strings(com.google.common.base.Strings) NamespaceNotFoundException(io.cdap.cdap.common.NamespaceNotFoundException) WriteConflictException(io.cdap.cdap.internal.app.runtime.artifact.WriteConflictException) JsonWriter(com.google.gson.stream.JsonWriter) Nullable(javax.annotation.Nullable) AuditPolicy(io.cdap.cdap.common.security.AuditPolicy) AbstractBodyConsumer(io.cdap.cdap.common.http.AbstractBodyConsumer) Throwables(com.google.common.base.Throwables) DatasetManagementException(io.cdap.cdap.api.dataset.DatasetManagementException) IOException(java.io.IOException) ConflictException(io.cdap.cdap.common.ConflictException) NotImplementedException(io.cdap.cdap.common.NotImplementedException) InputStreamReader(java.io.InputStreamReader) ProgramRuntimeService(io.cdap.cdap.app.runtime.ProgramRuntimeService) File(java.io.File) ExecutionException(java.util.concurrent.ExecutionException) HttpHeaderNames(io.netty.handler.codec.http.HttpHeaderNames) JsonObject(com.google.gson.JsonObject) NamespaceQueryAdmin(io.cdap.cdap.common.namespace.NamespaceQueryAdmin) NamespaceId(io.cdap.cdap.proto.id.NamespaceId) AccessException(io.cdap.cdap.api.security.AccessException) Inject(com.google.inject.Inject) LoggerFactory(org.slf4j.LoggerFactory) Path(javax.ws.rs.Path) Unpooled(io.netty.buffer.Unpooled) QueryParam(javax.ws.rs.QueryParam) Gson(com.google.gson.Gson) AuthenticationContext(io.cdap.cdap.security.spi.authentication.AuthenticationContext) DefaultValue(javax.ws.rs.DefaultValue) Splitter(com.google.common.base.Splitter) DELETE(javax.ws.rs.DELETE) SortOrder(io.cdap.cdap.spi.data.SortOrder) ApplicationUpdateDetail(io.cdap.cdap.proto.ApplicationUpdateDetail) BatchApplicationDetail(io.cdap.cdap.proto.BatchApplicationDetail) Collection(java.util.Collection) ApplicationLifecycleService(io.cdap.cdap.internal.app.services.ApplicationLifecycleService) HttpResponseStatus(io.netty.handler.codec.http.HttpResponseStatus) List(java.util.List) DefaultHttpHeaders(io.netty.handler.codec.http.DefaultHttpHeaders) CaseInsensitiveEnumTypeAdapterFactory(io.cdap.cdap.common.io.CaseInsensitiveEnumTypeAdapterFactory) Optional(java.util.Optional) Constants(io.cdap.cdap.common.conf.Constants) InvalidArtifactException(io.cdap.cdap.common.InvalidArtifactException) DirUtils(io.cdap.cdap.common.utils.DirUtils) ArtifactScope(io.cdap.cdap.api.artifact.ArtifactScope) ArtifactAlreadyExistsException(io.cdap.cdap.common.ArtifactAlreadyExistsException) NotFoundException(io.cdap.cdap.common.NotFoundException) StandardPermission(io.cdap.cdap.proto.security.StandardPermission) PathParam(javax.ws.rs.PathParam) TypeToken(com.google.common.reflect.TypeToken) ApplicationWithPrograms(io.cdap.cdap.internal.app.deploy.pipeline.ApplicationWithPrograms) EntityId(io.cdap.cdap.proto.id.EntityId) ServiceException(io.cdap.cdap.common.ServiceException) AtomicReference(java.util.concurrent.atomic.AtomicReference) JsonElement(com.google.gson.JsonElement) HashSet(java.util.HashSet) OutputStreamWriter(java.io.OutputStreamWriter) ByteBufInputStream(io.netty.buffer.ByteBufInputStream) AbstractAppFabricHttpHandler(io.cdap.cdap.gateway.handlers.util.AbstractAppFabricHttpHandler) ProgramController(io.cdap.cdap.app.runtime.ProgramController) Logger(org.slf4j.Logger) POST(javax.ws.rs.POST) HttpResponder(io.cdap.http.HttpResponder) HttpHeaderValues(io.netty.handler.codec.http.HttpHeaderValues) JsonSyntaxException(com.google.gson.JsonSyntaxException) ChunkResponder(io.cdap.http.ChunkResponder) ApplicationFilter(io.cdap.cdap.app.store.ApplicationFilter) ProgramId(io.cdap.cdap.proto.id.ProgramId) BadRequestException(io.cdap.cdap.common.BadRequestException) KerberosPrincipalId(io.cdap.cdap.proto.id.KerberosPrincipalId) ArtifactNotFoundException(io.cdap.cdap.common.ArtifactNotFoundException) CConfiguration(io.cdap.cdap.common.conf.CConfiguration) NamespacePathLocator(io.cdap.cdap.common.namespace.NamespacePathLocator) PUT(javax.ws.rs.PUT) FileReader(java.io.FileReader) AppRequest(io.cdap.cdap.proto.artifact.AppRequest) ApplicationRecord(io.cdap.cdap.proto.ApplicationRecord) Collections(java.util.Collections) AtomicReference(java.util.concurrent.atomic.AtomicReference) NamespaceId(io.cdap.cdap.proto.id.NamespaceId) HashSet(java.util.HashSet) ApplicationRecord(io.cdap.cdap.proto.ApplicationRecord) Path(javax.ws.rs.Path) GET(javax.ws.rs.GET)

Example 4 with ScanApplicationsRequest

use of io.cdap.cdap.app.store.ScanApplicationsRequest in project cdap by caskdata.

the class CDAPEntities method collect.

@Override
public void collect() throws Exception {
    reset();
    List<NamespaceMeta> namespaceMetas = nsQueryAdmin.list();
    namespaces = namespaceMetas.size();
    artifacts += artifactRepository.getArtifactSummaries(NamespaceId.SYSTEM, false).size();
    for (NamespaceMeta meta : namespaceMetas) {
        ScanApplicationsRequest scanApplicationsRequest = ScanApplicationsRequest.builder().setNamespaceId(meta.getNamespaceId()).build();
        appLifecycleService.scanApplications(scanApplicationsRequest, d -> {
            this.apps++;
            programs += d.getPrograms().size();
        });
        artifacts += artifactRepository.getArtifactSummaries(meta.getNamespaceId(), false).size();
        datasets += dsFramework.getInstances(meta.getNamespaceId()).size();
    }
}
Also used : ScanApplicationsRequest(io.cdap.cdap.app.store.ScanApplicationsRequest) NamespaceMeta(io.cdap.cdap.proto.NamespaceMeta)

Example 5 with ScanApplicationsRequest

use of io.cdap.cdap.app.store.ScanApplicationsRequest in project cdap by caskdata.

the class AppMetadataStore method scanApplications.

/**
 * Scans applications. Allows to optionally set namespace / filters and implement pagination. For pagination
 * set {@link ScanApplicationsRequest#getScanFrom()} to the last application id of the previous page.
 *
 * @param request parameters defining filters and sorting
 * @param func a {@link Function} to consume application metadata entries generated by the scan. The boolean
 *             value returned is {@code true}, the scan will continue; otherwise the scan will stop and return.
 *             Note that the parameter is a {@link Map.Entry} to allow lazy deserialization of
 *             {@link ApplicationMeta} and it should not be replaced with {@link BiFunction}.
 * @see ScanApplicationsRequest#builder(ScanApplicationsRequest) to create a next page / batch request
 * @throws IOException if failed to scan the storage
 */
public void scanApplications(ScanApplicationsRequest request, Function<Map.Entry<ApplicationId, ApplicationMeta>, Boolean> func) throws IOException {
    Range.Bound startBound = Range.Bound.INCLUSIVE;
    Collection<Field<?>> startFields = request.getNamespaceId() == null ? Collections.emptyList() : Collections.singletonList(Fields.stringField(StoreDefinition.AppMetadataStore.NAMESPACE_FIELD, request.getNamespaceId().getNamespace()));
    Range.Bound endBound = Range.Bound.INCLUSIVE;
    Collection<Field<?>> endFields = startFields;
    if (request.getScanFrom() != null) {
        if (request.getNamespaceId() != null && !request.getNamespaceId().equals(request.getScanFrom().getNamespaceId())) {
            throw new IllegalArgumentException("Requested to start scan from application " + request.getScanFrom() + " that is outside of scan namespace " + request.getNamespaceId());
        }
        startBound = Range.Bound.EXCLUSIVE;
        startFields = getApplicationPrimaryKeys(request.getScanFrom());
    }
    if (request.getScanTo() != null) {
        if (request.getNamespaceId() != null && !request.getNamespaceId().equals(request.getScanTo().getNamespaceId())) {
            throw new IllegalArgumentException("Requested to finish scan at application " + request.getScanTo() + " that is outside of scan namespace " + request.getNamespaceId());
        }
        endBound = Range.Bound.EXCLUSIVE;
        endFields = getApplicationPrimaryKeys(request.getScanTo());
    }
    Range range;
    if (request.getSortOrder() == SortOrder.ASC) {
        range = Range.create(startFields, startBound, endFields, endBound);
    } else {
        range = Range.create(endFields, endBound, startFields, startBound);
    }
    // As of now this is where we push filter to. it does not go to the StructuredTable,
    // but we don't deserialize ApplicationMeta unless needed
    Predicate<AppScanEntry> scanEntryPredicate = e -> true;
    for (ApplicationFilter filter : request.getFilters()) {
        if (filter instanceof ApplicationFilter.ApplicationIdFilter) {
            scanEntryPredicate = scanEntryPredicate.and(e -> ((ApplicationFilter.ApplicationIdFilter) filter).test(e.getKey()));
        } else if (filter instanceof ApplicationFilter.ArtifactIdFilter) {
            scanEntryPredicate = scanEntryPredicate.and(e -> ((ApplicationFilter.ArtifactIdFilter) filter).test(e.getValue().getSpec().getArtifactId()));
        } else {
            throw new UnsupportedOperationException("Application filter " + filter + " is not supported");
        }
    }
    StructuredTable table = getApplicationSpecificationTable();
    int limit = request.getLimit();
    try (CloseableIterator<StructuredRow> iterator = table.scan(range, Integer.MAX_VALUE, request.getSortOrder())) {
        boolean keepScanning = true;
        while (iterator.hasNext() && keepScanning && limit > 0) {
            StructuredRow row = iterator.next();
            AppScanEntry scanEntry = new AppScanEntry(row);
            if (scanEntryPredicate.test(scanEntry)) {
                keepScanning = func.apply(scanEntry);
                limit--;
            }
        }
    }
}
Also used : Arrays(java.util.Arrays) NamespaceId(io.cdap.cdap.proto.id.NamespaceId) StructuredRow(io.cdap.cdap.spi.data.StructuredRow) BiFunction(java.util.function.BiFunction) LoggerFactory(org.slf4j.LoggerFactory) Bytes(io.cdap.cdap.api.common.Bytes) Fields(io.cdap.cdap.spi.data.table.field.Fields) GsonBuilder(com.google.gson.GsonBuilder) ProgramRunCluster(io.cdap.cdap.proto.ProgramRunCluster) ScanApplicationsRequest(io.cdap.cdap.app.store.ScanApplicationsRequest) DatasetId(io.cdap.cdap.proto.id.DatasetId) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) Gson(com.google.gson.Gson) Map(java.util.Map) Field(io.cdap.cdap.spi.data.table.field.Field) RunId(org.apache.twill.api.RunId) BasicWorkflowToken(io.cdap.cdap.internal.app.runtime.workflow.BasicWorkflowToken) SortOrder(io.cdap.cdap.spi.data.SortOrder) BasicThrowable(io.cdap.cdap.proto.BasicThrowable) StoreDefinition(io.cdap.cdap.store.StoreDefinition) ImmutableMap(com.google.common.collect.ImmutableMap) Predicate(java.util.function.Predicate) Collection(java.util.Collection) ApplicationSpecification(io.cdap.cdap.api.app.ApplicationSpecification) Set(java.util.Set) ProgramRunStatus(io.cdap.cdap.proto.ProgramRunStatus) StructuredTableContext(io.cdap.cdap.spi.data.StructuredTableContext) Collectors(java.util.stream.Collectors) Sets(com.google.common.collect.Sets) ApplicationSpecificationAdapter(io.cdap.cdap.internal.app.ApplicationSpecificationAdapter) Objects(java.util.Objects) AbstractCloseableIterator(io.cdap.cdap.api.dataset.lib.AbstractCloseableIterator) List(java.util.List) Type(java.lang.reflect.Type) Optional(java.util.Optional) Constants(io.cdap.cdap.common.conf.Constants) ProfileId(io.cdap.cdap.proto.id.ProfileId) ProgramOptionConstants(io.cdap.cdap.internal.app.runtime.ProgramOptionConstants) ApplicationId(io.cdap.cdap.proto.id.ApplicationId) HashMap(java.util.HashMap) TypeToken(com.google.common.reflect.TypeToken) ProgramType(io.cdap.cdap.proto.ProgramType) Function(java.util.function.Function) JsonReader(com.google.gson.stream.JsonReader) ArrayList(java.util.ArrayList) HashSet(java.util.HashSet) LinkedHashMap(java.util.LinkedHashMap) WorkflowToken(io.cdap.cdap.api.workflow.WorkflowToken) ProgramRunId(io.cdap.cdap.proto.id.ProgramRunId) ImmutableList(com.google.common.collect.ImmutableList) BiConsumer(java.util.function.BiConsumer) SystemArguments(io.cdap.cdap.internal.app.runtime.SystemArguments) LinkedHashSet(java.util.LinkedHashSet) Nullable(javax.annotation.Nullable) WorkflowNodeStateDetail(io.cdap.cdap.proto.WorkflowNodeStateDetail) Logger(org.slf4j.Logger) RunIds(io.cdap.cdap.common.app.RunIds) ApplicationFilter(io.cdap.cdap.app.store.ApplicationFilter) ProgramId(io.cdap.cdap.proto.id.ProgramId) IOException(java.io.IOException) BadRequestException(io.cdap.cdap.common.BadRequestException) CloseableIterator(io.cdap.cdap.api.dataset.lib.CloseableIterator) ProgramRunClusterStatus(io.cdap.cdap.proto.ProgramRunClusterStatus) TableNotFoundException(io.cdap.cdap.spi.data.TableNotFoundException) TimeUnit(java.util.concurrent.TimeUnit) Consumer(java.util.function.Consumer) JsonToken(com.google.gson.stream.JsonToken) StringReader(java.io.StringReader) StructuredTable(io.cdap.cdap.spi.data.StructuredTable) Range(io.cdap.cdap.spi.data.table.field.Range) Preconditions(com.google.common.base.Preconditions) VisibleForTesting(com.google.common.annotations.VisibleForTesting) Collections(java.util.Collections) ArtifactId(io.cdap.cdap.api.artifact.ArtifactId) StructuredTable(io.cdap.cdap.spi.data.StructuredTable) StructuredRow(io.cdap.cdap.spi.data.StructuredRow) Range(io.cdap.cdap.spi.data.table.field.Range) Field(io.cdap.cdap.spi.data.table.field.Field) ApplicationFilter(io.cdap.cdap.app.store.ApplicationFilter)

Aggregations

ScanApplicationsRequest (io.cdap.cdap.app.store.ScanApplicationsRequest)10 ApplicationId (io.cdap.cdap.proto.id.ApplicationId)8 NamespaceId (io.cdap.cdap.proto.id.NamespaceId)5 ArrayList (java.util.ArrayList)5 AtomicReference (java.util.concurrent.atomic.AtomicReference)5 ApplicationSpecification (io.cdap.cdap.api.app.ApplicationSpecification)4 AtomicInteger (java.util.concurrent.atomic.AtomicInteger)4 ImmutableList (com.google.common.collect.ImmutableList)3 ImmutableMap (com.google.common.collect.ImmutableMap)3 Gson (com.google.gson.Gson)3 AllProgramsApp (io.cdap.cdap.AllProgramsApp)3 ArtifactId (io.cdap.cdap.api.artifact.ArtifactId)3 ApplicationFilter (io.cdap.cdap.app.store.ApplicationFilter)3 RunIds (io.cdap.cdap.common.app.RunIds)3 Constants (io.cdap.cdap.common.conf.Constants)3 SystemArguments (io.cdap.cdap.internal.app.runtime.SystemArguments)3 ProgramRunStatus (io.cdap.cdap.proto.ProgramRunStatus)3 ProgramType (io.cdap.cdap.proto.ProgramType)3 ProfileId (io.cdap.cdap.proto.id.ProfileId)3 ProgramId (io.cdap.cdap.proto.id.ProgramId)3