Solr-Suche in Alfresco 4.0 aktivieren
Auch in der Alfresco Community Edition lässt sich der Apache Suchserver Solr für die interne Suche nutzen. Es muss lediglich das Zusatzpaket heruntergeladen und richtig integriert bzw. konfiguriert werden.
Bisher habe ich es leider noch nicht geschafft Solr (bei nachträglicher Installation) dazu zu bewegen meine bisherigen Einträge vollständigen in den Suchindex aufzunehmen. Bei einer frischen Installation sollte die Integration allerdins kein Problem darstellen.
Mit Alfresco 4.2 wird die unten stehende Anleitung hinfällig, da auch in der Community Edition bereits Solr mitgeliefert wird.
Installation
Als erstes müssen Sie sich das für Ihre Version passende Solr-Paket von der Alfresco-Website herunterladen. Aktuell ist im Moment die Wiki-Seite http://wiki.alfresco.com/wiki/Community_file_list_4.0.e wo das Paket unter der Überschrift Solr zu finden ist.
Entpacken Sie die heruntergeladene ZIP-Datei und kopieren Sie den den Inhalt nach <alfresco>/solr wobei <alfresco> Ihr Installationsverzeichnis (meistens /opt/alfresco-4.x.x/) ist.
Kopieren Sie aus diesem Verzeichnis die Datei solr-tomcat-context.xml nach <alfresco>/tomcat/conf/Catalina/localhost/solr.xml und passen Sie die darin angegbenenen Pfade an.
<?xml version="1.0" encoding="utf-8"?>
<Context docBase="/opt/alfresco-4.0.e/solr/apache-solr-1.4.1.war" debug="0" crossContext="true">
<Environment name="solr/home" type="java.lang.String" value="/opt/alfresco-4.0.e/solr" override="true"/>
</Context>
Bearbeiten Sie nun auch die Properties-Dateien von Solr unter <alfresco>/solr/workspace-SpacesStore/conf/solrcore.properties und <alfresco>/solr/archive-SpacesStore/conf/solrcore.properties und passen Sie den Pfad der Variable data.dir.root entsprechend an.
Als letzten Schritt müssen Sie noch die aktuellen Zertifikate für die Kommunikation zwischen Alfresco und Solr kopieren. Kopieren Sie dazu den Ordner keystore aus dem solr-Verzeichnis nach <alfresco>/alf_data/.
Konfiguration
Nun müssen Sie Alfresco noch für die Verwendung von Solr konfigurieren. Fügen Sie die Solr-Konfiguration zusätzlich zur Lucene-Konfiguration hinzu. Die Alfresco-Konfigurationsdatei finden Sie unter: /opt/alfresco/tomcat/shared/classes/alfresco-global.properties
### Lucene Indexing ###
index.subsystem.name=lucene
index.recovery.mode=AUTO
index.recovery.mode=FULL
### Solr Indexing ###
dir.keystore=${dir.root}/keystore
#index.subsystem.name=solr
solr.host=localhost
solr.port=8080
solr.port.ssl=8443
Aufbau des Suchindexes
Bevor Sie nun zur Gänze auf Solr umsteigen können, muss zunächst das Repository von Solr erfasst werden. Dies geschieht im Hintergrund und parallel zum Lucene-System. Sie können den Status der Indizierung unter http://<alfrescoserver>:8080/solr/alfresco/admin/ ermitteln. Um auf die Administrationsoberfläche von Solr zugreifen zu können müssen Sie in Ihrem Browser das passende Clientzertifikat, zu finden unter <alfresco>/alf_data/keystore/browser.p12, installieren. Sobald der Suchindex aufgebaut ist können Sie in der Konfigurationsdatei die Konfiguration für die Lucene-Engine auskommentieren und die Zeile index.subsystem.name=solr aktivieren.
Um den Index von Grund auf neu aufzubauen genügt es Alfresco zu beenden, die folgende Verzeichnisse zu löschen und Alfresco wieder zu starten.
<alfresco>/alf_data/solr/archive/SpacesStore
<alfresco>/alf_data/solr/workspace/SpacesStore
<alfresco>/alf_data/solr/archive-SpacesStore/alfrescoModels/*
<alfresco>/alf_data/solr/workspace-SpacesStore/alfrescoModels/*
Fehlerbehebung bei Upgrades von Alfresco 3.x auf Alfresco 4.0
Da Alfresco 4.0 noch ohne das Zusatzmodul Records Management ausgeliefert wird, kann es bei Installationen die von Alfresco 3.x auf Alfresco 4.0 aktualisiert wurden, im Zusammenhang mit Solr, zu Fehlern kommen.
Fehlermeldung
13:11:33,314 ERROR [extensions.webscripts.AbstractRuntime] Exception from executeScript - redirecting to status template error: 10020002 Wrapped Exception (with status template): 10020005 Problem converting to Freemarker
org.springframework.extensions.webscripts.WebScriptException: 10020002 Wrapped Exception (with status template): 10020005 Problem converting to Freemarker
at org.springframework.extensions.webscripts.AbstractWebScript.createStatusException(AbstractWebScript.java:905)
at org.springframework.extensions.webscripts.DeclarativeWebScript.execute(DeclarativeWebScript.java:171)
at org.alfresco.repo.web.scripts.RepositoryContainer$2.execute(RepositoryContainer.java:393)
at org.alfresco.repo.transaction.RetryingTransactionHelper.doInTransaction(RetryingTransactionHelper.java:388)
at org.alfresco.repo.web.scripts.RepositoryContainer.transactionedExecute(RepositoryContainer.java:462)
at org.alfresco.repo.web.scripts.RepositoryContainer.transactionedExecuteAs(RepositoryContainer.java:500)
at org.alfresco.repo.web.scripts.RepositoryContainer.executeScript(RepositoryContainer.java:275)
at org.springframework.extensions.webscripts.AbstractRuntime.executeScript(AbstractRuntime.java:372)
at org.springframework.extensions.webscripts.AbstractRuntime.executeScript(AbstractRuntime.java:209)
at org.springframework.extensions.webscripts.servlet.WebScriptServlet.service(WebScriptServlet.java:118)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:717)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:290)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
at org.alfresco.web.app.servlet.GlobalLocalizationFilter.doFilter(GlobalLocalizationFilter.java:58)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:233)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:191)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:558)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:127)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:298)
at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:852)
at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:588)
at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:489)
at java.lang.Thread.run(Thread.java:619)
Caused by: org.alfresco.error.AlfrescoRuntimeException: 10020005 Problem converting to Freemarker
at org.alfresco.repo.web.scripts.solr.NodesMetaDataGet$1.handleNodeMetaData(NodesMetaDataGet.java:200)
at org.alfresco.repo.solr.SOLRTrackingComponentImpl$NodeMetaDataQueryRowHandler.processResult(SOLRTrackingComponentImpl.java:847)
at org.alfresco.repo.solr.SOLRTrackingComponentImpl.getNodesMetadata(SOLRTrackingComponentImpl.java:703)
at sun.reflect.GeneratedMethodAccessor536.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at org.alfresco.repo.management.subsystems.SubsystemProxyFactory$1.invoke(SubsystemProxyFactory.java:65)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:202)
at $Proxy145.getNodesMetadata(Unknown Source)
at org.alfresco.repo.web.scripts.solr.NodesMetaDataGet.executeImpl(NodesMetaDataGet.java:183)
at org.springframework.extensions.webscripts.DeclarativeWebScript.executeImpl(DeclarativeWebScript.java:235)
at org.springframework.extensions.webscripts.DeclarativeWebScript.execute(DeclarativeWebScript.java:64)
... 25 more
Caused by: org.alfresco.service.namespace.NamespaceException: A namespace prefix is not registered for uri http://www.alfresco.org/model/rmcustom/1.0
at org.alfresco.service.namespace.QName.toPrefixString(QName.java:414)
at org.alfresco.repo.web.scripts.solr.SOLRSerializer$SOLRTypeConverter$2.convert(SOLRSerializer.java:231)
at org.alfresco.repo.web.scripts.solr.SOLRSerializer$SOLRTypeConverter$2.convert(SOLRSerializer.java:228)
at org.alfresco.service.cmr.repository.datatype.TypeConverter.convert(TypeConverter.java:112)
at org.alfresco.repo.web.scripts.solr.SOLRSerializer.serializeToJSONString(SOLRSerializer.java:108)
at org.alfresco.repo.web.scripts.solr.SOLRSerializer.serialize(SOLRSerializer.java:170)
at org.alfresco.repo.web.scripts.solr.NodesMetaDataGet$FreemarkerNodeMetaData.<init>(NodesMetaDataGet.java:294)
at org.alfresco.repo.web.scripts.solr.NodesMetaDataGet$1.handleNodeMetaData(NodesMetaDataGet.java:195)
... 37 more
Lösung
Alfresco erwartet sich auf Grund der durch das Records Management angelegten Datenstruktur gewisse in Alfresco 4.0 nicht mehr vorhandene Namespaces. Das Problem lässt sich umgehen, in dem man Alfresco diese Namespaces wieder als Dummy zu Verfügung stellt.
Legen Sie dazu in Ihrem Alfresco Tomcat-Verzeichnis (meist unter /opt/alfresco-4.x.x/tomcat/) die Datei shared/classes/alfresco/extension/model/bartlwebModel.xml mit dem nachstehenden Inhalt an. Die Datei erzeugt ein eigenes Alfresco Modul, dass die nicht mehr vorhandenen Namespaces rmcustom and website wieder definiert.
<?xml version="1.0" encoding="UTF-8"?>
<model name="bw:bartlwebModel" xmlns="http://www.alfresco.org/model/dictionary/1.0">
<description>records management fake model</description>
<author>Christian Bartl</author>
<version>1.0</version>
<imports>
<import uri="http://www.alfresco.org/model/dictionary/1.0" prefix="d" />
</imports>
<namespaces>
<namespace uri="http://www.alfresco.org/model/rmcustom/1.0" prefix="rmcustom"/>
<namespace uri="http://www.alfresco.org/model/website/1.0" prefix="website"/>
</namespaces>
</model>
Nun registrieren Sie Ihr Modul bei Alfresco durch anlegen der Datei <alfresco>/tomcat/shared/classes/alfresco/extension/bartlweb-model-context.xml mit dem folgenden Inhalt.
<?xml version='1.0' encoding='UTF-8'?>
<!DOCTYPE beans PUBLIC '-//SPRING//DTD BEAN//EN'
'http://www.springframework.org/dtd/spring-beans.dtd'>
<beans>
<bean id="bartlweb.dictionaryBootstrap" parent="dictionaryModelBootstrap" depends-on="dictionaryBootstrap">
<property name="models">
<list>
<value>alfresco/extension/model/bartlwebModel.xml</value>
</list>
</property>
</bean>
</beans>