Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ private MaskingUtil() {
}

public static void maskProperties(NakshaFeature feature, Set<String> lowercasedPropertiesToMask) {
maskProperties(feature.getProperties(), lowercasedPropertiesToMask);
maskProperties((Map<String, Object>) feature, lowercasedPropertiesToMask);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nice one 😃

}

private static void maskProperties(Map<String, Object> propertiesAsMap, Set<String> propertiesToMaskLowercase) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,9 @@
import java.util.Set;
import naksha.base.NakshaError;
import naksha.base.NakshaException;
import naksha.model.request.RequestQuery;
import naksha.model.request.ops.Op;
import naksha.model.request.ops.QueryConverter;
import naksha.model.request.query.ITagQuery;
import naksha.model.request.query.TagAnd;
import naksha.model.request.query.TagExists;
Expand Down Expand Up @@ -52,6 +55,16 @@ private TagQueryUtil() {
return rootTagOrQuery;
}

public static @Nullable Op tagOpFromParams(final @Nullable QueryParameterList queryParams) {
final ITagQuery tagQuery = tagQueryFromParams(queryParams);
if (tagQuery == null) {
return null;
}
final RequestQuery requestQuery = new RequestQuery();
requestQuery.setTags(tagQuery);
return QueryConverter.PgQueryConverter_C.convert(requestQuery);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I see we could make convertTag public here and use it instead of using deprecated setTags, let's consult one of lib-psql owners for that.

}

