Search in sources :

Example 6 with SearchResult

use of org.eclipse.hono.service.management.SearchResult in project hono by eclipse.

the class AbstractTenantManagementSearchTenantsTest method testSearchTenantsWithCardToMatchSingleCharacter.

/**
 * Verifies that a request to search tenants with filters containing the wildcard character '?'
 * and matching tenants are found.
 *
 * @param ctx The vert.x test context.
 */
@Test
default void testSearchTenantsWithCardToMatchSingleCharacter(final VertxTestContext ctx) {
    final String tenantId1 = DeviceRegistryUtils.getUniqueIdentifier();
    final String tenantId2 = DeviceRegistryUtils.getUniqueIdentifier();
    final String tenantId3 = DeviceRegistryUtils.getUniqueIdentifier();
    final int pageSize = 1;
    final int pageOffset = 0;
    final Filter filter1 = new Filter("/ext/id", "testTenant-?");
    final Filter filter2 = new Filter("/ext/value", "test$?Value");
    final Sort sortOption = new Sort("/ext/id");
    sortOption.setDirection(Sort.Direction.DESC);
    createTenants(Map.of(tenantId1, new Tenant().setEnabled(false).setExtensions(Map.of("id", "testTenant-x", "value", "test$Value")), tenantId2, new Tenant().setEnabled(true).setExtensions(Map.of("id", "testTenant-2", "value", "test$2Value")), tenantId3, new Tenant().setEnabled(true).setExtensions(Map.of("id", "testTenant-3", "value", "test$3Value")))).onFailure(ctx::failNow).compose(ok -> getTenantManagementService().searchTenants(pageSize, pageOffset, List.of(filter1, filter2), List.of(sortOption), NoopSpan.INSTANCE)).onComplete(ctx.succeeding(s -> {
        ctx.verify(() -> {
            assertThat(s.getStatus()).isEqualTo(HttpURLConnection.HTTP_OK);
            final SearchResult<TenantWithId> searchResult = s.getPayload();
            assertThat(searchResult.getTotal()).isEqualTo(2);
            assertThat(searchResult.getResult()).hasSize(1);
            assertThat(searchResult.getResult().get(0).getId()).isEqualTo(tenantId3);
        });
        ctx.completeNow();
    }));
}
Also used : HttpURLConnection(java.net.HttpURLConnection) VertxTestContext(io.vertx.junit5.VertxTestContext) Filter(org.eclipse.hono.service.management.Filter) Truth.assertThat(com.google.common.truth.Truth.assertThat) ServiceInvocationException(org.eclipse.hono.client.ServiceInvocationException) Collectors(java.util.stream.Collectors) Future(io.vertx.core.Future) Test(org.junit.jupiter.api.Test) CompositeFuture(io.vertx.core.CompositeFuture) List(java.util.List) Sort(org.eclipse.hono.service.management.Sort) Adapter(org.eclipse.hono.util.Adapter) SearchResult(org.eclipse.hono.service.management.SearchResult) Map(java.util.Map) Optional(java.util.Optional) NoopSpan(io.opentracing.noop.NoopSpan) DeviceRegistryUtils(org.eclipse.hono.deviceregistry.util.DeviceRegistryUtils) Filter(org.eclipse.hono.service.management.Filter) Sort(org.eclipse.hono.service.management.Sort) SearchResult(org.eclipse.hono.service.management.SearchResult) Test(org.junit.jupiter.api.Test)

Example 7 with SearchResult

use of org.eclipse.hono.service.management.SearchResult in project hono by eclipse.

the class MongoDbBasedDao method processSearchResource.

