diff --git a/build-configuration/resources/couchdb.properties b/build-configuration/resources/couchdb.properties index b941d7336c..e5aa374e7c 100644 --- a/build-configuration/resources/couchdb.properties +++ b/build-configuration/resources/couchdb.properties @@ -20,6 +20,7 @@ couchdb.change_logs = sw360changelogs couchdb.config = sw360config couchdb.vulnerability_management = sw360vm lucenesearch.limit = 150 +couchdb.lucene.url = http://localhost:8080/couchdb-lucene # Warning: If you enable lucene leading wildcards you have to enable this configuration also in couchdb-lucene.ini # leading wildcard search is disabled as default because its a expensive operation. diff --git a/build-configuration/test-resources/couchdb.properties b/build-configuration/test-resources/couchdb.properties index 72e71337d9..c7bb8f87c3 100644 --- a/build-configuration/test-resources/couchdb.properties +++ b/build-configuration/test-resources/couchdb.properties @@ -16,3 +16,4 @@ couchdb.usersdb = sw360_test_users couchdb.attachments = sw360_test_attachments couchdb.config = sw360_test_config couchdb.vulnerability_management = sw360_test_vm +couchdb.lucene.url = http://localhost:8080/couchdb-lucene diff --git a/libraries/lib-datahandler/src/main/java/org/eclipse/sw360/datahandler/common/DatabaseSettings.java b/libraries/lib-datahandler/src/main/java/org/eclipse/sw360/datahandler/common/DatabaseSettings.java index 84c51006c1..e81ab0269b 100644 --- a/libraries/lib-datahandler/src/main/java/org/eclipse/sw360/datahandler/common/DatabaseSettings.java +++ b/libraries/lib-datahandler/src/main/java/org/eclipse/sw360/datahandler/common/DatabaseSettings.java @@ -27,6 +27,7 @@ public class DatabaseSettings { public static final String PROPERTIES_FILE_PATH = "/couchdb.properties"; public static final String COUCH_DB_URL; + public static final String COUCH_DB_LUCENE_URL; public static final String COUCH_DB_DATABASE; public static final String COUCH_DB_ATTACHMENTS; public static final String COUCH_DB_CHANGE_LOGS; @@ -44,6 +45,7 @@ public class DatabaseSettings { Properties props = CommonUtils.loadProperties(DatabaseSettings.class, PROPERTIES_FILE_PATH); COUCH_DB_URL = props.getProperty("couchdb.url", "http://localhost:5984"); + COUCH_DB_LUCENE_URL = props.getProperty("couchdb.lucene.url", "http://localhost:8080/couchdb-lucene"); COUCH_DB_DATABASE = props.getProperty("couchdb.database", "sw360db"); COUCH_DB_USERNAME = props.getProperty("couchdb.user", ""); COUCH_DB_PASSWORD = props.getProperty("couchdb.password", ""); diff --git a/libraries/lib-datahandler/src/main/java/org/eclipse/sw360/datahandler/couchdb/lucene/LuceneAwareDatabaseConnector.java b/libraries/lib-datahandler/src/main/java/org/eclipse/sw360/datahandler/couchdb/lucene/LuceneAwareDatabaseConnector.java index 466aa35bdd..359403ca37 100644 --- a/libraries/lib-datahandler/src/main/java/org/eclipse/sw360/datahandler/couchdb/lucene/LuceneAwareDatabaseConnector.java +++ b/libraries/lib-datahandler/src/main/java/org/eclipse/sw360/datahandler/couchdb/lucene/LuceneAwareDatabaseConnector.java @@ -9,11 +9,15 @@ */ package org.eclipse.sw360.datahandler.couchdb.lucene; +import com.github.ldriscoll.ektorplucene.EktorpLuceneObjectMapperFactory; import com.github.ldriscoll.ektorplucene.LuceneAwareCouchDbConnector; import com.github.ldriscoll.ektorplucene.LuceneQuery; import com.github.ldriscoll.ektorplucene.LuceneResult; import com.github.ldriscoll.ektorplucene.util.IndexUploader; import com.google.common.base.Joiner; +import java.net.HttpURLConnection; +import java.net.URL; + import org.apache.log4j.Logger; import org.eclipse.sw360.datahandler.common.DatabaseSettings; import org.eclipse.sw360.datahandler.couchdb.DatabaseConnector; @@ -22,13 +26,15 @@ import org.eclipse.sw360.datahandler.thrift.users.User; import org.ektorp.DbAccessException; import org.ektorp.http.HttpClient; - +import org.ektorp.http.URI; +import org.ektorp.support.DesignDocument; import java.io.IOException; import java.util.*; import java.util.function.Function; import java.util.function.Supplier; import java.util.stream.Collectors; import java.util.stream.Stream; +import com.fasterxml.jackson.databind.ObjectMapper; import static com.google.common.base.Strings.isNullOrEmpty; import static com.google.common.base.Strings.nullToEmpty; @@ -50,7 +56,7 @@ public class LuceneAwareDatabaseConnector extends LuceneAwareCouchDbConnector { private final DatabaseConnector connector; private static final List LUCENE_SPECIAL_CHARACTERS = Arrays.asList("[\\\\\\+\\-\\!\\~\\*\\?\\\"\\^\\:\\(\\)\\{\\}\\[\\]]", "\\&\\&", "\\|\\|"); - + private String dbNameForLuceneSearch; /** * Maximum number of results to return */ @@ -61,6 +67,7 @@ public class LuceneAwareDatabaseConnector extends LuceneAwareCouchDbConnector { */ public LuceneAwareDatabaseConnector(Supplier httpClient, String dbName) throws IOException { this(new DatabaseConnector(httpClient, dbName)); + this.dbNameForLuceneSearch = dbName; } /** @@ -118,10 +125,49 @@ private LuceneResult searchView(LuceneSearchView function, String queryString, b return queryLucene(query); } catch (DbAccessException e) { log.error("Error querying database.", e); + log.info("Trying to call lucene directly"); + try { + LuceneResult callLuceneDirectly = callLuceneDirectly(function, queryString, includeDocs); + return callLuceneDirectly; + } catch (Exception exp) { + log.error("Error querying Lucene directly.", exp); + } return null; } } + private LuceneResult callLuceneDirectly(LuceneSearchView function, String queryString, boolean includeDocs) + throws IOException { + URI queryURI = URI.of("/"); + queryURI.append(DEFAULT_LUCENE_INDEX); + queryURI.append(dbNameForLuceneSearch); + queryURI.append(function.searchView.startsWith(DesignDocument.ID_PREFIX) ? function.searchView + : DesignDocument.ID_PREFIX + function.searchView); + queryURI.append(function.searchFunction); + queryURI.param("include_docs", new Boolean(includeDocs).toString()); + if (resultLimit > 0) { + queryURI.param("limit", resultLimit); + } + queryURI.param("q", queryString.toString()); + URL luceneResourceUrl = new URL(DatabaseSettings.COUCH_DB_LUCENE_URL + queryURI.toString()); + HttpURLConnection connection = null; + try { + connection = (HttpURLConnection) luceneResourceUrl.openConnection(); + connection.setRequestMethod("GET"); + connection.connect(); + int responseCode = connection.getResponseCode(); + if (responseCode == 200) { + ObjectMapper objectMapper = new EktorpLuceneObjectMapperFactory().createObjectMapper(); + return objectMapper.readValue(connection.getInputStream(), LuceneResult.class); + } + } finally { + if (connection != null) { + connection.disconnect(); + } + } + return null; + } + ///////////////////////// // GETTERS AND SETTERS // /////////////////////////