diff --git a/src/main/java/nl/b3p/tailormap/api/configuration/dev/PopulateTestData.java b/src/main/java/nl/b3p/tailormap/api/configuration/dev/PopulateTestData.java index d8653c200..f3d3f3fb9 100644 --- a/src/main/java/nl/b3p/tailormap/api/configuration/dev/PopulateTestData.java +++ b/src/main/java/nl/b3p/tailormap/api/configuration/dev/PopulateTestData.java @@ -51,7 +51,6 @@ import nl.b3p.tailormap.api.persistence.json.GeoServiceLayerSettings; import nl.b3p.tailormap.api.persistence.json.GeoServiceSettings; import nl.b3p.tailormap.api.persistence.json.JDBCConnectionProperties; -import nl.b3p.tailormap.api.persistence.json.SearchIndexRef; import nl.b3p.tailormap.api.persistence.json.ServiceAuthentication; import nl.b3p.tailormap.api.persistence.json.TailormapObjectRef; import nl.b3p.tailormap.api.persistence.json.TileLayerHiDpiMode; @@ -1383,6 +1382,7 @@ public void createSolrIndex() throws Exception { .build()); GeoService geoService = geoServiceRepository.findById("snapshot-geoserver").orElseThrow(); + Application defaultApp = applicationRepository.findByName("default"); TMFeatureType begroeidterreindeelFT = geoService.findFeatureTypeForLayer( @@ -1408,13 +1408,33 @@ public void createSolrIndex() throws Exception { solrHelper.addFeatureTypeIndex(wegdeelIndex, wegdeelFT, featureSourceFactoryHelper); wegdeelIndex = searchIndexRepository.save(wegdeelIndex); - geoService - .getLayerSettings("postgis:begroeidterreindeel") - .setSearchIndex(new SearchIndexRef().searchIndexId(begroeidterreindeelIndex.getId())); - geoService - .getLayerSettings("sqlserver:wegdeel") - .setSearchIndex(new SearchIndexRef().searchIndexId(wegdeelIndex.getId())); - geoServiceRepository.save(geoService); + AppTreeLayerNode begroeidTerreindeelLayerNode = + defaultApp + .getAllAppTreeLayerNode() + .filter( + node -> + node.getId().equals("lyr:snapshot-geoserver:postgis:begroeidterreindeel")) + .findFirst() + .orElse(null); + + if (begroeidTerreindeelLayerNode != null) { + defaultApp + .getAppLayerSettings(begroeidTerreindeelLayerNode) + .setSearchIndexId(begroeidterreindeelIndex.getId()); + } + + AppTreeLayerNode wegdeel = + defaultApp + .getAllAppTreeLayerNode() + .filter(node -> node.getId().equals("lyr:snapshot-geoserver:sqlserver:wegdeel")) + .findFirst() + .orElse(null); + + if (wegdeel != null) { + defaultApp.getAppLayerSettings(wegdeel).setSearchIndexId(wegdeelIndex.getId()); + } + + applicationRepository.save(defaultApp); } } } diff --git a/src/main/java/nl/b3p/tailormap/api/controller/SearchController.java b/src/main/java/nl/b3p/tailormap/api/controller/SearchController.java index d6d8d852b..f46f7aed5 100644 --- a/src/main/java/nl/b3p/tailormap/api/controller/SearchController.java +++ b/src/main/java/nl/b3p/tailormap/api/controller/SearchController.java @@ -17,8 +17,8 @@ import nl.b3p.tailormap.api.persistence.Application; import nl.b3p.tailormap.api.persistence.GeoService; import nl.b3p.tailormap.api.persistence.SearchIndex; +import nl.b3p.tailormap.api.persistence.json.AppLayerSettings; import nl.b3p.tailormap.api.persistence.json.AppTreeLayerNode; -import nl.b3p.tailormap.api.persistence.json.GeoServiceLayer; import nl.b3p.tailormap.api.repository.SearchIndexRepository; import nl.b3p.tailormap.api.solr.SolrHelper; import nl.b3p.tailormap.api.viewer.model.SearchResponse; @@ -70,19 +70,21 @@ public SearchController(SearchIndexRepository searchIndexRepository) { public ResponseEntity search( @ModelAttribute AppTreeLayerNode appTreeLayerNode, @ModelAttribute GeoService service, - @ModelAttribute GeoServiceLayer layer, @ModelAttribute Application application, @RequestParam(required = false, name = "q") final String solrQuery, @RequestParam(required = false, defaultValue = "0") Integer start) { - if (layer == null) { + AppLayerSettings appLayerSettings = application.getAppLayerSettings(appTreeLayerNode); + + if (appLayerSettings.getSearchIndexId() == null) { throw new ResponseStatusException( - HttpStatus.NOT_FOUND, "Can't find layer " + appTreeLayerNode.getLayerName()); + HttpStatus.NOT_FOUND, + "Layer '%s' does not have a search index".formatted(appTreeLayerNode.getLayerName())); } final SearchIndex searchIndex = - service - .findSearchIndexForLayer(layer, searchIndexRepository) + searchIndexRepository + .findById(appLayerSettings.getSearchIndexId()) .orElseThrow( () -> new ResponseStatusException( diff --git a/src/main/java/nl/b3p/tailormap/api/persistence/GeoService.java b/src/main/java/nl/b3p/tailormap/api/persistence/GeoService.java index 626dab88e..ec195a93b 100644 --- a/src/main/java/nl/b3p/tailormap/api/persistence/GeoService.java +++ b/src/main/java/nl/b3p/tailormap/api/persistence/GeoService.java @@ -38,7 +38,6 @@ import nl.b3p.tailormap.api.persistence.json.TMServiceCaps; import nl.b3p.tailormap.api.persistence.listener.EntityEventPublisher; import nl.b3p.tailormap.api.repository.FeatureSourceRepository; -import nl.b3p.tailormap.api.repository.SearchIndexRepository; import nl.b3p.tailormap.api.util.TMStringUtils; import nl.b3p.tailormap.api.viewer.model.Service; import org.apache.commons.lang3.StringUtils; @@ -439,34 +438,6 @@ public TMFeatureType findFeatureTypeForLayer( return tmft; } - /** - * Find the search index for the given layer. If the layer has a specific search index, that one - * is returned. If not, {@code null} is returned. - * - * @param layer the layer to find the search index for - * @param searchIndexRepository repository to find the search index - * @return the search index for the layer, or {@code null} if no search index is found - */ - public Optional findSearchIndexForLayer( - GeoServiceLayer layer, SearchIndexRepository searchIndexRepository) { - - GeoServiceDefaultLayerSettings defaultLayerSettings = getSettings().getDefaultLayerSettings(); - GeoServiceLayerSettings layerSettings = getLayerSettings(layer.getName()); - - Long searchIndexId = null; - if (layerSettings != null && layerSettings.getSearchIndex() != null) { - searchIndexId = layerSettings.getSearchIndex().getSearchIndexId(); - } - if (searchIndexId == null - && defaultLayerSettings != null - && defaultLayerSettings.getSearchIndex() != null) { - searchIndexId = defaultLayerSettings.getSearchIndex().getSearchIndexId(); - } - return (null == searchIndexId) - ? Optional.empty() - : searchIndexRepository.findById(searchIndexId); - } - /** * Remove all parameters from the URL that are listed in {@link #REMOVE_PARAMS}. * diff --git a/src/main/java/nl/b3p/tailormap/api/persistence/helper/ApplicationHelper.java b/src/main/java/nl/b3p/tailormap/api/persistence/helper/ApplicationHelper.java index c6f2115df..87a169cf8 100644 --- a/src/main/java/nl/b3p/tailormap/api/persistence/helper/ApplicationHelper.java +++ b/src/main/java/nl/b3p/tailormap/api/persistence/helper/ApplicationHelper.java @@ -21,6 +21,7 @@ import nl.b3p.tailormap.api.persistence.Application; import nl.b3p.tailormap.api.persistence.Configuration; import nl.b3p.tailormap.api.persistence.GeoService; +import nl.b3p.tailormap.api.persistence.SearchIndex; import nl.b3p.tailormap.api.persistence.TMFeatureType; import nl.b3p.tailormap.api.persistence.json.AppContent; import nl.b3p.tailormap.api.persistence.json.AppLayerSettings; @@ -37,8 +38,10 @@ import nl.b3p.tailormap.api.repository.ConfigurationRepository; import nl.b3p.tailormap.api.repository.FeatureSourceRepository; import nl.b3p.tailormap.api.repository.GeoServiceRepository; +import nl.b3p.tailormap.api.repository.SearchIndexRepository; import nl.b3p.tailormap.api.security.AuthorizationService; import nl.b3p.tailormap.api.viewer.model.AppLayer; +import nl.b3p.tailormap.api.viewer.model.LayerSearchIndex; import nl.b3p.tailormap.api.viewer.model.LayerTreeNode; import nl.b3p.tailormap.api.viewer.model.MapResponse; import nl.b3p.tailormap.api.viewer.model.TMCoordinateReferenceSystem; @@ -65,6 +68,7 @@ public class ApplicationHelper { private final FeatureSourceRepository featureSourceRepository; private final EntityManager entityManager; private final AuthorizationService authorizationService; + private final SearchIndexRepository searchIndexRepository; public ApplicationHelper( GeoServiceHelper geoServiceHelper, @@ -73,7 +77,8 @@ public ApplicationHelper( ApplicationRepository applicationRepository, FeatureSourceRepository featureSourceRepository, EntityManager entityManager, - AuthorizationService authorizationService) { + AuthorizationService authorizationService, + SearchIndexRepository searchIndexRepository) { this.geoServiceHelper = geoServiceHelper; this.geoServiceRepository = geoServiceRepository; this.configurationRepository = configurationRepository; @@ -81,6 +86,7 @@ public ApplicationHelper( this.featureSourceRepository = featureSourceRepository; this.entityManager = entityManager; this.authorizationService = authorizationService; + this.searchIndexRepository = searchIndexRepository; } public Application getServiceApplication( @@ -330,6 +336,12 @@ private boolean addAppLayerItem(AppTreeLayerNode layerRef) { } } + SearchIndex searchIndex = null; + if (appLayerSettings.getSearchIndexId() != null) { + searchIndex = + searchIndexRepository.findById(appLayerSettings.getSearchIndexId()).orElse(null); + } + mr.addAppLayersItem( new AppLayer() .id(layerRef.getId()) @@ -354,6 +366,10 @@ private boolean addAppLayerItem(AppTreeLayerNode layerRef) { .tileGridExtent(serviceLayerSettings.getTileGridExtent()) .opacity(appLayerSettings.getOpacity()) .autoRefreshInSeconds(appLayerSettings.getAutoRefreshInSeconds()) + .searchIndex( + searchIndex != null + ? new LayerSearchIndex().id(searchIndex.getId()).name(searchIndex.getName()) + : null) .legendImageUrl(legendImageUrl) .visible(layerRef.getVisible()) .attribution(attribution) diff --git a/src/main/resources/openapi/persistence-schemas.yaml b/src/main/resources/openapi/persistence-schemas.yaml index f04501827..f16edafe3 100644 --- a/src/main/resources/openapi/persistence-schemas.yaml +++ b/src/main/resources/openapi/persistence-schemas.yaml @@ -356,8 +356,6 @@ components: type: boolean featureType: $ref: '#/components/schemas/FeatureTypeRef' - searchIndex: - $ref: '#/components/schemas/SearchIndexRef' attribution: description: 'Attribution to show for this layer.' nullable: true @@ -375,17 +373,6 @@ components: items: $ref: '#/components/schemas/AuthorizationRule' - SearchIndexRef: - description: Reference (by id) to a search index. - required: - - SearchIndexId - properties: - searchIndexId: - type: integer - format: int64 - nullable: false - uniqueItems: true - FeatureTypeRef: required: [featureSourceId, featureTypeName] properties: @@ -621,6 +608,10 @@ components: type: integer nullable: true format: int64 + searchIndexId: + type: integer + nullable: true + format: int64 hideAttributes: description: List of attribute names that should be hidden (in addition to attributes already hidden by the feature type settings). diff --git a/src/main/resources/openapi/viewer-schemas.yaml b/src/main/resources/openapi/viewer-schemas.yaml index cef5907f3..898233e37 100644 --- a/src/main/resources/openapi/viewer-schemas.yaml +++ b/src/main/resources/openapi/viewer-schemas.yaml @@ -148,6 +148,8 @@ components: type: number format: double nullable: true + searchIndex: + $ref: '#/components/schemas/LayerSearchIndex' LayerTreeNode: @@ -221,6 +223,15 @@ components: - id - serviceId + LayerSearchIndex: + type: object + properties: + id: + type: integer + format: int64 + name: + type: string + LayerExportCapabilities: type: object required: [exportable] diff --git a/src/test/java/nl/b3p/tailormap/api/persistence/helper/ApplicationHelperTest.java b/src/test/java/nl/b3p/tailormap/api/persistence/helper/ApplicationHelperTest.java index 26eb11904..3c6cf3418 100644 --- a/src/test/java/nl/b3p/tailormap/api/persistence/helper/ApplicationHelperTest.java +++ b/src/test/java/nl/b3p/tailormap/api/persistence/helper/ApplicationHelperTest.java @@ -16,6 +16,7 @@ import nl.b3p.tailormap.api.repository.ConfigurationRepository; import nl.b3p.tailormap.api.repository.FeatureSourceRepository; import nl.b3p.tailormap.api.repository.GeoServiceRepository; +import nl.b3p.tailormap.api.repository.SearchIndexRepository; import nl.b3p.tailormap.api.security.AuthorizationService; import nl.b3p.tailormap.api.viewer.model.MapResponse; import nl.b3p.tailormap.api.viewer.model.TMCoordinateReferenceSystem; @@ -34,6 +35,7 @@ class ApplicationHelperTest { @MockBean ApplicationRepository applicationRepository; @MockBean EntityManager entityManager; @MockBean AuthorizationService authorizationService; + @MockBean SearchIndexRepository searchIndexRepository; @Autowired ApplicationHelper applicationHelper; @Test