/**
 * Finds resources such as tenant or device from the given MongoDB collection with the provided
 * paging, filtering and sorting options.
 * <p>
 * A MongoDB aggregation pipeline is used to find the resources from the given MongoDB collection.
 *
 * @param pageSize The maximum number of results to include in a response.
 * @param pageOffset The offset into the result set from which to include objects in the response.
 *                   This allows to retrieve the whole result set page by page.
 * @param filterDocument The document used for filtering the resources in a MongoDB aggregation pipeline.
 * @param sortDocument The document used for sorting the resources in a MongoDB aggregation pipeline.
 * @param resultMapper The mapper used for mapping the result for the search operation.
 * @param <T> The type of the result namely {@link org.eclipse.hono.service.management.device.DeviceWithId} or
 *           {@link org.eclipse.hono.service.management.tenant.TenantWithId}
 * @return A future indicating the outcome of the operation. The future will succeed if the search operation
 *         is successful and some resources are found. If no resources are found then the future will fail
 *         with a {@link ClientErrorException} with status {@link HttpURLConnection#HTTP_NOT_FOUND}.
 *         The future will be failed with a {@link ServiceInvocationException} if the query could not be executed.
 * @throws NullPointerException if any of the parameters is {@code null}.
 * @throws IllegalArgumentException if page size is &lt;= 0 or page offset is &lt; 0.
 * @see <a href="https://docs.mongodb.com/manual/core/aggregation-pipeline">MongoDB Aggregation Pipeline</a>
 */
protected <T> Future<SearchResult<T>> processSearchResource(final int pageSize, final int pageOffset, final JsonObject filterDocument, final JsonObject sortDocument, final Function<JsonObject, List<T>> resultMapper) {
    if (pageSize <= 0) {
        throw new IllegalArgumentException("page size must be a positive integer");
    }
    if (pageOffset < 0) {
        throw new IllegalArgumentException("page offset must not be negative");
    }
    Objects.requireNonNull(filterDocument);
    Objects.requireNonNull(sortDocument);
    Objects.requireNonNull(resultMapper);
    final JsonArray aggregationPipelineQuery = getSearchResourceQuery(pageSize, pageOffset, filterDocument, sortDocument);
    final Promise<JsonObject> searchPromise = Promise.promise();
    if (LOG.isTraceEnabled()) {
        LOG.trace("searching resources using aggregation pipeline:{}{}", System.lineSeparator(), aggregationPipelineQuery.encodePrettily());
    }
    mongoClient.aggregate(collectionName, aggregationPipelineQuery).exceptionHandler(searchPromise::fail).handler(searchPromise::complete);
    return searchPromise.future().onSuccess(searchResult -> {
        if (LOG.isTraceEnabled()) {
            LOG.trace("search result:{}{}", System.lineSeparator(), searchResult.encodePrettily());
        }
    }).map(result -> Optional.ofNullable(result.getInteger(RegistryManagementConstants.FIELD_RESULT_SET_SIZE)).filter(total -> total > 0).map(total -> new SearchResult<>(total, resultMapper.apply(result))).orElseThrow(() -> new ClientErrorException(HttpURLConnection.HTTP_NOT_FOUND))).recover(this::mapError);
}
Also used : JsonArray(io.vertx.core.json.JsonArray) HttpURLConnection(java.net.HttpURLConnection) LoggerFactory(org.slf4j.LoggerFactory) ClientErrorException(org.eclipse.hono.client.ClientErrorException) ServiceInvocationException(org.eclipse.hono.client.ServiceInvocationException) Function(java.util.function.Function) PreDestroy(javax.annotation.PreDestroy) FieldLevelEncryption(org.eclipse.hono.deviceregistry.util.FieldLevelEncryption) SearchResult(org.eclipse.hono.service.management.SearchResult) JsonObject(io.vertx.core.json.JsonObject) AsyncResult(io.vertx.core.AsyncResult) RegistryManagementConstants(org.eclipse.hono.util.RegistryManagementConstants) Logger(org.slf4j.Logger) Tracer(io.opentracing.Tracer) MongoException(com.mongodb.MongoException) NoopTracerFactory(io.opentracing.noop.NoopTracerFactory) Promise(io.vertx.core.Promise) ServerErrorException(org.eclipse.hono.client.ServerErrorException) MongoClient(io.vertx.ext.mongo.MongoClient) Future(io.vertx.core.Future) Objects(java.util.Objects) JsonArray(io.vertx.core.json.JsonArray) List(java.util.List) BaseDto(org.eclipse.hono.service.management.BaseDto) IndexOptions(io.vertx.ext.mongo.IndexOptions) Optional(java.util.Optional) Handler(io.vertx.core.Handler) ErrorCategory(com.mongodb.ErrorCategory) JsonObject(io.vertx.core.json.JsonObject) ClientErrorException(org.eclipse.hono.client.ClientErrorException) SearchResult(org.eclipse.hono.service.management.SearchResult)

