Merged HEAD-BUG-FIX (5.0/Cloud) to HEAD (5.0/Cloud)

84822: Merged PLATFORM1 (5.0/Cloud) to HEAD-BUG-FIX (5.0/Cloud)
      82523: Fix for     ACE-1044  SOLR 4 - Back up and recovery
      - added baseUrl configuration
      - improved admin


git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@85181 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
Mark Rogers
2014-09-20 08:42:16 +00:00
parent afe200fbd5
commit 0dac120b1c
10 changed files with 100 additions and 53 deletions

View File

@@ -81,7 +81,7 @@
<value>solrHttpClientFactory</value> <value>solrHttpClientFactory</value>
</property> </property>
<property name="baseUrl"> <property name="baseUrl">
<value>/solr/alfresco</value> <value>${solr.baseUrl}/alfresco</value>
</property> </property>
<property name="protocol"> <property name="protocol">
<value>workspace</value> <value>workspace</value>
@@ -98,7 +98,7 @@
<value>solrHttpClientFactory</value> <value>solrHttpClientFactory</value>
</property> </property>
<property name="baseUrl"> <property name="baseUrl">
<value>/solr/archive</value> <value>${solr.baseUrl}/archive</value>
</property> </property>
<property name="protocol"> <property name="protocol">
<value>archive</value> <value>archive</value>
@@ -133,14 +133,16 @@
<property name="solrPingCronExpression" value="${solr.solrPingCronExpression}"/> <property name="solrPingCronExpression" value="${solr.solrPingCronExpression}"/>
<property name="solrConnectTimeout" value="${solr.solrConnectTimeout}"/> <property name="solrConnectTimeout" value="${solr.solrConnectTimeout}"/>
<property name="httpClientFactory" ref="solrHttpClientFactory"/> <property name="httpClientFactory" ref="solrHttpClientFactory"/>
<property name="scheduler"> <property name="baseUrl" value="${solr.baseUrl}"/>
<ref bean="searchSchedulerFactory" /> <property name="scheduler">
</property> <ref bean="searchSchedulerFactory" />
</property>
</bean> </bean>
<bean id="search.solrAdminHTTPCLient" class="org.alfresco.repo.search.impl.solr.SolrAdminHTTPClient" init-method="init"> <bean id="search.solrAdminHTTPCLient" class="org.alfresco.repo.search.impl.solr.SolrAdminHTTPClient" init-method="init">
<property name="httpClientFactory" ref="solrHttpClientFactory"/> <property name="httpClientFactory" ref="solrHttpClientFactory"/>
<property name="baseUrl" value="${solr.baseUrl}"/>
</bean> </bean>

View File

@@ -2,4 +2,5 @@ solr.host=localhost
solr.port=8080 solr.port=8080
solr.port.ssl=8443 solr.port.ssl=8443
solr.query.includeGroupsForRoleAdmin=false solr.query.includeGroupsForRoleAdmin=false
solr.query.maximumResultsFromUnlimitedQuery=${system.acl.maxPermissionChecks} solr.query.maximumResultsFromUnlimitedQuery=${system.acl.maxPermissionChecks}
solr.baseUrl=/solr

View File

@@ -49,6 +49,9 @@
<property name="solrAdminClient"> <property name="solrAdminClient">
<ref bean="solrAdminClient" /> <ref bean="solrAdminClient" />
</property> </property>
<property name="fixNumberToKeepOffByOneError">
<value>true</value>
</property>
</bean> </bean>
<!-- archive://SpacesStore - archive --> <!-- archive://SpacesStore - archive -->

View File

@@ -1,7 +1,7 @@
solr.backup.alfresco.cronExpression=0 0 2 * * ? solr.backup.alfresco.cronExpression=0 0 2 * * ?
solr.backup.archive.cronExpression=0 0 4 * * ? solr.backup.archive.cronExpression=0 0 4 * * ?
solr.backup.alfresco.remoteBackupLocation=${dir.root}/solrBackup/alfresco solr.backup.alfresco.remoteBackupLocation=${dir.root}/solr4Backup/alfresco
solr.backup.archive.remoteBackupLocation=${dir.root}/solrBackup/archive solr.backup.archive.remoteBackupLocation=${dir.root}/solr4Backup/archive
solr.backup.alfresco.numberToKeep=3 solr.backup.alfresco.numberToKeep=3
solr.backup.archive.numberToKeep=3 solr.backup.archive.numberToKeep=3

