From e0d90daec7fd5b26e478c3792ef20c8dc4e344e4 Mon Sep 17 00:00:00 2001 From: srosse <none@none> Date: Wed, 22 Apr 2015 18:47:44 +0200 Subject: [PATCH] OO-1522: refactor to folder worker poll in a thread pool executor with a very short queue and a CallerRunPolicy to slow down the main indexer if the executor is busy --- .../org/olat/search/_spring/searchContext.xml | 13 +-- .../service/document/IdentityDocument.java | 6 +- .../search/service/indexer/FolderIndexer.java | 102 ++-------------- .../service/indexer/FolderIndexerWorker.java | 62 +++------- .../indexer/FolderIndexerWorkerPool.java | 110 ------------------ .../service/indexer/FullIndexerStatus.java | 4 +- .../olat/search/service/indexer/Index.java | 10 +- .../search/service/indexer/LeafIndexer.java | 90 ++++++++++++++ .../service/indexer/OlatFullIndexer.java | 65 +++++++---- .../indexer/group/GroupFolderIndexer.java | 1 + .../indexer/group/GroupWikiIndexer.java | 27 ++--- .../indexer/identity/IdentityIndexer.java | 38 +++--- .../indexer/identity/ProfileIndexer.java | 2 +- .../indexer/identity/PublicFolderIndexer.java | 3 +- .../repository/ImsCPRepositoryIndexer.java | 23 ++-- .../course/BCCourseNodeIndexer.java | 12 +- .../course/CPCourseNodeIndexer.java | 2 +- .../course/DialogCourseNodeIndexer.java | 31 ++--- .../course/FOCourseNodeIndexer.java | 15 ++- .../ProjectBrokerCourseNodeIndexer.java | 22 ++-- .../course/SPCourseNodeIndexer.java | 61 +++++----- .../course/STCourseNodeIndexer.java | 14 ++- .../course/TACourseNodeIndexer.java | 60 +++++----- .../course/WikiCourseNodeIndexer.java | 20 ++-- 24 files changed, 340 insertions(+), 453 deletions(-) delete mode 100644 src/main/java/org/olat/search/service/indexer/FolderIndexerWorkerPool.java create mode 100644 src/main/java/org/olat/search/service/indexer/LeafIndexer.java diff --git a/src/main/java/org/olat/search/_spring/searchContext.xml b/src/main/java/org/olat/search/_spring/searchContext.xml index d847b8cece5..3a433a78ea9 100644 --- a/src/main/java/org/olat/search/_spring/searchContext.xml +++ b/src/main/java/org/olat/search/_spring/searchContext.xml @@ -42,7 +42,7 @@ <property name="indexerCron" value="${search.indexing.cronjob}" /> </bean> - <bean id="searchExecutor" class="org.springframework.core.task.support.ExecutorServiceAdapter"> + <bean id="searchExecutor" class="org.springframework.core.task.support.ExecutorServiceAdapter"> <constructor-arg index="0" ref="searchSpringExecutor" /> </bean> @@ -115,9 +115,9 @@ <property name="targetMethod" value="init" /> <property name="arguments"> <value> - searchService=${search.service} + searchService=${search.service} - generateIndexAtStartup=${generate.index.at.startup} + generateIndexAtStartup=${generate.index.at.startup} tempIndexPath=${search.index.tempIndex} tempSpellCheckPath=${search.index.tempSpellcheck} pdfTextBufferPath=${search.index.pdfBuffer} @@ -143,10 +143,9 @@ <!-- updater runs every xx ms (0=stopped) --> <!-- The updater is NOT implemented for all index elements, do not use it for now! --> updateInterval=0 - ramBufferSizeMb=16 - - </value> - </property> + ramBufferSizeMb=16 + </value> + </property> </bean> <!-- Indexer factory --> diff --git a/src/main/java/org/olat/search/service/document/IdentityDocument.java b/src/main/java/org/olat/search/service/document/IdentityDocument.java index 58220b533cd..1d15d9e71db 100644 --- a/src/main/java/org/olat/search/service/document/IdentityDocument.java +++ b/src/main/java/org/olat/search/service/document/IdentityDocument.java @@ -101,7 +101,5 @@ public class IdentityDocument extends OlatDocument { if (log.isDebug()) log.debug(identityDocument.toString()); return identityDocument.getLuceneDocument(); - } - - -} + } +} \ No newline at end of file diff --git a/src/main/java/org/olat/search/service/indexer/FolderIndexer.java b/src/main/java/org/olat/search/service/indexer/FolderIndexer.java index e8f6ebafc37..182d7689eab 100644 --- a/src/main/java/org/olat/search/service/indexer/FolderIndexer.java +++ b/src/main/java/org/olat/search/service/indexer/FolderIndexer.java @@ -25,19 +25,10 @@ package org.olat.search.service.indexer; - import java.io.IOException; -import org.apache.lucene.document.Document; -import org.olat.core.CoreSpringFactory; -import org.olat.core.commons.persistence.DBFactory; -import org.olat.core.util.WorkThreadInformations; import org.olat.core.util.vfs.VFSContainer; -import org.olat.core.util.vfs.VFSItem; -import org.olat.core.util.vfs.VFSLeaf; import org.olat.search.service.SearchResourceContext; -import org.olat.search.service.document.file.DocumentAccessException; -import org.olat.search.service.document.file.FileDocumentFactory; /** * Common folder indexer. Index all files form a certain VFS-container as starting point. @@ -47,92 +38,13 @@ public abstract class FolderIndexer extends AbstractHierarchicalIndexer { protected void doIndexVFSContainer(SearchResourceContext parentResourceContext, VFSContainer container, OlatFullIndexer indexWriter, String filePath, FolderIndexerAccess accessRule) throws IOException, InterruptedException { - if (FolderIndexerWorkerPool.getInstance().isDisabled()) { - // Do index in single thread mode - doIndexVFSContainerByMySelf(parentResourceContext, container, indexWriter, filePath, accessRule); - } else { - // Start new thread to index folder - FolderIndexerWorker runnableFolderIndexer = FolderIndexerWorkerPool.getInstance().getIndexer(); - runnableFolderIndexer.setAccessRule(accessRule); - runnableFolderIndexer.setParentResourceContext(parentResourceContext); - runnableFolderIndexer.setContainer(container); - runnableFolderIndexer.setIndexWriter(indexWriter); - runnableFolderIndexer.setFilePath(filePath); - // Start Indexing from this rootContainer in an own thread - runnableFolderIndexer.start(); - } - } - - // This index methods will be used in single-thread mode only (FolderIndexerWorkerPool is disabled) - ////////////////////////////////////////////////////////////////////////////////////////////////// - private void doIndexVFSContainerByMySelf(SearchResourceContext parentResourceContext, VFSContainer container, OlatFullIndexer indexWriter, String filePath, FolderIndexerAccess accessRule) - throws IOException, InterruptedException { - // Items: List of VFSContainer & VFSLeaf - String myFilePath = filePath; - for (VFSItem item : container.getItems()) { - if (item instanceof VFSContainer) { - // ok it is a container go further - if (isLogDebugEnabled()) logDebug(item.getName() + " is a VFSContainer => go further "); - if(accessRule.allowed(item)) { - doIndexVFSContainerByMySelf(parentResourceContext, (VFSContainer)item, indexWriter, myFilePath + "/" + ((VFSContainer)item).getName(), accessRule); - } - } else if (item instanceof VFSLeaf) { - // ok it is a file => analyse it - if (isLogDebugEnabled()) logDebug(item.getName() + " is a VFSLeaf => analyse file"); - if(accessRule.allowed(item)) { - doIndexVFSLeafByMySelf(parentResourceContext, (VFSLeaf)item, indexWriter, myFilePath); - } - } else { - logWarn("Unkown element in item-list class=" + item.getClass(), null); - } - // TODO:cg/27.10.2010 try to fix Indexer ERROR 'Overdue resource check-out stack trace.' on OLATNG - DBFactory.getInstance().commitAndCloseSession(); - } + FolderIndexerWorker runnableFolderIndexer = new FolderIndexerWorker(); + runnableFolderIndexer.setAccessRule(accessRule); + runnableFolderIndexer.setParentResourceContext(parentResourceContext); + runnableFolderIndexer.setContainer(container); + runnableFolderIndexer.setIndexWriter(indexWriter); + runnableFolderIndexer.setFilePath(filePath); + indexWriter.submit(runnableFolderIndexer); } - protected void doIndexVFSLeafByMySelf(SearchResourceContext leafResourceContext, VFSLeaf leaf, OlatFullIndexer indexWriter, String filePath) throws InterruptedException { - if (isLogDebugEnabled()) logDebug("Analyse VFSLeaf=" + leaf.getName()); - try { - if (CoreSpringFactory.getImpl(FileDocumentFactory.class).isFileSupported(leaf)) { - String myFilePath = ""; - if (filePath.endsWith("/")) { - myFilePath = filePath + leaf.getName(); - } else { - myFilePath = filePath + "/" + leaf.getName(); - } - leafResourceContext.setFilePath(myFilePath); - //fxdiff FXOLAT-97: high CPU load tracker - WorkThreadInformations.set("Index VFSLeaf=" + myFilePath + " at " + leafResourceContext.getResourceUrl()); - Document document = CoreSpringFactory.getImpl(FileDocumentFactory.class).createDocument(leafResourceContext, leaf); - indexWriter.addDocument(document); - } else { - if (isLogDebugEnabled()) logDebug("Documenttype not supported. file=" + leaf.getName()); - } - } catch (DocumentAccessException e) { - if (isLogDebugEnabled()) logDebug("Can not access document." + e.getMessage()); - } catch (IOException ioEx) { - logWarn("IOException: Can not index leaf=" + leaf.getName(), ioEx); - } catch (InterruptedException iex) { - throw new InterruptedException(iex.getMessage()); - } catch (Exception ex) { - logWarn("Exception: Can not index leaf=" + leaf.getName(), ex); - //fxdiff FXOLAT-97: high CPU load tracker - } finally { - WorkThreadInformations.unset(); - } - } - - /** - * @param leaf - * @return Full file-path of leaf without leaf-name - */ - protected String getPathFor(VFSLeaf leaf) { - String path = ""; - VFSContainer parentContainer = leaf.getParentContainer(); - while (parentContainer.getParentContainer() != null) { - path = parentContainer.getName() + "/" + path; - parentContainer = parentContainer.getParentContainer(); - } - return path; - } } \ No newline at end of file diff --git a/src/main/java/org/olat/search/service/indexer/FolderIndexerWorker.java b/src/main/java/org/olat/search/service/indexer/FolderIndexerWorker.java index 2302f7989e8..a4f071e43e7 100644 --- a/src/main/java/org/olat/search/service/indexer/FolderIndexerWorker.java +++ b/src/main/java/org/olat/search/service/indexer/FolderIndexerWorker.java @@ -27,6 +27,7 @@ package org.olat.search.service.indexer; import java.io.IOException; +import java.util.concurrent.Callable; import org.apache.lucene.document.Document; import org.olat.core.CoreSpringFactory; @@ -45,44 +46,28 @@ import org.olat.search.service.document.file.FileDocumentFactory; * Common folder indexer. Index all files form a certain VFS-container as starting point. * @author Christian Guretzki */ -public class FolderIndexerWorker implements Runnable{ +public class FolderIndexerWorker implements Callable<Boolean> { - private static OLog log = Tracing.createLoggerFor(FolderIndexerWorker.class); + private static final OLog log = Tracing.createLoggerFor(FolderIndexerWorker.class); - public static final int STATE_RUNNING = 1; - public static final int STATE_FINISHED = 2; - - private Thread folderIndexer = null; - private SearchResourceContext parentResourceContext; private VFSContainer container; private OlatFullIndexer indexWriter; private String filePath; private FolderIndexerAccess accessRule; - private final String threadId; - - private int state = 0; private final FileDocumentFactory docFactory; - public FolderIndexerWorker(int threadId) { - this.threadId = Integer.toString(threadId); + public FolderIndexerWorker() { docFactory = CoreSpringFactory.getImpl(FileDocumentFactory.class); } - public void start() { - folderIndexer = new Thread(this, "folderIndexer-" + threadId ); - folderIndexer.setPriority(Thread.MIN_PRIORITY); - folderIndexer.setDaemon(true); - folderIndexer.start(); - state = STATE_RUNNING; - } - - public void run() { - try { - if (log.isDebug()) log.debug("folderIndexer-" + threadId + " run..."); + @Override + public Boolean call() throws Exception { + boolean allOk = false; + try { doIndexVFSContainer(parentResourceContext, container, indexWriter, filePath, accessRule); - if (log.isDebug()) log.debug("folderIndexer-" + threadId + " finished"); + allOk = true; } catch (IOException e) { log.warn("IOException in run", e); } catch (InterruptedException e) { @@ -93,10 +78,8 @@ public class FolderIndexerWorker implements Runnable{ } finally { //db session a saved in a thread local DBFactory.getInstance().commitAndCloseSession(); - FolderIndexerWorkerPool.getInstance().release(this); } - log.debug("folderIndexer-" + threadId + " end of run"); - state = STATE_FINISHED; + return allOk; } protected void doIndexVFSContainer(SearchResourceContext resourceContext, VFSContainer cont, OlatFullIndexer writer, String fPath, FolderIndexerAccess aRule) @@ -131,10 +114,10 @@ public class FolderIndexerWorker implements Runnable{ //fxdiff FXOLAT-97: high CPU load tracker WorkThreadInformations.setInfoFiles(myFilePath, leaf); WorkThreadInformations.set("Index VFSLeaf=" + myFilePath + " at " + leafResourceContext.getResourceUrl()); - Document document = docFactory.createDocument(leafResourceContext, leaf); - if(document != null) {//document wihich are disabled return null - writer.addDocument(document); - } + Document document = docFactory.createDocument(leafResourceContext, leaf); + if(document != null) {//document which are disabled return null + writer.addDocument(document); + } } else { if (log.isDebug()) log.debug("Documenttype not supported. file=" + leaf.getName()); } @@ -146,13 +129,10 @@ public class FolderIndexerWorker implements Runnable{ log.warn("IOException: Can not index leaf=" + leaf.getName(), ioEx); } catch (Exception ex) { log.warn("Exception: Can not index leaf=" + leaf.getName(), ex); - //fxdiff FXOLAT-97: high CPU load tracker } finally { WorkThreadInformations.unset(); } } - - public void setParentResourceContext(SearchResourceContext newParentResourceContext) { this.parentResourceContext = newParentResourceContext; @@ -173,18 +153,4 @@ public class FolderIndexerWorker implements Runnable{ public void setAccessRule(FolderIndexerAccess accessRule) { this.accessRule = accessRule; } - - public String getId() { - return threadId; - } - - /** - * @return Returns the state. - */ - public int getState() { - if ((folderIndexer != null) && folderIndexer.isAlive()) { - return STATE_RUNNING; - } - return state; - } } diff --git a/src/main/java/org/olat/search/service/indexer/FolderIndexerWorkerPool.java b/src/main/java/org/olat/search/service/indexer/FolderIndexerWorkerPool.java deleted file mode 100644 index c47b11cbe30..00000000000 --- a/src/main/java/org/olat/search/service/indexer/FolderIndexerWorkerPool.java +++ /dev/null @@ -1,110 +0,0 @@ -/** -* OLAT - Online Learning and Training<br> -* http://www.olat.org -* <p> -* Licensed under the Apache License, Version 2.0 (the "License"); <br> -* you may not use this file except in compliance with the License.<br> -* You may obtain a copy of the License at -* <p> -* http://www.apache.org/licenses/LICENSE-2.0 -* <p> -* Unless required by applicable law or agreed to in writing,<br> -* software distributed under the License is distributed on an "AS IS" BASIS, <br> -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. <br> -* See the License for the specific language governing permissions and <br> -* limitations under the License. -* <p> -* Copyright (c) since 2004 at Multimedia- & E-Learning Services (MELS),<br> -* University of Zurich, Switzerland. -* <hr> -* <a href="http://www.openolat.org"> -* OpenOLAT - Online Learning and Training</a><br> -* This file has been modified by the OpenOLAT community. Changes are licensed -* under the Apache 2.0 license as the original file. -*/ - -package org.olat.search.service.indexer; - - -import java.util.List; -import java.util.Vector; - -import org.olat.core.logging.OLog; -import org.olat.core.logging.Tracing; -import org.olat.search.service.SearchServiceFactory; - -/** - * Pool of folder indexer worker. - * @author Christian Guretzki - */ -public class FolderIndexerWorkerPool { - private OLog log = Tracing.createLoggerFor(FolderIndexerWorkerPool.class); - private int poolSize = 10; - private static FolderIndexerWorkerPool instance = null; - private List<FolderIndexerWorker> indexerList; - private List<FolderIndexerWorker> runningIndexerList; - - /** - * - */ - public FolderIndexerWorkerPool() { - poolSize = SearchServiceFactory.getService().getSearchModuleConfig().getFolderPoolSize(); - indexerList = new Vector<FolderIndexerWorker>(); - // - for (int i = 0; i < poolSize; i++) { - indexerList.add(new FolderIndexerWorker(i)); - } - runningIndexerList = new Vector<FolderIndexerWorker>(); - } - - protected static FolderIndexerWorkerPool getInstance() { - if (instance == null) { - instance = new FolderIndexerWorkerPool(); - } - return instance; - } - - public void release(FolderIndexerWorker indexer) { - if (log.isDebug()) log.debug("indexer=" + indexer.getId() + " released"); - runningIndexerList.remove(indexer); - int id = Integer.parseInt(indexer.getId()); - indexerList.add(new FolderIndexerWorker(id)); - if (log.isDebug()) log.debug("Available indexer=" + indexerList.size() + " Running indexer=" + runningIndexerList.size()); - } - - public FolderIndexerWorker getIndexer( ) { - while(indexerList.isEmpty()) { - try { - Thread.sleep(1000); - } catch (InterruptedException e) { - // - } - } - FolderIndexerWorker freeFolderIndexer = indexerList.remove(0); - runningIndexerList.add(freeFolderIndexer); - if (log.isDebug()) log.debug("indexer=" + freeFolderIndexer.getId() + " selected"); - if (log.isDebug()) log.debug("Available indexer=" + indexerList.size() + " Running indexer=" + runningIndexerList.size()); - return freeFolderIndexer; - } - - /** - * - * @return Return true if any indexer is still running - */ - public boolean isIndexerRunning() { - return indexerList.size() < this.poolSize; - } - - public int getNumberOfRunningIndexer() { - return runningIndexerList.size(); - } - - public int getNumberOfAvailableIndexer() { - return indexerList.size(); - } - - public boolean isDisabled() { - return poolSize == 0; - } - -} diff --git a/src/main/java/org/olat/search/service/indexer/FullIndexerStatus.java b/src/main/java/org/olat/search/service/indexer/FullIndexerStatus.java index 57cf3c24469..366005d7d77 100644 --- a/src/main/java/org/olat/search/service/indexer/FullIndexerStatus.java +++ b/src/main/java/org/olat/search/service/indexer/FullIndexerStatus.java @@ -190,7 +190,7 @@ public class FullIndexerStatus { * @return Returns the runningFolderIndexer. */ public int getNumberRunningFolderIndexer() { - return FolderIndexerWorkerPool.getInstance().getNumberOfRunningIndexer(); + return -1;//FolderIndexerWorkerPool.getInstance().getNumberOfRunningIndexer(); } @@ -198,7 +198,7 @@ public class FullIndexerStatus { * @return Returns the availableFolderIndexer. */ public int getNumberAvailableFolderIndexer() { - return FolderIndexerWorkerPool.getInstance().getNumberOfAvailableIndexer(); + return -1;//FolderIndexerWorkerPool.getInstance().getNumberOfAvailableIndexer(); } diff --git a/src/main/java/org/olat/search/service/indexer/Index.java b/src/main/java/org/olat/search/service/indexer/Index.java index 87668bad24d..25db3b52e23 100644 --- a/src/main/java/org/olat/search/service/indexer/Index.java +++ b/src/main/java/org/olat/search/service/indexer/Index.java @@ -63,15 +63,15 @@ public class Index { * @param restartInterval Restart interval of full-index in milliseconds. * @param indexInterval Sleeping time in milliseconds between adding documents to index. */ - public Index(SearchModule searchModuleConfig, SearchSpellChecker spellChecker, MainIndexer mainIndexer, + public Index(SearchModule searchModule, SearchSpellChecker spellChecker, MainIndexer mainIndexer, LifeFullIndexer lifeIndexer, CoordinatorManager coordinatorManager) { this.spellChecker = spellChecker; - this.indexPath = searchModuleConfig.getFullIndexPath(); - this.tempIndexPath = searchModuleConfig.getFullTempIndexPath(); - this.permanentIndexPath = searchModuleConfig.getFullPermanentIndexPath(); + this.indexPath = searchModule.getFullIndexPath(); + this.tempIndexPath = searchModule.getFullTempIndexPath(); + this.permanentIndexPath = searchModule.getFullPermanentIndexPath(); this.lifeIndexer = lifeIndexer; - fullIndexer = new OlatFullIndexer(this, searchModuleConfig, mainIndexer, coordinatorManager); + fullIndexer = new OlatFullIndexer(this, searchModule, mainIndexer, coordinatorManager); } /** diff --git a/src/main/java/org/olat/search/service/indexer/LeafIndexer.java b/src/main/java/org/olat/search/service/indexer/LeafIndexer.java new file mode 100644 index 00000000000..ce1ca25ecf4 --- /dev/null +++ b/src/main/java/org/olat/search/service/indexer/LeafIndexer.java @@ -0,0 +1,90 @@ +/** +* OLAT - Online Learning and Training<br> +* http://www.olat.org +* <p> +* Licensed under the Apache License, Version 2.0 (the "License"); <br> +* you may not use this file except in compliance with the License.<br> +* You may obtain a copy of the License at +* <p> +* http://www.apache.org/licenses/LICENSE-2.0 +* <p> +* Unless required by applicable law or agreed to in writing,<br> +* software distributed under the License is distributed on an "AS IS" BASIS, <br> +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. <br> +* See the License for the specific language governing permissions and <br> +* limitations under the License. +* <p> +* Copyright (c) since 2004 at Multimedia- & E-Learning Services (MELS),<br> +* University of Zurich, Switzerland. +* <hr> +* <a href="http://www.openolat.org"> +* OpenOLAT - Online Learning and Training</a><br> +* This file has been modified by the OpenOLAT community. Changes are licensed +* under the Apache 2.0 license as the original file. +*/ + +package org.olat.search.service.indexer; + + +import java.io.IOException; + +import org.apache.lucene.document.Document; +import org.olat.core.CoreSpringFactory; +import org.olat.core.util.WorkThreadInformations; +import org.olat.core.util.vfs.VFSContainer; +import org.olat.core.util.vfs.VFSLeaf; +import org.olat.search.service.SearchResourceContext; +import org.olat.search.service.document.file.DocumentAccessException; +import org.olat.search.service.document.file.FileDocumentFactory; + +/** + * Common folder indexer. Index all files form a certain VFS-container as starting point. + * @author Christian Guretzki + */ +public abstract class LeafIndexer extends AbstractHierarchicalIndexer { + + protected void doIndexVFSLeafByMySelf(SearchResourceContext leafResourceContext, VFSLeaf leaf, OlatFullIndexer indexWriter, String filePath) throws InterruptedException { + if (isLogDebugEnabled()) logDebug("Analyse VFSLeaf=" + leaf.getName()); + try { + if (CoreSpringFactory.getImpl(FileDocumentFactory.class).isFileSupported(leaf)) { + String myFilePath = ""; + if (filePath.endsWith("/")) { + myFilePath = filePath + leaf.getName(); + } else { + myFilePath = filePath + "/" + leaf.getName(); + } + leafResourceContext.setFilePath(myFilePath); + + WorkThreadInformations.set("Index VFSLeaf=" + myFilePath + " at " + leafResourceContext.getResourceUrl()); + Document document = CoreSpringFactory.getImpl(FileDocumentFactory.class).createDocument(leafResourceContext, leaf); + indexWriter.addDocument(document); + } else { + if (isLogDebugEnabled()) logDebug("Documenttype not supported. file=" + leaf.getName()); + } + } catch (DocumentAccessException e) { + if (isLogDebugEnabled()) logDebug("Can not access document." + e.getMessage()); + } catch (IOException ioEx) { + logWarn("IOException: Can not index leaf=" + leaf.getName(), ioEx); + } catch (InterruptedException iex) { + throw new InterruptedException(iex.getMessage()); + } catch (Exception ex) { + logWarn("Exception: Can not index leaf=" + leaf.getName(), ex); + } finally { + WorkThreadInformations.unset(); + } + } + + /** + * @param leaf + * @return Full file-path of leaf without leaf-name + */ + protected String getPathFor(VFSLeaf leaf) { + String path = ""; + VFSContainer parentContainer = leaf.getParentContainer(); + while (parentContainer.getParentContainer() != null) { + path = parentContainer.getName() + "/" + path; + parentContainer = parentContainer.getParentContainer(); + } + return path; + } +} \ No newline at end of file diff --git a/src/main/java/org/olat/search/service/indexer/OlatFullIndexer.java b/src/main/java/org/olat/search/service/indexer/OlatFullIndexer.java index f0006595a8c..fbe94ac7127 100644 --- a/src/main/java/org/olat/search/service/indexer/OlatFullIndexer.java +++ b/src/main/java/org/olat/search/service/indexer/OlatFullIndexer.java @@ -73,9 +73,10 @@ public class OlatFullIndexer { private static final OLog log = Tracing.createLoggerFor(OlatFullIndexer.class); private static final int INDEX_MERGE_FACTOR = 1000; + private static final int MAX_WAITING_COUNT = 600;// = 10Min - private String indexPath; - private String tempIndexPath; + private String indexPath; + private String tempIndexPath; /** * Reference to indexer for done callback. @@ -90,6 +91,8 @@ public class OlatFullIndexer { private double ramBufferSizeMB; + private final int indexerPoolSize; + /** Current status of full-indexer. */ private FullIndexerStatus fullIndexerStatus; @@ -105,13 +108,13 @@ public class OlatFullIndexer { private Map<String,Integer> documentCounters; private Map<String,Integer> fileTypeCounters; - private MainIndexer mainIndexer; - private CoordinatorManager coordinatorManager; + private final MainIndexer mainIndexer; + private final CoordinatorManager coordinatorManager; private static final Object indexerWriterBlock = new Object(); + private ThreadPoolExecutor indexerExecutor; private ThreadPoolExecutor indexerWriterExecutor; - /** * * @param tempIndexPath Absolute file path to temporary index directory. @@ -119,16 +122,21 @@ public class OlatFullIndexer { * @param restartInterval Restart interval in milliseconds. * @param indexInterval Sleep time in milliseconds between adding documents. */ - public OlatFullIndexer(Index index, SearchModule searchModuleConfig, + public OlatFullIndexer(Index index, SearchModule searchModule, MainIndexer mainIndexer, CoordinatorManager coordinatorManager) { this.index = index; this.mainIndexer = mainIndexer; this.coordinatorManager = coordinatorManager; - indexPath = searchModuleConfig.getFullIndexPath(); - tempIndexPath = searchModuleConfig.getFullTempIndexPath(); - indexInterval = searchModuleConfig.getIndexInterval(); - documentsPerInterval = searchModuleConfig.getDocumentsPerInterval(); - ramBufferSizeMB = searchModuleConfig.getRAMBufferSizeMB(); + if(searchModule.getFolderPoolSize() <= 2) { + indexerPoolSize = 1; + } else { + indexerPoolSize = searchModule.getFolderPoolSize() - 1; + } + indexPath = searchModule.getFullIndexPath(); + tempIndexPath = searchModule.getFullTempIndexPath(); + indexInterval = searchModule.getIndexInterval(); + documentsPerInterval = searchModule.getDocumentsPerInterval(); + ramBufferSizeMB = searchModule.getRAMBufferSizeMB(); fullIndexerStatus = new FullIndexerStatus(1); stopIndexing = true; initStatus(); @@ -141,6 +149,7 @@ public class OlatFullIndexer { final AtomicLong last = new AtomicLong(1); try { Files.walkFileTree(indexDir.toPath(), new SimpleFileVisitor<Path>(){ + @Override public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException { if(attrs.isRegularFile()) { FileTime time = attrs.lastModifiedTime(); @@ -210,7 +219,12 @@ public class OlatFullIndexer { private void doIndex() throws InterruptedException{ try { WorkThreadInformations.setLongRunningTask("indexer"); - + + if(indexerExecutor == null) { + BlockingQueue<Runnable> queue = new LinkedBlockingQueue<Runnable>(2); + indexerExecutor = new ThreadPoolExecutor(indexerPoolSize, indexerPoolSize, 0L, TimeUnit.MILLISECONDS, + queue, new ThreadPoolExecutor.CallerRunsPolicy()); + } if(indexerWriterExecutor == null) { BlockingQueue<Runnable> queue = new LinkedBlockingQueue<Runnable>(2); indexerWriterExecutor = new ThreadPoolExecutor(1, 1, 0L, TimeUnit.MILLISECONDS, queue); @@ -224,22 +238,18 @@ public class OlatFullIndexer { SearchResourceContext searchResourceContext = new SearchResourceContext(); log.info("doIndex start. OlatFullIndexer with Debug output"); mainIndexer.doIndex(searchResourceContext, null /*no parent*/, this); + DBFactory.getInstance().commitAndCloseSession(); log.info("Wait until every folder indexer is finished"); + indexerExecutor.shutdown(); + indexerExecutor.awaitTermination(10, TimeUnit.MINUTES); DBFactory.getInstance().commitAndCloseSession(); - // check if every folder indexer is finished max waiting-time 10Min (=waitingCount-limit = 60) - int waitingCount = 0; - int MAX_WAITING_COUNT = 60;// = 10Min - while (FolderIndexerWorkerPool.getInstance().isIndexerRunning() && (waitingCount++ < MAX_WAITING_COUNT) ) { - Thread.sleep(10000); - } - if (waitingCount >= MAX_WAITING_COUNT) log.info("Finished with max waiting time!"); log.info("Wait until index writer executor is finished"); int waitWriter = 0; - while (indexerWriterExecutor.getActiveCount() > 0 && (waitWriter++ < (10 * MAX_WAITING_COUNT))) { + while (indexerWriterExecutor.getActiveCount() > 0 && (waitWriter++ < MAX_WAITING_COUNT)) { Thread.sleep(1000); } @@ -256,12 +266,25 @@ public class OlatFullIndexer { DBFactory.getInstance().commitAndCloseSession(); log.debug("doIndex: commit & close session"); + if(indexerExecutor != null) { + indexerExecutor.shutdownNow(); + indexerExecutor = null; + } if(indexerWriterExecutor != null) { indexerWriterExecutor.shutdownNow(); indexerWriterExecutor = null; } } } + + public Future<Boolean> submit(Callable<Boolean> task) { + if(indexerExecutor != null && !indexerExecutor.isShutdown()) { + return indexerExecutor.submit(task); + } else { + log.error("Try to submit a task to index executor but it's closed."); + return null; + } + } /** * @@ -302,8 +325,10 @@ public class OlatFullIndexer { // no logging available (shut down) => do nothing } } + fullIndexerStatus.setStatus(FullIndexerStatus.STATUS_STOPPED); stopIndexing = true; + try { log.info("quit indexing run."); } catch (NullPointerException nex) { diff --git a/src/main/java/org/olat/search/service/indexer/group/GroupFolderIndexer.java b/src/main/java/org/olat/search/service/indexer/group/GroupFolderIndexer.java index 93c3f1ce51e..47b43f97e72 100644 --- a/src/main/java/org/olat/search/service/indexer/group/GroupFolderIndexer.java +++ b/src/main/java/org/olat/search/service/indexer/group/GroupFolderIndexer.java @@ -59,6 +59,7 @@ public class GroupFolderIndexer extends FolderIndexer{ this.collaborationManager = collaborationManager; } + @Override public void doIndex(SearchResourceContext parentResourceContext, Object businessObj, OlatFullIndexer indexWriter) throws IOException,InterruptedException { if (!(businessObj instanceof BusinessGroup) ) throw new AssertException("businessObj must be BusinessGroup"); diff --git a/src/main/java/org/olat/search/service/indexer/group/GroupWikiIndexer.java b/src/main/java/org/olat/search/service/indexer/group/GroupWikiIndexer.java index 5445e7b583e..e764c50e7bc 100644 --- a/src/main/java/org/olat/search/service/indexer/group/GroupWikiIndexer.java +++ b/src/main/java/org/olat/search/service/indexer/group/GroupWikiIndexer.java @@ -40,22 +40,23 @@ import org.olat.modules.wiki.WikiManager; import org.olat.modules.wiki.WikiPage; import org.olat.search.service.SearchResourceContext; import org.olat.search.service.document.WikiPageDocument; -import org.olat.search.service.indexer.FolderIndexer; +import org.olat.search.service.indexer.AbstractHierarchicalIndexer; import org.olat.search.service.indexer.OlatFullIndexer; /** * Index all group folders. * @author Christian Guretzki */ -public class GroupWikiIndexer extends FolderIndexer{ +public class GroupWikiIndexer extends AbstractHierarchicalIndexer { //Must correspond with LocalString_xx.properties // Do not use '_' because we want to seach for certain documenttype and lucene haev problems with '_' public static final String TYPE = "type.group.wiki"; @Override public void doIndex(SearchResourceContext parentResourceContext, Object businessObj, OlatFullIndexer indexWriter) throws IOException,InterruptedException { - if (!(businessObj instanceof BusinessGroup) ) + if (!(businessObj instanceof BusinessGroup)) throw new AssertException("businessObj must be BusinessGroup"); + BusinessGroup businessGroup = (BusinessGroup)businessObj; // Index Group Wiki @@ -64,17 +65,17 @@ public class GroupWikiIndexer extends FolderIndexer{ if (collabTools.isToolEnabled(CollaborationTools.TOOL_WIKI) ) { try { Wiki wiki = WikiManager.getInstance().getOrLoadWiki(businessGroup); - // loop over all wiki pages - List<WikiPage> wikiPageList = wiki.getAllPagesWithContent(); - for (WikiPage wikiPage : wikiPageList) { - SearchResourceContext wikiResourceContext = new SearchResourceContext(parentResourceContext); - wikiResourceContext.setBusinessControlFor(BusinessGroupMainRunController.ORES_TOOLWIKI); - wikiResourceContext.setDocumentType(TYPE); - wikiResourceContext.setFilePath(wikiPage.getPageName()); + // loop over all wiki pages + List<WikiPage> wikiPageList = wiki.getAllPagesWithContent(); + for (WikiPage wikiPage : wikiPageList) { + SearchResourceContext wikiResourceContext = new SearchResourceContext(parentResourceContext); + wikiResourceContext.setBusinessControlFor(BusinessGroupMainRunController.ORES_TOOLWIKI); + wikiResourceContext.setDocumentType(TYPE); + wikiResourceContext.setFilePath(wikiPage.getPageName()); - Document document = WikiPageDocument.createDocument(wikiResourceContext, wikiPage); - indexWriter.addDocument(document); - } + Document document = WikiPageDocument.createDocument(wikiResourceContext, wikiPage); + indexWriter.addDocument(document); + } } catch (NullPointerException nex) { logWarn("NullPointerException in GroupWikiIndexer.doIndex.", nex); } diff --git a/src/main/java/org/olat/search/service/indexer/identity/IdentityIndexer.java b/src/main/java/org/olat/search/service/indexer/identity/IdentityIndexer.java index ef16df93bf8..10245ea97c1 100644 --- a/src/main/java/org/olat/search/service/indexer/identity/IdentityIndexer.java +++ b/src/main/java/org/olat/search/service/indexer/identity/IdentityIndexer.java @@ -53,32 +53,26 @@ public class IdentityIndexer extends AbstractHierarchicalIndexer { } @Override - public void doIndex(SearchResourceContext parentResourceContext, Object parentObject, OlatFullIndexer indexWriter) throws IOException, - InterruptedException { + public void doIndex(SearchResourceContext parentResourceContext, Object parentObject, OlatFullIndexer indexWriter) + throws IOException, InterruptedException { - int counter = 0; - BaseSecurity secMgr = BaseSecurityManager.getInstance(); - List<Identity> identities = secMgr.getIdentitiesByPowerSearch(null, null, true, null, null, null, null, null, null, null, Identity.STATUS_ACTIV); - if (isLogDebugEnabled()) logDebug("Found " + identities.size() + " active identities to index"); - - // committing here to make sure the loadBusinessGroup below does actually - // reload from the database and not only use the session cache - // (see org.hibernate.Session.get(): - // If the instance, or a proxy for the instance, is already associated with the session, return that instance or proxy.) - DBFactory.getInstance().commitAndCloseSession(); + int counter = 0; + BaseSecurity secMgr = BaseSecurityManager.getInstance(); + List<Identity> identities = secMgr.getIdentitiesByPowerSearch(null, null, true, null, null, null, null, null, null, null, Identity.STATUS_ACTIV); + if (isLogDebugEnabled()) logDebug("Found " + identities.size() + " active identities to index"); + DBFactory.getInstance().commitAndCloseSession(); - for (Identity identity : identities) { - try { - // reload the businessGroup here before indexing it to make sure it has not been deleted in the meantime - Identity reloadedIdentity = secMgr.findIdentityByName(identity.getName()); - if (reloadedIdentity==null || (reloadedIdentity.getStatus()>=Identity.STATUS_VISIBLE_LIMIT)) { + for (Identity identity : identities) { + try { + // reload the identity here before indexing it to make sure it has not been deleted in the meantime + identity = secMgr.findIdentityByName(identity.getName()); + if (identity == null || (identity.getStatus()>=Identity.STATUS_VISIBLE_LIMIT)) { logInfo("doIndex: identity was deleted while we were indexing. The deleted identity was: "+identity); continue; } - identity = reloadedIdentity; - if (isLogDebugEnabled()) logDebug("Indexing identity::" + identity.getName() + " and counter::" + counter); - // Create a search context for this identity. The search context will open the users visiting card in a new tab + if (isLogDebugEnabled()) logDebug("Indexing identity::" + identity.getName() + " and counter::" + counter); + // Create a search context for this identity. The search context will open the users visiting card in a new tab SearchResourceContext searchResourceContext = new SearchResourceContext(parentResourceContext); searchResourceContext.setBusinessControlFor(OresHelper.createOLATResourceableInstance(Identity.class, identity.getKey())); searchResourceContext.setParentContextType(TYPE); @@ -88,12 +82,12 @@ public class IdentityIndexer extends AbstractHierarchicalIndexer { indexer.doIndex(searchResourceContext, identity, indexWriter); } - counter++; + counter++; } catch (Exception ex) { logWarn("Exception while indexing identity::" + identity.getName() + ". Skipping this user, try next one.", ex); DBFactory.getInstance(false).rollbackAndCloseSession(); } } - if (isLogDebugEnabled()) logDebug("IdentityIndexer finished with counter::" + counter); + if (isLogDebugEnabled()) logDebug("IdentityIndexer finished with counter::" + counter); } } diff --git a/src/main/java/org/olat/search/service/indexer/identity/ProfileIndexer.java b/src/main/java/org/olat/search/service/indexer/identity/ProfileIndexer.java index 641ea2a04b1..7a6249e1676 100644 --- a/src/main/java/org/olat/search/service/indexer/identity/ProfileIndexer.java +++ b/src/main/java/org/olat/search/service/indexer/identity/ProfileIndexer.java @@ -42,6 +42,7 @@ public class ProfileIndexer extends AbstractHierarchicalIndexer { /** * @see org.olat.search.service.indexer.Indexer#getSupportedTypeName() */ + @Override public String getSupportedTypeName() { return Identity.class.getSimpleName(); } @@ -62,6 +63,5 @@ public class ProfileIndexer extends AbstractHierarchicalIndexer { logWarn("Exception while indexing profile for identity::" + parentObject.toString() + ". Skipping this user, try next one.", ex); } if (isLogDebugEnabled()) logDebug("ProfileIndexer finished for user::" + parentObject.toString()); - } } diff --git a/src/main/java/org/olat/search/service/indexer/identity/PublicFolderIndexer.java b/src/main/java/org/olat/search/service/indexer/identity/PublicFolderIndexer.java index c37ed9661fb..1a8a94f05a0 100644 --- a/src/main/java/org/olat/search/service/indexer/identity/PublicFolderIndexer.java +++ b/src/main/java/org/olat/search/service/indexer/identity/PublicFolderIndexer.java @@ -45,6 +45,7 @@ public class PublicFolderIndexer extends FolderIndexer { /** * @see org.olat.search.service.indexer.Indexer#getSupportedTypeName() */ + @Override public String getSupportedTypeName() { return Identity.class.getSimpleName(); } @@ -52,7 +53,7 @@ public class PublicFolderIndexer extends FolderIndexer { /** * @see org.olat.repository.handlers.RepositoryHandler#supportsDownload() */ - + @Override public void doIndex(SearchResourceContext parentResourceContext, Object parentObject, OlatFullIndexer indexWriter) { try { diff --git a/src/main/java/org/olat/search/service/indexer/repository/ImsCPRepositoryIndexer.java b/src/main/java/org/olat/search/service/indexer/repository/ImsCPRepositoryIndexer.java index 5a7543f69c7..380584886ff 100644 --- a/src/main/java/org/olat/search/service/indexer/repository/ImsCPRepositoryIndexer.java +++ b/src/main/java/org/olat/search/service/indexer/repository/ImsCPRepositoryIndexer.java @@ -28,7 +28,6 @@ package org.olat.search.service.indexer.repository; import java.io.File; import java.io.IOException; -import org.olat.core.logging.AssertException; import org.olat.core.util.vfs.LocalFolderImpl; import org.olat.core.util.vfs.VFSContainer; import org.olat.fileresource.FileResourceManager; @@ -49,10 +48,8 @@ public class ImsCPRepositoryIndexer extends FolderIndexer { public final static String TYPE = "type.repository.entry.imscp"; public final static String ORES_TYPE_CP = ImsCPFileResource.TYPE_NAME; - - /** - * - */ + + @Override public String getSupportedTypeName() { return ORES_TYPE_CP; } @@ -64,15 +61,15 @@ public class ImsCPRepositoryIndexer extends FolderIndexer { public void doIndex(SearchResourceContext resourceContext, Object parentObject, OlatFullIndexer indexWriter) throws IOException,InterruptedException { RepositoryEntry repositoryEntry = (RepositoryEntry) parentObject; if (isLogDebugEnabled()) logDebug("Analyse IMS CP RepositoryEntry..."); - resourceContext.setDocumentType(TYPE); - if (repositoryEntry == null) throw new AssertException("no Repository"); - File cpRoot = FileResourceManager.getInstance().unzipFileResource(repositoryEntry.getOlatResource()); - if (cpRoot == null) throw new AssertException("file of repository entry " + repositoryEntry.getKey() + "was missing"); - - SearchResourceContext cpContext = new SearchResourceContext(resourceContext); - VFSContainer rootContainer = new LocalFolderImpl(cpRoot); - doIndexVFSContainer(cpContext, rootContainer, indexWriter, "", FolderIndexerAccess.FULL_ACCESS); + if (repositoryEntry != null) { + File cpRoot = FileResourceManager.getInstance().unzipFileResource(repositoryEntry.getOlatResource()); + if (cpRoot != null) { + SearchResourceContext cpContext = new SearchResourceContext(resourceContext); + VFSContainer rootContainer = new LocalFolderImpl(cpRoot); + doIndexVFSContainer(cpContext, rootContainer, indexWriter, "", FolderIndexerAccess.FULL_ACCESS); + } + } } } diff --git a/src/main/java/org/olat/search/service/indexer/repository/course/BCCourseNodeIndexer.java b/src/main/java/org/olat/search/service/indexer/repository/course/BCCourseNodeIndexer.java index c26cf35458f..179854487ce 100644 --- a/src/main/java/org/olat/search/service/indexer/repository/course/BCCourseNodeIndexer.java +++ b/src/main/java/org/olat/search/service/indexer/repository/course/BCCourseNodeIndexer.java @@ -48,19 +48,21 @@ public class BCCourseNodeIndexer extends FolderIndexer implements CourseNodeInde private final static String SUPPORTED_TYPE_NAME = "org.olat.course.nodes.BCCourseNode"; + @Override public void doIndex(SearchResourceContext repositoryResourceContext, ICourse course, CourseNode courseNode, OlatFullIndexer indexWriter) throws IOException,InterruptedException { if (isLogDebugEnabled()) logDebug("Index Briefcase..." ); - SearchResourceContext courseNodeResourceContext = new SearchResourceContext(repositoryResourceContext); - courseNodeResourceContext.setBusinessControlFor(courseNode); - courseNodeResourceContext.setDocumentType(TYPE); - courseNodeResourceContext.setTitle(courseNode.getShortTitle()); - courseNodeResourceContext.setDescription(courseNode.getLongTitle()); + SearchResourceContext courseNodeResourceContext = new SearchResourceContext(repositoryResourceContext); + courseNodeResourceContext.setBusinessControlFor(courseNode); + courseNodeResourceContext.setDocumentType(TYPE); + courseNodeResourceContext.setTitle(courseNode.getShortTitle()); + courseNodeResourceContext.setDescription(courseNode.getLongTitle()); OlatNamedContainerImpl namedContainer = BCCourseNode.getNodeFolderContainer((BCCourseNode) courseNode, course.getCourseEnvironment()); doIndexVFSContainer(courseNodeResourceContext,namedContainer,indexWriter,"", FolderIndexerAccess.FULL_ACCESS); } + @Override public String getSupportedTypeName() { return SUPPORTED_TYPE_NAME; } diff --git a/src/main/java/org/olat/search/service/indexer/repository/course/CPCourseNodeIndexer.java b/src/main/java/org/olat/search/service/indexer/repository/course/CPCourseNodeIndexer.java index b6740ac4f5a..45f2d2439a9 100644 --- a/src/main/java/org/olat/search/service/indexer/repository/course/CPCourseNodeIndexer.java +++ b/src/main/java/org/olat/search/service/indexer/repository/course/CPCourseNodeIndexer.java @@ -66,7 +66,7 @@ public class CPCourseNodeIndexer extends FolderIndexer implements CourseNodeInde File cpRoot = FileResourceManager.getInstance().unzipFileResource(re.getOlatResource()); if(cpRoot != null) { VFSContainer rootContainer = new LocalFolderImpl(cpRoot); - doIndexVFSContainer(courseNodeResourceContext,rootContainer,indexWriter,"", FolderIndexerAccess.FULL_ACCESS); + doIndexVFSContainer(courseNodeResourceContext, rootContainer, indexWriter, "", FolderIndexerAccess.FULL_ACCESS); } } } diff --git a/src/main/java/org/olat/search/service/indexer/repository/course/DialogCourseNodeIndexer.java b/src/main/java/org/olat/search/service/indexer/repository/course/DialogCourseNodeIndexer.java index fed0cfdd8a1..c6142f03e09 100644 --- a/src/main/java/org/olat/search/service/indexer/repository/course/DialogCourseNodeIndexer.java +++ b/src/main/java/org/olat/search/service/indexer/repository/course/DialogCourseNodeIndexer.java @@ -80,14 +80,15 @@ public class DialogCourseNodeIndexer extends DefaultIndexer implements CourseNod // } + @Override public void doIndex(SearchResourceContext repositoryResourceContext, ICourse course, CourseNode courseNode, OlatFullIndexer indexWriter) throws IOException,InterruptedException { - SearchResourceContext courseNodeResourceContext = new SearchResourceContext(repositoryResourceContext); - courseNodeResourceContext.setBusinessControlFor(courseNode); - courseNodeResourceContext.setTitle(courseNode.getShortTitle()); - courseNodeResourceContext.setDescription(courseNode.getLongTitle()); + SearchResourceContext courseNodeResourceContext = new SearchResourceContext(repositoryResourceContext); + courseNodeResourceContext.setBusinessControlFor(courseNode); + courseNodeResourceContext.setTitle(courseNode.getShortTitle()); + courseNodeResourceContext.setDescription(courseNode.getLongTitle()); - CoursePropertyManager coursePropMgr = course.getCourseEnvironment().getCoursePropertyManager(); - DialogElementsPropertyManager dialogElmsMgr = DialogElementsPropertyManager.getInstance(); + CoursePropertyManager coursePropMgr = course.getCourseEnvironment().getCoursePropertyManager(); + DialogElementsPropertyManager dialogElmsMgr = DialogElementsPropertyManager.getInstance(); DialogPropertyElements elements = dialogElmsMgr.findDialogElements(coursePropMgr, courseNode); List<DialogElement> list = new ArrayList<DialogElement>(); if (elements != null) list = elements.getDialogPropertyElements(); @@ -96,7 +97,7 @@ public class DialogCourseNodeIndexer extends DefaultIndexer implements CourseNod DialogElement element = iter.next(); element.getAuthor(); element.getDate(); - Forum forum = ForumManager.getInstance().loadForum(element.getForumKey()); + Forum forum = ForumManager.getInstance().loadForum(element.getForumKey()); // do IndexForum doIndexAllMessages(courseNodeResourceContext, forum, indexWriter ); // do Index File @@ -121,10 +122,10 @@ public class DialogCourseNodeIndexer extends DefaultIndexer implements CourseNod if (CoreSpringFactory.getImpl(FileDocumentFactory.class).isFileSupported(leaf)) { leafResourceContext.setFilePath(filename); leafResourceContext.setDocumentType(TYPE_FILE); - //fxdiff FXOLAT-97: high CPU load tracker + WorkThreadInformations.set("Index Dialog VFSLeaf=" + filename + " at " + leafResourceContext.getResourceUrl()); - Document document = CoreSpringFactory.getImpl(FileDocumentFactory.class).createDocument(leafResourceContext, leaf); - indexWriter.addDocument(document); + Document document = CoreSpringFactory.getImpl(FileDocumentFactory.class).createDocument(leafResourceContext, leaf); + indexWriter.addDocument(document); } else { if (isLogDebugEnabled()) logDebug("Documenttype not supported. file=" + leaf.getName()); } @@ -134,11 +135,10 @@ public class DialogCourseNodeIndexer extends DefaultIndexer implements CourseNod logWarn("IOException: Can not index leaf=" + leaf.getName(), ioEx); } catch (InterruptedException iex) { throw new InterruptedException(iex.getMessage()); - } catch (Exception ex) { + } catch (Exception ex) { logWarn("Exception: Can not index leaf=" + leaf.getName(), ex); - //fxdiff FXOLAT-97: high CPU load tracker } finally { - WorkThreadInformations.unset(); + WorkThreadInformations.unset(); } } @@ -154,10 +154,12 @@ public class DialogCourseNodeIndexer extends DefaultIndexer implements CourseNod } } + @Override public String getSupportedTypeName() { return SUPPORTED_TYPE_NAME; } + @Override public boolean checkAccess(ContextEntry contextEntry, BusinessControl businessControl, Identity identity, Roles roles) { ContextEntry ce = businessControl.popLauncherContextEntry(); OLATResourceable ores = ce.getOLATResourceable(); @@ -175,7 +177,7 @@ public class DialogCourseNodeIndexer extends DefaultIndexer implements CourseNod } boolean isMessageHidden = Status.getStatus(threadtop.getStatusCode()).isHidden(); //assumes that if is owner then is moderator so it is allowed to see the hidden forum threads - //TODO: (LD) fix this!!! - the contextEntry is not the right context for this check + //TODO: (LD) fix this!!! - the contextEntry is not the right context for this check boolean isOwner = BaseSecurityManager.getInstance().isIdentityPermittedOnResourceable(identity, Constants.PERMISSION_ACCESS, contextEntry.getOLATResourceable()); if(isMessageHidden && !isOwner) { return false; @@ -186,5 +188,4 @@ public class DialogCourseNodeIndexer extends DefaultIndexer implements CourseNod return false; } } - } diff --git a/src/main/java/org/olat/search/service/indexer/repository/course/FOCourseNodeIndexer.java b/src/main/java/org/olat/search/service/indexer/repository/course/FOCourseNodeIndexer.java index af7bb9230c8..fd11d7357f8 100644 --- a/src/main/java/org/olat/search/service/indexer/repository/course/FOCourseNodeIndexer.java +++ b/src/main/java/org/olat/search/service/indexer/repository/course/FOCourseNodeIndexer.java @@ -59,15 +59,16 @@ public class FOCourseNodeIndexer extends ForumIndexer implements CourseNodeIndex public final static String TYPE = "type.course.node.forum.message"; private final static String SUPPORTED_TYPE_NAME = "org.olat.course.nodes.FOCourseNode"; - + + @Override public void doIndex(SearchResourceContext repositoryResourceContext, ICourse course, CourseNode courseNode, OlatFullIndexer indexWriter) { try { SearchResourceContext courseNodeResourceContext = new SearchResourceContext(repositoryResourceContext); - courseNodeResourceContext.setBusinessControlFor(courseNode); - courseNodeResourceContext.setDocumentType(TYPE); - courseNodeResourceContext.setTitle(courseNode.getShortTitle()); - courseNodeResourceContext.setDescription(courseNode.getLongTitle()); - doIndexForum(courseNodeResourceContext, course, courseNode, indexWriter); + courseNodeResourceContext.setBusinessControlFor(courseNode); + courseNodeResourceContext.setDocumentType(TYPE); + courseNodeResourceContext.setTitle(courseNode.getShortTitle()); + courseNodeResourceContext.setDescription(courseNode.getLongTitle()); + doIndexForum(courseNodeResourceContext, course, courseNode, indexWriter); } catch(Exception ex) { log.error("Exception indexing courseNode=" + courseNode, ex); } catch (Error err) { @@ -75,10 +76,12 @@ public class FOCourseNodeIndexer extends ForumIndexer implements CourseNodeIndex } } + @Override public String getSupportedTypeName() { return SUPPORTED_TYPE_NAME; } + @Override public boolean checkAccess(ContextEntry contextEntry, BusinessControl businessControl, Identity identity, Roles roles) { ContextEntry ce = businessControl.popLauncherContextEntry(); Long resourceableId = ce.getOLATResourceable().getResourceableId(); diff --git a/src/main/java/org/olat/search/service/indexer/repository/course/ProjectBrokerCourseNodeIndexer.java b/src/main/java/org/olat/search/service/indexer/repository/course/ProjectBrokerCourseNodeIndexer.java index 2388a97ca2d..a0e3052f7d1 100644 --- a/src/main/java/org/olat/search/service/indexer/repository/course/ProjectBrokerCourseNodeIndexer.java +++ b/src/main/java/org/olat/search/service/indexer/repository/course/ProjectBrokerCourseNodeIndexer.java @@ -40,28 +40,29 @@ import org.olat.course.nodes.projectbroker.service.ProjectBrokerManager; import org.olat.course.properties.CoursePropertyManager; import org.olat.search.service.SearchResourceContext; import org.olat.search.service.document.ProjectBrokerProjectDocument; -import org.olat.search.service.indexer.FolderIndexer; +import org.olat.search.service.indexer.AbstractHierarchicalIndexer; import org.olat.search.service.indexer.OlatFullIndexer; /** * Indexer for project-broker course-node. * @author Christian Guretzki */ -public class ProjectBrokerCourseNodeIndexer extends FolderIndexer implements CourseNodeIndexer { - private OLog log = Tracing.createLoggerFor(this.getClass()); +public class ProjectBrokerCourseNodeIndexer extends AbstractHierarchicalIndexer implements CourseNodeIndexer { + private static final OLog log = Tracing.createLoggerFor(ProjectBrokerCourseNodeIndexer.class); public static final String TYPE = "type.course.node.projectbroker"; private final static String SUPPORTED_TYPE_NAME = "org.olat.course.nodes.ProjectBrokerCourseNode"; + @Override public void doIndex(SearchResourceContext repositoryResourceContext, ICourse course, CourseNode courseNode, OlatFullIndexer indexWriter) throws IOException,InterruptedException { - SearchResourceContext courseNodeResourceContext = new SearchResourceContext(repositoryResourceContext); - courseNodeResourceContext.setBusinessControlFor(courseNode); - courseNodeResourceContext.setDocumentType(TYPE); - courseNodeResourceContext.setTitle(courseNode.getShortTitle()); - courseNodeResourceContext.setDescription(courseNode.getLongTitle()); + SearchResourceContext courseNodeResourceContext = new SearchResourceContext(repositoryResourceContext); + courseNodeResourceContext.setBusinessControlFor(courseNode); + courseNodeResourceContext.setDocumentType(TYPE); + courseNodeResourceContext.setTitle(courseNode.getShortTitle()); + courseNodeResourceContext.setDescription(courseNode.getLongTitle()); - // go further, index my projects + // go further, index my projects CoursePropertyManager cpm = course.getCourseEnvironment().getCoursePropertyManager(); ProjectBrokerManager projectBrokerManager = CoreSpringFactory.getImpl(ProjectBrokerManager.class); Long projectBrokerId = projectBrokerManager.getProjectBrokerId(cpm, courseNode); @@ -71,12 +72,13 @@ public class ProjectBrokerCourseNodeIndexer extends FolderIndexer implements Cou Project project = iterator.next(); Document document = ProjectBrokerProjectDocument.createDocument(courseNodeResourceContext, project); indexWriter.addDocument(document); - } + } } else { log.debug("projectBrokerId is null, courseNode=" + courseNode + " , course=" + course); } } + @Override public String getSupportedTypeName() { return SUPPORTED_TYPE_NAME; } diff --git a/src/main/java/org/olat/search/service/indexer/repository/course/SPCourseNodeIndexer.java b/src/main/java/org/olat/search/service/indexer/repository/course/SPCourseNodeIndexer.java index 86c7d924d39..14d11759a13 100644 --- a/src/main/java/org/olat/search/service/indexer/repository/course/SPCourseNodeIndexer.java +++ b/src/main/java/org/olat/search/service/indexer/repository/course/SPCourseNodeIndexer.java @@ -45,14 +45,14 @@ import org.olat.course.nodes.CourseNode; import org.olat.course.nodes.SPCourseNode; import org.olat.course.nodes.sp.SPEditController; import org.olat.search.service.SearchResourceContext; -import org.olat.search.service.indexer.FolderIndexer; +import org.olat.search.service.indexer.LeafIndexer; import org.olat.search.service.indexer.OlatFullIndexer; /** * Indexer for SP (SinglePage) course-node. * @author Christian Guretzki */ -public class SPCourseNodeIndexer extends FolderIndexer implements CourseNodeIndexer { +public class SPCourseNodeIndexer extends LeafIndexer implements CourseNodeIndexer { private static final OLog log = Tracing.createLoggerFor(SPCourseNodeIndexer.class); // Must correspond with LocalString_xx.properties @@ -60,40 +60,41 @@ public class SPCourseNodeIndexer extends FolderIndexer implements CourseNodeInde public final static String TYPE = "type.course.node.sp"; private final static String SUPPORTED_TYPE_NAME = "org.olat.course.nodes.SPCourseNode"; - private final static boolean indexOnlyChosenFile = false; + private final static boolean indexOnlyChosenFile = false; - private static final Pattern HREF_PATTERN = Pattern.compile("href=\\\"([^\\\"]*)\\\"", Pattern.MULTILINE | Pattern.CASE_INSENSITIVE); - private static final String HTML_SUFFIXES = "html htm xhtml xml"; + private static final Pattern HREF_PATTERN = Pattern.compile("href=\\\"([^\\\"]*)\\\"", Pattern.MULTILINE | Pattern.CASE_INSENSITIVE); + private static final String HTML_SUFFIXES = "html htm xhtml xml"; + @Override public void doIndex(SearchResourceContext repositoryResourceContext, ICourse course, CourseNode courseNode, OlatFullIndexer indexWriter) throws IOException,InterruptedException { if (log.isDebug()) log.debug("Index SinglePage..."); - SearchResourceContext courseNodeResourceContext = new SearchResourceContext(repositoryResourceContext); - courseNodeResourceContext.setBusinessControlFor(courseNode); - courseNodeResourceContext.setDocumentType(TYPE); - courseNodeResourceContext.setTitle(courseNode.getShortTitle()); - courseNodeResourceContext.setDescription(courseNode.getLongTitle()); + SearchResourceContext courseNodeResourceContext = new SearchResourceContext(repositoryResourceContext); + courseNodeResourceContext.setBusinessControlFor(courseNode); + courseNodeResourceContext.setDocumentType(TYPE); + courseNodeResourceContext.setTitle(courseNode.getShortTitle()); + courseNodeResourceContext.setDescription(courseNode.getLongTitle()); - VFSContainer rootContainer = SPCourseNode.getNodeFolderContainer((SPCourseNode) courseNode, course.getCourseEnvironment()); - String chosenFile = (String) courseNode.getModuleConfiguration().get(SPEditController.CONFIG_KEY_FILE); - // First: Index choosen HTML file - if (log.isDebug()) log.debug("Index chosen file in SP. chosenFile=" + chosenFile); - VFSLeaf leaf = (VFSLeaf)rootContainer.resolve(chosenFile); - if (leaf != null) { - String filePath = getPathFor(leaf); - if (log.isDebug()) log.debug("Found chosen file in SP. filePath=" + filePath ); - doIndexVFSLeafByMySelf(courseNodeResourceContext, leaf, indexWriter, filePath); - if (!indexOnlyChosenFile) { - if (log.isDebug()) log.debug("Index sub pages in SP."); - Set<String> alreadyIndexFileNames = new HashSet<String>(); - alreadyIndexFileNames.add(chosenFile); - indexSubPages(courseNodeResourceContext,rootContainer,indexWriter,leaf,alreadyIndexFileNames,0,filePath); - } else { - if (log.isDebug()) log.debug("Index only chosen file in SP."); - } - } else { - if (log.isDebug()) log.debug("Can not found choosen file in SP => Nothing indexed."); - } + VFSContainer rootContainer = SPCourseNode.getNodeFolderContainer((SPCourseNode) courseNode, course.getCourseEnvironment()); + String chosenFile = (String) courseNode.getModuleConfiguration().get(SPEditController.CONFIG_KEY_FILE); + // First: Index choosen HTML file + if (log.isDebug()) log.debug("Index chosen file in SP. chosenFile=" + chosenFile); + VFSLeaf leaf = (VFSLeaf)rootContainer.resolve(chosenFile); + if (leaf != null) { + String filePath = getPathFor(leaf); + if (log.isDebug()) log.debug("Found chosen file in SP. filePath=" + filePath ); + doIndexVFSLeafByMySelf(courseNodeResourceContext, leaf, indexWriter, filePath); + if (!indexOnlyChosenFile) { + if (log.isDebug()) log.debug("Index sub pages in SP."); + Set<String> alreadyIndexFileNames = new HashSet<String>(); + alreadyIndexFileNames.add(chosenFile); + indexSubPages(courseNodeResourceContext,rootContainer,indexWriter,leaf,alreadyIndexFileNames,0,filePath); + } else if (log.isDebug()) { + log.debug("Index only chosen file in SP."); + } + } else if (log.isDebug()) { + log.debug("Can not found choosen file in SP => Nothing indexed."); + } } public String getSupportedTypeName() { diff --git a/src/main/java/org/olat/search/service/indexer/repository/course/STCourseNodeIndexer.java b/src/main/java/org/olat/search/service/indexer/repository/course/STCourseNodeIndexer.java index d7d4259dfe3..7a9ffc0a9e9 100644 --- a/src/main/java/org/olat/search/service/indexer/repository/course/STCourseNodeIndexer.java +++ b/src/main/java/org/olat/search/service/indexer/repository/course/STCourseNodeIndexer.java @@ -38,14 +38,14 @@ import org.olat.course.nodes.st.STCourseNodeEditController; import org.olat.modules.ModuleConfiguration; import org.olat.search.service.SearchResourceContext; import org.olat.search.service.document.CourseNodeDocument; -import org.olat.search.service.indexer.FolderIndexer; +import org.olat.search.service.indexer.LeafIndexer; import org.olat.search.service.indexer.OlatFullIndexer; /** * Indexer for ST (Structure) course-node. * @author Christian Guretzki */ -public class STCourseNodeIndexer extends FolderIndexer implements CourseNodeIndexer { +public class STCourseNodeIndexer extends LeafIndexer implements CourseNodeIndexer { private static final OLog log = Tracing.createLoggerFor(STCourseNodeIndexer.class); // Must correspond with LocalString_xx.properties @@ -60,16 +60,17 @@ public class STCourseNodeIndexer extends FolderIndexer implements CourseNodeInde // } + @Override public void doIndex(SearchResourceContext repositoryResourceContext, ICourse course, CourseNode courseNode, OlatFullIndexer indexWriter) throws IOException,InterruptedException { if (log.isDebug()) log.debug("Index StructureNode..."); SearchResourceContext courseNodeResourceContext = new SearchResourceContext(repositoryResourceContext); courseNodeResourceContext.setBusinessControlFor(courseNode); - courseNodeResourceContext.setDocumentType(TYPE); - courseNodeResourceContext.setTitle(courseNode.getShortTitle()); - courseNodeResourceContext.setDescription(courseNode.getLongTitle()); + courseNodeResourceContext.setDocumentType(TYPE); + courseNodeResourceContext.setTitle(courseNode.getShortTitle()); + courseNodeResourceContext.setDescription(courseNode.getLongTitle()); - Document document = CourseNodeDocument.createDocument(courseNodeResourceContext, courseNode); + Document document = CourseNodeDocument.createDocument(courseNodeResourceContext, courseNode); indexWriter.addDocument(document); ModuleConfiguration config = courseNode.getModuleConfiguration(); @@ -83,6 +84,7 @@ public class STCourseNodeIndexer extends FolderIndexer implements CourseNodeInde } } + @Override public String getSupportedTypeName() { return SUPPORTED_TYPE_NAME; } diff --git a/src/main/java/org/olat/search/service/indexer/repository/course/TACourseNodeIndexer.java b/src/main/java/org/olat/search/service/indexer/repository/course/TACourseNodeIndexer.java index 34b45677ab9..ae3ba59f83d 100644 --- a/src/main/java/org/olat/search/service/indexer/repository/course/TACourseNodeIndexer.java +++ b/src/main/java/org/olat/search/service/indexer/repository/course/TACourseNodeIndexer.java @@ -58,37 +58,37 @@ public class TACourseNodeIndexer extends FolderIndexer implements CourseNodeInde @Override public void doIndex(SearchResourceContext repositoryResourceContext, ICourse course, CourseNode courseNode, OlatFullIndexer indexWriter) throws IOException,InterruptedException { - SearchResourceContext courseNodeResourceContext = new SearchResourceContext(repositoryResourceContext); - courseNodeResourceContext.setBusinessControlFor(courseNode); - courseNodeResourceContext.setTitle(courseNode.getShortTitle()); - courseNodeResourceContext.setDescription(courseNode.getLongTitle()); + SearchResourceContext courseNodeResourceContext = new SearchResourceContext(repositoryResourceContext); + courseNodeResourceContext.setBusinessControlFor(courseNode); + courseNodeResourceContext.setTitle(courseNode.getShortTitle()); + courseNodeResourceContext.setDescription(courseNode.getLongTitle()); - // Index Task - File fTaskfolder = new File(FolderConfig.getCanonicalRoot() + TACourseNode.getTaskFolderPathRelToFolderRoot(course.getCourseEnvironment(), courseNode)); - VFSContainer taskRootContainer = new LocalFolderImpl(fTaskfolder); - courseNodeResourceContext.setDocumentType(TYPE_TASK); - doIndexVFSContainer(courseNodeResourceContext, taskRootContainer, indexWriter, "", FolderIndexerAccess.FULL_ACCESS); - - // Index Dropbox - String dropboxFilePath = FolderConfig.getCanonicalRoot() + DropboxController.getDropboxPathRelToFolderRoot(course.getCourseEnvironment(), courseNode); - File fDropboxFolder = new File(dropboxFilePath); - VFSContainer dropboxRootContainer = new LocalFolderImpl(fDropboxFolder); - courseNodeResourceContext.setDocumentType(TYPE_DROPBOX); - doIndexVFSContainer(courseNodeResourceContext, dropboxRootContainer, indexWriter, "", FolderIndexerAccess.FULL_ACCESS); - - // Index Returnbox - String returnboxFilePath = FolderConfig.getCanonicalRoot() + ReturnboxController.getReturnboxPathRelToFolderRoot(course.getCourseEnvironment(), courseNode); - File fResturnboxFolder = new File(returnboxFilePath); - VFSContainer returnboxRootContainer = new LocalFolderImpl(fResturnboxFolder); - courseNodeResourceContext.setDocumentType(TYPE_RETURNBOX); - doIndexVFSContainer(courseNodeResourceContext, returnboxRootContainer, indexWriter, "", FolderIndexerAccess.FULL_ACCESS); - - // Index Solutionbox - String solutionFilePath = FolderConfig.getCanonicalRoot() + SolutionController.getSolutionPathRelToFolderRoot(course.getCourseEnvironment(), courseNode); - File fSolutionFolder = new File(solutionFilePath); - VFSContainer solutionRootContainer = new LocalFolderImpl(fSolutionFolder); - courseNodeResourceContext.setDocumentType(TYPE_SOLUTIONBOX); - doIndexVFSContainer(courseNodeResourceContext, solutionRootContainer, indexWriter, "", FolderIndexerAccess.FULL_ACCESS); + // Index Task + File fTaskfolder = new File(FolderConfig.getCanonicalRoot() + TACourseNode.getTaskFolderPathRelToFolderRoot(course.getCourseEnvironment(), courseNode)); + VFSContainer taskRootContainer = new LocalFolderImpl(fTaskfolder); + courseNodeResourceContext.setDocumentType(TYPE_TASK); + doIndexVFSContainer(courseNodeResourceContext, taskRootContainer, indexWriter, "", FolderIndexerAccess.FULL_ACCESS); + + // Index Dropbox + String dropboxFilePath = FolderConfig.getCanonicalRoot() + DropboxController.getDropboxPathRelToFolderRoot(course.getCourseEnvironment(), courseNode); + File fDropboxFolder = new File(dropboxFilePath); + VFSContainer dropboxRootContainer = new LocalFolderImpl(fDropboxFolder); + courseNodeResourceContext.setDocumentType(TYPE_DROPBOX); + doIndexVFSContainer(courseNodeResourceContext, dropboxRootContainer, indexWriter, "", FolderIndexerAccess.FULL_ACCESS); + + // Index Returnbox + String returnboxFilePath = FolderConfig.getCanonicalRoot() + ReturnboxController.getReturnboxPathRelToFolderRoot(course.getCourseEnvironment(), courseNode); + File fResturnboxFolder = new File(returnboxFilePath); + VFSContainer returnboxRootContainer = new LocalFolderImpl(fResturnboxFolder); + courseNodeResourceContext.setDocumentType(TYPE_RETURNBOX); + doIndexVFSContainer(courseNodeResourceContext, returnboxRootContainer, indexWriter, "", FolderIndexerAccess.FULL_ACCESS); + + // Index Solutionbox + String solutionFilePath = FolderConfig.getCanonicalRoot() + SolutionController.getSolutionPathRelToFolderRoot(course.getCourseEnvironment(), courseNode); + File fSolutionFolder = new File(solutionFilePath); + VFSContainer solutionRootContainer = new LocalFolderImpl(fSolutionFolder); + courseNodeResourceContext.setDocumentType(TYPE_SOLUTIONBOX); + doIndexVFSContainer(courseNodeResourceContext, solutionRootContainer, indexWriter, "", FolderIndexerAccess.FULL_ACCESS); } @Override diff --git a/src/main/java/org/olat/search/service/indexer/repository/course/WikiCourseNodeIndexer.java b/src/main/java/org/olat/search/service/indexer/repository/course/WikiCourseNodeIndexer.java index 09ce829146e..b6360603385 100644 --- a/src/main/java/org/olat/search/service/indexer/repository/course/WikiCourseNodeIndexer.java +++ b/src/main/java/org/olat/search/service/indexer/repository/course/WikiCourseNodeIndexer.java @@ -38,14 +38,14 @@ import org.olat.modules.wiki.WikiPage; import org.olat.repository.RepositoryEntry; import org.olat.search.service.SearchResourceContext; import org.olat.search.service.document.WikiPageDocument; -import org.olat.search.service.indexer.FolderIndexer; +import org.olat.search.service.indexer.AbstractHierarchicalIndexer; import org.olat.search.service.indexer.OlatFullIndexer; /** * Indexer for Wiki course-node. * @author Christian Guretzki */ -public class WikiCourseNodeIndexer extends FolderIndexer implements CourseNodeIndexer { +public class WikiCourseNodeIndexer extends AbstractHierarchicalIndexer implements CourseNodeIndexer { private static final OLog log = Tracing.createLoggerFor(WikiCourseNodeIndexer.class); // Must correspond with LocalString_xx.properties @@ -58,20 +58,21 @@ public class WikiCourseNodeIndexer extends FolderIndexer implements CourseNodeIn public void doIndex(SearchResourceContext repositoryResourceContext, ICourse course, CourseNode courseNode, OlatFullIndexer indexWriter) { if (log.isDebug()) log.debug("Index wiki..."); String repoEntryName = "*name not available*"; - try { - RepositoryEntry repositoryEntry = courseNode.getReferencedRepositoryEntry(); - if(repositoryEntry == null) return; - repoEntryName = repositoryEntry.getDisplayname(); + try { + RepositoryEntry repositoryEntry = courseNode.getReferencedRepositoryEntry(); + if(repositoryEntry == null) return; + + repoEntryName = repositoryEntry.getDisplayname(); Wiki wiki = WikiManager.getInstance().getOrLoadWiki(courseNode.getReferencedRepositoryEntry().getOlatResource()); // loop over all wiki pages List<WikiPage> wikiPageList = wiki.getAllPagesWithContent(); for (WikiPage wikiPage : wikiPageList) { - try { + try { SearchResourceContext courseNodeResourceContext = new SearchResourceContext(repositoryResourceContext); courseNodeResourceContext.setBusinessControlFor(courseNode); courseNodeResourceContext.setDocumentType(TYPE); - courseNodeResourceContext.setTitle(courseNode.getShortTitle()); - courseNodeResourceContext.setDescription(courseNode.getLongTitle()); + courseNodeResourceContext.setTitle(courseNode.getShortTitle()); + courseNodeResourceContext.setDescription(courseNode.getLongTitle()); courseNodeResourceContext.setFilePath(wikiPage.getPageName()); Document document = WikiPageDocument.createDocument(courseNodeResourceContext, wikiPage); @@ -85,6 +86,7 @@ public class WikiCourseNodeIndexer extends FolderIndexer implements CourseNodeIn } } + @Override public String getSupportedTypeName() { return SUPPORTED_TYPE_NAME; } -- GitLab