private static void processParams(
final @NotNull TagOr rootOrQuery,
final @NotNull QueryParameter tagParams
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
package com.here.naksha.app.service.http.tasks;

import static com.here.naksha.common.http.apis.ApiParamsConst.DEF_ADMIN_FEATURE_LIMIT;
import static com.here.naksha.common.http.apis.ApiParamsConst.LIMIT;
import static java.util.Collections.emptyList;
import static java.util.Objects.requireNonNull;
import static naksha.base.JvmBoxingUtil.box;
Expand All @@ -27,7 +28,12 @@

import com.here.naksha.app.service.http.HttpResponseType;
import com.here.naksha.app.service.http.NakshaHttpVerticle;
import com.here.naksha.app.service.http.apis.ApiParams;
import com.here.naksha.app.service.http.ops.PropertySelectionUtil;
import com.here.naksha.app.service.http.ops.TagQueryUtil;
import com.here.naksha.app.service.http.tasks.processor.FeaturePostProcessor;
import com.here.naksha.app.service.http.tasks.processor.PropertySelectionPostProcessor;
import com.here.naksha.app.service.http.tasks.processor.SequentialPostProcessor;
import com.here.naksha.app.service.models.IterateHandle;
import com.here.naksha.lib.core.AbstractTask;
import com.here.naksha.lib.core.INaksha;
Expand All @@ -41,10 +47,10 @@
import java.util.Map;
import naksha.base.AnyObject;
import naksha.base.FromJsonOptions;
import naksha.base.Platform;
import naksha.base.Action;
import naksha.model.NakshaContext;
import naksha.base.NakshaError;
import naksha.base.Platform;
import naksha.model.SessionOptions;
import naksha.model.XyzFeatureCollection;
import naksha.model.objects.NakshaFeature;
Expand All @@ -54,6 +60,8 @@
import naksha.model.request.Response;
import naksha.model.request.SuccessResponse;
import naksha.model.request.WriteRequest;
import naksha.model.request.ops.Op;
import com.here.naksha.lib.core.models.payload.events.QueryParameterList;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.slf4j.Logger;
Expand Down Expand Up @@ -108,6 +116,25 @@ protected XyzResponse handleNoElements(@NotNull NoElementsStrategy noElementsStr
return verticle.sendErrorResponse(routingContext, noElementsStrategy.nakshaError);
}

protected <F extends NakshaFeature> @NotNull XyzResponse executeAdminListRequest(
@NotNull String collection,
@NotNull Class<F> type,
@Nullable FeaturePostProcessor<F> masking) {
final QueryParameterList queryParams = ApiParams.queryParamsFromRequest(routingContext);
int limit = ApiParams.extractQueryParamAsInt(queryParams, LIMIT, false, DEF_ADMIN_FEATURE_LIMIT);
limit = (limit < 0 || limit > DEF_ADMIN_FEATURE_LIMIT) ? DEF_ADMIN_FEATURE_LIMIT : limit;
final var propPaths = PropertySelectionUtil.buildPropPathSetFromQueryParams(queryParams);
final FeaturePostProcessor<F> postProcessor = SequentialPostProcessor.combine(
masking, propPaths == null ? null : new PropertySelectionPostProcessor<>(propPaths));
final Op tagOp = TagQueryUtil.tagOpFromParams(queryParams);
final ReadFeatures request = new ReadFeatures().withCollectionId(collection);
request.setQueryMembers(tagOp);
request.setLimit(limit);
request.setCatalogId(naksha().getAdminMapId());
final Response response = executeReadRequestFromSpaceStorage(request);
return transformResponseToXyzCollectionResponse(response, type, 0, limit, null, postProcessor);
}

protected <F extends NakshaFeature> @NotNull XyzResponse transformResponseToXyzFeatureResponse(
final @Nullable Response response,
final @NotNull Class<F> type,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -105,13 +105,7 @@ protected void init() {
}

private @NotNull XyzResponse executeGetHandlers() {
// Create ReadFeatures Request to read all handlers from Admin DB
final ReadFeatures request = new ReadFeatures().withCollectionId(EVENT_HANDLERS);
request.setCatalogId(naksha().getAdminMapId());
// Submit request to NH Space Storage
Response response = executeReadRequestFromSpaceStorage(request);
// transform Response to Http FeatureCollection response
return transformResponseToXyzCollectionResponse(response, EventHandlerConfig.class, HANDLER_MASKING);
return executeAdminListRequest(EVENT_HANDLERS, EventHandlerConfig.class, HANDLER_MASKING);
}

private @NotNull XyzResponse executeGetHandlerById() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -518,13 +518,13 @@ protected void init() {
if (propPaths == null || propPaths.isEmpty()) {
return MOM_10_POST_PROCESSOR;
}
return combine(MOM_10_POST_PROCESSOR, new PropertySelectionPostProcessor(propPaths));
return combine(MOM_10_POST_PROCESSOR, new PropertySelectionPostProcessor<>(propPaths));
}

private @NotNull FeaturePostProcessor<NakshaFeature> postProcessor(
Set<String> propPaths, boolean clip, SpGeometry clipGeo) {
if (propPaths != null && !propPaths.isEmpty()) {
PropertySelectionPostProcessor propSelectionPostProcessor = new PropertySelectionPostProcessor(propPaths);
PropertySelectionPostProcessor<NakshaFeature> propSelectionPostProcessor = new PropertySelectionPostProcessor<>(propPaths);
if (clip) {
return combine(MOM_10_POST_PROCESSOR, propSelectionPostProcessor, new GeoClipPostProcessor(clipGeo));
} else {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@

import static com.here.naksha.app.service.http.apis.ApiParams.extractMandatoryPathParam;
import static com.here.naksha.app.service.http.tasks.NoElementsStrategy.NOT_FOUND_ON_NO_ELEMENTS;
import static com.here.naksha.common.http.apis.ApiParamsConst.DEF_ADMIN_FEATURE_LIMIT;
import static com.here.naksha.common.http.apis.ApiParamsConst.SPACE_ID;
import static com.here.naksha.lib.core.HubInternalIdentifiers.SPACES;

Expand Down Expand Up @@ -132,10 +131,7 @@ private XyzResponse executeDeleteSpace() {
}

private @NotNull XyzResponse executeGetSpaces() {
final ReadFeatures request = new ReadFeatures().withCollectionId(SPACES);
request.setCatalogId(naksha().getAdminMapId());
Response response = executeReadRequestFromSpaceStorage(request);
return transformResponseToXyzCollectionResponse(response, Space.class, 0, DEF_ADMIN_FEATURE_LIMIT, null, null);
return executeAdminListRequest(SPACES, Space.class, null);
}

private @NotNull XyzResponse executeGetSpaceById() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -103,10 +103,7 @@ protected void init() {
}

private @NotNull XyzResponse executeGetStorages() {
final ReadFeatures request = new ReadFeatures().withCollectionId(STORAGES);
request.setCatalogId(naksha().getAdminMapId());
Response response = executeReadRequestFromSpaceStorage(request);
return transformResponseToXyzCollectionResponse(response, NakshaStorage.class, STORAGE_MASKING);
return executeAdminListRequest(STORAGES, NakshaStorage.class, STORAGE_MASKING);
}

private @NotNull XyzResponse executeGetStorageById() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,10 @@
import com.here.naksha.lib.core.util.PropertyPathUtil;
import java.util.Map;
import java.util.Set;
import naksha.base.Platform;
import naksha.model.objects.NakshaFeature;

public final class PropertySelectionPostProcessor implements FeaturePostProcessor<NakshaFeature> {
public final class PropertySelectionPostProcessor<T extends NakshaFeature> implements FeaturePostProcessor<T> {

private final Set<String> propPaths;

Expand All @@ -32,10 +33,12 @@ public PropertySelectionPostProcessor(Set<String> propPaths) {
}

@Override
public NakshaFeature postProcess(NakshaFeature feature) {
Map<String, Object> tgtMap = PropertyPathUtil.extractPropertyMapFromFeature(feature, propPaths);
NakshaFeature newF = new NakshaFeature();
newF.putAll(tgtMap);
return newF;
public T postProcess(T feature) {
final Map<String, Object> targetMap = PropertyPathUtil.extractPropertyMapFromFeature(feature, propPaths);
@SuppressWarnings("unchecked")
final Class<T> type = (Class<T>) feature.getClass();
final T selected = Platform.javaProxy(Platform.newMap(), type);
selected.putAll(targetMap);
return selected;
}
}
17 changes: 15 additions & 2 deletions here-naksha-app-service/src/jvmMain/resources/swagger/openapi.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,10 @@ paths:
description: >-
Lists the storages, which the current authenticated user has access to.
operationId: getStorages
parameters:
- $ref: '#/components/parameters/TagList'
- $ref: '#/components/parameters/PropertiesSelection'
- $ref: '#/components/parameters/Limit'
responses:
'200':
$ref: '#/components/responses/StoragesResponse'
Expand Down Expand Up @@ -193,6 +197,10 @@ paths:
summary: List event handlers
description: Lists the event handlers, which the current authenticated user has access to.
operationId: getHandlers
parameters:
- $ref: '#/components/parameters/TagList'
- $ref: '#/components/parameters/PropertiesSelection'
- $ref: '#/components/parameters/Limit'
responses:
'200':
$ref: '#/components/responses/HandlersResponse'
Expand Down Expand Up @@ -329,6 +337,10 @@ paths:
summary: List spaces
description: Lists the spaces, which the current authenticated user has access to.
operationId: getSpaces
parameters:
- $ref: '#/components/parameters/TagList'
- $ref: '#/components/parameters/PropertiesSelection'
- $ref: '#/components/parameters/Limit'
responses:
'200':
$ref: '#/components/responses/SpacesResponse'
Expand Down Expand Up @@ -1070,8 +1082,9 @@ components:
name: limit
in: query
description: >-
The maximum number of features in the response.
Default is _30000_. Hard limit is _100000_.
The maximum number of resources in the response.
For Map Features - default and max limit is 30000.
For all Admin Features (like Storages, EventHandlers, Spaces) - default and max limit is 1000.
schema:
type: integer
Longitude:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@
import static com.here.naksha.app.common.assertions.ResponseAssertions.assertThat;
import static org.junit.jupiter.api.Named.named;

import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.here.naksha.app.common.ApiTest;
import com.here.naksha.app.common.CommonApiTestSetup;
import com.here.naksha.app.common.NakshaTestWebClient;
Expand Down Expand Up @@ -386,6 +388,35 @@ void tc0140_testGetHandlers() throws Exception {
List<String> eventHandlerIds =
returnedXyzFeatures.stream().map(NakshaFeature::getId).toList();
Assertions.assertTrue(eventHandlerIds.containsAll(expectedHandlerIds));

final HttpResponse<String> orResponse =
getNakshaClient().get("hub/handlers?tags=handler_tag_alpha,handler_tag_beta", streamId);
assertThat(orResponse).hasStatus(200);
final List<String> orHandlerIds = parseJson(orResponse.body(), XyzFeatureCollection.class).getFeatures().stream()
.map(NakshaFeature::getId).toList();
Assertions.assertEquals(2, orHandlerIds.size());
Assertions.assertTrue(orHandlerIds.containsAll(expectedHandlerIds));

final HttpResponse<String> andResponse =
getNakshaClient().get("hub/handlers?tags=handler_tag_alpha+handler_tag_shared", streamId);
assertThat(andResponse).hasStatus(200);
Assertions.assertEquals(List.of("tc_140_event_handler_1"),
parseJson(andResponse.body(), XyzFeatureCollection.class).getFeatures().stream()
.map(NakshaFeature::getId).toList());

final HttpResponse<String> noMatchResponse =
getNakshaClient().get("hub/handlers?tags=handler_tag_missing", streamId);
assertThat(noMatchResponse).hasStatus(200);
Assertions.assertEquals(0, parseJson(noMatchResponse.body(), XyzFeatureCollection.class).getFeatures().size());

final HttpResponse<String> selectedResponse = getNakshaClient().get(
"hub/handlers?tags=handler_tag_alpha,handler_tag_beta&selection=p.selectionMarker&limit=1", streamId);
assertThat(selectedResponse).hasStatus(200);
final JsonNode selectedFeatures = new ObjectMapper().readTree(selectedResponse.body()).get("features");
Assertions.assertEquals(1, selectedFeatures.size());
final JsonNode selectedProperties = selectedFeatures.get(0).get("properties");
Assertions.assertTrue(selectedProperties.has("selectionMarker"));
Assertions.assertFalse(selectedProperties.has("storageId"));
}

/*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,8 @@

import com.here.naksha.app.common.ApiTest;
import com.here.naksha.app.common.NakshaTestWebClient;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import java.net.http.HttpResponse;
import java.util.List;
import java.util.UUID;
Expand Down Expand Up @@ -165,6 +167,34 @@ void tc0240_testGetSpaces() throws Exception {
List<String> spaceIds =
returnedXyzFeatures.stream().map(NakshaFeature::getId).toList();
Assertions.assertTrue(spaceIds.containsAll(expectedSpaceIds));

final HttpResponse<String> orResponse =
getNakshaClient().get("hub/spaces?tags=space_tag_alpha,space_tag_beta", streamId);
assertEquals(200, orResponse.statusCode());
final List<String> orSpaceIds = parseJson(orResponse.body(), XyzFeatureCollection.class).getFeatures().stream()
.map(NakshaFeature::getId).toList();
assertEquals(2, orSpaceIds.size());
Assertions.assertTrue(orSpaceIds.containsAll(expectedSpaceIds));

final HttpResponse<String> andResponse =
getNakshaClient().get("hub/spaces?tags=space_tag_alpha+space_tag_shared", streamId);
assertEquals(200, andResponse.statusCode());
assertEquals(List.of("tc_240_space_1"), parseJson(andResponse.body(), XyzFeatureCollection.class)
.getFeatures().stream().map(NakshaFeature::getId).toList());

final HttpResponse<String> noMatchResponse =
getNakshaClient().get("hub/spaces?tags=space_tag_missing", streamId);
assertEquals(200, noMatchResponse.statusCode());
assertEquals(0, parseJson(noMatchResponse.body(), XyzFeatureCollection.class).getFeatures().size());

final HttpResponse<String> selectedResponse = getNakshaClient().get(
"hub/spaces?tags=space_tag_alpha,space_tag_beta&selection=p.selectionMarker&limit=1", streamId);
assertEquals(200, selectedResponse.statusCode());
final JsonNode selectedFeatures = new ObjectMapper().readTree(selectedResponse.body()).get("features");
assertEquals(1, selectedFeatures.size());
final JsonNode selectedProperties = selectedFeatures.get(0).get("properties");
Assertions.assertTrue(selectedProperties.has("selectionMarker"));
Assertions.assertFalse(selectedProperties.has("collection"));
}

@Test
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -187,6 +187,34 @@ void tc0040_testGetStorages() throws Exception {
}
}
}

final HttpResponse<String> orResponse =
getNakshaClient().get("hub/storages?tags=storage_tag_alpha,storage_tag_beta", streamId);
assertEquals(200, orResponse.statusCode());
final List<String> orStorageIds = parseJson(orResponse.body(), XyzFeatureCollection.class).getFeatures().stream()
.map(NakshaFeature::getId).toList();
assertEquals(2, orStorageIds.size());
Assertions.assertTrue(orStorageIds.containsAll(expectedStorageIds));

final HttpResponse<String> andResponse =
getNakshaClient().get("hub/storages?tags=storage_tag_alpha+storage_tag_shared", streamId);
assertEquals(200, andResponse.statusCode());
assertEquals(List.of("tc_040_storage_1"), parseJson(andResponse.body(), XyzFeatureCollection.class)
.getFeatures().stream().map(NakshaFeature::getId).toList());

final HttpResponse<String> noMatchResponse =
getNakshaClient().get("hub/storages?tags=storage_tag_missing", streamId);
assertEquals(200, noMatchResponse.statusCode());
assertEquals(0, parseJson(noMatchResponse.body(), XyzFeatureCollection.class).getFeatures().size());

final HttpResponse<String> selectedResponse = getNakshaClient().get(
"hub/storages?tags=storage_tag_alpha,storage_tag_beta&selection=p.appName&limit=1", streamId);
assertEquals(200, selectedResponse.statusCode());
final JsonNode selectedFeatures = new ObjectMapper().readTree(selectedResponse.body()).get("features");
assertEquals(1, selectedFeatures.size());
final JsonNode selectedProperties = selectedFeatures.get(0).get("properties");
Assertions.assertTrue(selectedProperties.has("appName"));
Assertions.assertFalse(selectedProperties.has("dbConfig"));
}

@Test
Expand Down
Loading
Loading