Author: jacopoc
Date: Mon Oct 14 14:42:53 2013 New Revision: 1531918 URL: http://svn.apache.org/r1531918 Log: Implemented a series of ecas to submit for indexing products when product related information is added/updated/deleted. Thanks to Scott Gray for the initial implementation of these ecas. Added: ofbiz/trunk/specialpurpose/lucene/entitydef/ ofbiz/trunk/specialpurpose/lucene/entitydef/eecas_product.xml (with props) Modified: ofbiz/trunk/specialpurpose/lucene/ofbiz-component.xml ofbiz/trunk/specialpurpose/lucene/servicedef/services.xml ofbiz/trunk/specialpurpose/lucene/src/org/ofbiz/content/search/ProductIndexer.java ofbiz/trunk/specialpurpose/lucene/src/org/ofbiz/content/search/SearchServices.java Added: ofbiz/trunk/specialpurpose/lucene/entitydef/eecas_product.xml URL: http://svn.apache.org/viewvc/ofbiz/trunk/specialpurpose/lucene/entitydef/eecas_product.xml?rev=1531918&view=auto ============================================================================== --- ofbiz/trunk/specialpurpose/lucene/entitydef/eecas_product.xml (added) +++ ofbiz/trunk/specialpurpose/lucene/entitydef/eecas_product.xml Mon Oct 14 14:42:53 2013 @@ -0,0 +1,72 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- +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. +--> + +<entity-eca xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="http://ofbiz.apache.org/dtds/entity-eca.xsd"> + + <!-- Product Keyword Indexing ECAs --> + <eca entity="Product" operation="create-store-remove" event="return"> + <action service="indexProduct" mode="sync"/> + </eca> + <eca entity="ProductFeatureAppl" operation="create-store-remove" event="return"> + <action service="indexProduct" mode="sync"/> + </eca> + <eca entity="ProductAttribute" operation="create-store-remove" event="return"> + <action service="indexProduct" mode="sync"/> + </eca> + <eca entity="GoodIndentification" operation="create-store-remove" event="return"> + <action service="indexProduct" mode="sync"/> + </eca> + <eca entity="ProductContent" operation="create-store-remove" event="return"> + <action service="indexProduct" mode="sync"/> + </eca> + <eca entity="ProductCategoryMember" operation="create-store-remove" event="return"> + <action service="indexProduct" mode="sync"/> + </eca> + <eca entity="ProductPrice" operation="create-store-remove" event="return"> + <action service="indexProduct" mode="sync"/> + </eca> + <eca entity="SupplierProduct" operation="create-store-remove" event="return"> + <action service="indexProduct" mode="sync"/> + </eca> + + <eca entity="ProductAssoc" operation="create-store-remove" event="return"> + <action service="indexProductsFromProductAssoc" mode="sync"/> + </eca> + <eca entity="DataResource" operation="store" event="return"> + <action service="indexProductsFromDataResource" mode="sync"/> + </eca> + <eca entity="Content" operation="store" event="return"> + <action service="indexProductsFromContent" mode="sync"/> + </eca> + <eca entity="ProductCategoryRollup" operation="create-store-remove" event="return"> + <action service="indexProductsFromCategory" mode="sync"/> + </eca> + <eca entity="ProdCatalogCategory" operation="create-store-remove" event="return"> + <action service="indexProductsFromCategory" mode="sync"/> + </eca> + <!-- Don't need to index on create or remove since the feature won't be attached to any products at those points --> + <eca entity="ProductFeature" operation="store" event="return"> + <action service="indexProductsFromFeature" mode="sync"/> + </eca> + <eca entity="ProductFeatureGroupAppl" operation="create-store-remove" event="return"> + <action service="indexProductsFromFeature" mode="sync"/> + </eca> +</entity-eca> Propchange: ofbiz/trunk/specialpurpose/lucene/entitydef/eecas_product.xml ------------------------------------------------------------------------------ svn:eol-style = native Propchange: ofbiz/trunk/specialpurpose/lucene/entitydef/eecas_product.xml ------------------------------------------------------------------------------ svn:keywords = Date Rev Author URL Id Propchange: ofbiz/trunk/specialpurpose/lucene/entitydef/eecas_product.xml ------------------------------------------------------------------------------ svn:mime-type = text/xml Modified: ofbiz/trunk/specialpurpose/lucene/ofbiz-component.xml URL: http://svn.apache.org/viewvc/ofbiz/trunk/specialpurpose/lucene/ofbiz-component.xml?rev=1531918&r1=1531917&r2=1531918&view=diff ============================================================================== --- ofbiz/trunk/specialpurpose/lucene/ofbiz-component.xml (original) +++ ofbiz/trunk/specialpurpose/lucene/ofbiz-component.xml Mon Oct 14 14:42:53 2013 @@ -30,6 +30,9 @@ under the License. <classpath type="jar" location="build/lib/*"/> <classpath type="jar" location="lib/*"/> + <!-- entity resources: model(s), eca(s), group, and data definitions --> + <entity-resource type="eca" reader-name="main" loader="main" location="entitydef/eecas_product.xml"/> + <!-- service resources: model(s), eca(s) and group definitions --> <service-resource type="model" loader="main" location="servicedef/services.xml"/> Modified: ofbiz/trunk/specialpurpose/lucene/servicedef/services.xml URL: http://svn.apache.org/viewvc/ofbiz/trunk/specialpurpose/lucene/servicedef/services.xml?rev=1531918&r1=1531917&r2=1531918&view=diff ============================================================================== --- ofbiz/trunk/specialpurpose/lucene/servicedef/services.xml (original) +++ ofbiz/trunk/specialpurpose/lucene/servicedef/services.xml Mon Oct 14 14:42:53 2013 @@ -30,5 +30,28 @@ under the License. <attribute mode="OUT" name="badIndexList" optional="true" type="List"/> <attribute mode="OUT" name="goodIndexCount" optional="true" type="Integer"/> </service> - + + <service name="indexProduct" engine="java" location="org.ofbiz.content.search.SearchServices" invoke="indexProduct"> + <description>Submit for indexing the specified productId</description> + <attribute name="productId" mode="IN" type="String" optional="false"/> + </service> + + <!-- Services to locate and submit for indexing all products affected by an associated data change --> + <service name="indexProductsFromFeature" engine="java" location="org.ofbiz.content.search.SearchServices" invoke="indexProductsFromFeature"> + <attribute name="productFeatureId" mode="IN" type="String" optional="false"/> + </service> + <service name="indexProductsFromProductAssoc" engine="java" location="org.ofbiz.content.search.SearchServices" invoke="indexProductsFromProductAssoc"> + <attribute name="productId" mode="IN" type="String"/> + <attribute name="productIdTo" mode="IN" type="String"/> + </service> + <service name="indexProductsFromDataResource" engine="java" location="org.ofbiz.content.search.SearchServices" invoke="indexProductsFromDataResource"> + <attribute name="dataResourceId" mode="IN" type="String"/> + </service> + <service name="indexProductsFromContent" engine="java" location="org.ofbiz.content.search.SearchServices" invoke="indexProductsFromContent"> + <attribute name="contentId" mode="IN" type="String"/> + </service> + <service name="indexProductsFromCategory" engine="java" location="org.ofbiz.content.search.SearchServices" invoke="indexProductsFromCategory"> + <attribute name="productCategoryId" mode="IN" type="String"/> + </service> + </services> \ No newline at end of file Modified: ofbiz/trunk/specialpurpose/lucene/src/org/ofbiz/content/search/ProductIndexer.java URL: http://svn.apache.org/viewvc/ofbiz/trunk/specialpurpose/lucene/src/org/ofbiz/content/search/ProductIndexer.java?rev=1531918&r1=1531917&r2=1531918&view=diff ============================================================================== --- ofbiz/trunk/specialpurpose/lucene/src/org/ofbiz/content/search/ProductIndexer.java (original) +++ ofbiz/trunk/specialpurpose/lucene/src/org/ofbiz/content/search/ProductIndexer.java Mon Oct 14 14:42:53 2013 @@ -28,8 +28,6 @@ import java.util.Set; import java.util.TreeSet; import java.util.concurrent.LinkedBlockingQueue; -import org.apache.lucene.document.IntField; -import org.apache.lucene.document.LongField; import org.ofbiz.base.util.Debug; import org.ofbiz.base.util.GeneralException; import org.ofbiz.base.util.UtilDateTime; @@ -45,11 +43,11 @@ import org.ofbiz.entity.condition.Entity import org.ofbiz.entity.util.EntityUtil; import org.apache.lucene.analysis.standard.StandardAnalyzer; -import org.apache.lucene.analysis.Analyzer; import org.apache.lucene.document.Document; import org.apache.lucene.document.DoubleField; import org.apache.lucene.document.Field; import org.apache.lucene.document.Field.Store; +import org.apache.lucene.document.LongField; import org.apache.lucene.document.StringField; import org.apache.lucene.document.TextField; import org.apache.lucene.index.CorruptIndexException; @@ -68,15 +66,12 @@ public class ProductIndexer extends Thre private LinkedBlockingQueue<String> productIndexQueue = new LinkedBlockingQueue<String>(); private Delegator delegator; private Directory indexDirectory; - private IndexWriterConfig indexWriterConfiguration; private static final String NULL_STRING = "NULL"; // TODO: Move to property file private static final int UNCOMMITTED_DOC_LIMIT = 100; private ProductIndexer(Delegator delegator) { this.delegator = delegator; - Analyzer analyzer = new StandardAnalyzer(SearchWorker.LUCENE_VERSION); - this.indexWriterConfiguration = new IndexWriterConfig(SearchWorker.LUCENE_VERSION, analyzer); try { this.indexDirectory = FSDirectory.open(new File(SearchWorker.getIndexPath("products"))); } catch (CorruptIndexException e) { @@ -124,7 +119,7 @@ public class ProductIndexer extends Thre Term documentIdentifier = new Term("productId", productId); if (indexWriter == null) { try { - indexWriter = new IndexWriter(this.indexDirectory, this.indexWriterConfiguration); + indexWriter = new IndexWriter(this.indexDirectory, new IndexWriterConfig(SearchWorker.LUCENE_VERSION, new StandardAnalyzer(SearchWorker.LUCENE_VERSION))); } catch (CorruptIndexException e) { Debug.logError("Corrupted lucene index: " + e.getMessage(), module); break; Modified: ofbiz/trunk/specialpurpose/lucene/src/org/ofbiz/content/search/SearchServices.java URL: http://svn.apache.org/viewvc/ofbiz/trunk/specialpurpose/lucene/src/org/ofbiz/content/search/SearchServices.java?rev=1531918&r1=1531917&r2=1531918&view=diff ============================================================================== --- ofbiz/trunk/specialpurpose/lucene/src/org/ofbiz/content/search/SearchServices.java (original) +++ ofbiz/trunk/specialpurpose/lucene/src/org/ofbiz/content/search/SearchServices.java Mon Oct 14 14:42:53 2013 @@ -26,12 +26,17 @@ import java.util.HashMap; import java.util.List; import java.util.Locale; import java.util.Map; +import java.util.Set; import org.ofbiz.base.util.Debug; import org.ofbiz.base.util.UtilMisc; import org.ofbiz.base.util.UtilProperties; import org.ofbiz.entity.Delegator; +import org.ofbiz.entity.GenericEntityException; +import org.ofbiz.entity.GenericValue; +import org.ofbiz.entity.util.EntityUtil; import org.ofbiz.service.DispatchContext; +import org.ofbiz.service.GenericServiceException; import org.ofbiz.service.ServiceUtil; import org.ofbiz.service.LocalDispatcher; @@ -69,4 +74,117 @@ public class SearchServices { if (Debug.infoOn()) Debug.logInfo("Indexing done in: " + (end.getTime()-start.getTime()) + " ms", module); return results; } + + public static Map<String, Object> indexProduct(DispatchContext dctx, Map<String, ? extends Object> context) { + Delegator delegator = dctx.getDelegator(); + String productId = (String) context.get("productId"); + ProductIndexer indexer = ProductIndexer.getInstance(delegator); + indexer.queue(productId); + return ServiceUtil.returnSuccess(); + } + + public static Map<String, Object> indexProductsFromFeature(DispatchContext dctx, Map<String, ? extends Object> context) { + Delegator delegator = dctx.getDelegator(); + LocalDispatcher dispatcher = dctx.getDispatcher(); + try { + List<GenericValue> productFeatureAppls = delegator.findByAnd("ProductFeatureAppl", UtilMisc.toMap("productFeatureId", context.get("productFeatureId")), null, false); + // Only re-index the active appls, future dated ones will get picked up on that product's re-index date + productFeatureAppls = EntityUtil.filterByDate(productFeatureAppls); + + for (GenericValue productFeatureAppl : productFeatureAppls) { + try { + dispatcher.runSync("indexProduct", UtilMisc.toMap("productId", productFeatureAppl.get("productId"))); + } catch (GenericServiceException e) { + Debug.logError(e, module); + } + } + + } catch (GenericEntityException e) { + Debug.logError(e, module); + } + return ServiceUtil.returnSuccess(); + } + + public static Map<String, Object> indexProductsFromProductAssoc(DispatchContext dctx, Map<String, ? extends Object> context) { + LocalDispatcher dispatcher = dctx.getDispatcher(); + try { + dispatcher.runSync("indexProduct", UtilMisc.toMap("productId", context.get("productId"))); + dispatcher.runSync("indexProduct", UtilMisc.toMap("productId", context.get("productIdTo"))); + } catch (GenericServiceException e) { + Debug.logError(e, module); + } + return ServiceUtil.returnSuccess(); + } + + public static Map<String, Object> indexProductsFromDataResource(DispatchContext dctx, Map<String, ? extends Object> context) { + Delegator delegator = dctx.getDelegator(); + LocalDispatcher dispatcher = dctx.getDispatcher(); + try { + List<GenericValue> contents = delegator.findByAnd("Content", UtilMisc.toMap("dataResourceId", context.get("dataResourceId")), null, false); + for (GenericValue content : contents) { + dispatcher.runSync("indexProductsFromContent", + UtilMisc.toMap( + "userLogin", context.get("userLogin"), + "contentId", content.get("contentId"))); + } + } catch (GenericEntityException e) { + Debug.logError(e, module); + } catch (GenericServiceException e) { + Debug.logError(e, module); + } + return ServiceUtil.returnSuccess(); + } + public static Map<String, Object> indexProductsFromContent(DispatchContext dctx, Map<String, ? extends Object> context) { + Delegator delegator = dctx.getDelegator(); + LocalDispatcher dispatcher = dctx.getDispatcher(); + try { + List<GenericValue> productContents = delegator.findByAnd("ProductContent", UtilMisc.toMap("contentId", context.get("contentId")), null, false); + for (GenericValue productContent : productContents) { + try { + dispatcher.runSync("indexProduct", UtilMisc.toMap("productId", productContent.get("productId"))); + } catch (GenericServiceException e) { + Debug.logError(e, module); + } + } + } catch (GenericEntityException e) { + Debug.logError(e, module); + } + return ServiceUtil.returnSuccess(); + } + public static Map<String, Object> indexProductsFromCategory(DispatchContext dctx, Map<String, Object> context) { + Delegator delegator = dctx.getDelegator(); + LocalDispatcher dispatcher = dctx.getDispatcher(); + try { + String productCategoryId = (String) context.get("productCategoryId"); + indexProductCategoryMembers(productCategoryId, delegator, dispatcher); + indexProductCategoryRollup(productCategoryId, delegator, dispatcher, UtilMisc.<String>toSet(productCategoryId)); + } catch (GenericEntityException e) { + Debug.logError(e, module); + } + return ServiceUtil.returnSuccess(); + } + private static void indexProductCategoryRollup(String parentProductCategoryId, Delegator delegator, LocalDispatcher dispatcher, Set<String> excludeProductCategoryIds) throws GenericEntityException { + List<GenericValue> productCategoryRollups = delegator.findByAnd("ProductCategoryRollup", UtilMisc.toMap("parentProductCategoryId", parentProductCategoryId), null, false); + for (GenericValue productCategoryRollup : productCategoryRollups) { + String productCategoryId = productCategoryRollup.getString("productCategoryId"); + // Avoid infinite recursion + if (!excludeProductCategoryIds.add(productCategoryId)) { + continue; + } + indexProductCategoryMembers(productCategoryId, delegator, dispatcher); + indexProductCategoryRollup(productCategoryId, delegator, dispatcher, excludeProductCategoryIds); + } + } + + private static void indexProductCategoryMembers(String productCategoryId, Delegator delegator, LocalDispatcher dispatcher) throws GenericEntityException { + List<GenericValue> productCategoryMembers = delegator.findByAnd("ProductCategoryMember", UtilMisc.toMap("productCategoryId", productCategoryId), null, false); + for (GenericValue productCategoryMember : productCategoryMembers) { + try { + dispatcher.runSync("indexProduct", UtilMisc.toMap("productId", productCategoryMember.get("productId"))); + } catch (GenericServiceException e) { + Debug.logError(e, module); + } + } + } + } |
Free forum by Nabble | Edit this page |