Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

chore(couchdb): Support CouchDb Lucene 2.1.0 with CouchDb 2.1.2 and backward compatibility #926

Merged
merged 1 commit into from
Aug 10, 2020
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
1 change: 1 addition & 0 deletions build-configuration/resources/couchdb.properties
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
1 change: 1 addition & 0 deletions build-configuration/test-resources/couchdb.properties
Original file line number Diff line number Diff line change
Expand Up @@ -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
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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", "");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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;
Expand All @@ -50,7 +56,7 @@ public class LuceneAwareDatabaseConnector extends LuceneAwareCouchDbConnector {
private final DatabaseConnector connector;

private static final List<String> LUCENE_SPECIAL_CHARACTERS = Arrays.asList("[\\\\\\+\\-\\!\\~\\*\\?\\\"\\^\\:\\(\\)\\{\\}\\[\\]]", "\\&\\&", "\\|\\|");

private String dbNameForLuceneSearch;
/**
* Maximum number of results to return
*/
Expand All @@ -61,6 +67,7 @@ public class LuceneAwareDatabaseConnector extends LuceneAwareCouchDbConnector {
*/
public LuceneAwareDatabaseConnector(Supplier<HttpClient> httpClient, String dbName) throws IOException {
this(new DatabaseConnector(httpClient, dbName));
this.dbNameForLuceneSearch = dbName;
}

/**
Expand Down Expand Up @@ -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 //
/////////////////////////
Expand Down