blob: 596a06c1ff8261439a2d8b5621f90485d4b7b440 [file] [log] [blame]
/*******************************************************************************
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*******************************************************************************/
package org.apache.ofbiz.solr;
import java.io.IOException;
import java.net.ConnectException;
import java.net.MalformedURLException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import org.apache.commons.lang.StringUtils;
import org.apache.solr.client.solrj.SolrQuery;
import org.apache.solr.client.solrj.SolrServerException;
import org.apache.solr.client.solrj.impl.HttpSolrClient;
import org.apache.solr.client.solrj.response.FacetField;
import org.apache.solr.client.solrj.response.FacetField.Count;
import org.apache.solr.client.solrj.response.QueryResponse;
import org.apache.solr.client.solrj.response.SpellCheckResponse.Suggestion;
import org.apache.solr.common.SolrInputDocument;
import org.apache.ofbiz.base.util.Debug;
import org.apache.ofbiz.base.util.UtilGenerics;
import org.apache.ofbiz.base.util.UtilMisc;
import org.apache.ofbiz.base.util.UtilProperties;
import org.apache.ofbiz.base.util.UtilValidate;
import org.apache.ofbiz.entity.Delegator;
import org.apache.ofbiz.entity.GenericDelegator;
import org.apache.ofbiz.entity.GenericEntityException;
import org.apache.ofbiz.entity.GenericValue;
import org.apache.ofbiz.service.DispatchContext;
import org.apache.ofbiz.service.GenericServiceException;
import org.apache.ofbiz.service.LocalDispatcher;
import org.apache.ofbiz.service.ServiceAuthException;
import org.apache.ofbiz.service.ServiceUtil;
import org.apache.ofbiz.service.ServiceValidationException;
/**
* Base class for OFBiz Test Tools test case implementations.
*/
public abstract class SolrProductSearch {
public static final String module = SolrProductSearch.class.getName();
public static final String resource = "SolrUiLabels";
/**
* Adds product to solr, with product denoted by productId field in instance attribute
* - intended for use with ECAs/SECAs.
*/
public static Map<String, Object> addToSolr(DispatchContext dctx, Map<String, Object> context) throws GenericEntityException {
Map<String, Object> result;
LocalDispatcher dispatcher = dctx.getDispatcher();
Delegator delegator = dctx.getDelegator();
GenericValue productInstance = (GenericValue) context.get("instance");
String productId = (String) productInstance.get("productId");
String solrIndexName = (String) context.get("indexName");
if (SolrUtil.isSolrEcaEnabled()) {
// Debug.logVerbose("Solr: addToSolr: Running indexing for productId '" + productId + "'", module);
try {
GenericValue product = delegator.findOne("Product", UtilMisc.toMap("productId", productId), false);
Map<String, Object> dispatchContext = ProductUtil.getProductContent(product, dctx, context);
dispatchContext.put("treatConnectErrorNonFatal", SolrUtil.isEcaTreatConnectErrorNonFatal());
dispatchContext.put("indexName", solrIndexName);
Map<String, Object> runResult = dispatcher.runSync("addToSolrIndex", dispatchContext);
String runMsg = ServiceUtil.getErrorMessage(runResult);
if (UtilValidate.isEmpty(runMsg)) {
runMsg = null;
}
if (ServiceUtil.isError(runResult)) {
result = ServiceUtil.returnError(runMsg);
}
else if (ServiceUtil.isFailure(runResult)) {
result = ServiceUtil.returnFailure(runMsg);
}
else {
result = ServiceUtil.returnSuccess();
}
} catch (GenericEntityException gee) {
Debug.logError(gee, gee.getMessage(), module);
result = ServiceUtil.returnError(gee.toString());
} catch (GenericServiceException gse) {
Debug.logError(gse, gse.getMessage(), module);
result = ServiceUtil.returnError(gse.toString());
} catch (Exception e) {
Debug.logError(e, e.getMessage(), module);
result = ServiceUtil.returnError(e.toString());
}
}
else {
final String statusMsg = "Solr ECA indexing disabled; skipping indexing for productId '" + productId + "'";
Debug.logVerbose("Solr: addToSolr: " + statusMsg, module);
result = ServiceUtil.returnSuccess();
}
return result;
}
/**
* Adds product to solr index.
*/
public static Map<String, Object> addToSolrIndex(DispatchContext dctx, Map<String, Object> context) throws GenericEntityException {
HttpSolrClient client = null;
Locale locale = (Locale)context.get("locale");
Map<String, Object> result;
String productId = (String) context.get("productId");
String solrIndexName = (String) context.get("indexName");
// connectErrorNonFatal is a necessary option because in some cases it may be considered normal that solr server is unavailable;
// don't want to return error and abort transactions in these cases.
Boolean treatConnectErrorNonFatal = (Boolean) context.get("treatConnectErrorNonFatal");
try {
Debug.logInfo("Solr: Generating and indexing document for productId '" + productId + "'", module);
client = SolrUtil.getInstance().getHttpSolrClient(solrIndexName);
//Debug.log(server.ping().toString());
// Construct Documents
SolrInputDocument doc1 = SolrUtil.generateSolrDocument(context);
Collection<SolrInputDocument> docs = new ArrayList<SolrInputDocument>();
if (Debug.verboseOn()) {
Debug.logVerbose("Solr: Indexing document: " + doc1.toString(), module);
}
docs.add(doc1);
// push Documents to server
client.add(docs);
client.commit();
final String statusStr = UtilProperties.getMessage(resource, "SolrDocumentForProductIdAddedToSolrIndex", UtilMisc.toMap("productId", context.get("productId")), locale);
Debug.logInfo("Solr: " + statusStr, module);
result = ServiceUtil.returnSuccess(statusStr);
} catch (MalformedURLException e) {
Debug.logError(e, e.getMessage(), module);
result = ServiceUtil.returnError(e.toString());
result.put("errorType", "urlError");
} catch (SolrServerException e) {
if (e.getCause() != null && e.getCause() instanceof ConnectException) {
final String statusStr = UtilProperties.getMessage(resource, "SolrFailureConnectingToSolrServerToCommitProductId", UtilMisc.toMap("productId", context.get("productId")), locale);
if (Boolean.TRUE.equals(treatConnectErrorNonFatal)) {
Debug.logWarning(e, "Solr: " + statusStr, module);
result = ServiceUtil.returnFailure(statusStr);
}
else {
Debug.logError(e, "Solr: " + statusStr, module);
result = ServiceUtil.returnError(statusStr);
}
result.put("errorType", "connectError");
}
else {
Debug.logError(e, e.getMessage(), module);
result = ServiceUtil.returnError(e.toString());
result.put("errorType", "solrServerError");
}
} catch (IOException e) {
Debug.logError(e, e.getMessage(), module);
result = ServiceUtil.returnError(e.toString());
result.put("errorType", "ioError");
} finally {
if (client != null) {
try {
client.close();
} catch (IOException e) {
// do nothing
}
}
}
return result;
}
/**
* Adds a List of products to the solr index.
* <p>
* This is faster than reflushing the index each time.
*/
public static Map<String, Object> addListToSolrIndex(DispatchContext dctx, Map<String, Object> context) throws GenericEntityException {
String solrIndexName = (String) context.get("indexName");
Locale locale = (Locale) context.get("locale");
HttpSolrClient client = null;
Map<String, Object> result;
Boolean treatConnectErrorNonFatal = (Boolean) context.get("treatConnectErrorNonFatal");
try {
Collection<SolrInputDocument> docs = new ArrayList<SolrInputDocument>();
// Construct Documents
List<Map<String, Object>> fieldList = UtilGenerics.<Map<String, Object>>checkList(context.get("fieldList"));
Debug.logInfo("Solr: Generating and adding " + fieldList.size() + " documents to solr index", module);
for (Iterator<Map<String, Object>> fieldListIterator = fieldList.iterator(); fieldListIterator.hasNext();) {
SolrInputDocument doc1 = SolrUtil.generateSolrDocument(fieldListIterator.next());
if (Debug.verboseOn()) {
Debug.logVerbose("Solr: Indexing document: " + doc1.toString(), module);
}
docs.add(doc1);
}
// push Documents to server
client = SolrUtil.getInstance().getHttpSolrClient(solrIndexName);
client.add(docs);
client.commit();
final String statusStr = UtilProperties.getMessage(resource, "SolrAddedDocumentsToSolrIndex", UtilMisc.toMap("fieldList", fieldList.size()), locale);
Debug.logInfo("Solr: " + statusStr, module);
result = ServiceUtil.returnSuccess(statusStr);
} catch (MalformedURLException e) {
Debug.logError(e, e.getMessage(), module);
result = ServiceUtil.returnError(e.toString());
result.put("errorType", "urlError");
} catch (SolrServerException e) {
if (e.getCause() != null && e.getCause() instanceof ConnectException) {
final String statusStr = UtilProperties.getMessage(resource, "SolrFailureConnectingToSolrServerToCommitProductList", UtilMisc.toMap("productId", context.get("productId")), locale);
if (Boolean.TRUE.equals(treatConnectErrorNonFatal)) {
Debug.logWarning(e, "Solr: " + statusStr, module);
result = ServiceUtil.returnFailure(statusStr);
}
else {
Debug.logError(e, "Solr: " + statusStr, module);
result = ServiceUtil.returnError(statusStr);
}
result.put("errorType", "connectError");
}
else {
Debug.logError(e, e.getMessage(), module);
result = ServiceUtil.returnError(e.toString());
result.put("errorType", "solrServerError");
}
} catch (IOException e) {
Debug.logError(e, e.getMessage(), module);
result = ServiceUtil.returnError(e.toString());
result.put("errorType", "ioError");
} finally {
if (client != null) {
try {
client.close();
} catch (IOException e) {
// do nothing
}
}
}
return result;
}
/**
* Runs a query on the Solr Search Engine and returns the results.
* <p>
* This function only returns an object of type QueryResponse, so it is probably not a good idea to call it directly from within the
* groovy files (As a decent example on how to use it, however, use keywordSearch instead).
*/
public static Map<String, Object> runSolrQuery(DispatchContext dctx, Map<String, Object> context) {
// get Connection
HttpSolrClient client = null;
String solrIndexName = (String) context.get("indexName");
Map<String, Object> result;
try {
client = SolrUtil.getInstance().getHttpSolrClient(solrIndexName);
// create Query Object
SolrQuery solrQuery = new SolrQuery();
solrQuery.setQuery((String) context.get("query"));
// solrQuery.setQueryType("dismax");
boolean faceted = (Boolean) context.get("facet");
if (faceted) {
solrQuery.setFacet(faceted);
solrQuery.addFacetField("manu");
solrQuery.addFacetField("cat");
solrQuery.setFacetMinCount(1);
solrQuery.setFacetLimit(8);
solrQuery.addFacetQuery("listPrice:[0 TO 50]");
solrQuery.addFacetQuery("listPrice:[50 TO 100]");
solrQuery.addFacetQuery("listPrice:[100 TO 250]");
solrQuery.addFacetQuery("listPrice:[250 TO 500]");
solrQuery.addFacetQuery("listPrice:[500 TO 1000]");
solrQuery.addFacetQuery("listPrice:[1000 TO 2500]");
solrQuery.addFacetQuery("listPrice:[2500 TO 5000]");
solrQuery.addFacetQuery("listPrice:[5000 TO 10000]");
solrQuery.addFacetQuery("listPrice:[10000 TO 50000]");
solrQuery.addFacetQuery("listPrice:[50000 TO *]");
}
boolean spellCheck = (Boolean) context.get("spellcheck");
if(spellCheck){
solrQuery.setParam("spellcheck", spellCheck);
}
boolean highLight = (Boolean) context.get("highlight");
if (highLight) {
solrQuery.setHighlight(highLight);
solrQuery.setHighlightSimplePre("<span class=\"highlight\">");
solrQuery.addHighlightField("description");
solrQuery.setHighlightSimplePost("</span>");
solrQuery.setHighlightSnippets(2);
}
// Set additional Parameter
// SolrQuery.ORDER order = SolrQuery.ORDER.desc;
if (context.get("viewIndex") != null && (Integer) context.get("viewIndex") > 0) {
solrQuery.setStart((Integer) context.get("viewIndex"));
}
if (context.get("viewSize") != null && (Integer) context.get("viewSize") > 0) {
solrQuery.setRows((Integer) context.get("viewSize"));
}
// if ((List) context.get("queryFilter") != null && ((ArrayList<SolrDocument>) context.get("queryFilter")).size() > 0) {
// List filter = (List) context.get("queryFilter");
// String[] tn = new String[filter.size()];
// Iterator it = filter.iterator();
// for (int i = 0; i < filter.size(); i++) {
// tn[i] = (String) filter.get(i);
// }
// solrQuery.setFilterQueries(tn);
// }
String queryFilter = (String) context.get("queryFilter");
if(UtilValidate.isNotEmpty(queryFilter))
solrQuery.setFilterQueries(queryFilter.split(" "));
if ((String) context.get("returnFields") != null) {
solrQuery.setFields((String) context.get("returnFields"));
}
// if((Boolean)context.get("sortByReverse"))order.reverse();
if ((String) context.get("sortBy") != null && ((String) context.get("sortBy")).length() > 0) {
SolrQuery.ORDER order;
if (!((Boolean) context.get("sortByReverse")))
order = SolrQuery.ORDER.asc;
else
order = SolrQuery.ORDER.desc;
solrQuery.setSort(((String) context.get("sortBy")).replaceFirst("-", ""), order);
}
if ((String) context.get("facetQuery") != null) {
solrQuery.addFacetQuery((String) context.get("facetQuery"));
}
QueryResponse rsp = client.query(solrQuery);
result = ServiceUtil.returnSuccess();
result.put("queryResult", rsp);
} catch (Exception e) {
Debug.logError(e, e.getMessage(), module);
result = ServiceUtil.returnError(e.toString());
} finally {
if (client != null) {
try {
client.close();
} catch (IOException e) {
// do nothing
}
}
}
return result;
}
/**
* Performs solr products search.
*/
public static Map<String, Object> productsSearch(DispatchContext dctx, Map<String, Object> context) {
Map<String, Object> result;
Locale locale = (Locale) context.get("locale");
LocalDispatcher dispatcher = dctx.getDispatcher();
String solrIndexName = (String) context.get("indexName");
try {
Map<String, Object> dispatchMap = new HashMap<String, Object>();
if (UtilValidate.isNotEmpty(context.get("productCategoryId"))){
String productCategoryId = (String) context.get("productCategoryId");
dispatchMap.put("query", "cat:*" + productCategoryId+"*");
}
else
return ServiceUtil.returnError(UtilProperties.getMessage(resource, "SolrMissingProductCategoryId", locale));
if (context.get("viewSize") != null)
dispatchMap.put("viewSize", Integer.parseInt(((String) context.get("viewSize"))));
if (context.get("viewIndex") != null)
dispatchMap.put("viewIndex", Integer.parseInt((String) context.get("viewIndex")));
if (context.get("queryFilter") != null)
dispatchMap.put("queryFilter", context.get("queryFilter"));
dispatchMap.put("facet", false);
dispatchMap.put("spellcheck", true);
dispatchMap.put("highlight", true);
dispatchMap.put("indexName", solrIndexName);
Map<String, Object> searchResult = dispatcher.runSync("runSolrQuery", dispatchMap);
QueryResponse queryResult = (QueryResponse) searchResult.get("queryResult");
result = ServiceUtil.returnSuccess();
result.put("results", queryResult.getResults());
result.put("listSize", queryResult.getResults().getNumFound());
result.put("viewIndex", queryResult.getResults().getStart());
result.put("viewSize", queryResult.getResults().size());
} catch (Exception e) {
Debug.logError(e, e.getMessage(), module);
result = ServiceUtil.returnError(e.toString());
}
return result;
}
/**
* Performs keyword search.
* <p>
* The search form requires the result to be in a specific layout, so this will generate the proper results.
*/
public static Map<String, Object> keywordSearch(DispatchContext dctx, Map<String, Object> context) {
Map<String, Object> result;
LocalDispatcher dispatcher = dctx.getDispatcher();
String solrIndexName = (String) context.get("indexName");
try {
if (context.get("query") == null || context.get("query").equals(""))
context.put("query", "*:*");
Map<String, Object> dispatchMap = new HashMap<String, Object>();
if (context.get("viewSize") != null)
dispatchMap.put("viewSize", Integer.parseInt(((String) context.get("viewSize"))));
if (context.get("viewIndex") != null)
dispatchMap.put("viewIndex", Integer.parseInt((String) context.get("viewIndex")));
if (context.get("query") != null)
dispatchMap.put("query", context.get("query"));
if (context.get("queryFilter") != null)
dispatchMap.put("queryFilter", context.get("queryFilter"));
dispatchMap.put("spellcheck", true);
dispatchMap.put("indexName", solrIndexName);
Map<String, Object> searchResult = dispatcher.runSync("runSolrQuery", dispatchMap);
QueryResponse queryResult = (QueryResponse) searchResult.get("queryResult");
List<List<String>> suggestions = new ArrayList<List<String>>();
if (queryResult.getSpellCheckResponse() != null && queryResult.getSpellCheckResponse().getSuggestions() != null) {
Iterator<Suggestion> iter = queryResult.getSpellCheckResponse().getSuggestions().iterator();
while (iter.hasNext()) {
Suggestion resultDoc = iter.next();
Debug.logInfo("Suggestion " + resultDoc.getAlternatives(), module);
suggestions.add(resultDoc.getAlternatives());
}
}
Boolean isCorrectlySpelled = true;
if (queryResult.getSpellCheckResponse() != null) {
isCorrectlySpelled = queryResult.getSpellCheckResponse().isCorrectlySpelled();
}
result = ServiceUtil.returnSuccess();
result.put("isCorrectlySpelled", isCorrectlySpelled);
Map<String, Integer> facetQuery = queryResult.getFacetQuery();
Map<String, String> facetQueries = new HashMap<String, String>();
for (String fq : facetQuery.keySet()) {
if (facetQuery.get(fq).intValue() > 0)
facetQueries.put(fq, fq.replaceAll("^.*\\u005B(.*)\\u005D", "$1") + " (" + facetQuery.get(fq).intValue() + ")");
}
Map<String, Map<String, Long>> facetFields = new HashMap<String, Map<String, Long>>();
List<FacetField> facets = queryResult.getFacetFields();
for (FacetField facet : facets) {
Map<String, Long> facetEntry = new HashMap<String, Long>();
List<FacetField.Count> facetEntries = facet.getValues();
if (UtilValidate.isNotEmpty(facetEntries)) {
for (FacetField.Count fcount : facetEntries)
facetEntry.put(fcount.getName(), fcount.getCount());
facetFields.put(facet.getName(), facetEntry);
}
}
result.put("results", queryResult.getResults());
result.put("facetFields", facetFields);
result.put("facetQueries", facetQueries);
result.put("queryTime", queryResult.getElapsedTime());
result.put("listSize", queryResult.getResults().getNumFound());
result.put("viewIndex", queryResult.getResults().getStart());
result.put("viewSize", queryResult.getResults().size());
result.put("suggestions", suggestions);
} catch (Exception e) {
Debug.logError(e, e.getMessage(), module);
result = ServiceUtil.returnError(e.toString());
}
return result;
}
/**
* Returns a map of the categories currently available under the root element.
*/
public static Map<String, Object> getAvailableCategories(DispatchContext dctx, Map<String, Object> context) {
Map<String, Object> result;
String solrIndexName = (String) context.get("indexName");
try {
boolean displayProducts = false;
if (UtilValidate.isNotEmpty(context.get("displayProducts")))
displayProducts = (Boolean) context.get("displayProducts");
int viewIndex = 0;
int viewSize = 9;
if (displayProducts) {
viewIndex = (Integer) context.get("viewIndex");
viewSize = (Integer) context.get("viewSize");
}
String catalogId = null;
if (UtilValidate.isNotEmpty(context.get("catalogId")))
catalogId = (String) context.get("catalogId");
String productCategoryId = (String) context.get("productCategoryId") != null ? CategoryUtil.getCategoryNameWithTrail((String) context.get("productCategoryId"),dctx) : null;
Debug.logInfo("productCategoryId " + productCategoryId, module);
Map<String, Object> query = SolrUtil.categoriesAvailable(catalogId, productCategoryId, (String) context.get("productId"), displayProducts, viewIndex, viewSize, solrIndexName);
QueryResponse cat = (QueryResponse) query.get("rows");
result = ServiceUtil.returnSuccess();
result.put("numFound", (long) 0);
Map<String, Object> categories = new HashMap<String, Object>();
List<FacetField> catList = (List<FacetField>) cat.getFacetFields();
for (Iterator<FacetField> catIterator = catList.iterator(); catIterator.hasNext();) {
FacetField field = (FacetField) catIterator.next();
List<Count> catL = (List<Count>) field.getValues();
if (catL != null) {
// Debug.logInfo("FacetFields = " + catL, module);
for (Iterator<Count> catIter = catL.iterator(); catIter.hasNext();) {
FacetField.Count f = (FacetField.Count) catIter.next();
if (f.getCount() > 0) {
categories.put(f.getName(), Long.toString(f.getCount()));
}
}
result.put("categories", categories);
result.put("numFound", cat.getResults().getNumFound());
// Debug.logInfo("The returned map is this:" + result, module);
}
}
} catch (Exception e) {
result = ServiceUtil.returnError(e.toString());
result.put("numFound", (long) 0);
}
return result;
}
/**
* Return a map of the side deep categories.
*/
public static Map<String, Object> getSideDeepCategories(DispatchContext dctx, Map<String, Object> context) {
Map<String, Object> result;
String solrIndexName = (String) context.get("indexName");
try {
String catalogId = null;
if (UtilValidate.isNotEmpty(context.get("catalogId")))
catalogId = (String) context.get("catalogId");
String productCategoryId = (String) context.get("productCategoryId") != null ? CategoryUtil.getCategoryNameWithTrail((String) context.get("productCategoryId"),dctx) : null;
result = ServiceUtil.returnSuccess();
Map<String, List<Map<String, Object>>> catLevel = new HashMap<String, List<Map<String, Object>>>();
Debug.logInfo("productCategoryId: "+productCategoryId, module);
//Add toplevel categories
String[] trailElements = productCategoryId.split("/");
//iterate over actual results
for(String elements : trailElements){
//catIds must be greater than 3 chars
if(elements.length()>3){
Debug.logInfo("elements: "+elements,module);
String categoryPath = CategoryUtil.getCategoryNameWithTrail(elements,dctx);
String[] categoryPathArray = categoryPath.split("/");
int level = Integer.parseInt(categoryPathArray[0]);
String facetQuery = CategoryUtil.getFacetFilterForCategory(categoryPath, dctx);
//Debug.logInfo("categoryPath: "+categoryPath + " facetQuery: "+facetQuery,module);
Map<String, Object> query = SolrUtil.categoriesAvailable(catalogId, categoryPath, null, facetQuery, false, 0, 0, solrIndexName);
QueryResponse cat = (QueryResponse) query.get("rows");
List<Map<String, Object>> categories = new ArrayList<Map<String, Object>>();
List<FacetField> catList = (List<FacetField>) cat.getFacetFields();
for (Iterator<FacetField> catIterator = catList.iterator(); catIterator.hasNext();) {
FacetField field = (FacetField) catIterator.next();
List<Count> catL = (List<Count>) field.getValues();
if (catL != null) {
for (Iterator<Count> catIter = catL.iterator(); catIter.hasNext();) {
FacetField.Count f = (FacetField.Count) catIter.next();
if (f.getCount() > 0) {
Map<String, Object> catMap = new HashMap<String, Object>();
LinkedList<String> iName = new LinkedList<String>();
iName.addAll(Arrays.asList(f.getName().split("/")));
//Debug.logInfo("topLevel "+topLevel,"");
// int l = Integer.parseInt((String) iName.getFirst());
catMap.put("catId",iName.getLast());
iName.removeFirst();
String path = f.getName();
catMap.put("path",path);
if(level>0){
iName.removeLast();
catMap.put("parentCategory",StringUtils.join(iName, "/"));
}else{
catMap.put("parentCategory",null);
}
catMap.put("count", Long.toString(f.getCount()));
categories.add(catMap);
}
}
}
}
catLevel.put("menu-"+level, categories);
}
}
result.put("categories", catLevel);
result.put("numFound", (long) 0);
} catch (Exception e) {
result = ServiceUtil.returnError(e.toString());
result.put("numFound", (long) 0);
}
return result;
}
/**
* Rebuilds the solr index.
*/
public static Map<String, Object> rebuildSolrIndex(DispatchContext dctx, Map<String, Object> context) throws GenericEntityException {
HttpSolrClient client = null;
Map<String, Object> result;
GenericDelegator delegator = (GenericDelegator) dctx.getDelegator();
LocalDispatcher dispatcher = dctx.getDispatcher();
GenericValue userLogin = (GenericValue) context.get("userLogin");
Locale locale = (Locale) context.get("locale");
String solrIndexName = (String) context.get("indexName");
Boolean treatConnectErrorNonFatal = (Boolean) context.get("treatConnectErrorNonFatal");
try {
client = SolrUtil.getInstance().getHttpSolrClient(solrIndexName);
// now lets fetch all products
List<Map<String, Object>> solrDocs = new ArrayList<Map<String, Object>>();
List<GenericValue> products = delegator.findList("Product", null, null, null, null, true);
int numDocs = 0;
if (products != null) {
numDocs = products.size();
}
Debug.logInfo("Solr: Clearing solr index and rebuilding with " + numDocs + " found products", module);
Iterator<GenericValue> productIterator = products.iterator();
while (productIterator.hasNext()) {
GenericValue product = productIterator.next();
Map<String, Object> dispatchContext = ProductUtil.getProductContent(product, dctx, context);
solrDocs.add(dispatchContext);
}
// this removes everything from the index
client.deleteByQuery("*:*");
client.commit();
// THis adds all products to the Index (instantly)
Map<String, Object> runResult = dispatcher.runSync("addListToSolrIndex", UtilMisc.toMap("fieldList", solrDocs, "userLogin", userLogin,
"locale", locale, "indexName", solrIndexName, "treatConnectErrorNonFatal", treatConnectErrorNonFatal));
String runMsg = ServiceUtil.getErrorMessage(runResult);
if (UtilValidate.isEmpty(runMsg)) {
runMsg = null;
}
if (ServiceUtil.isError(runResult)) {
result = ServiceUtil.returnError(runMsg);
}
else if (ServiceUtil.isFailure(runResult)) {
result = ServiceUtil.returnFailure(runMsg);
}
else {
final String statusMsg = UtilProperties.getMessage(resource, "SolrClearedSolrIndexAndReindexedDocuments", UtilMisc.toMap("numDocs", numDocs), locale);
result = ServiceUtil.returnSuccess(statusMsg);
}
} catch (MalformedURLException e) {
Debug.logError(e, e.getMessage(), module);
result = ServiceUtil.returnError(e.toString());
} catch (SolrServerException e) {
if (e.getCause() != null && e.getCause() instanceof ConnectException) {
final String statusStr = UtilProperties.getMessage(resource, "SolrFailureConnectingToSolrServerToRebuildIndex", locale);
if (Boolean.TRUE.equals(treatConnectErrorNonFatal)) {
Debug.logWarning(e, "Solr: " + statusStr, module);
result = ServiceUtil.returnFailure(statusStr);
}
else {
Debug.logError(e, "Solr: " + statusStr, module);
result = ServiceUtil.returnError(statusStr);
}
}
else {
Debug.logError(e, e.getMessage(), module);
result = ServiceUtil.returnError(e.toString());
}
} catch (IOException e) {
Debug.logError(e, e.getMessage(), module);
result = ServiceUtil.returnError(e.toString());
} catch (ServiceAuthException e) {
Debug.logError(e, e.getMessage(), module);
result = ServiceUtil.returnError(e.toString());
} catch (ServiceValidationException e) {
Debug.logError(e, e.getMessage(), module);
result = ServiceUtil.returnError(e.toString());
} catch (GenericServiceException e) {
Debug.logError(e, e.getMessage(), module);
result = ServiceUtil.returnError(e.toString());
} catch (Exception e) {
Debug.logError(e, e.getMessage(), module);
result = ServiceUtil.returnError(e.toString());
} finally {
if (client != null) {
try {
client.close();
} catch (IOException e) {
// do nothing
}
}
}
return result;
}
}