Example 8 with SearchResult

use of org.eclipse.hono.service.management.SearchResult in project hono by eclipse.

the class AbstractDeviceManagementSearchDevicesTest method testSearchDevicesWithSortOption.

/**
 * Verifies that a request to search devices with a sort option succeeds and the result is in accordance with the
 * specified sort option.
 *
 * @param ctx The vert.x test context.
 */
@Test
default void testSearchDevicesWithSortOption(final VertxTestContext ctx) {
    final String tenantId = DeviceRegistryUtils.getUniqueIdentifier();
    final int pageSize = 1;
    final int pageOffset = 0;
    final Filter filter = new Filter("/enabled", true);
    final Sort sortOption = new Sort("/ext/id");
    sortOption.setDirection(Sort.Direction.DESC);
    createDevices(tenantId, Map.of("testDevice1", new Device().setEnabled(true).setExtensions(Map.of("id", "aaa")), "testDevice2", new Device().setEnabled(true).setExtensions(Map.of("id", "bbb")))).compose(ok -> getDeviceManagementService().searchDevices(tenantId, pageSize, pageOffset, List.of(filter), List.of(sortOption), NoopSpan.INSTANCE)).onComplete(ctx.succeeding(s -> {
        ctx.verify(() -> {
            assertThat(s.getStatus()).isEqualTo(HttpURLConnection.HTTP_OK);
            final SearchResult<DeviceWithId> searchResult = s.getPayload();
            assertThat(searchResult.getTotal()).isEqualTo(2);
            assertThat(searchResult.getResult()).hasSize(1);
            assertThat(searchResult.getResult().get(0).getId()).isEqualTo("testDevice2");
        });
        ctx.completeNow();
    }));
}
Also used : HttpURLConnection(java.net.HttpURLConnection) VertxTestContext(io.vertx.junit5.VertxTestContext) Filter(org.eclipse.hono.service.management.Filter) Truth.assertThat(com.google.common.truth.Truth.assertThat) Future(io.vertx.core.Future) Test(org.junit.jupiter.api.Test) List(java.util.List) Sort(org.eclipse.hono.service.management.Sort) SearchResult(org.eclipse.hono.service.management.SearchResult) Map(java.util.Map) Optional(java.util.Optional) Assertions(org.eclipse.hono.deviceregistry.util.Assertions) NoopSpan(io.opentracing.noop.NoopSpan) DeviceRegistryUtils(org.eclipse.hono.deviceregistry.util.DeviceRegistryUtils) Filter(org.eclipse.hono.service.management.Filter) Sort(org.eclipse.hono.service.management.Sort) SearchResult(org.eclipse.hono.service.management.SearchResult) Test(org.junit.jupiter.api.Test)

Example 9 with SearchResult

use of org.eclipse.hono.service.management.SearchResult in project hono by eclipse.

the class MongoDbBasedDeviceDao method find.

/**
 * {@inheritDoc}
 */