View File

@@ -81,7 +81,7 @@
<value>solrHttpClientFactory</value> <value>solrHttpClientFactory</value>
</property> </property>
<property name="baseUrl"> <property name="baseUrl">
<value>/solr4/alfresco</value> <value>${solr.baseUrl}/alfresco</value>
</property> </property>
<property name="protocol"> <property name="protocol">
<value>workspace</value> <value>workspace</value>
@@ -98,7 +98,7 @@
<value>solrHttpClientFactory</value> <value>solrHttpClientFactory</value>
</property> </property>
<property name="baseUrl"> <property name="baseUrl">
<value>/solr4/archive</value> <value>${solr.baseUrl}/archive</value>
</property> </property>
<property name="protocol"> <property name="protocol">
<value>archive</value> <value>archive</value>
@@ -133,14 +133,16 @@
<property name="solrPingCronExpression" value="${solr.solrPingCronExpression}"/> <property name="solrPingCronExpression" value="${solr.solrPingCronExpression}"/>
<property name="solrConnectTimeout" value="${solr.solrConnectTimeout}"/> <property name="solrConnectTimeout" value="${solr.solrConnectTimeout}"/>
<property name="httpClientFactory" ref="solrHttpClientFactory"/> <property name="httpClientFactory" ref="solrHttpClientFactory"/>
<property name="scheduler"> <property name="baseUrl" value="${solr.baseUrl}"/>
<ref bean="searchSchedulerFactory" /> <property name="scheduler">
</property> <ref bean="searchSchedulerFactory" />
</property>
</bean> </bean>
<bean id="search.solrAdminHTTPCLient" class="org.alfresco.repo.search.impl.solr.SolrAdminHTTPClient" init-method="init"> <bean id="search.solrAdminHTTPCLient" class="org.alfresco.repo.search.impl.solr.SolrAdminHTTPClient" init-method="init">
<property name="httpClientFactory" ref="solrHttpClientFactory"/> <property name="httpClientFactory" ref="solrHttpClientFactory"/>
<property name="baseUrl" value="${solr.baseUrl}"/>
</bean> </bean>

View File

@@ -2,4 +2,5 @@ solr.host=localhost
solr.port=8083 solr.port=8083
solr.port.ssl=8446 solr.port.ssl=8446
solr.query.includeGroupsForRoleAdmin=false solr.query.includeGroupsForRoleAdmin=false
solr.query.maximumResultsFromUnlimitedQuery=${system.acl.maxPermissionChecks} solr.query.maximumResultsFromUnlimitedQuery=${system.acl.maxPermissionChecks}
solr.baseUrl=/solr4

View File

