From 04f1650d267c06940d4462fd86b47c5dbe446119 Mon Sep 17 00:00:00 2001 From: alex-odysseus <75131044+alex-odysseus@users.noreply.github.com> Date: Wed, 4 Oct 2023 20:23:12 +0200 Subject: [PATCH] Finalizing externalizing Vocabulary Search Apache Solr implementation (#2308) Referring common Vocabulary Search classes from Standardized Analysis API (org.ohdsi:standardized-analysis-specs:1.5.0) Adding webapi-solr profile and referencing a new webapi-solr repository (org.ohdsi:webapi-solr:1.0.0) Finalizing externalizing the Vocabulary Search Apache Solr implementation ===================================== Additionally fixing a failing unit test CohortResultsServiceTest.prepareGetTimeToEventDrilldown --- pom.xml | 34 +++-- .../HeraclesConfigurationInfo.java | 2 +- .../webapi/conceptset/ConceptSetExport.java | 4 +- .../ohdsi/webapi/info/ConfigurationInfo.java | 16 --- .../org/ohdsi/webapi/info/InfoService.java | 2 +- .../person/PersonConfigurationInfo.java | 2 +- .../plugins/PluginsConfigurationInfo.java | 2 +- .../security/SecurityConfigurationInfo.java | 2 +- .../webapi/service/ConceptSetService.java | 3 +- .../webapi/service/VocabularyService.java | 6 +- .../org/ohdsi/webapi/vocabulary/Concept.java | 48 ------- .../vocabulary/DatabaseSearchProvider.java | 3 + .../webapi/vocabulary/RelatedConcept.java | 2 + .../webapi/vocabulary/SearchProvider.java | 12 -- .../vocabulary/SearchProviderConfig.java | 19 --- .../vocabulary/VocabularySearchService.java | 3 + .../VocabularySearchServiceImpl.java | 2 + .../solr/SolrConfigurationInfo.java | 31 ---- .../vocabulary/solr/SolrSearchClient.java | 78 ---------- .../vocabulary/solr/SolrSearchProvider.java | 134 ------------------ .../getTimeToEventDrilldown-expected.sql | 16 +-- 21 files changed, 55 insertions(+), 366 deletions(-) delete mode 100644 src/main/java/org/ohdsi/webapi/info/ConfigurationInfo.java delete mode 100644 src/main/java/org/ohdsi/webapi/vocabulary/Concept.java delete mode 100644 src/main/java/org/ohdsi/webapi/vocabulary/SearchProvider.java delete mode 100644 src/main/java/org/ohdsi/webapi/vocabulary/SearchProviderConfig.java delete mode 100644 src/main/java/org/ohdsi/webapi/vocabulary/solr/SolrConfigurationInfo.java delete mode 100644 src/main/java/org/ohdsi/webapi/vocabulary/solr/SolrSearchClient.java delete mode 100644 src/main/java/org/ohdsi/webapi/vocabulary/solr/SolrSearchProvider.java diff --git a/pom.xml b/pom.xml index e805c57019..a2a0797cd0 100644 --- a/pom.xml +++ b/pom.xml @@ -66,10 +66,6 @@ 5 false - - - {!complexphrase inOrder=true} - 8.11.2 5 @@ -1131,7 +1127,7 @@ org.ohdsi standardized-analysis-specs - 1.4.0 + 1.5.0 com.fasterxml.jackson.core @@ -1197,12 +1193,6 @@ - - org.apache.solr - solr-solrj - ${solr.version} - jar - com.qmino miredot-annotations @@ -1851,5 +1841,27 @@ + + webapi-solr + + + + {!complexphrase inOrder=true} + 8.11.2 + + + + org.ohdsi + webapi-solr + 1.0.0 + + + org.apache.solr + solr-solrj + ${solr.version} + jar + + + diff --git a/src/main/java/org/ohdsi/webapi/cohortanalysis/HeraclesConfigurationInfo.java b/src/main/java/org/ohdsi/webapi/cohortanalysis/HeraclesConfigurationInfo.java index 76c91d0f4b..11ff69514c 100644 --- a/src/main/java/org/ohdsi/webapi/cohortanalysis/HeraclesConfigurationInfo.java +++ b/src/main/java/org/ohdsi/webapi/cohortanalysis/HeraclesConfigurationInfo.java @@ -1,6 +1,6 @@ package org.ohdsi.webapi.cohortanalysis; -import org.ohdsi.webapi.info.ConfigurationInfo; +import org.ohdsi.info.ConfigurationInfo; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Component; diff --git a/src/main/java/org/ohdsi/webapi/conceptset/ConceptSetExport.java b/src/main/java/org/ohdsi/webapi/conceptset/ConceptSetExport.java index 64b3991705..0941589c83 100644 --- a/src/main/java/org/ohdsi/webapi/conceptset/ConceptSetExport.java +++ b/src/main/java/org/ohdsi/webapi/conceptset/ConceptSetExport.java @@ -6,9 +6,11 @@ package org.ohdsi.webapi.conceptset; import com.fasterxml.jackson.annotation.JsonProperty; + import java.util.Collection; + import org.ohdsi.circe.vocabulary.ConceptSetExpression; -import org.ohdsi.webapi.vocabulary.Concept; +import org.ohdsi.vocabulary.Concept; /** * diff --git a/src/main/java/org/ohdsi/webapi/info/ConfigurationInfo.java b/src/main/java/org/ohdsi/webapi/info/ConfigurationInfo.java deleted file mode 100644 index 1068fc1072..0000000000 --- a/src/main/java/org/ohdsi/webapi/info/ConfigurationInfo.java +++ /dev/null @@ -1,16 +0,0 @@ -package org.ohdsi.webapi.info; - -import java.util.HashMap; -import java.util.Map; - -public abstract class ConfigurationInfo { - - protected final Map properties = new HashMap<>(); - - public abstract String getKey(); - - public Map getProperties() { - - return properties; - } -} diff --git a/src/main/java/org/ohdsi/webapi/info/InfoService.java b/src/main/java/org/ohdsi/webapi/info/InfoService.java index 0613bb5e68..0b0a15a63f 100644 --- a/src/main/java/org/ohdsi/webapi/info/InfoService.java +++ b/src/main/java/org/ohdsi/webapi/info/InfoService.java @@ -24,7 +24,7 @@ import javax.ws.rs.core.MediaType; import org.apache.commons.lang3.StringUtils; -import org.ohdsi.webapi.info.ConfigurationInfo; +import org.ohdsi.info.ConfigurationInfo; import org.springframework.boot.info.BuildProperties; import org.springframework.stereotype.Controller; diff --git a/src/main/java/org/ohdsi/webapi/person/PersonConfigurationInfo.java b/src/main/java/org/ohdsi/webapi/person/PersonConfigurationInfo.java index 355c094245..7eb18772ec 100644 --- a/src/main/java/org/ohdsi/webapi/person/PersonConfigurationInfo.java +++ b/src/main/java/org/ohdsi/webapi/person/PersonConfigurationInfo.java @@ -1,6 +1,6 @@ package org.ohdsi.webapi.person; -import org.ohdsi.webapi.info.ConfigurationInfo; +import org.ohdsi.info.ConfigurationInfo; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Component; diff --git a/src/main/java/org/ohdsi/webapi/plugins/PluginsConfigurationInfo.java b/src/main/java/org/ohdsi/webapi/plugins/PluginsConfigurationInfo.java index d063f74044..e666410504 100644 --- a/src/main/java/org/ohdsi/webapi/plugins/PluginsConfigurationInfo.java +++ b/src/main/java/org/ohdsi/webapi/plugins/PluginsConfigurationInfo.java @@ -1,6 +1,6 @@ package org.ohdsi.webapi.plugins; -import org.ohdsi.webapi.info.ConfigurationInfo; +import org.ohdsi.info.ConfigurationInfo; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Component; diff --git a/src/main/java/org/ohdsi/webapi/security/SecurityConfigurationInfo.java b/src/main/java/org/ohdsi/webapi/security/SecurityConfigurationInfo.java index 36d9274e7e..4eb477ee2c 100644 --- a/src/main/java/org/ohdsi/webapi/security/SecurityConfigurationInfo.java +++ b/src/main/java/org/ohdsi/webapi/security/SecurityConfigurationInfo.java @@ -1,9 +1,9 @@ package org.ohdsi.webapi.security; +import org.ohdsi.info.ConfigurationInfo; import org.ohdsi.webapi.Constants; import org.ohdsi.webapi.shiro.management.AtlasRegularSecurity; import org.ohdsi.webapi.shiro.management.Security; -import org.ohdsi.webapi.info.ConfigurationInfo; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Component; diff --git a/src/main/java/org/ohdsi/webapi/service/ConceptSetService.java b/src/main/java/org/ohdsi/webapi/service/ConceptSetService.java index c2c44c0291..2f80ef991e 100644 --- a/src/main/java/org/ohdsi/webapi/service/ConceptSetService.java +++ b/src/main/java/org/ohdsi/webapi/service/ConceptSetService.java @@ -19,6 +19,7 @@ import java.util.*; import java.util.stream.Collectors; import java.util.stream.StreamSupport; + import javax.transaction.Transactional; import javax.ws.rs.*; import javax.ws.rs.core.MediaType; @@ -26,6 +27,7 @@ import org.apache.shiro.authz.UnauthorizedException; import org.ohdsi.circe.vocabulary.ConceptSetExpression; +import org.ohdsi.vocabulary.Concept; import org.ohdsi.webapi.check.CheckResult; import org.ohdsi.webapi.check.checker.conceptset.ConceptSetChecker; import org.ohdsi.webapi.conceptset.ConceptSet; @@ -56,7 +58,6 @@ import org.ohdsi.webapi.versioning.dto.VersionDTO; import org.ohdsi.webapi.versioning.dto.VersionUpdateDTO; import org.ohdsi.webapi.versioning.service.VersionService; -import org.ohdsi.webapi.vocabulary.Concept; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.core.convert.support.GenericConversionService; diff --git a/src/main/java/org/ohdsi/webapi/service/VocabularyService.java b/src/main/java/org/ohdsi/webapi/service/VocabularyService.java index 651b317928..e034fb41c2 100644 --- a/src/main/java/org/ohdsi/webapi/service/VocabularyService.java +++ b/src/main/java/org/ohdsi/webapi/service/VocabularyService.java @@ -2,8 +2,10 @@ import static org.ohdsi.webapi.service.cscompare.ConceptSetCompareService.CONCEPT_SET_COMPARISON_ROW_MAPPER; import static org.ohdsi.webapi.util.SecurityUtils.whitelist; + import com.google.common.collect.Lists; import com.google.common.collect.Maps; + import java.sql.ResultSet; import java.sql.SQLException; import java.util.*; @@ -34,6 +36,8 @@ import org.ohdsi.circe.vocabulary.ConceptSetExpressionQueryBuilder; import org.ohdsi.sql.SqlRender; import org.ohdsi.sql.SqlTranslate; +import org.ohdsi.vocabulary.Concept; +import org.ohdsi.vocabulary.SearchProviderConfig; import org.ohdsi.webapi.activity.Activity.ActivityType; import org.ohdsi.webapi.activity.Tracker; import org.ohdsi.webapi.conceptset.ConceptSetComparison; @@ -49,7 +53,6 @@ import org.ohdsi.webapi.source.SourceInfo; import org.ohdsi.webapi.util.PreparedSqlRender; import org.ohdsi.webapi.util.PreparedStatementRenderer; -import org.ohdsi.webapi.vocabulary.Concept; import org.ohdsi.webapi.vocabulary.ConceptRecommendedNotInstalledException; import org.ohdsi.webapi.vocabulary.ConceptRelationship; import org.ohdsi.webapi.vocabulary.ConceptSearch; @@ -58,7 +61,6 @@ import org.ohdsi.webapi.vocabulary.RecommendedConcept; import org.ohdsi.webapi.vocabulary.RelatedConcept; import org.ohdsi.webapi.vocabulary.RelatedConceptSearch; -import org.ohdsi.webapi.vocabulary.SearchProviderConfig; import org.ohdsi.webapi.vocabulary.Vocabulary; import org.ohdsi.webapi.vocabulary.VocabularyInfo; import org.ohdsi.webapi.vocabulary.VocabularySearchService; diff --git a/src/main/java/org/ohdsi/webapi/vocabulary/Concept.java b/src/main/java/org/ohdsi/webapi/vocabulary/Concept.java deleted file mode 100644 index 84ae34a944..0000000000 --- a/src/main/java/org/ohdsi/webapi/vocabulary/Concept.java +++ /dev/null @@ -1,48 +0,0 @@ -package org.ohdsi.webapi.vocabulary; - -import com.fasterxml.jackson.annotation.JsonIgnoreProperties; -import com.fasterxml.jackson.annotation.JsonInclude; -import com.fasterxml.jackson.annotation.JsonProperty; -import com.fasterxml.jackson.annotation.JsonPropertyOrder; - -import java.util.Date; -import java.util.Objects; - -@JsonInclude() -@JsonIgnoreProperties(ignoreUnknown = true) -@JsonPropertyOrder({ - "CONCEPT_ID", "CONCEPT_NAME", "STANDARD_CONCEPT", - "STANDARD_CONCEPT_CAPTION", "INVALID_REASON", "INVALID_REASON_CAPTION", - "CONCEPT_CODE", "DOMAIN_ID", "VOCABULARY_ID", "CONCEPT_CLASS_ID", - "VALID_START_DATE", "VALID_END_DATE" -}) -public class Concept extends org.ohdsi.circe.vocabulary.Concept { - - @JsonProperty("VALID_START_DATE") - public Date validStartDate; - - @JsonProperty("VALID_END_DATE") - public Date validEndDate; - - @Override - public boolean equals(Object o) { - if (this == o) { - return true; - } - if (!(o instanceof Concept)) { - return false; - } - final Concept other = (Concept) o; - return Objects.equals(conceptId, other.conceptId) && Objects.equals(conceptName, other.conceptName) && - Objects.equals(standardConcept, other.standardConcept) && Objects.equals(invalidReason, other.invalidReason) && - Objects.equals(conceptCode, other.conceptCode) && Objects.equals(domainId, other.domainId) && - Objects.equals(vocabularyId, other.vocabularyId) && Objects.equals(conceptClassId, other.conceptClassId) && - Objects.equals(validStartDate, other.validStartDate) && Objects.equals(validEndDate, other.validEndDate); - } - - @Override - public int hashCode() { - return Objects.hash(conceptId, conceptName, standardConcept, invalidReason, conceptCode, - domainId, vocabularyId, conceptClassId, validStartDate, validEndDate); - } -} diff --git a/src/main/java/org/ohdsi/webapi/vocabulary/DatabaseSearchProvider.java b/src/main/java/org/ohdsi/webapi/vocabulary/DatabaseSearchProvider.java index a25da3215b..491b47ad40 100644 --- a/src/main/java/org/ohdsi/webapi/vocabulary/DatabaseSearchProvider.java +++ b/src/main/java/org/ohdsi/webapi/vocabulary/DatabaseSearchProvider.java @@ -2,6 +2,9 @@ import java.util.Collection; +import org.ohdsi.vocabulary.Concept; +import org.ohdsi.vocabulary.SearchProvider; +import org.ohdsi.vocabulary.SearchProviderConfig; import org.ohdsi.webapi.service.VocabularyService; import org.ohdsi.webapi.source.Source; import org.ohdsi.webapi.source.SourceRepository; diff --git a/src/main/java/org/ohdsi/webapi/vocabulary/RelatedConcept.java b/src/main/java/org/ohdsi/webapi/vocabulary/RelatedConcept.java index c92495f98c..5951191bfa 100644 --- a/src/main/java/org/ohdsi/webapi/vocabulary/RelatedConcept.java +++ b/src/main/java/org/ohdsi/webapi/vocabulary/RelatedConcept.java @@ -6,6 +6,8 @@ import java.util.ArrayList; +import org.ohdsi.vocabulary.Concept; + /** * * @author fdefalco diff --git a/src/main/java/org/ohdsi/webapi/vocabulary/SearchProvider.java b/src/main/java/org/ohdsi/webapi/vocabulary/SearchProvider.java deleted file mode 100644 index d733ba4d90..0000000000 --- a/src/main/java/org/ohdsi/webapi/vocabulary/SearchProvider.java +++ /dev/null @@ -1,12 +0,0 @@ -package org.ohdsi.webapi.vocabulary; - -import org.ohdsi.webapi.vocabulary.Concept; -import org.ohdsi.webapi.vocabulary.SearchProviderConfig; - -import java.util.Collection; - -public interface SearchProvider { - boolean supports(String vocabularyVersionKey); - int getPriority(); - Collection executeSearch(SearchProviderConfig config, String query, String rows) throws Exception; -} diff --git a/src/main/java/org/ohdsi/webapi/vocabulary/SearchProviderConfig.java b/src/main/java/org/ohdsi/webapi/vocabulary/SearchProviderConfig.java deleted file mode 100644 index 3981645925..0000000000 --- a/src/main/java/org/ohdsi/webapi/vocabulary/SearchProviderConfig.java +++ /dev/null @@ -1,19 +0,0 @@ -package org.ohdsi.webapi.vocabulary; - -public class SearchProviderConfig { - private String sourceKey; - private String versionKey; - - public SearchProviderConfig(String sourceKey, String versionKey) { - this.sourceKey = sourceKey; - this.versionKey = versionKey; - } - - public String getVersionKey() { - return versionKey; - } - - public String getSourceKey() { - return sourceKey; - } -} diff --git a/src/main/java/org/ohdsi/webapi/vocabulary/VocabularySearchService.java b/src/main/java/org/ohdsi/webapi/vocabulary/VocabularySearchService.java index d1866043d0..7815faa840 100644 --- a/src/main/java/org/ohdsi/webapi/vocabulary/VocabularySearchService.java +++ b/src/main/java/org/ohdsi/webapi/vocabulary/VocabularySearchService.java @@ -1,5 +1,8 @@ package org.ohdsi.webapi.vocabulary; +import org.ohdsi.vocabulary.SearchProvider; +import org.ohdsi.vocabulary.SearchProviderConfig; + public interface VocabularySearchService { SearchProvider getSearchProvider(SearchProviderConfig config); } diff --git a/src/main/java/org/ohdsi/webapi/vocabulary/VocabularySearchServiceImpl.java b/src/main/java/org/ohdsi/webapi/vocabulary/VocabularySearchServiceImpl.java index 49aa791917..abbd6309ae 100644 --- a/src/main/java/org/ohdsi/webapi/vocabulary/VocabularySearchServiceImpl.java +++ b/src/main/java/org/ohdsi/webapi/vocabulary/VocabularySearchServiceImpl.java @@ -3,6 +3,8 @@ import java.util.Arrays; import java.util.Comparator; +import org.ohdsi.vocabulary.SearchProvider; +import org.ohdsi.vocabulary.SearchProviderConfig; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.stereotype.Service; diff --git a/src/main/java/org/ohdsi/webapi/vocabulary/solr/SolrConfigurationInfo.java b/src/main/java/org/ohdsi/webapi/vocabulary/solr/SolrConfigurationInfo.java deleted file mode 100644 index 859d0510ee..0000000000 --- a/src/main/java/org/ohdsi/webapi/vocabulary/solr/SolrConfigurationInfo.java +++ /dev/null @@ -1,31 +0,0 @@ -package org.ohdsi.webapi.vocabulary.solr; - -import org.ohdsi.webapi.info.ConfigurationInfo; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Component; - -import java.util.ArrayList; -import java.util.List; - -@Component -public class SolrConfigurationInfo extends ConfigurationInfo { - private static final String KEY = "vocabulary"; - - @Autowired - public SolrConfigurationInfo(SolrSearchClient solrSearchClient) { - properties.put("solrEnabled", true); - if (solrSearchClient.enabled()) { - try { - List cores = new ArrayList<>(solrSearchClient.getCores()); - properties.put("cores", cores); - } catch (Exception e) { - properties.put("cores", "unable to retrieve from endpoint."); - } - } - } - - @Override - public String getKey() { - return KEY; - } -} diff --git a/src/main/java/org/ohdsi/webapi/vocabulary/solr/SolrSearchClient.java b/src/main/java/org/ohdsi/webapi/vocabulary/solr/SolrSearchClient.java deleted file mode 100644 index 6170c9f3f8..0000000000 --- a/src/main/java/org/ohdsi/webapi/vocabulary/solr/SolrSearchClient.java +++ /dev/null @@ -1,78 +0,0 @@ -package org.ohdsi.webapi.vocabulary.solr; - -import java.util.Arrays; -import java.util.HashSet; -import java.util.List; -import org.apache.commons.lang.StringUtils; -import org.apache.solr.client.solrj.SolrClient; -import org.apache.solr.client.solrj.impl.HttpSolrClient; -import org.apache.solr.client.solrj.request.CoreAdminRequest; -import org.apache.solr.client.solrj.response.CoreAdminResponse; -import org.apache.solr.client.solrj.util.ClientUtils; -import org.apache.solr.common.params.CoreAdminParams; -import org.springframework.beans.factory.annotation.Value; -import org.springframework.stereotype.Component; - -@Component -public class SolrSearchClient { - @Value("${solr.endpoint}") - private String solrEndpoint; - - @Value("${solr.query.prefix}") - private String solrQueryPrefix; - - public static final List SOLR_ESCAPE_CHARACTERS = Arrays.asList("(", ")", "{", "}", "[", "]", "^", "\"", ":"); - - public boolean enabled() { - return !StringUtils.isEmpty(solrEndpoint); - } - - public SolrClient getSolrClient(String coreName) { - return new HttpSolrClient.Builder(solrEndpoint + "/" + coreName).build(); - } - - public HashSet getCores() throws Exception { - HashSet returnVal = new HashSet<>(); - SolrClient client = this.getSolrClient(""); - CoreAdminRequest request = new CoreAdminRequest(); - request.setAction(CoreAdminParams.CoreAdminAction.STATUS); - CoreAdminResponse cores; - - try { - cores = request.process(client); - for (int i = 0; i < cores.getCoreStatus().size(); i++) { - returnVal.add(cores.getCoreStatus().getName(i)); - } - } catch (Exception ex) { - throw ex; - } - return returnVal; - } - - public String formatSearchQuery(String query) { - return formatSearchQuery(query, true); - } - - public String formatSearchQuery(String query, Boolean useWildcardSearch) { - String returnVal; - if (useWildcardSearch) { - returnVal = solrQueryPrefix + "query:\"*" + ClientUtils.escapeQueryChars(query) + "*\""; - } else { - returnVal = "query:" + escapeNonWildcardQuery(query); - } - System.out.println(returnVal); - return returnVal; - } - - // This escape function is used when building the non wildcard - // query since the ClientUtils.escapeQueryChars will replace - // add an extra "\" to spaces which can change the query results. - // So, here we escape a subset of the special characters for - // this edge case - public String escapeNonWildcardQuery(String query) { - for (String item : SOLR_ESCAPE_CHARACTERS) { - query = query.replace(item, "\\" + item); - } - return query; - } -} diff --git a/src/main/java/org/ohdsi/webapi/vocabulary/solr/SolrSearchProvider.java b/src/main/java/org/ohdsi/webapi/vocabulary/solr/SolrSearchProvider.java deleted file mode 100644 index ea888e14cf..0000000000 --- a/src/main/java/org/ohdsi/webapi/vocabulary/solr/SolrSearchProvider.java +++ /dev/null @@ -1,134 +0,0 @@ -package org.ohdsi.webapi.vocabulary.solr; - -import org.apache.commons.beanutils.ConvertUtils; -import org.apache.commons.lang3.math.NumberUtils; -import org.apache.commons.lang3.time.DateFormatUtils; -import org.apache.commons.lang3.time.DateUtils; -import org.apache.solr.client.solrj.SolrClient; -import org.apache.solr.client.solrj.SolrQuery; -import org.apache.solr.client.solrj.SolrServerException; -import org.apache.solr.client.solrj.impl.BaseHttpSolrClient.RemoteSolrException; -import org.apache.solr.client.solrj.response.QueryResponse; -import org.apache.solr.common.SolrDocument; -import org.apache.solr.common.SolrDocumentList; -import org.ohdsi.webapi.vocabulary.Concept; -import org.ohdsi.webapi.vocabulary.SearchProviderConfig; -import org.ohdsi.webapi.vocabulary.SearchProvider; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Component; - -import javax.annotation.PostConstruct; -import java.io.IOException; -import java.util.ArrayList; -import java.util.Collection; -import java.util.Date; -import java.util.HashSet; - -@Component -public class SolrSearchProvider implements SearchProvider { - protected final Logger log = LoggerFactory.getLogger(getClass()); - - private static final int SOLR_PRIORITY = 1000; - private static HashSet solrCores = new HashSet<>(); - - @Autowired - SolrSearchClient solrSearchClient; - - @PostConstruct - protected void init() { - if (solrSearchClient.enabled()) { - try { - solrCores = solrSearchClient.getCores(); - } catch (Exception ex) { - log.error("SOLR Core Initialization Error: WebAPI was unable to obtain the list of available cores.", ex); - } - } - } - - @Override - public boolean supports(String vocabularyVersionKey) { - return solrCores.contains(vocabularyVersionKey); - } - - @Override - public int getPriority() { - return SOLR_PRIORITY; - } - - @Override - public Collection executeSearch(SearchProviderConfig config, String query, String rows) throws IOException, SolrServerException { - ArrayList concepts = new ArrayList<>(); - SolrClient client = solrSearchClient.getSolrClient(config.getVersionKey()); - - SolrQuery q = new SolrQuery(); - SolrDocumentList results = new SolrDocumentList(); - QueryResponse response; - q.setStart(0); - q.setRows(Integer.parseInt(rows)); - boolean solrSearchError = false; - try { - q.setQuery(solrSearchClient.formatSearchQuery(query)); - response = client.query(q); - results = response.getResults(); - } catch (RemoteSolrException rse) { - // In this case, the default wildcard search did not work - // properly. Log this error and try an alternative approach. - log.error("SOLR Search Query: \"" + query + "\" failed with message: " + rse.getMessage()); - solrSearchError = true; - } - - // If we did not receive results from issuing the initial wildcard - // query OR there was an exception usually due to a maxBooleanClause - // violation from doing a wildcard search on a very common term, then - // we will make another attempt using the standard query approach - if (results.isEmpty() || solrSearchError) { - q.setQuery(solrSearchClient.formatSearchQuery(query, Boolean.FALSE)); - response = client.query(q); - results = response.getResults(); - } - - for (int i = 0; i < results.size(); ++i) { - SolrDocument d = results.get(i); - Concept c = new Concept(); - c.conceptName = convertObjectToString(d.getFieldValue("concept_name")); - c.conceptId = convertObjectToLong(d.getFieldValue("id")); - c.conceptClassId = convertObjectToString(d.getFieldValue("concept_class_id"), ""); - c.conceptCode = convertObjectToString(d.getFieldValue("concept_code"), ""); - c.domainId = ConvertUtils.convert(d.getFieldValue("domain_id")); - c.invalidReason = convertObjectToString(d.getFieldValue("invalid_reason"), "V"); - c.standardConcept = convertObjectToString(d.getFieldValue("standard_concept"), "N"); - c.vocabularyId = ConvertUtils.convert(d.getFieldValue("vocabulary_id")); - c.validStartDate = convertObjectToDate(d.getFieldValue("valid_start_date")); - c.validEndDate = convertObjectToDate(d.getFieldValue("valid_end_date")); - concepts.add(c); - } - - return concepts; - } - - protected String convertObjectToString(Object obj) { - return convertObjectToString(obj, null); - } - - protected String convertObjectToString(Object obj, String defaultValue) { - String returnVal = ConvertUtils.convert(obj); - if (defaultValue != null && returnVal == null) { - returnVal = defaultValue; - } - return returnVal; - } - - protected Long convertObjectToLong(Object obj) { - return NumberUtils.createLong(ConvertUtils.convert(obj)); - } - - protected Date convertObjectToDate(Object obj) { - try { - return DateUtils.parseDate(ConvertUtils.convert(obj), DateFormatUtils.ISO_8601_EXTENDED_DATE_FORMAT.getPattern()); - } catch (final Exception e) { - return null; - } - } -} diff --git a/src/test/resources/cohortresults/sql/cohortSpecific/getTimeToEventDrilldown-expected.sql b/src/test/resources/cohortresults/sql/cohortSpecific/getTimeToEventDrilldown-expected.sql index 5a27d96f2e..d688134b47 100644 --- a/src/test/resources/cohortresults/sql/cohortSpecific/getTimeToEventDrilldown-expected.sql +++ b/src/test/resources/cohortresults/sql/cohortSpecific/getTimeToEventDrilldown-expected.sql @@ -20,16 +20,16 @@ WITH denominator AS ( SELECT exposure_cohort_definition_id, outcome_cohort_definition_id, - CAST(CASE WHEN isNumeric(stratum_2) = 1 THEN stratum_2 ELSE null END AS INT) as stratum_1, sum(count_value) as count_value + CAST(CASE WHEN analysis_id = 1805 THEN stratum_2 ELSE null END AS INT) as stratum_1, sum(count_value) as count_value FROM result_schema.penelope_results WHERE exposure_cohort_definition_id = ? AND outcome_cohort_definition_id = ? AND analysis_id = 1805 GROUP BY exposure_cohort_definition_id, outcome_cohort_definition_id, - CAST(CASE WHEN isNumeric(stratum_2) = 1 THEN stratum_2 ELSE null END AS INT) + CAST(CASE WHEN analysis_id = 1805 THEN stratum_2 ELSE null END AS INT) ) t0 - WHERE CAST(CASE WHEN isNumeric(stratum_1) = 1 THEN stratum_1 ELSE null END AS INT)<= 10 OR count_value > 0 + WHERE stratum_1 <= 10 OR count_value > 0 GROUP BY exposure_cohort_definition_id, outcome_cohort_definition_id, stratum_1 ) t1 @@ -57,16 +57,16 @@ WITH denominator AS ( SELECT exposure_cohort_definition_id, outcome_cohort_definition_id, - CAST(CASE WHEN isNumeric(stratum_2) = 1 THEN stratum_2 ELSE null END AS INT) as stratum_1, sum(count_value) as count_value + CAST(CASE WHEN analysis_id = 1806 THEN stratum_2 ELSE null END AS INT) as stratum_1, sum(count_value) as count_value FROM result_schema.penelope_results WHERE exposure_cohort_definition_id = ? AND outcome_cohort_definition_id = ? AND analysis_id = 1806 GROUP BY exposure_cohort_definition_id, outcome_cohort_definition_id, - CAST(CASE WHEN isNumeric(stratum_2) = 1 THEN stratum_2 ELSE null END AS INT) + CAST(CASE WHEN analysis_id = 1806 THEN stratum_2 ELSE null END AS INT) ) t0 - WHERE CAST(CASE WHEN isNumeric(stratum_1) = 1 THEN stratum_1 ELSE null END AS INT)<= 10 OR count_value > 0 + WHERE stratum_1 <= 10 OR count_value > 0 GROUP BY exposure_cohort_definition_id, outcome_cohort_definition_id, stratum_1 ) t1 INNER JOIN @@ -88,7 +88,7 @@ numerator_first as ( SELECT exposure_cohort_definition_id, outcome_cohort_definition_id, - CAST(CASE WHEN isNumeric(stratum_1) = 1 THEN stratum_1 ELSE null END AS INT)*30 AS duration, + CAST(CASE WHEN analysis_id = 12 THEN stratum_1 ELSE null END AS INT)*30 AS duration, count_value FROM result_schema.penelope_results WHERE exposure_cohort_definition_id = ? @@ -99,7 +99,7 @@ numerator_all as ( SELECT exposure_cohort_definition_id, outcome_cohort_definition_id, - CAST(CASE WHEN isNumeric(stratum_1) = 1 THEN stratum_1 ELSE null END AS INT)*30 AS duration, + CAST(CASE WHEN analysis_id = 13 THEN stratum_1 ELSE null END AS INT)*30 AS duration, count_value FROM result_schema.penelope_results WHERE exposure_cohort_definition_id = ?