@Override
public Future<SearchResult<DeviceWithId>> find(final String tenantId, final int pageSize, final int pageOffset, final List<Filter> filters, final List<Sort> sortOptions, final SpanContext tracingContext) {
    Objects.requireNonNull(tenantId);
    Objects.requireNonNull(filters);
    Objects.requireNonNull(sortOptions);
    if (pageSize <= 0) {
        throw new IllegalArgumentException("page size must be a positive integer");
    }
    if (pageOffset < 0) {
        throw new IllegalArgumentException("page offset must not be negative");
    }
    final Span span = tracer.buildSpan("find Devices").addReference(References.CHILD_OF, tracingContext).start();
    final JsonObject filterDocument = MongoDbDocumentBuilder.builder().withTenantId(tenantId).withDeviceFilters(filters).document();
    final JsonObject sortDocument = MongoDbDocumentBuilder.builder().withDeviceSortOptions(sortOptions).document();
    return processSearchResource(pageSize, pageOffset, filterDocument, sortDocument, MongoDbBasedDeviceDao::getDevicesWithId).onFailure(t -> TracingHelper.logError(span, "error finding devices", t)).onComplete(r -> span.finish());
}
Also used : HttpURLConnection(java.net.HttpURLConnection) Filter(org.eclipse.hono.service.management.Filter) LoggerFactory(org.slf4j.LoggerFactory) AtomicBoolean(java.util.concurrent.atomic.AtomicBoolean) ClientErrorException(org.eclipse.hono.client.ClientErrorException) Status(io.vertx.ext.healthchecks.Status) Sort(org.eclipse.hono.service.management.Sort) HealthCheckHandler(io.vertx.ext.healthchecks.HealthCheckHandler) HealthCheckProvider(org.eclipse.hono.service.HealthCheckProvider) SearchResult(org.eclipse.hono.service.management.SearchResult) References(io.opentracing.References) JsonObject(io.vertx.core.json.JsonObject) TracingHelper(org.eclipse.hono.tracing.TracingHelper) RegistryManagementConstants(org.eclipse.hono.util.RegistryManagementConstants) DeviceWithId(org.eclipse.hono.service.management.device.DeviceWithId) Logger(org.slf4j.Logger) Tracer(io.opentracing.Tracer) Promise(io.vertx.core.Promise) Set(java.util.Set) MongoClient(io.vertx.ext.mongo.MongoClient) RegistrationConstants(org.eclipse.hono.util.RegistrationConstants) UUID(java.util.UUID) Collectors(java.util.stream.Collectors) DeviceDto(org.eclipse.hono.service.management.device.DeviceDto) Future(io.vertx.core.Future) SpanContext(io.opentracing.SpanContext) Objects(java.util.Objects) JsonArray(io.vertx.core.json.JsonArray) List(java.util.List) IndexOptions(io.vertx.ext.mongo.IndexOptions) Optional(java.util.Optional) Span(io.opentracing.Span) FindOptions(io.vertx.ext.mongo.FindOptions) UpdateOptions(io.vertx.ext.mongo.UpdateOptions) MongoDbDocumentBuilder(org.eclipse.hono.deviceregistry.mongodb.utils.MongoDbDocumentBuilder) JsonObject(io.vertx.core.json.JsonObject) Span(io.opentracing.Span)

Example 10 with SearchResult

use of org.eclipse.hono.service.management.SearchResult in project hono by eclipse.

the class MongoDbBasedTenantDao method find.

/**
 * {@inheritDoc}
 */