@@ -1,5 +1,5 @@
/* /*
* Copyright (C) 2005-2010 Alfresco Software Limited. * Copyright (C) 2005-2014 Alfresco Software Limited.
* *
* This file is part of Alfresco * This file is part of Alfresco
* *
@@ -42,6 +42,7 @@ import org.alfresco.service.cmr.search.SearchParameters.FieldFacetMethod;
import org.alfresco.service.cmr.search.SearchParameters.FieldFacetSort; import org.alfresco.service.cmr.search.SearchParameters.FieldFacetSort;
import org.alfresco.service.cmr.search.SearchParameters.SortDefinition; import org.alfresco.service.cmr.search.SearchParameters.SortDefinition;
import org.alfresco.service.cmr.security.PermissionService; import org.alfresco.service.cmr.security.PermissionService;
import org.alfresco.util.ParameterCheck;
import org.apache.commons.codec.net.URLCodec; import org.apache.commons.codec.net.URLCodec;
import org.apache.commons.httpclient.Header; import org.apache.commons.httpclient.Header;
import org.apache.commons.httpclient.HttpClient; import org.apache.commons.httpclient.HttpClient;
@@ -51,6 +52,7 @@ import org.apache.commons.httpclient.URI;
import org.apache.commons.httpclient.UsernamePasswordCredentials; import org.apache.commons.httpclient.UsernamePasswordCredentials;
import org.apache.commons.httpclient.auth.AuthScope; import org.apache.commons.httpclient.auth.AuthScope;
import org.apache.commons.httpclient.methods.ByteArrayRequestEntity; import org.apache.commons.httpclient.methods.ByteArrayRequestEntity;
import org.apache.commons.httpclient.methods.GetMethod;
import org.apache.commons.httpclient.methods.PostMethod; import org.apache.commons.httpclient.methods.PostMethod;
import org.apache.commons.httpclient.params.HttpClientParams; import org.apache.commons.httpclient.params.HttpClientParams;
import org.apache.commons.logging.Log; import org.apache.commons.logging.Log;
@@ -68,6 +70,8 @@ public class SolrAdminHTTPClient
{ {
static Log s_logger = LogFactory.getLog(SolrAdminHTTPClient.class); static Log s_logger = LogFactory.getLog(SolrAdminHTTPClient.class);
private String adminUrl;
private String baseUrl; private String baseUrl;
private HttpClient httpClient; private HttpClient httpClient;
@@ -77,11 +81,19 @@ public class SolrAdminHTTPClient
{ {
} }
public void setBaseUrl(String baseUrl)
{
this.baseUrl = baseUrl;
}
public void init() public void init()
{ {
ParameterCheck.mandatory("baseUrl", baseUrl);
StringBuilder sb = new StringBuilder(); StringBuilder sb = new StringBuilder();
sb.append("/solr/admin/cores"); sb.append(baseUrl + "/admin/cores");
this.baseUrl = sb.toString(); this.adminUrl = sb.toString();
httpClient = httpClientFactory.getHttpClient(); httpClient = httpClientFactory.getHttpClient();
HttpClientParams params = httpClient.getParams(); HttpClientParams params = httpClient.getParams();
@@ -106,7 +118,7 @@ public class SolrAdminHTTPClient
String value = args.get(key); String value = args.get(key);
if(url.length() == 0) if(url.length() == 0)
{ {
url.append(baseUrl); url.append(adminUrl);
url.append("?"); url.append("?");
url.append(encoder.encode(key, "UTF-8")); url.append(encoder.encode(key, "UTF-8"));
url.append("="); url.append("=");
@@ -122,36 +134,37 @@ public class SolrAdminHTTPClient
} }
PostMethod post = new PostMethod(url.toString()); //PostMethod post = new PostMethod(url.toString());
GetMethod get = new GetMethod(url.toString());
try try
{ {
httpClient.executeMethod(post); httpClient.executeMethod(get);
if(post.getStatusCode() == HttpStatus.SC_MOVED_PERMANENTLY || post.getStatusCode() == HttpStatus.SC_MOVED_TEMPORARILY) if(get.getStatusCode() == HttpStatus.SC_MOVED_PERMANENTLY || get.getStatusCode() == HttpStatus.SC_MOVED_TEMPORARILY)
{ {
Header locationHeader = post.getResponseHeader("location"); Header locationHeader = get.getResponseHeader("location");
if (locationHeader != null) if (locationHeader != null)
{ {
String redirectLocation = locationHeader.getValue(); String redirectLocation = locationHeader.getValue();
post.setURI(new URI(redirectLocation, true)); get.setURI(new URI(redirectLocation, true));
httpClient.executeMethod(post); httpClient.executeMethod(get);
} }
} }
if (post.getStatusCode() != HttpServletResponse.SC_OK) if (get.getStatusCode() != HttpServletResponse.SC_OK)
{ {
throw new LuceneQueryParserException("Request failed " + post.getStatusCode() + " " + url.toString()); throw new LuceneQueryParserException("Request failed " + get.getStatusCode() + " " + url.toString());
} }
Reader reader = new BufferedReader(new InputStreamReader(post.getResponseBodyAsStream())); Reader reader = new BufferedReader(new InputStreamReader(get.getResponseBodyAsStream()));
// TODO - replace with streaming-based solution e.g. SimpleJSON ContentHandler // TODO - replace with streaming-based solution e.g. SimpleJSON ContentHandler
JSONObject json = new JSONObject(new JSONTokener(reader)); JSONObject json = new JSONObject(new JSONTokener(reader));
return json; return json;
} }
finally finally
{ {
post.releaseConnection(); get.releaseConnection();
} }
} }
catch (UnsupportedEncodingException e) catch (UnsupportedEncodingException e)

View File

@@ -1,5 +1,5 @@
/* /*
* Copyright (C) 2005-2010 Alfresco Software Limited. * Copyright (C) 2005-2014 Alfresco Software Limited.
* *
* This file is part of Alfresco * This file is part of Alfresco
* *
@@ -51,10 +51,22 @@ public class SolrBackupClient implements InitializingBean
private int numberToKeep; private int numberToKeep;
private String core; private String core;
private boolean fixNumberToKeepOffByOneError = false;
private SOLRAdminClient solrAdminClient; private SOLRAdminClient solrAdminClient;
/**
* @param fixNumberToKeepOffByOneError the fixNumberToKeepOffByOneError to set
*/
public void setFixNumberToKeepOffByOneError(boolean fixNumberToKeepOffByOneError)
{
this.fixNumberToKeepOffByOneError = fixNumberToKeepOffByOneError;
}
public void setSolrAdminClient(SOLRAdminClient solrAdminClient) public void setSolrAdminClient(SOLRAdminClient solrAdminClient)
{ {
this.solrAdminClient = solrAdminClient; this.solrAdminClient = solrAdminClient;
@@ -142,7 +154,14 @@ public class SolrBackupClient implements InitializingBean
params.set("qt", "/"+core+"/replication"); params.set("qt", "/"+core+"/replication");
params.set("command", "backup"); params.set("command", "backup");
params.set("location", remoteBackupLocation); params.set("location", remoteBackupLocation);
params.set("numberToKeep", numberToKeep); if(fixNumberToKeepOffByOneError)
{
params.set("numberToKeep", numberToKeep > 1 ? (numberToKeep + 1) : numberToKeep);
}
else
{
params.set("numberToKeep", numberToKeep);
}
try try
{ {

View File

@@ -1,5 +1,5 @@
/* /*
* Copyright (C) 2005-2010 Alfresco Software Limited. * Copyright (C) 2005-2014 Alfresco Software Limited.
* *
* This file is part of Alfresco * This file is part of Alfresco
* *
@@ -114,26 +114,26 @@ public class SolrChildApplicationContextFactory extends ChildApplicationContextF
Date now = new Date(); Date now = new Date();
JSONObject alfresco = summary.getJSONObject("alfresco"); JSONObject alfresco = summary.has("alfresco") ? summary.getJSONObject("alfresco") : null;
String alfrescoLag = alfresco.getString("TX Lag"); String alfrescoLag = alfresco == null ? "Unavailable" : alfresco.getString("TX Lag");
String alfrescoActive = alfresco.getString("Active"); String alfrescoActive = alfresco == null ? "false" : alfresco.getString("Active");
String alfrescoDuration = alfresco.getString("TX Duration"); String alfrescoDuration = alfresco == null ? "Unavailable" : alfresco.getString("TX Duration");
String alfrescoLastIndexedTxn = alfresco.getString("Id for last TX in index"); String alfrescoLastIndexedTxn = alfresco == null ? "Unavailable" : alfresco.getString("Id for last TX in index");
String alfrescoApproxTxnsReminaing = alfresco.getString("Approx transactions remaining"); String alfrescoApproxTxnsReminaing = alfresco == null ? "Unavailable" : alfresco.getString("Approx transactions remaining");
String alfrescoApproxIndexingTimeReminaing = alfresco.getString("Approx transaction indexing time remaining"); String alfrescoApproxIndexingTimeReminaing = alfresco == null ? "Unavailable" : alfresco.getString("Approx transaction indexing time remaining");
String alfrescoDisk = alfresco.getString("On disk (GB)"); String alfrescoDisk = alfresco == null ? "Unavailable" : alfresco.getString("On disk (GB)");
String alfrescoMemory = alfresco.getString("Total Searcher Cache (GB)"); String alfrescoMemory = alfresco == null ? "Unavailable" : alfresco.getString("Total Searcher Cache (GB)");
JSONObject archive = summary.getJSONObject("archive"); JSONObject archive = summary.has("archive") ? summary.getJSONObject("archive") : null;
String archiveLag = archive.getString("TX Lag"); String archiveLag = archive == null ? "Unavailable" : archive.getString("TX Lag");
String archiveActive = archive.getString("Active"); String archiveActive = archive == null ? "false" : archive.getString("Active");
String archiveDuration = archive.getString("TX Duration"); String archiveDuration = archive == null ? "Unavailable" : archive.getString("TX Duration");
String archiveLastIndexedTxn = archive.getString("Id for last TX in index"); String archiveLastIndexedTxn = archive == null ? "Unavailable" : archive.getString("Id for last TX in index");
String archiveApproxTxnsReminaing = archive.getString("Approx transactions remaining"); String archiveApproxTxnsReminaing = archive == null ? "Unavailable" : archive.getString("Approx transactions remaining");
String archiveApproxIndexingTimeReminaing = archive.getString("Approx transaction indexing time remaining"); String archiveApproxIndexingTimeReminaing = archive == null ? "Unavailable" : archive.getString("Approx transaction indexing time remaining");
String archiveDisk = archive.getString("On disk (GB)"); String archiveDisk = archive == null ? "Unavailable" : archive.getString("On disk (GB)");
String archiveMemory = archive.getString("Total Searcher Cache (GB)"); String archiveMemory = archive == null ? "Unavailable" : archive.getString("Total Searcher Cache (GB)");
if (name.equals(SolrChildApplicationContextFactory.ALFRESCO_ACTIVE)) if (name.equals(SolrChildApplicationContextFactory.ALFRESCO_ACTIVE))
{ {

View File

@@ -1,5 +1,5 @@
/* /*
* Copyright (C) 2005-2011 Alfresco Software Limited. * Copyright (C) 2005-2014 Alfresco Software Limited.
* *
* This file is part of Alfresco * This file is part of Alfresco
* *
@@ -65,6 +65,7 @@ public class SOLRAdminClient implements ApplicationEventPublisherAware, Disposab
private String solrUser; private String solrUser;
private String solrPassword; private String solrPassword;
private String solrPingCronExpression; private String solrPingCronExpression;
private String baseUrl;
private CommonsHttpSolrServer server; private CommonsHttpSolrServer server;
private int solrConnectTimeout = 30000; // ms private int solrConnectTimeout = 30000; // ms
@@ -123,8 +124,13 @@ public class SOLRAdminClient implements ApplicationEventPublisherAware, Disposab
{ {
this.httpClientFactory = httpClientFactory; this.httpClientFactory = httpClientFactory;
} }
/** public void setBaseUrl(String baseUrl)
{
this.baseUrl = baseUrl;
}
/**
* @param scheduler the scheduler to set * @param scheduler the scheduler to set
*/ */
public void setScheduler(Scheduler scheduler) public void setScheduler(Scheduler scheduler)
@@ -148,7 +154,7 @@ public class SOLRAdminClient implements ApplicationEventPublisherAware, Disposab
sb.append(solrHost); sb.append(solrHost);
sb.append(":"); sb.append(":");
sb.append(httpClientFactory.isSSL() ? solrSSLPort: solrPort); sb.append(httpClientFactory.isSSL() ? solrSSLPort: solrPort);
sb.append("/solr"); sb.append(baseUrl);
this.solrUrl = sb.toString(); this.solrUrl = sb.toString();
HttpClient httpClient = httpClientFactory.getHttpClient(); HttpClient httpClient = httpClientFactory.getHttpClient();