mirror of
https://github.com/Alfresco/alfresco-community-repo.git
synced 2025-08-07 17:49:17 +00:00
Fix for ALF-10561 SOLR stops indexing if it is given a property that is neither indexed or stored - it throws an exception
Fix ALF-10358 SOLR No easy way to get the current last TX indexed to monitor how the SOLR index is building git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@30857 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
@@ -1035,7 +1035,7 @@
|
||||
<property name="httpClientFactory" ref="solrHttpClientFactory"/>
|
||||
</bean>
|
||||
|
||||
<bean id="solr" class="org.alfresco.repo.management.subsystems.ChildApplicationContextFactory" parent="abstractPropertyBackedBean">
|
||||
<bean id="solr" class="org.alfresco.repo.search.impl.solr.SolrChildApplicationContextFactory" parent="abstractPropertyBackedBean">
|
||||
<property name="autoStart">
|
||||
<value>false</value>
|
||||
</property>
|
||||
|
@@ -56,6 +56,10 @@
|
||||
</property>
|
||||
</bean>
|
||||
|
||||
<bean id="search.solrAdminHTTPCLient" class="org.alfresco.repo.search.impl.solr.SolrAdminHTTPClient" init-method="init">
|
||||
<property name="httpClientFactory" ref="solrHttpClientFactory"/>
|
||||
</bean>
|
||||
|
||||
|
||||
<bean id="search.lucene.alfresco" class="org.alfresco.repo.search.impl.solr.SolrQueryLanguage" >
|
||||
<property name="factories">
|
||||
|
@@ -0,0 +1,175 @@
|
||||
/*
|
||||
* Copyright (C) 2005-2010 Alfresco Software Limited.
|
||||
*
|
||||
* This file is part of Alfresco
|
||||
*
|
||||
* Alfresco is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Alfresco is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package org.alfresco.repo.search.impl.solr;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStreamReader;
|
||||
import java.io.Reader;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.util.HashMap;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
import org.alfresco.error.AlfrescoRuntimeException;
|
||||
import org.alfresco.httpclient.HttpClientFactory;
|
||||
import org.alfresco.repo.domain.node.NodeDAO;
|
||||
import org.alfresco.repo.search.impl.lucene.LuceneQueryParserException;
|
||||
import org.alfresco.repo.search.impl.lucene.SolrJSONResultSet;
|
||||
import org.alfresco.service.cmr.repository.datatype.DefaultTypeConverter;
|
||||
import org.alfresco.service.cmr.search.ResultSet;
|
||||
import org.alfresco.service.cmr.search.SearchParameters;
|
||||
import org.alfresco.service.cmr.search.SearchParameters.FieldFacet;
|
||||
import org.alfresco.service.cmr.search.SearchParameters.FieldFacetMethod;
|
||||
import org.alfresco.service.cmr.search.SearchParameters.FieldFacetSort;
|
||||
import org.alfresco.service.cmr.search.SearchParameters.SortDefinition;
|
||||
import org.alfresco.service.cmr.security.PermissionService;
|
||||
import org.apache.commons.codec.net.URLCodec;
|
||||
import org.apache.commons.httpclient.Header;
|
||||
import org.apache.commons.httpclient.HttpClient;
|
||||
import org.apache.commons.httpclient.HttpException;
|
||||
import org.apache.commons.httpclient.HttpStatus;
|
||||
import org.apache.commons.httpclient.URI;
|
||||
import org.apache.commons.httpclient.UsernamePasswordCredentials;
|
||||
import org.apache.commons.httpclient.auth.AuthScope;
|
||||
import org.apache.commons.httpclient.methods.ByteArrayRequestEntity;
|
||||
import org.apache.commons.httpclient.methods.PostMethod;
|
||||
import org.apache.commons.httpclient.params.HttpClientParams;
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.json.JSONArray;
|
||||
import org.json.JSONException;
|
||||
import org.json.JSONObject;
|
||||
import org.json.JSONTokener;
|
||||
import org.springframework.extensions.surf.util.I18NUtil;
|
||||
|
||||
/**
|
||||
* @author Andy
|
||||
*/
|
||||
public class SolrAdminHTTPClient
|
||||
{
|
||||
static Log s_logger = LogFactory.getLog(SolrAdminHTTPClient.class);
|
||||
|
||||
private String baseUrl;
|
||||
|
||||
private HttpClient httpClient;
|
||||
private HttpClientFactory httpClientFactory;
|
||||
|
||||
public SolrAdminHTTPClient()
|
||||
{
|
||||
}
|
||||
|
||||
public void init()
|
||||
{
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.append("/solr/admin/cores");
|
||||
this.baseUrl = sb.toString();
|
||||
|
||||
httpClient = httpClientFactory.getHttpClient();
|
||||
HttpClientParams params = httpClient.getParams();
|
||||
params.setBooleanParameter(HttpClientParams.PREEMPTIVE_AUTHENTICATION, true);
|
||||
httpClient.getState().setCredentials(new AuthScope(AuthScope.ANY_HOST, AuthScope.ANY_PORT), new UsernamePasswordCredentials("admin", "admin"));
|
||||
}
|
||||
|
||||
public void setHttpClientFactory(HttpClientFactory httpClientFactory)
|
||||
{
|
||||
this.httpClientFactory = httpClientFactory;
|
||||
}
|
||||
|
||||
public JSONObject execute(HashMap<String, String>args)
|
||||
{
|
||||
try
|
||||
{
|
||||
URLCodec encoder = new URLCodec();
|
||||
StringBuilder url = new StringBuilder();
|
||||
|
||||
for(String key : args.keySet())
|
||||
{
|
||||
String value = args.get(key);
|
||||
if(url.length() == 0)
|
||||
{
|
||||
url.append(baseUrl);
|
||||
url.append("?");
|
||||
url.append(encoder.encode(key, "UTF-8"));
|
||||
url.append("=");
|
||||
url.append(encoder.encode(value, "UTF-8"));
|
||||
}
|
||||
else
|
||||
{
|
||||
url.append("&");
|
||||
url.append(encoder.encode(key, "UTF-8"));
|
||||
url.append("=");
|
||||
url.append(encoder.encode(value, "UTF-8"));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
PostMethod post = new PostMethod(url.toString());
|
||||
|
||||
try
|
||||
{
|
||||
httpClient.executeMethod(post);
|
||||
|
||||
if(post.getStatusCode() == HttpStatus.SC_MOVED_PERMANENTLY || post.getStatusCode() == HttpStatus.SC_MOVED_TEMPORARILY)
|
||||
{
|
||||
Header locationHeader = post.getResponseHeader("location");
|
||||
if (locationHeader != null)
|
||||
{
|
||||
String redirectLocation = locationHeader.getValue();
|
||||
post.setURI(new URI(redirectLocation, true));
|
||||
httpClient.executeMethod(post);
|
||||
}
|
||||
}
|
||||
|
||||
if (post.getStatusCode() != HttpServletResponse.SC_OK)
|
||||
{
|
||||
throw new LuceneQueryParserException("Request failed " + post.getStatusCode() + " " + url.toString());
|
||||
}
|
||||
|
||||
Reader reader = new BufferedReader(new InputStreamReader(post.getResponseBodyAsStream()));
|
||||
// TODO - replace with streaming-based solution e.g. SimpleJSON ContentHandler
|
||||
JSONObject json = new JSONObject(new JSONTokener(reader));
|
||||
return json;
|
||||
}
|
||||
finally
|
||||
{
|
||||
post.releaseConnection();
|
||||
}
|
||||
}
|
||||
catch (UnsupportedEncodingException e)
|
||||
{
|
||||
throw new LuceneQueryParserException("", e);
|
||||
}
|
||||
catch (HttpException e)
|
||||
{
|
||||
throw new LuceneQueryParserException("", e);
|
||||
}
|
||||
catch (IOException e)
|
||||
{
|
||||
throw new LuceneQueryParserException("", e);
|
||||
}
|
||||
catch (JSONException e)
|
||||
{
|
||||
throw new LuceneQueryParserException("", e);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@@ -0,0 +1,162 @@
|
||||
/*
|
||||
* Copyright (C) 2005-2010 Alfresco Software Limited.
|
||||
*
|
||||
* This file is part of Alfresco
|
||||
*
|
||||
* Alfresco is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Alfresco is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package org.alfresco.repo.search.impl.solr;
|
||||
|
||||
import java.util.Date;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.TreeSet;
|
||||
|
||||
import org.alfresco.repo.management.subsystems.ChildApplicationContextFactory;
|
||||
import org.alfresco.repo.search.impl.lucene.LuceneQueryParserException;
|
||||
import org.alfresco.service.cmr.repository.datatype.Duration;
|
||||
import org.json.JSONException;
|
||||
import org.json.JSONObject;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
|
||||
/**
|
||||
* @author Andy
|
||||
*/
|
||||
public class SolrChildApplicationContextFactory extends ChildApplicationContextFactory
|
||||
{
|
||||
|
||||
private static String ALFRESCO_ACTIVE = "tracker.alfresco.active";
|
||||
|
||||
private static String ALFRESCO_LAG = "tracker.alfresco.lag";
|
||||
|
||||
private static String ALFRESCO_LAG_DURATION = "tracker.alfresco.lag.duration";
|
||||
|
||||
private static String ARCHIVE_ACTIVE = "tracker.archive.active";
|
||||
|
||||
private static String ARCHIVE_LAG = "tracker.archive.lag";
|
||||
|
||||
private static String ARCHIVE_LAG_DURATION = "tracker.archive.lag.duration";
|
||||
|
||||
@Override
|
||||
public boolean isUpdateable(String name)
|
||||
{
|
||||
// TODO Auto-generated method stub
|
||||
return super.isUpdateable(name)
|
||||
&& !name.equals(SolrChildApplicationContextFactory.ALFRESCO_ACTIVE) && !name.equals(SolrChildApplicationContextFactory.ALFRESCO_LAG)
|
||||
&& !name.equals(SolrChildApplicationContextFactory.ALFRESCO_LAG_DURATION) && !name.equals(SolrChildApplicationContextFactory.ARCHIVE_ACTIVE)
|
||||
&& !name.equals(SolrChildApplicationContextFactory.ARCHIVE_LAG) && !name.equals(SolrChildApplicationContextFactory.ARCHIVE_LAG_DURATION);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getProperty(String name)
|
||||
{
|
||||
if (name.equals(SolrChildApplicationContextFactory.ALFRESCO_ACTIVE)
|
||||
|| name.equals(SolrChildApplicationContextFactory.ALFRESCO_LAG) || name.equals(SolrChildApplicationContextFactory.ALFRESCO_LAG_DURATION) || name.equals(SolrChildApplicationContextFactory.ARCHIVE_ACTIVE)
|
||||
|| name.equals(SolrChildApplicationContextFactory.ARCHIVE_LAG) || name.equals(SolrChildApplicationContextFactory.ARCHIVE_LAG_DURATION))
|
||||
{
|
||||
try
|
||||
{
|
||||
ApplicationContext ctx = getApplicationContext();
|
||||
SolrAdminHTTPClient adminClient = (SolrAdminHTTPClient) ctx.getBean("search.solrAdminHTTPCLient");
|
||||
HashMap<String, String> args = new HashMap<String, String>();
|
||||
args.put("action", "SUMMARY");
|
||||
args.put("wt", "json");
|
||||
JSONObject json = adminClient.execute(args);
|
||||
JSONObject summary = json.getJSONObject("Summary");
|
||||
|
||||
Date now = new Date();
|
||||
|
||||
JSONObject alfresco = summary.getJSONObject("alfresco");
|
||||
String alfrescoLag = alfresco.getString("Lag");
|
||||
String alfrescoActive = alfresco.getString("Active");
|
||||
String alfrescoDuration = alfresco.getString("Duration");
|
||||
|
||||
|
||||
JSONObject archive = summary.getJSONObject("archive");
|
||||
String archiveLag = archive.getString("Lag");
|
||||
String archiveActive = archive.getString("Active");
|
||||
String archiveDuration = archive.getString("Duration");
|
||||
|
||||
if (name.equals(SolrChildApplicationContextFactory.ALFRESCO_ACTIVE))
|
||||
{
|
||||
return alfrescoActive;
|
||||
}
|
||||
else if (name.equals(SolrChildApplicationContextFactory.ALFRESCO_LAG))
|
||||
{
|
||||
return alfrescoLag;
|
||||
}
|
||||
else if (name.equals(SolrChildApplicationContextFactory.ALFRESCO_LAG_DURATION))
|
||||
{
|
||||
return alfrescoDuration;
|
||||
}
|
||||
else if (name.equals(SolrChildApplicationContextFactory.ARCHIVE_ACTIVE))
|
||||
{
|
||||
return archiveActive;
|
||||
}
|
||||
else if (name.equals(SolrChildApplicationContextFactory.ARCHIVE_LAG))
|
||||
{
|
||||
return archiveLag;
|
||||
}
|
||||
else if (name.equals(SolrChildApplicationContextFactory.ARCHIVE_LAG_DURATION))
|
||||
{
|
||||
return archiveDuration;
|
||||
}
|
||||
else
|
||||
{
|
||||
return "Unavailable";
|
||||
}
|
||||
}
|
||||
catch (LuceneQueryParserException lqe)
|
||||
{
|
||||
return "Unavailable: " + lqe.getMessage();
|
||||
}
|
||||
catch (JSONException e)
|
||||
{
|
||||
return "Unavailable: " + e.getMessage();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return super.getProperty(name);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<String> getPropertyNames()
|
||||
{
|
||||
Set<String> result = new TreeSet<String>();
|
||||
result.add(SolrChildApplicationContextFactory.ALFRESCO_ACTIVE);
|
||||
result.add(SolrChildApplicationContextFactory.ALFRESCO_LAG);
|
||||
result.add(SolrChildApplicationContextFactory.ALFRESCO_LAG_DURATION);
|
||||
result.add(SolrChildApplicationContextFactory.ARCHIVE_ACTIVE);
|
||||
result.add(SolrChildApplicationContextFactory.ARCHIVE_LAG);
|
||||
result.add(SolrChildApplicationContextFactory.ARCHIVE_LAG_DURATION);
|
||||
result.addAll(super.getPropertyNames());
|
||||
return result;
|
||||
}
|
||||
|
||||
public void setProperty(String name, String value)
|
||||
{
|
||||
if (name.equals(SolrChildApplicationContextFactory.ALFRESCO_ACTIVE)
|
||||
|| name.equals(SolrChildApplicationContextFactory.ALFRESCO_LAG) || name.equals(SolrChildApplicationContextFactory.ALFRESCO_LAG_DURATION) || name.equals(SolrChildApplicationContextFactory.ARCHIVE_ACTIVE)
|
||||
|| name.equals(SolrChildApplicationContextFactory.ARCHIVE_LAG) || name.equals(SolrChildApplicationContextFactory.ARCHIVE_LAG_DURATION))
|
||||
{
|
||||
throw new IllegalStateException("Illegal write to property \"" + name + "\"");
|
||||
}
|
||||
super.setProperty(name, value);
|
||||
}
|
||||
|
||||
}
|
@@ -142,4 +142,10 @@ public interface SOLRTrackingComponent
|
||||
* @param enabled
|
||||
*/
|
||||
void setEnabled(boolean enabled);
|
||||
|
||||
/**
|
||||
* Get the last transaction timestamp from the repo
|
||||
* @return
|
||||
*/
|
||||
public Long getMaxTxnCommitTime();
|
||||
}
|
||||
|
@@ -796,4 +796,13 @@ public class SOLRTrackingComponentImpl implements SOLRTrackingComponent
|
||||
more = callback.handleNodeMetaData(row);
|
||||
}
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.alfresco.repo.solr.SOLRTrackingComponent#getLastTransactionTimestamp()
|
||||
*/
|
||||
@Override
|
||||
public Long getMaxTxnCommitTime()
|
||||
{
|
||||
return nodeDAO.getMaxTxnCommitTime();
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user