@Override
public Future<SearchResult<TenantWithId>> find(final int pageSize, final int pageOffset, final List<Filter> filters, final List<Sort> sortOptions, final SpanContext tracingContext) {
    Objects.requireNonNull(filters);
    Objects.requireNonNull(sortOptions);
    if (pageSize <= 0) {
        throw new IllegalArgumentException("page size must be a positive integer");
    }
    if (pageOffset < 0) {
        throw new IllegalArgumentException("page offset must not be negative");
    }
    final Span span = tracer.buildSpan("find Tenants").addReference(References.CHILD_OF, tracingContext).start();
    final JsonObject filterDocument = MongoDbDocumentBuilder.builder().withTenantFilters(filters).document();
    final JsonObject sortDocument = MongoDbDocumentBuilder.builder().withTenantSortOptions(sortOptions).document();
    return processSearchResource(pageSize, pageOffset, filterDocument, sortDocument, MongoDbBasedTenantDao::getTenantsWithId).onFailure(t -> TracingHelper.logError(span, "error finding tenants", t)).onComplete(r -> span.finish());
}
Also used : HttpURLConnection(java.net.HttpURLConnection) X500Principal(javax.security.auth.x500.X500Principal) Filter(org.eclipse.hono.service.management.Filter) LoggerFactory(org.slf4j.LoggerFactory) AtomicBoolean(java.util.concurrent.atomic.AtomicBoolean) ClientErrorException(org.eclipse.hono.client.ClientErrorException) Constants(org.eclipse.hono.util.Constants) Tenant(org.eclipse.hono.service.management.tenant.Tenant) ArrayList(java.util.ArrayList) Status(io.vertx.ext.healthchecks.Status) Sort(org.eclipse.hono.service.management.Sort) HealthCheckHandler(io.vertx.ext.healthchecks.HealthCheckHandler) HealthCheckProvider(org.eclipse.hono.service.HealthCheckProvider) SearchResult(org.eclipse.hono.service.management.SearchResult) References(io.opentracing.References) JsonObject(io.vertx.core.json.JsonObject) TracingHelper(org.eclipse.hono.tracing.TracingHelper) TenantDto(org.eclipse.hono.service.management.tenant.TenantDto) RegistryManagementConstants(org.eclipse.hono.util.RegistryManagementConstants) Logger(org.slf4j.Logger) Tracer(io.opentracing.Tracer) Promise(io.vertx.core.Promise) TenantWithId(org.eclipse.hono.service.management.tenant.TenantWithId) MongoClient(io.vertx.ext.mongo.MongoClient) UUID(java.util.UUID) Collectors(java.util.stream.Collectors) Future(io.vertx.core.Future) SpanContext(io.opentracing.SpanContext) Objects(java.util.Objects) List(java.util.List) IndexOptions(io.vertx.ext.mongo.IndexOptions) Optional(java.util.Optional) Span(io.opentracing.Span) FindOptions(io.vertx.ext.mongo.FindOptions) UpdateOptions(io.vertx.ext.mongo.UpdateOptions) MongoDbDocumentBuilder(org.eclipse.hono.deviceregistry.mongodb.utils.MongoDbDocumentBuilder) JsonObject(io.vertx.core.json.JsonObject) Span(io.opentracing.Span)

Aggregations

Future (io.vertx.core.Future)12 HttpURLConnection (java.net.HttpURLConnection)12 List (java.util.List)12 Optional (java.util.Optional)12 SearchResult (org.eclipse.hono.service.management.SearchResult)12 Filter (org.eclipse.hono.service.management.Filter)11 Sort (org.eclipse.hono.service.management.Sort)11 Truth.assertThat (com.google.common.truth.Truth.assertThat)9 NoopSpan (io.opentracing.noop.NoopSpan)9 VertxTestContext (io.vertx.junit5.VertxTestContext)9 Map (java.util.Map)9 Collectors (java.util.stream.Collectors)9 DeviceRegistryUtils (org.eclipse.hono.deviceregistry.util.DeviceRegistryUtils)9 Test (org.junit.jupiter.api.Test)9 ServiceInvocationException (org.eclipse.hono.client.ServiceInvocationException)8 CompositeFuture (io.vertx.core.CompositeFuture)7 Adapter (org.eclipse.hono.util.Adapter)7 Tracer (io.opentracing.Tracer)3 Promise (io.vertx.core.Promise)3 JsonObject (io.vertx.core.json.JsonObject)3