diff --git a/config/alfresco/subsystems/Search/lucene/lucene-search-context.xml b/config/alfresco/subsystems/Search/lucene/lucene-search-context.xml index 6e7f8d6c4f..7aed4fd509 100644 --- a/config/alfresco/subsystems/Search/lucene/lucene-search-context.xml +++ b/config/alfresco/subsystems/Search/lucene/lucene-search-context.xml @@ -139,38 +139,6 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ${dir.indexes} diff --git a/config/alfresco/subsystems/Search/solr/solr-search-context.xml b/config/alfresco/subsystems/Search/solr/solr-search-context.xml index 8f9eb7f88d..861e9b5307 100644 --- a/config/alfresco/subsystems/Search/solr/solr-search-context.xml +++ b/config/alfresco/subsystems/Search/solr/solr-search-context.xml @@ -29,21 +29,37 @@ - - + ${solr.base.url} - - - - + + + + + + + + + + + + + + + + + + + + + + @@ -52,56 +68,97 @@ lucene + + + + + + + + + + + + + + solr-alfresco + + + + + - - - - - - - + - + fts-alfresco + + + - - - - - - - - + + + + solr-fts-alfresco + + + + - - - - - - - + + + solr-cmis + + + + + + + + + + + + + + cmis-alfrecso + + + + + + + + + + + + + + cmis-strict + + + + diff --git a/source/java/org/alfresco/repo/search/impl/solr/SolrAlfrescoFTSQueryLanguage.java b/source/java/org/alfresco/repo/search/impl/solr/SolrAlfrescoFTSQueryLanguage.java deleted file mode 100644 index 76bfde910e..0000000000 --- a/source/java/org/alfresco/repo/search/impl/solr/SolrAlfrescoFTSQueryLanguage.java +++ /dev/null @@ -1,291 +0,0 @@ -/* - * Copyright (C) 2005-2010 Alfresco Software Limited. - * - * This file is part of Alfresco - * - * Alfresco is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Alfresco is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Alfresco. If not, see . - */ -package org.alfresco.repo.search.impl.solr; - -import java.io.BufferedReader; -import java.io.IOException; -import java.io.InputStreamReader; -import java.io.Reader; -import java.io.UnsupportedEncodingException; -import java.util.List; -import java.util.Locale; - -import javax.servlet.http.HttpServletResponse; - -import org.alfresco.repo.domain.node.NodeDAO; -import org.alfresco.repo.search.impl.lucene.ADMLuceneSearcherImpl; -import org.alfresco.repo.search.impl.lucene.AbstractLuceneQueryLanguage; -import org.alfresco.repo.search.impl.lucene.LuceneQueryParserException; -import org.alfresco.repo.search.impl.lucene.SolrJSONResultSet; -import org.alfresco.repo.security.authentication.AuthenticationUtil; -import org.alfresco.service.cmr.repository.datatype.DefaultTypeConverter; -import org.alfresco.service.cmr.search.ResultSet; -import org.alfresco.service.cmr.search.ResultSetRow; -import org.alfresco.service.cmr.search.SearchParameters; -import org.alfresco.service.cmr.search.SearchService; -import org.alfresco.service.cmr.search.SearchParameters.SortDefinition; -import org.alfresco.service.cmr.security.PermissionService; -import org.apache.commons.codec.net.URLCodec; -import org.apache.commons.httpclient.HttpClient; -import org.apache.commons.httpclient.HttpException; -import org.apache.commons.httpclient.UsernamePasswordCredentials; -import org.apache.commons.httpclient.auth.AuthScope; -import org.apache.commons.httpclient.methods.ByteArrayRequestEntity; -import org.apache.commons.httpclient.methods.PostMethod; -import org.apache.commons.httpclient.methods.RequestEntity; -import org.apache.commons.httpclient.params.HttpClientParams; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.json.JSONArray; -import org.json.JSONException; -import org.json.JSONObject; -import org.json.JSONTokener; -import org.springframework.extensions.surf.util.I18NUtil; - -/** - * @author Andy - */ -public class SolrAlfrescoFTSQueryLanguage extends AbstractSolrQueryLanguage -{ - static Log s_logger = LogFactory.getLog(SolrAlfrescoFTSQueryLanguage.class); - - private NodeDAO nodeDAO; - - private PermissionService permissionService; - - public SolrAlfrescoFTSQueryLanguage() - { - this.setName(SearchService.LANGUAGE_SOLR_FTS_ALFRESCO); - } - - /** - * @param nodeDAO the nodeDAO to set - */ - public void setNodeDAO(NodeDAO nodeDAO) - { - this.nodeDAO = nodeDAO; - } - - /** - * @param permissionService the permissionService to set - */ - public void setPermissionService(PermissionService permissionService) - { - this.permissionService = permissionService; - } - - /* - * (non-Javadoc) - * @seeorg.alfresco.repo.search.impl.lucene.LuceneQueryLanguageSPI#executeQuery(org.alfresco.service.cmr.search. - * SearchParameters, org.alfresco.repo.search.impl.lucene.ADMLuceneSearcherImpl) - */ - @Override - public ResultSet executeQuery(SearchParameters searchParameters, ADMLuceneSearcherImpl admLuceneSearcher) - { - try - { - HttpClient httpClient = new HttpClient(); - httpClient.getParams().setBooleanParameter(HttpClientParams.PREEMPTIVE_AUTHENTICATION, true); - httpClient.getState().setCredentials(new AuthScope(AuthScope.ANY_HOST, AuthScope.ANY_PORT), new UsernamePasswordCredentials("admin", "admin")); - - URLCodec encoder = new URLCodec(); - StringBuilder url = new StringBuilder(); - url.append(getBaseUrl()); - url.append("/alfresco/afts"); - //duplicate the query in the URL - url.append("?q="); - - url.append(encoder.encode(searchParameters.getQuery(), "UTF-8")); - url.append("&wt=").append(encoder.encode("json", "UTF-8")); - url.append("&fl=").append(encoder.encode("*,score", "UTF-8")); - if(searchParameters.getMaxItems() > 0) - { - url.append("&rows=").append(encoder.encode(""+searchParameters.getMaxItems(), "UTF-8")); - } - else - { - url.append("&rows=").append(encoder.encode(""+Integer.MAX_VALUE, "UTF-8")); - } - url.append("&df=").append(encoder.encode(searchParameters.getDefaultFieldName(), "UTF-8")); - url.append("&start=").append(encoder.encode(""+searchParameters.getSkipCount(), "UTF-8")); - - Locale locale = I18NUtil.getLocale(); - if(searchParameters.getLocales().size() > 0) - { - locale = searchParameters.getLocales().get(0); - } - url.append("&locale="); - url.append(encoder.encode(locale.toString(), "UTF-8")); - - StringBuffer sortBuffer = new StringBuffer(); - for(SortDefinition sortDefinition : searchParameters.getSortDefinitions()) - { - if(sortBuffer.length() == 0) - { - sortBuffer.append("&sort="); - } - else - { - sortBuffer.append(encoder.encode(", ", "UTF-8")); - } - sortBuffer.append(encoder.encode(sortDefinition.getField(), "UTF-8")).append(encoder.encode(" ", "UTF-8")); - if(sortDefinition.isAscending()) - { - sortBuffer.append(encoder.encode("asc", "UTF-8")); - } - else - { - sortBuffer.append(encoder.encode("desc", "UTF-8")); - } - - } - url.append(sortBuffer); - - // Authorities go over in body - - StringBuilder authQuery = new StringBuilder(); - for(String authority : permissionService.getAuthorisations()) - { - if(authQuery.length() > 0) - { - authQuery.append(" "); - } - authQuery.append("AUTHORITY:\"").append(authority).append("\""); - } - - //url.append("&fq="); - //encoder = new URLCodec(); - //url.append(encoder.encode(authQuery.toString(), "UTF-8")); - - url.append("&fq=").append(encoder.encode("{!afts}AUTHORITY_FILTER_FROM_JSON", "UTF-8")); - - // facets would go on url? - - JSONObject body = new JSONObject(); - body.put("query", searchParameters.getQuery()); - //body.put("defaultField", searchParameters.getDefaultFieldName()); - - body.put("filter", authQuery); - - JSONArray locales = new JSONArray(); - for(Locale currentLocale : searchParameters.getLocales()) - { - locales.put(DefaultTypeConverter.INSTANCE.convert(String.class, currentLocale)); - } - if(locales.length() == 0) - { - locales.put(I18NUtil.getLocale()); - } - body.put("locales", locales); - - JSONArray templates = new JSONArray(); - for(String templateName : searchParameters.getQueryTemplates().keySet()) - { - JSONObject template = new JSONObject(); - template.put("name", templateName); - template.put("template", searchParameters.getQueryTemplates().get(templateName)); - templates.put(template); - } - body.put("templates", templates); - - JSONArray allAttributes = new JSONArray(); - for(String attribute : searchParameters.getAllAttributes()) - { - allAttributes.put(attribute); - } - body.put("allAttributes", allAttributes); - - body.put("defaultFTSOperator", searchParameters.getDefaultFTSOperator()); - body.put("defaultFTSFieldOperator", searchParameters.getDefaultFTSFieldOperator()); - if(searchParameters.getMlAnalaysisMode() != null) - { - body.put("mlAnalaysisMode", searchParameters.getMlAnalaysisMode().toString()); - } - body.put("defaultNamespace", searchParameters.getNamespace()); - - - JSONArray textAttributes = new JSONArray(); - for(String attribute : searchParameters.getTextAttributes()) - { - textAttributes.put(attribute); - } - body.put("textAttributes", textAttributes); - - PostMethod post = new PostMethod(url.toString()); - post.setRequestEntity(new ByteArrayRequestEntity(body.toString().getBytes("UTF-8"), "application/json")); - - httpClient.executeMethod(post); - - if (post.getStatusCode() != HttpServletResponse.SC_OK) - { - throw new LuceneQueryParserException("Request failed " + post.getStatusCode()+" "+url.toString()); - } - - - Reader reader = new BufferedReader(new InputStreamReader(post.getResponseBodyAsStream())); - // TODO - replace with streaming-based solution e.g. SimpleJSON ContentHandler - JSONObject json = new JSONObject(new JSONTokener(reader)); - SolrJSONResultSet results = new SolrJSONResultSet(json, nodeDAO, searchParameters); - if(s_logger.isDebugEnabled()) - { - s_logger.debug("Sent :"+url); - s_logger.debug(" with: "+body.toString()); - s_logger.debug("Got: "+results.getNumberFound()+ " in "+results.getQueryTime()+ " ms"); - } - - return results; - } - catch (UnsupportedEncodingException e) - { - throw new LuceneQueryParserException("", e); - } - catch (HttpException e) - { - throw new LuceneQueryParserException("", e); - } - catch (IOException e) - { - throw new LuceneQueryParserException("", e); - } - catch (JSONException e) - { - throw new LuceneQueryParserException("", e); - } - } - - public static void main(String[] args) - { - SolrAlfrescoFTSQueryLanguage solrAlfrescoFTSQueryLanguage = new SolrAlfrescoFTSQueryLanguage(); - SearchParameters sp = new SearchParameters(); - sp.setQuery("PATH:\"//.\""); - sp.setMaxItems(100); - sp.setSkipCount(12); - ResultSet rs = solrAlfrescoFTSQueryLanguage.executeQuery(sp, null); - System.out.println("Found "+rs.length()); - System.out.println("More "+rs.hasMore()); - System.out.println("Start "+rs.getStart()); - - for(ResultSetRow row : rs) - { - System.out.println("Score "+row.getScore()); - } - rs.close(); - } - -} diff --git a/source/java/org/alfresco/repo/search/impl/solr/SolrAlfrescoQueryLanguage.java b/source/java/org/alfresco/repo/search/impl/solr/SolrAlfrescoQueryLanguage.java deleted file mode 100644 index a069f766a5..0000000000 --- a/source/java/org/alfresco/repo/search/impl/solr/SolrAlfrescoQueryLanguage.java +++ /dev/null @@ -1,292 +0,0 @@ -/* - * Copyright (C) 2005-2010 Alfresco Software Limited. - * - * This file is part of Alfresco - * - * Alfresco is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Alfresco is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Alfresco. If not, see . - */ -package org.alfresco.repo.search.impl.solr; - -import java.io.BufferedReader; -import java.io.IOException; -import java.io.InputStreamReader; -import java.io.Reader; -import java.io.UnsupportedEncodingException; -import java.util.List; -import java.util.Locale; - -import javax.servlet.http.HttpServletResponse; - -import org.alfresco.repo.domain.node.NodeDAO; -import org.alfresco.repo.search.impl.lucene.ADMLuceneSearcherImpl; -import org.alfresco.repo.search.impl.lucene.AbstractLuceneQueryLanguage; -import org.alfresco.repo.search.impl.lucene.LuceneQueryParserException; -import org.alfresco.repo.search.impl.lucene.SolrJSONResultSet; -import org.alfresco.repo.security.authentication.AuthenticationUtil; -import org.alfresco.service.cmr.repository.datatype.DefaultTypeConverter; -import org.alfresco.service.cmr.search.ResultSet; -import org.alfresco.service.cmr.search.ResultSetRow; -import org.alfresco.service.cmr.search.SearchParameters; -import org.alfresco.service.cmr.search.SearchService; -import org.alfresco.service.cmr.search.SearchParameters.SortDefinition; -import org.alfresco.service.cmr.security.PermissionService; -import org.apache.commons.codec.net.URLCodec; -import org.apache.commons.httpclient.HttpClient; -import org.apache.commons.httpclient.HttpException; -import org.apache.commons.httpclient.UsernamePasswordCredentials; -import org.apache.commons.httpclient.auth.AuthScope; -import org.apache.commons.httpclient.methods.ByteArrayRequestEntity; -import org.apache.commons.httpclient.methods.PostMethod; -import org.apache.commons.httpclient.methods.RequestEntity; -import org.apache.commons.httpclient.params.HttpClientParams; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.json.JSONArray; -import org.json.JSONException; -import org.json.JSONObject; -import org.json.JSONTokener; -import org.springframework.extensions.surf.util.I18NUtil; - -/** - * @author Andy - */ -public class SolrAlfrescoQueryLanguage extends AbstractSolrQueryLanguage -{ - static Log s_logger = LogFactory.getLog(SolrAlfrescoQueryLanguage.class); - - private NodeDAO nodeDAO; - - private PermissionService permissionService; - - public SolrAlfrescoQueryLanguage() - { - this.setName(SearchService.LANGUAGE_SOLR_ALFRESCO); - } - - /** - * @param nodeDAO the nodeDAO to set - */ - public void setNodeDAO(NodeDAO nodeDAO) - { - this.nodeDAO = nodeDAO; - } - - /** - * @param permissionService the permissionService to set - */ - public void setPermissionService(PermissionService permissionService) - { - this.permissionService = permissionService; - } - - /* - * (non-Javadoc) - * @seeorg.alfresco.repo.search.impl.lucene.LuceneQueryLanguageSPI#executeQuery(org.alfresco.service.cmr.search. - * SearchParameters, org.alfresco.repo.search.impl.lucene.ADMLuceneSearcherImpl) - */ - @Override - public ResultSet executeQuery(SearchParameters searchParameters, ADMLuceneSearcherImpl admLuceneSearcher) - { - try - { - HttpClient httpClient = new HttpClient(); - httpClient.getParams().setBooleanParameter(HttpClientParams.PREEMPTIVE_AUTHENTICATION, true); - httpClient.getState().setCredentials(new AuthScope(AuthScope.ANY_HOST, AuthScope.ANY_PORT), new UsernamePasswordCredentials("admin", "admin")); - - URLCodec encoder = new URLCodec(); - StringBuilder url = new StringBuilder(); - url.append(getBaseUrl()); - url.append("/alfresco/alfresco"); - //duplicate the query in the URL - //duplicate the query in the URL - url.append("?q="); - - url.append(encoder.encode(searchParameters.getQuery(), "UTF-8")); - url.append("&wt=").append(encoder.encode("json", "UTF-8")); - url.append("&fl=").append(encoder.encode("*,score", "UTF-8")); - if(searchParameters.getMaxItems() > 0) - { - url.append("&rows=").append(encoder.encode(""+searchParameters.getMaxItems(), "UTF-8")); - } - else - { - url.append("&rows=").append(encoder.encode(""+Integer.MAX_VALUE, "UTF-8")); - } - url.append("&df=").append(encoder.encode(searchParameters.getDefaultFieldName(), "UTF-8")); - url.append("&start=").append(encoder.encode(""+searchParameters.getSkipCount(), "UTF-8")); - - Locale locale = I18NUtil.getLocale(); - if(searchParameters.getLocales().size() > 0) - { - locale = searchParameters.getLocales().get(0); - } - url.append("&locale="); - url.append(encoder.encode(locale.toString(), "UTF-8")); - - StringBuffer sortBuffer = new StringBuffer(); - for(SortDefinition sortDefinition : searchParameters.getSortDefinitions()) - { - if(sortBuffer.length() == 0) - { - sortBuffer.append("&sort="); - } - else - { - sortBuffer.append(encoder.encode(", ", "UTF-8")); - } - sortBuffer.append(encoder.encode(sortDefinition.getField(), "UTF-8")).append(encoder.encode(" ", "UTF-8")); - if(sortDefinition.isAscending()) - { - sortBuffer.append(encoder.encode("asc", "UTF-8")); - } - else - { - sortBuffer.append(encoder.encode("desc", "UTF-8")); - } - - } - url.append(sortBuffer); - - // Authorities go over in body - - StringBuilder authQuery = new StringBuilder(); - for(String authority : permissionService.getAuthorisations()) - { - if(authQuery.length() > 0) - { - authQuery.append(" "); - } - authQuery.append("AUTHORITY:\"").append(authority).append("\""); - } - - //url.append("&fq="); - //encoder = new URLCodec(); - //url.append(encoder.encode(authQuery.toString(), "UTF-8")); - - url.append("&fq=").append(encoder.encode("{!afts}AUTHORITY_FILTER_FROM_JSON", "UTF-8")); - - // facets would go on url? - - JSONObject body = new JSONObject(); - body.put("query", searchParameters.getQuery()); - //body.put("defaultField", searchParameters.getDefaultFieldName()); - - body.put("filter", authQuery); - - JSONArray locales = new JSONArray(); - for(Locale currentLocale : searchParameters.getLocales()) - { - locales.put(DefaultTypeConverter.INSTANCE.convert(String.class, currentLocale)); - } - if(locales.length() == 0) - { - locales.put(I18NUtil.getLocale()); - } - body.put("locales", locales); - - JSONArray templates = new JSONArray(); - for(String templateName : searchParameters.getQueryTemplates().keySet()) - { - JSONObject template = new JSONObject(); - template.put("name", templateName); - template.put("template", searchParameters.getQueryTemplates().get(templateName)); - templates.put(template); - } - body.put("templates", templates); - - JSONArray allAttributes = new JSONArray(); - for(String attribute : searchParameters.getAllAttributes()) - { - allAttributes.put(attribute); - } - body.put("allAttributes", allAttributes); - - body.put("defaultFTSOperator", searchParameters.getDefaultFTSOperator()); - body.put("defaultFTSFieldOperator", searchParameters.getDefaultFTSFieldOperator()); - if(searchParameters.getMlAnalaysisMode() != null) - { - body.put("mlAnalaysisMode", searchParameters.getMlAnalaysisMode().toString()); - } - body.put("defaultNamespace", searchParameters.getNamespace()); - - - JSONArray textAttributes = new JSONArray(); - for(String attribute : searchParameters.getTextAttributes()) - { - textAttributes.put(attribute); - } - body.put("textAttributes", textAttributes); - - PostMethod post = new PostMethod(url.toString()); - post.setRequestEntity(new ByteArrayRequestEntity(body.toString().getBytes("UTF-8"), "application/json")); - - httpClient.executeMethod(post); - - if (post.getStatusCode() != HttpServletResponse.SC_OK) - { - throw new LuceneQueryParserException("Request failed " + post.getStatusCode()+" "+url.toString()); - } - - - Reader reader = new BufferedReader(new InputStreamReader(post.getResponseBodyAsStream())); - // TODO - replace with streaming-based solution e.g. SimpleJSON ContentHandler - JSONObject json = new JSONObject(new JSONTokener(reader)); - SolrJSONResultSet results = new SolrJSONResultSet(json, nodeDAO, searchParameters); - if(s_logger.isDebugEnabled()) - { - s_logger.debug("Sent :"+url); - s_logger.debug(" with: "+body.toString()); - s_logger.debug("Got: "+results.getNumberFound()+ " in "+results.getQueryTime()+ " ms"); - } - - return results; - } - catch (UnsupportedEncodingException e) - { - throw new LuceneQueryParserException("", e); - } - catch (HttpException e) - { - throw new LuceneQueryParserException("", e); - } - catch (IOException e) - { - throw new LuceneQueryParserException("", e); - } - catch (JSONException e) - { - throw new LuceneQueryParserException("", e); - } - } - - public static void main(String[] args) - { - SolrAlfrescoQueryLanguage solrAlfrescoFTSQueryLanguage = new SolrAlfrescoQueryLanguage(); - SearchParameters sp = new SearchParameters(); - sp.setQuery("PATH:\"//.\""); - sp.setMaxItems(100); - sp.setSkipCount(12); - ResultSet rs = solrAlfrescoFTSQueryLanguage.executeQuery(sp, null); - System.out.println("Found "+rs.length()); - System.out.println("More "+rs.hasMore()); - System.out.println("Start "+rs.getStart()); - - for(ResultSetRow row : rs) - { - System.out.println("Score "+row.getScore()); - } - rs.close(); - } - -} diff --git a/source/java/org/alfresco/repo/search/impl/solr/SolrCMISQueryLanguage.java b/source/java/org/alfresco/repo/search/impl/solr/SolrQueryHTTPClient.java similarity index 64% rename from source/java/org/alfresco/repo/search/impl/solr/SolrCMISQueryLanguage.java rename to source/java/org/alfresco/repo/search/impl/solr/SolrQueryHTTPClient.java index ff1f6375e4..cf2bd0573e 100644 --- a/source/java/org/alfresco/repo/search/impl/solr/SolrCMISQueryLanguage.java +++ b/source/java/org/alfresco/repo/search/impl/solr/SolrQueryHTTPClient.java @@ -24,24 +24,23 @@ import java.io.InputStreamReader; import java.io.Reader; import java.io.UnsupportedEncodingException; import java.util.Locale; +import java.util.Map; import javax.servlet.http.HttpServletResponse; +import org.alfresco.error.AlfrescoRuntimeException; import org.alfresco.repo.domain.node.NodeDAO; -import org.alfresco.repo.search.impl.lucene.ADMLuceneSearcherImpl; -import org.alfresco.repo.search.impl.lucene.AbstractLuceneQueryLanguage; import org.alfresco.repo.search.impl.lucene.LuceneQueryParserException; import org.alfresco.repo.search.impl.lucene.SolrJSONResultSet; import org.alfresco.service.cmr.repository.datatype.DefaultTypeConverter; import org.alfresco.service.cmr.search.ResultSet; -import org.alfresco.service.cmr.search.ResultSetRow; import org.alfresco.service.cmr.search.SearchParameters; import org.alfresco.service.cmr.search.SearchParameters.SortDefinition; -import org.alfresco.service.cmr.search.SearchService; import org.alfresco.service.cmr.security.PermissionService; import org.apache.commons.codec.net.URLCodec; import org.apache.commons.httpclient.HttpClient; import org.apache.commons.httpclient.HttpException; +import org.apache.commons.httpclient.MultiThreadedHttpConnectionManager; import org.apache.commons.httpclient.UsernamePasswordCredentials; import org.apache.commons.httpclient.auth.AuthScope; import org.apache.commons.httpclient.methods.ByteArrayRequestEntity; @@ -58,85 +57,109 @@ import org.springframework.extensions.surf.util.I18NUtil; /** * @author Andy */ -public class SolrCMISQueryLanguage extends AbstractSolrQueryLanguage +public class SolrQueryHTTPClient { - static Log s_logger = LogFactory.getLog(SolrCMISQueryLanguage.class); + static Log s_logger = LogFactory.getLog(SolrQueryHTTPClient.class); private NodeDAO nodeDAO; private PermissionService permissionService; - public SolrCMISQueryLanguage() + private Map languageMappings; + + private Map storeMappings; + + private String baseUrl; + + private HttpClient httpClient; + + public SolrQueryHTTPClient() { - this.setName(SearchService.LANGUAGE_SOLR_CMIS); + MultiThreadedHttpConnectionManager connectionManager = new MultiThreadedHttpConnectionManager(); + httpClient = new HttpClient(connectionManager); + httpClient.getParams().setBooleanParameter(HttpClientParams.PREEMPTIVE_AUTHENTICATION, true); + httpClient.getState().setCredentials(new AuthScope(AuthScope.ANY_HOST, AuthScope.ANY_PORT), new UsernamePasswordCredentials("admin", "admin")); } - - /** - * @param nodeDAO - * the nodeDAO to set - */ + public void setNodeDAO(NodeDAO nodeDAO) { this.nodeDAO = nodeDAO; } - /** - * @param permissionService - * the permissionService to set - */ public void setPermissionService(PermissionService permissionService) { this.permissionService = permissionService; } - /* - * (non-Javadoc) - * @seeorg.alfresco.repo.search.impl.lucene.LuceneQueryLanguageSPI#executeQuery(org.alfresco.service.cmr.search. - * SearchParameters, org.alfresco.repo.search.impl.lucene.ADMLuceneSearcherImpl) - */ - @Override - public ResultSet executeQuery(SearchParameters searchParameters, ADMLuceneSearcherImpl admLuceneSearcher) + public void setLanguageMappings(Map languageMappings) + { + this.languageMappings = languageMappings; + } + + public void setStoreMappings(Map storeMappings) + { + this.storeMappings = storeMappings; + } + + public void setBaseUrl(String baseUrl) + { + this.baseUrl = baseUrl; + } + + public ResultSet executeQuery(SearchParameters searchParameters, String language) { try { - HttpClient httpClient = new HttpClient(); - httpClient.getParams().setBooleanParameter(HttpClientParams.PREEMPTIVE_AUTHENTICATION, true); - httpClient.getState().setCredentials(new AuthScope(AuthScope.ANY_HOST, AuthScope.ANY_PORT), new UsernamePasswordCredentials("admin", "admin")); URLCodec encoder = new URLCodec(); StringBuilder url = new StringBuilder(); - url.append(getBaseUrl()); - url.append("/alfresco/cmis"); - //duplicate the query in the URL - //duplicate the query in the URL + url.append(baseUrl); + if (searchParameters.getStores().size() == 0) + { + throw new AlfrescoRuntimeException("No store for query"); + } + String storeUrlFragment = storeMappings.get(searchParameters.getStores().get(0).toString()); + if (storeUrlFragment == null) + { + throw new AlfrescoRuntimeException("No solr query support for store " + searchParameters.getStores().get(0).toString()); + } + url.append("/").append(storeUrlFragment); + String languageUrlFragment = languageMappings.get(language); + if (languageUrlFragment == null) + { + throw new AlfrescoRuntimeException("No solr query support for language " + language); + } + url.append("/").append(languageUrlFragment); + + // duplicate the query in the URL url.append("?q="); - + url.append(encoder.encode(searchParameters.getQuery(), "UTF-8")); url.append("&wt=").append(encoder.encode("json", "UTF-8")); url.append("&fl=").append(encoder.encode("*,score", "UTF-8")); - if(searchParameters.getMaxItems() > 0) + if (searchParameters.getMaxItems() > 0) { - url.append("&rows=").append(encoder.encode(""+searchParameters.getMaxItems(), "UTF-8")); + url.append("&rows=").append(encoder.encode("" + searchParameters.getMaxItems(), "UTF-8")); } else { - url.append("&rows=").append(encoder.encode(""+Integer.MAX_VALUE, "UTF-8")); + url.append("&rows=").append(encoder.encode("" + Integer.MAX_VALUE, "UTF-8")); } url.append("&df=").append(encoder.encode(searchParameters.getDefaultFieldName(), "UTF-8")); - url.append("&start=").append(encoder.encode(""+searchParameters.getSkipCount(), "UTF-8")); - + url.append("&start=").append(encoder.encode("" + searchParameters.getSkipCount(), "UTF-8")); + Locale locale = I18NUtil.getLocale(); - if(searchParameters.getLocales().size() > 0) + if (searchParameters.getLocales().size() > 0) { locale = searchParameters.getLocales().get(0); } url.append("&locale="); url.append(encoder.encode(locale.toString(), "UTF-8")); - + StringBuffer sortBuffer = new StringBuffer(); - for(SortDefinition sortDefinition : searchParameters.getSortDefinitions()) + for (SortDefinition sortDefinition : searchParameters.getSortDefinitions()) { - if(sortBuffer.length() == 0) + if (sortBuffer.length() == 0) { sortBuffer.append("&sort="); } @@ -145,7 +168,7 @@ public class SolrCMISQueryLanguage extends AbstractSolrQueryLanguage sortBuffer.append(encoder.encode(", ", "UTF-8")); } sortBuffer.append(encoder.encode(sortDefinition.getField(), "UTF-8")).append(encoder.encode(" ", "UTF-8")); - if(sortDefinition.isAscending()) + if (sortDefinition.isAscending()) { sortBuffer.append(encoder.encode("asc", "UTF-8")); } @@ -153,26 +176,26 @@ public class SolrCMISQueryLanguage extends AbstractSolrQueryLanguage { sortBuffer.append(encoder.encode("desc", "UTF-8")); } - + } url.append(sortBuffer); - + // Authorities go over in body - + StringBuilder authQuery = new StringBuilder(); - for(String authority : permissionService.getAuthorisations()) + for (String authority : permissionService.getAuthorisations()) { - if(authQuery.length() > 0) + if (authQuery.length() > 0) { authQuery.append(" "); } authQuery.append("AUTHORITY:\"").append(authority).append("\""); } - - //url.append("&fq="); - //encoder = new URLCodec(); - //url.append(encoder.encode(authQuery.toString(), "UTF-8")); - + + // url.append("&fq="); + // encoder = new URLCodec(); + // url.append(encoder.encode(authQuery.toString(), "UTF-8")); + url.append("&fq=").append(encoder.encode("{!afts}AUTHORITY_FILTER_FROM_JSON", "UTF-8")); // facets would go on url? @@ -194,7 +217,6 @@ public class SolrCMISQueryLanguage extends AbstractSolrQueryLanguage } body.put("locales", locales); - // templates etc may affect CONTAINS() clause JSONArray templates = new JSONArray(); for (String templateName : searchParameters.getQueryTemplates().keySet()) { @@ -230,25 +252,32 @@ public class SolrCMISQueryLanguage extends AbstractSolrQueryLanguage PostMethod post = new PostMethod(url.toString()); post.setRequestEntity(new ByteArrayRequestEntity(body.toString().getBytes("UTF-8"), "application/json")); - httpClient.executeMethod(post); - - if (post.getStatusCode() != HttpServletResponse.SC_OK) + try { - throw new LuceneQueryParserException("Request failed " + post.getStatusCode() + " " + url.toString()); - } + httpClient.executeMethod(post); - Reader reader = new BufferedReader(new InputStreamReader(post.getResponseBodyAsStream())); - // TODO - replace with streaming-based solution e.g. SimpleJSON ContentHandler - JSONObject json = new JSONObject(new JSONTokener(reader)); - SolrJSONResultSet results = new SolrJSONResultSet(json, nodeDAO, searchParameters); - if (s_logger.isDebugEnabled()) + if (post.getStatusCode() != HttpServletResponse.SC_OK) + { + throw new LuceneQueryParserException("Request failed " + post.getStatusCode() + " " + url.toString()); + } + + Reader reader = new BufferedReader(new InputStreamReader(post.getResponseBodyAsStream())); + // TODO - replace with streaming-based solution e.g. SimpleJSON ContentHandler + JSONObject json = new JSONObject(new JSONTokener(reader)); + SolrJSONResultSet results = new SolrJSONResultSet(json, nodeDAO, searchParameters); + if (s_logger.isDebugEnabled()) + { + s_logger.debug("Sent :" + url); + s_logger.debug(" with: " + body.toString()); + s_logger.debug("Got: " + results.getNumberFound() + " in " + results.getQueryTime() + " ms"); + } + + return results; + } + finally { - s_logger.debug("Sent :" + url); - s_logger.debug(" with: " + body.toString()); - s_logger.debug("Got: " + results.getNumberFound() + " in " + results.getQueryTime() + " ms"); + post.releaseConnection(); } - - return results; } catch (UnsupportedEncodingException e) { @@ -268,23 +297,4 @@ public class SolrCMISQueryLanguage extends AbstractSolrQueryLanguage } } - public static void main(String[] args) - { - SolrCMISQueryLanguage solrAlfrescoFTSQueryLanguage = new SolrCMISQueryLanguage(); - SearchParameters sp = new SearchParameters(); - sp.setQuery("PATH:\"//.\""); - sp.setMaxItems(100); - sp.setSkipCount(12); - ResultSet rs = solrAlfrescoFTSQueryLanguage.executeQuery(sp, null); - System.out.println("Found " + rs.length()); - System.out.println("More " + rs.hasMore()); - System.out.println("Start " + rs.getStart()); - - for (ResultSetRow row : rs) - { - System.out.println("Score " + row.getScore()); - } - rs.close(); - } - } diff --git a/source/java/org/alfresco/repo/search/impl/solr/AbstractSolrQueryLanguage.java b/source/java/org/alfresco/repo/search/impl/solr/SolrQueryLanguage.java similarity index 52% rename from source/java/org/alfresco/repo/search/impl/solr/AbstractSolrQueryLanguage.java rename to source/java/org/alfresco/repo/search/impl/solr/SolrQueryLanguage.java index 40efd9e1ef..1a1d694ddd 100644 --- a/source/java/org/alfresco/repo/search/impl/solr/AbstractSolrQueryLanguage.java +++ b/source/java/org/alfresco/repo/search/impl/solr/SolrQueryLanguage.java @@ -18,25 +18,35 @@ */ package org.alfresco.repo.search.impl.solr; +import org.alfresco.repo.search.impl.lucene.ADMLuceneSearcherImpl; import org.alfresco.repo.search.impl.lucene.AbstractLuceneQueryLanguage; +import org.alfresco.service.cmr.search.ResultSet; +import org.alfresco.service.cmr.search.SearchParameters; /** * @author Andy * */ -public abstract class AbstractSolrQueryLanguage extends AbstractLuceneQueryLanguage +public class SolrQueryLanguage extends AbstractLuceneQueryLanguage { - private String baseUrl; + private SolrQueryHTTPClient solrQueryHTTPClient; - public String getBaseUrl() - { - return baseUrl; - } - - public void setBaseUrl(String baseUrl) - { - this.baseUrl = baseUrl; - } + public void setSolrQueryHTTPClient(SolrQueryHTTPClient solrQueryHTTPClient) + { + this.solrQueryHTTPClient = solrQueryHTTPClient; + } + + + + /* (non-Javadoc) + * @see org.alfresco.repo.search.impl.lucene.LuceneQueryLanguageSPI#executeQuery(org.alfresco.service.cmr.search.SearchParameters, org.alfresco.repo.search.impl.lucene.ADMLuceneSearcherImpl) + */ + @Override + public ResultSet executeQuery(SearchParameters searchParameters, ADMLuceneSearcherImpl admLuceneSearcher) + { + return solrQueryHTTPClient.executeQuery(searchParameters, getName()); + } + }