Skip to content

Commit

Permalink
Introduce the SolrService
Browse files Browse the repository at this point in the history
from PR #844
  • Loading branch information
mprins committed Sep 13, 2024
1 parent d8c3c1d commit 6af4b90
Show file tree
Hide file tree
Showing 5 changed files with 78 additions and 75 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,6 @@
import java.util.List;
import java.util.Map;
import java.util.NoSuchElementException;
import java.util.concurrent.TimeUnit;
import org.apache.solr.client.solrj.impl.ConcurrentUpdateHttp2SolrClient;
import org.apache.solr.client.solrj.impl.Http2SolrClient;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
Expand Down Expand Up @@ -77,6 +74,7 @@
import org.tailormap.api.repository.UserRepository;
import org.tailormap.api.security.InternalAdminAuthentication;
import org.tailormap.api.solr.SolrHelper;
import org.tailormap.api.solr.SolrService;
import org.tailormap.api.viewer.model.AppStyling;
import org.tailormap.api.viewer.model.Component;
import org.tailormap.api.viewer.model.ComponentConfig;
Expand Down Expand Up @@ -107,15 +105,13 @@ public class PopulateTestData {
@Value("${MAP5_URL:#{null}}")
private String map5url;

@Value("${tailormap-api.solr-core-name:tailormap}")
private String solrCoreName;

private final ApplicationContext appContext;
private final UserRepository userRepository;
private final GroupRepository groupRepository;
private final CatalogRepository catalogRepository;
private final GeoServiceRepository geoServiceRepository;
private final GeoServiceHelper geoServiceHelper;
private final SolrService solrService;

private final FeatureSourceRepository featureSourceRepository;
private final ApplicationRepository applicationRepository;
Expand All @@ -131,6 +127,7 @@ public PopulateTestData(
CatalogRepository catalogRepository,
GeoServiceRepository geoServiceRepository,
GeoServiceHelper geoServiceHelper,
SolrService solrService,
FeatureSourceRepository featureSourceRepository,
ApplicationRepository applicationRepository,
ConfigurationRepository configurationRepository,
Expand All @@ -143,6 +140,7 @@ public PopulateTestData(
this.catalogRepository = catalogRepository;
this.geoServiceRepository = geoServiceRepository;
this.geoServiceHelper = geoServiceHelper;
this.solrService = solrService;
this.featureSourceRepository = featureSourceRepository;
this.applicationRepository = applicationRepository;
this.configurationRepository = configurationRepository;
Expand Down Expand Up @@ -1344,24 +1342,9 @@ public void createSolrIndex() throws Exception {
logger.info("Creating Solr index");
@SuppressWarnings("PMD.AvoidUsingHardCodedIP")
final String solrUrl =
"http://"
+ (connectToSpatialDbsAtLocalhost ? "127.0.0.1" : "solr")
+ ":8983/solr/"
+ solrCoreName;
SolrHelper solrHelper =
new SolrHelper(
new ConcurrentUpdateHttp2SolrClient.Builder(
solrUrl,
new Http2SolrClient.Builder()
.useHttp1_1(true)
.withFollowRedirects(true)
.withConnectionTimeout(10000, TimeUnit.MILLISECONDS)
.withRequestTimeout(60000, TimeUnit.MILLISECONDS)
.build())
.withQueueSize(SolrHelper.SOLR_BATCH_SIZE * 2)
.withThreadCount(10)
.build());

"http://" + (connectToSpatialDbsAtLocalhost ? "127.0.0.1" : "solr") + ":8983/solr/";
this.solrService.setSolrUrl(solrUrl);
SolrHelper solrHelper = new SolrHelper(this.solrService.getSolrClientForIndexing());
GeoService geoService = geoServiceRepository.findById("snapshot-geoserver").orElseThrow();
Application defaultApp = applicationRepository.findByName("default");

Expand Down
22 changes: 5 additions & 17 deletions src/main/java/org/tailormap/api/controller/SearchController.java
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,8 @@
import java.io.IOException;
import java.io.Serializable;
import java.lang.invoke.MethodHandles;
import java.util.concurrent.TimeUnit;
import org.apache.solr.client.solrj.SolrClient;
import org.apache.solr.client.solrj.SolrServerException;
import org.apache.solr.client.solrj.impl.Http2SolrClient;
import org.apache.solr.common.SolrException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
Expand All @@ -37,6 +35,7 @@
import org.tailormap.api.persistence.json.AppTreeLayerNode;
import org.tailormap.api.repository.SearchIndexRepository;
import org.tailormap.api.solr.SolrHelper;
import org.tailormap.api.solr.SolrService;
import org.tailormap.api.viewer.model.SearchResponse;

@AppRestController
Expand All @@ -49,18 +48,14 @@ public class SearchController {
LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());

private final SearchIndexRepository searchIndexRepository;

@Value("${tailormap-api.solr-url}")
private String solrUrl;

@Value("${tailormap-api.solr-core-name:tailormap}")
private String solrCoreName;
private final SolrService solrService;

@Value("${tailormap-api.pageSize:100}")
private int numResultsToReturn;

public SearchController(SearchIndexRepository searchIndexRepository) {
public SearchController(SearchIndexRepository searchIndexRepository, SolrService solrService) {
this.searchIndexRepository = searchIndexRepository;
this.solrService = solrService;
}

@Transactional(readOnly = true)
Expand Down Expand Up @@ -92,7 +87,7 @@ public ResponseEntity<Serializable> search(
"Layer '%s' does not have a search index"
.formatted(appTreeLayerNode.getLayerName())));

try (SolrClient solrClient = getSolrClient();
try (SolrClient solrClient = solrService.getSolrClientForSearching();
SolrHelper solrHelper = new SolrHelper(solrClient)) {
final SearchResponse searchResponse =
solrHelper.findInIndex(searchIndex, solrQuery, start, numResultsToReturn);
Expand All @@ -109,11 +104,4 @@ public ResponseEntity<Serializable> search(
HttpStatus.BAD_REQUEST, "Error while searching with given query", e);
}
}

private SolrClient getSolrClient() {
return new Http2SolrClient.Builder(solrUrl + solrCoreName)
.withConnectionTimeout(10, TimeUnit.SECONDS)
.withFollowRedirects(true)
.build();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,16 +14,12 @@
import java.io.IOException;
import java.lang.invoke.MethodHandles;
import java.util.NoSuchElementException;
import java.util.concurrent.TimeUnit;
import org.apache.solr.client.solrj.SolrClient;
import org.apache.solr.client.solrj.SolrServerException;
import org.apache.solr.client.solrj.impl.ConcurrentUpdateHttp2SolrClient;
import org.apache.solr.client.solrj.impl.Http2SolrClient;
import org.apache.solr.client.solrj.response.SolrPingResponse;
import org.apache.solr.common.SolrException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
Expand All @@ -41,31 +37,29 @@
import org.tailormap.api.repository.FeatureTypeRepository;
import org.tailormap.api.repository.SearchIndexRepository;
import org.tailormap.api.solr.SolrHelper;
import org.tailormap.api.solr.SolrService;
import org.tailormap.api.viewer.model.ErrorResponse;

/** Admin controller for Solr. */
@RestController
public class SolrAdminController {
@Value("${tailormap-api.solr-url}")
private String solrUrl;

@Value("${tailormap-api.solr-core-name:tailormap}")
private String solrCoreName;

private static final Logger logger =
LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
private final FeatureSourceFactoryHelper featureSourceFactoryHelper;

private final FeatureTypeRepository featureTypeRepository;
private final SearchIndexRepository searchIndexRepository;
private final SolrService solrService;

public SolrAdminController(
FeatureSourceFactoryHelper featureSourceFactoryHelper,
FeatureTypeRepository featureTypeRepository,
SearchIndexRepository searchIndexRepository) {
SearchIndexRepository searchIndexRepository,
SolrService solrService) {
this.featureSourceFactoryHelper = featureSourceFactoryHelper;
this.featureTypeRepository = featureTypeRepository;
this.searchIndexRepository = searchIndexRepository;
this.solrService = solrService;
}

/**
Expand All @@ -92,7 +86,7 @@ public SolrAdminController(
path = "${tailormap-api.admin.base-path}/index/ping",
produces = MediaType.APPLICATION_JSON_VALUE)
public ResponseEntity<?> pingSolr() {
try (SolrClient solrClient = getSolrClient()) {
try (SolrClient solrClient = solrService.getSolrClientForSearching()) {
final SolrPingResponse ping = solrClient.ping();
logger.info("Solr ping status {}", ping.getResponse().get("status"));
return ResponseEntity.ok(
Expand All @@ -111,24 +105,6 @@ public ResponseEntity<?> pingSolr() {
}
}

/**
* Get a concurrent update Solr client for bulk operations.
*
* @return the Solr client
*/
private SolrClient getSolrClient() {
return new ConcurrentUpdateHttp2SolrClient.Builder(
solrUrl + solrCoreName,
new Http2SolrClient.Builder()
.withFollowRedirects(true)
.withConnectionTimeout(10000, TimeUnit.MILLISECONDS)
.withRequestTimeout(60000, TimeUnit.MILLISECONDS)
.build())
.withQueueSize(SolrHelper.SOLR_BATCH_SIZE * 2)
.withThreadCount(10)
.build();
}

/**
* (re-) Index a layer.
*
Expand Down Expand Up @@ -195,7 +171,7 @@ public ResponseEntity<?> index(@PathVariable Long searchIndexId) {
boolean createNewIndex =
(null == searchIndex.getLastIndexed()
|| searchIndex.getStatus() == SearchIndex.Status.INITIAL);
try (SolrClient solrClient = getSolrClient();
try (SolrClient solrClient = solrService.getSolrClientForIndexing();
SolrHelper solrHelper = new SolrHelper(solrClient)) {
solrHelper.addFeatureTypeIndex(searchIndex, indexingFT, featureSourceFactoryHelper);
searchIndexRepository.save(searchIndex);
Expand Down Expand Up @@ -244,7 +220,7 @@ public ResponseEntity<?> index(@PathVariable Long searchIndexId) {
produces = MediaType.APPLICATION_JSON_VALUE)
@Transactional
public ResponseEntity<?> clearIndex(@PathVariable Long searchIndexId) {
try (SolrClient solrClient = getSolrClient();
try (SolrClient solrClient = solrService.getSolrClientForSearching();
SolrHelper solrHelper = new SolrHelper(solrClient)) {
solrHelper.clearIndexForLayer(searchIndexId);
// do not delete the SearchIndex metadata object
Expand Down
4 changes: 2 additions & 2 deletions src/main/java/org/tailormap/api/solr/SolrHelper.java
Original file line number Diff line number Diff line change
Expand Up @@ -258,8 +258,8 @@ public SearchResponse findInIndex(
if (null == solrQuery || solrQuery.isBlank()) {
solrQuery = "*";
}
// TODO We could escape special/syntax characters, but that also prevents using keys like ~ and
// *
// TODO We could escape special/syntax characters, but that also prevents using
// keys like ~ and *
// solrQuery = ClientUtils.escapeQueryChars(solrQuery);

final SolrQuery query =
Expand Down
56 changes: 56 additions & 0 deletions src/main/java/org/tailormap/api/solr/SolrService.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
/*
* Copyright (C) 2024 B3Partners B.V.
*
* SPDX-License-Identifier: MIT
*/
package org.tailormap.api.solr;

import java.util.concurrent.TimeUnit;
import org.apache.solr.client.solrj.SolrClient;
import org.apache.solr.client.solrj.impl.ConcurrentUpdateHttp2SolrClient;
import org.apache.solr.client.solrj.impl.Http2SolrClient;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

@Service
public class SolrService {
@Value("${tailormap-api.solr-url}")
private String solrUrl;

@Value("${tailormap-api.solr-core-name:tailormap}")
private String solrCoreName;

/**
* Get a concurrent update Solr client for bulk operations.
*
* @return the Solr client
*/
public SolrClient getSolrClientForIndexing() {
return new ConcurrentUpdateHttp2SolrClient.Builder(
this.solrUrl + this.solrCoreName,
new Http2SolrClient.Builder()
.withFollowRedirects(true)
.withConnectionTimeout(10000, TimeUnit.MILLISECONDS)
.withRequestTimeout(60000, TimeUnit.MILLISECONDS)
.build())
.withQueueSize(SolrHelper.SOLR_BATCH_SIZE * 2)
.withThreadCount(10)
.build();
}

/**
* Get a Solr client for searching.
*
* @return the Solr client
*/
public SolrClient getSolrClientForSearching() {
return new Http2SolrClient.Builder(this.solrUrl + this.solrCoreName)
.withConnectionTimeout(10, TimeUnit.SECONDS)
.withFollowRedirects(true)
.build();
}

public void setSolrUrl(String solrUrl) {
this.solrUrl = solrUrl;
}
}

0 comments on commit 6af4b90

Please sign in to comment.