Merged 5.1.N (5.1.2) to 5.2.N (5.2.1)

125605 rmunteanu: Merged 5.1.1 (5.1.1) to 5.1.N (5.1.2)
      125498 slanglois: MNT-16155 Update source headers - remove svn:eol-style property on Java and JSP source files


git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/BRANCHES/DEV/5.2.N/root@125783 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
Raluca Munteanu
2016-04-26 13:03:25 +00:00
parent 8674e2bfc8
commit dc6b2852d0
830 changed files with 142585 additions and 142585 deletions

View File

@@ -1,64 +1,64 @@
package org.alfresco.repo.solr;
import org.alfresco.service.namespace.QName;
/**
* Represents a diff between the set of current repository Alfresco models and the set maintained in SOLR.
* The diff can represent a new, changed or removed Alfresco model. For a new model the newChecksum is
* populated; for a changed model both checksums are populated; for a removed model neither checksum is populated.
*
* @since 4.0
*/
public class AlfrescoModelDiff
{
public static enum TYPE
{
NEW, CHANGED, REMOVED;
};
private String modelName;
private TYPE type;
private Long oldChecksum;
private Long newChecksum;
/**
* use full model name or it will be converted to the prefix form - as we are requesting the model it may not be on the other side - so the namespace is unknown.
* @param modelName String
* @param type TYPE
* @param oldChecksum Long
* @param newChecksum Long
*/
public AlfrescoModelDiff(String modelName, TYPE type, Long oldChecksum, Long newChecksum)
{
super();
this.modelName = modelName;
this.type = type;
this.oldChecksum = oldChecksum;
this.newChecksum = newChecksum;
}
public AlfrescoModelDiff(QName modelName, TYPE type, Long oldChecksum, Long newChecksum)
{
this(modelName.toString(), type, oldChecksum, newChecksum);
}
public String getModelName()
{
return modelName;
}
public TYPE getType()
{
return type;
}
public Long getOldChecksum()
{
return oldChecksum;
}
public Long getNewChecksum()
{
return newChecksum;
}
}
package org.alfresco.repo.solr;
import org.alfresco.service.namespace.QName;
/**
* Represents a diff between the set of current repository Alfresco models and the set maintained in SOLR.
* The diff can represent a new, changed or removed Alfresco model. For a new model the newChecksum is
* populated; for a changed model both checksums are populated; for a removed model neither checksum is populated.
*
* @since 4.0
*/
public class AlfrescoModelDiff
{
public static enum TYPE
{
NEW, CHANGED, REMOVED;
};
private String modelName;
private TYPE type;
private Long oldChecksum;
private Long newChecksum;
/**
* use full model name or it will be converted to the prefix form - as we are requesting the model it may not be on the other side - so the namespace is unknown.
* @param modelName String
* @param type TYPE
* @param oldChecksum Long
* @param newChecksum Long
*/
public AlfrescoModelDiff(String modelName, TYPE type, Long oldChecksum, Long newChecksum)
{
super();
this.modelName = modelName;
this.type = type;
this.oldChecksum = oldChecksum;
this.newChecksum = newChecksum;
}
public AlfrescoModelDiff(QName modelName, TYPE type, Long oldChecksum, Long newChecksum)
{
this(modelName.toString(), type, oldChecksum, newChecksum);
}
public String getModelName()
{
return modelName;
}
public TYPE getType()
{
return type;
}
public Long getOldChecksum()
{
return oldChecksum;
}
public Long getNewChecksum()
{
return newChecksum;
}
}

View File

@@ -1,111 +1,111 @@
package org.alfresco.repo.solr;
/**
* Filters for node metadata results e.g. include properties, aspect, ... or not
*
* @since 4.0
*
*/
public class MetaDataResultsFilter
{
private boolean includeProperties = true;
private boolean includeAspects = true;
private boolean includeType = true;
private boolean includeAclId = true;
private boolean includeOwner = true;
private boolean includePaths = true;
private boolean includeParentAssociations = true;
private boolean includeChildAssociations = true;
private boolean includeNodeRef = true;
private boolean includeChildIds = true;
private boolean includeTxnId = true;
public boolean getIncludeChildAssociations()
{
return includeChildAssociations;
}
public void setIncludeChildAssociations(boolean includeChildAssociations)
{
this.includeChildAssociations = includeChildAssociations;
}
public boolean getIncludeNodeRef()
{
return includeNodeRef;
}
public void setIncludeNodeRef(boolean includeNodeRef)
{
this.includeNodeRef = includeNodeRef;
}
public boolean getIncludeParentAssociations()
{
return includeParentAssociations;
}
public void setIncludeParentAssociations(boolean includeParentAssociations)
{
this.includeParentAssociations = includeParentAssociations;
}
public boolean getIncludeProperties()
{
return includeProperties;
}
public void setIncludeProperties(boolean includeProperties)
{
this.includeProperties = includeProperties;
}
public boolean getIncludeAspects()
{
return includeAspects;
}
public void setIncludeAspects(boolean includeAspects)
{
this.includeAspects = includeAspects;
}
public boolean getIncludeType()
{
return includeType;
}
public void setIncludeType(boolean includeType)
{
this.includeType = includeType;
}
public boolean getIncludeAclId()
{
return includeAclId;
}
public void setIncludeAclId(boolean includeAclId)
{
this.includeAclId = includeAclId;
}
public boolean getIncludeOwner()
{
return includeOwner;
}
public void setIncludeOwner(boolean includeOwner)
{
this.includeOwner = includeOwner;
}
public boolean getIncludePaths()
{
return includePaths;
}
public void setIncludePaths(boolean includePaths)
{
this.includePaths = includePaths;
}
public boolean getIncludeChildIds()
{
return includeChildIds;
}
public void setIncludeChildIds(boolean includeChildIds)
{
this.includeChildIds = includeChildIds;
}
public boolean getIncludeTxnId()
{
return includeTxnId;
}
public void setIncludeTxnId(boolean includeTxnId)
{
this.includeTxnId = includeTxnId;
}
}
package org.alfresco.repo.solr;
/**
* Filters for node metadata results e.g. include properties, aspect, ... or not
*
* @since 4.0
*
*/
public class MetaDataResultsFilter
{
private boolean includeProperties = true;
private boolean includeAspects = true;
private boolean includeType = true;
private boolean includeAclId = true;
private boolean includeOwner = true;
private boolean includePaths = true;
private boolean includeParentAssociations = true;
private boolean includeChildAssociations = true;
private boolean includeNodeRef = true;
private boolean includeChildIds = true;
private boolean includeTxnId = true;
public boolean getIncludeChildAssociations()
{
return includeChildAssociations;
}
public void setIncludeChildAssociations(boolean includeChildAssociations)
{
this.includeChildAssociations = includeChildAssociations;
}
public boolean getIncludeNodeRef()
{
return includeNodeRef;
}
public void setIncludeNodeRef(boolean includeNodeRef)
{
this.includeNodeRef = includeNodeRef;
}
public boolean getIncludeParentAssociations()
{
return includeParentAssociations;
}
public void setIncludeParentAssociations(boolean includeParentAssociations)
{
this.includeParentAssociations = includeParentAssociations;
}
public boolean getIncludeProperties()
{
return includeProperties;
}
public void setIncludeProperties(boolean includeProperties)
{
this.includeProperties = includeProperties;
}
public boolean getIncludeAspects()
{
return includeAspects;
}
public void setIncludeAspects(boolean includeAspects)
{
this.includeAspects = includeAspects;
}
public boolean getIncludeType()
{
return includeType;
}
public void setIncludeType(boolean includeType)
{
this.includeType = includeType;
}
public boolean getIncludeAclId()
{
return includeAclId;
}
public void setIncludeAclId(boolean includeAclId)
{
this.includeAclId = includeAclId;
}
public boolean getIncludeOwner()
{
return includeOwner;
}
public void setIncludeOwner(boolean includeOwner)
{
this.includeOwner = includeOwner;
}
public boolean getIncludePaths()
{
return includePaths;
}
public void setIncludePaths(boolean includePaths)
{
this.includePaths = includePaths;
}
public boolean getIncludeChildIds()
{
return includeChildIds;
}
public void setIncludeChildIds(boolean includeChildIds)
{
this.includeChildIds = includeChildIds;
}
public boolean getIncludeTxnId()
{
return includeTxnId;
}
public void setIncludeTxnId(boolean includeTxnId)
{
this.includeTxnId = includeTxnId;
}
}

View File

@@ -1,159 +1,159 @@
package org.alfresco.repo.solr;
import java.io.Serializable;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.alfresco.service.cmr.repository.ChildAssociationRef;
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.cmr.repository.Path;
import org.alfresco.service.namespace.QName;
import org.alfresco.util.Pair;
/**
*
* @since 4.0
*/
public class NodeMetaData
{
private Long nodeId;
private NodeRef nodeRef;
private String owner;
private QName nodeType;
private Long aclId;
private Map<QName, Serializable> properties;
private Set<QName> aspects;
private Collection<Pair<Path, QName>> paths;
private Collection<Collection<String>> namePaths;
private List<ChildAssociationRef> childAssocs;
private List<ChildAssociationRef> parentAssocs;
private Long parentAssocsCrc;
private List<Long> childIds;
private Long txnId;
private String tenantDomain;
public String getOwner()
{
return owner;
}
public void setOwner(String owner)
{
this.owner = owner;
}
public NodeRef getNodeRef()
{
return nodeRef;
}
public void setNodeRef(NodeRef nodeRef)
{
this.nodeRef = nodeRef;
}
public Collection<Pair<Path, QName>> getPaths()
{
return paths;
}
public void setPaths(Collection<Pair<Path, QName>> paths)
{
this.paths = paths;
}
public Collection<Collection<String>> getNamePaths()
{
return namePaths;
}
public void setNamePaths(Collection<Collection<String>> namePaths)
{
this.namePaths = namePaths;
}
public QName getNodeType()
{
return nodeType;
}
public void setNodeType(QName nodeType)
{
this.nodeType = nodeType;
}
public Long getNodeId()
{
return nodeId;
}
public void setNodeId(Long nodeId)
{
this.nodeId = nodeId;
}
public Long getAclId()
{
return aclId;
}
public void setAclId(Long aclId)
{
this.aclId = aclId;
}
public Map<QName, Serializable> getProperties()
{
return properties;
}
public void setProperties(Map<QName, Serializable> properties)
{
this.properties = properties;
}
public Set<QName> getAspects()
{
return aspects;
}
public void setAspects(Set<QName> aspects)
{
this.aspects = aspects;
}
public List<ChildAssociationRef> getChildAssocs()
{
return childAssocs;
}
public void setChildAssocs(List<ChildAssociationRef> childAssocs)
{
this.childAssocs = childAssocs;
}
/**
* @param parentAssocs List<ChildAssociationRef>
* @param parentAssocsCrc Long
*/
public void setParentAssocs(List<ChildAssociationRef> parentAssocs, Long parentAssocsCrc)
{
this.parentAssocs = parentAssocs;
this.parentAssocsCrc = parentAssocsCrc;
}
public List<ChildAssociationRef> getParentAssocs()
{
return parentAssocs;
}
public Long getParentAssocsCrc()
{
return parentAssocsCrc;
}
public List<Long> getChildIds()
{
return childIds;
}
public void setChildIds(List<Long> childIds)
{
this.childIds = childIds;
}
public Long getTxnId()
{
return txnId;
}
public void setTxnId(Long txnId)
{
this.txnId = txnId;
}
public String getTenantDomain()
{
return tenantDomain;
}
public void setTenantDomain(String tenantDomain)
{
this.tenantDomain = tenantDomain;
}
}
package org.alfresco.repo.solr;
import java.io.Serializable;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.alfresco.service.cmr.repository.ChildAssociationRef;
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.cmr.repository.Path;
import org.alfresco.service.namespace.QName;
import org.alfresco.util.Pair;
/**
*
* @since 4.0
*/
public class NodeMetaData
{
private Long nodeId;
private NodeRef nodeRef;
private String owner;
private QName nodeType;
private Long aclId;
private Map<QName, Serializable> properties;
private Set<QName> aspects;
private Collection<Pair<Path, QName>> paths;
private Collection<Collection<String>> namePaths;
private List<ChildAssociationRef> childAssocs;
private List<ChildAssociationRef> parentAssocs;
private Long parentAssocsCrc;
private List<Long> childIds;
private Long txnId;
private String tenantDomain;
public String getOwner()
{
return owner;
}
public void setOwner(String owner)
{
this.owner = owner;
}
public NodeRef getNodeRef()
{
return nodeRef;
}
public void setNodeRef(NodeRef nodeRef)
{
this.nodeRef = nodeRef;
}
public Collection<Pair<Path, QName>> getPaths()
{
return paths;
}
public void setPaths(Collection<Pair<Path, QName>> paths)
{
this.paths = paths;
}
public Collection<Collection<String>> getNamePaths()
{
return namePaths;
}
public void setNamePaths(Collection<Collection<String>> namePaths)
{
this.namePaths = namePaths;
}
public QName getNodeType()
{
return nodeType;
}
public void setNodeType(QName nodeType)
{
this.nodeType = nodeType;
}
public Long getNodeId()
{
return nodeId;
}
public void setNodeId(Long nodeId)
{
this.nodeId = nodeId;
}
public Long getAclId()
{
return aclId;
}
public void setAclId(Long aclId)
{
this.aclId = aclId;
}
public Map<QName, Serializable> getProperties()
{
return properties;
}
public void setProperties(Map<QName, Serializable> properties)
{
this.properties = properties;
}
public Set<QName> getAspects()
{
return aspects;
}
public void setAspects(Set<QName> aspects)
{
this.aspects = aspects;
}
public List<ChildAssociationRef> getChildAssocs()
{
return childAssocs;
}
public void setChildAssocs(List<ChildAssociationRef> childAssocs)
{
this.childAssocs = childAssocs;
}
/**
* @param parentAssocs List<ChildAssociationRef>
* @param parentAssocsCrc Long
*/
public void setParentAssocs(List<ChildAssociationRef> parentAssocs, Long parentAssocsCrc)
{
this.parentAssocs = parentAssocs;
this.parentAssocsCrc = parentAssocsCrc;
}
public List<ChildAssociationRef> getParentAssocs()
{
return parentAssocs;
}
public Long getParentAssocsCrc()
{
return parentAssocsCrc;
}
public List<Long> getChildIds()
{
return childIds;
}
public void setChildIds(List<Long> childIds)
{
this.childIds = childIds;
}
public Long getTxnId()
{
return txnId;
}
public void setTxnId(Long txnId)
{
this.txnId = txnId;
}
public String getTenantDomain()
{
return tenantDomain;
}
public void setTenantDomain(String tenantDomain)
{
this.tenantDomain = tenantDomain;
}
}

View File

@@ -1,93 +1,93 @@
package org.alfresco.repo.solr;
import java.util.List;
/**
* Stores node meta data query parameters for use in SOLR DAO queries
*
* @since 4.0
*/
public class NodeMetaDataParameters
{
private List<Long> transactionIds;
private Long fromTxnId;
private Long toTxnId;
// default is 'all' results
private int maxResults = 0;
private Long fromNodeId;
private Long toNodeId;
private List<Long> nodeIds;
public int getMaxResults()
{
return maxResults;
}
public void setMaxResults(int maxResults)
{
this.maxResults = maxResults;
}
public List<Long> getNodeIds()
{
return nodeIds;
}
public void setNodeIds(List<Long> nodeIds)
{
this.nodeIds = nodeIds;
}
public void setTransactionIds(List<Long> txnIds)
{
this.transactionIds = txnIds;
}
public List<Long> getTransactionIds()
{
return transactionIds;
}
public Long getFromTxnId()
{
return fromTxnId;
}
public void setFromTxnId(Long fromTxnId)
{
this.fromTxnId = fromTxnId;
}
public Long getToTxnId()
{
return toTxnId;
}
public void setToTxnId(Long toTxnId)
{
this.toTxnId = toTxnId;
}
public Long getFromNodeId()
{
return fromNodeId;
}
public void setFromNodeId(Long fromNodeId)
{
this.fromNodeId = fromNodeId;
}
public Long getToNodeId()
{
return toNodeId;
}
public void setToNodeId(Long toNodeId)
{
this.toNodeId = toNodeId;
}
}
package org.alfresco.repo.solr;
import java.util.List;
/**
* Stores node meta data query parameters for use in SOLR DAO queries
*
* @since 4.0
*/
public class NodeMetaDataParameters
{
private List<Long> transactionIds;
private Long fromTxnId;
private Long toTxnId;
// default is 'all' results
private int maxResults = 0;
private Long fromNodeId;
private Long toNodeId;
private List<Long> nodeIds;
public int getMaxResults()
{
return maxResults;
}
public void setMaxResults(int maxResults)
{
this.maxResults = maxResults;
}
public List<Long> getNodeIds()
{
return nodeIds;
}
public void setNodeIds(List<Long> nodeIds)
{
this.nodeIds = nodeIds;
}
public void setTransactionIds(List<Long> txnIds)
{
this.transactionIds = txnIds;
}
public List<Long> getTransactionIds()
{
return transactionIds;
}
public Long getFromTxnId()
{
return fromTxnId;
}
public void setFromTxnId(Long fromTxnId)
{
this.fromTxnId = fromTxnId;
}
public Long getToTxnId()
{
return toTxnId;
}
public void setToTxnId(Long toTxnId)
{
this.toTxnId = toTxnId;
}
public Long getFromNodeId()
{
return fromNodeId;
}
public void setFromNodeId(Long fromNodeId)
{
this.fromNodeId = fromNodeId;
}
public Long getToNodeId()
{
return toNodeId;
}
public void setToNodeId(Long toNodeId)
{
this.toNodeId = toNodeId;
}
}

View File

@@ -1,378 +1,378 @@
package org.alfresco.repo.solr;
import java.net.MalformedURLException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.concurrent.locks.ReentrantReadWriteLock;
import java.util.concurrent.locks.ReentrantReadWriteLock.WriteLock;
import org.alfresco.error.AlfrescoRuntimeException;
import org.alfresco.httpclient.HttpClientFactory;
import org.alfresco.util.ParameterCheck;
import org.apache.commons.httpclient.Credentials;
import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.UsernamePasswordCredentials;
import org.apache.commons.httpclient.auth.AuthScope;
import org.apache.solr.client.solrj.SolrServerException;
import org.apache.solr.client.solrj.impl.CommonsHttpSolrServer;
import org.apache.solr.client.solrj.impl.XMLResponseParser;
import org.apache.solr.client.solrj.response.QueryResponse;
import org.apache.solr.common.params.ModifiableSolrParams;
import org.apache.solr.common.util.NamedList;
import org.quartz.CronTrigger;
import org.quartz.JobDataMap;
import org.quartz.JobDetail;
import org.quartz.Scheduler;
import org.quartz.SchedulerException;
import org.quartz.Trigger;
import org.springframework.beans.factory.DisposableBean;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.context.ApplicationEventPublisherAware;
/**
* Provides an interface to the Solr admin APIs, used by the Alfresco Enterprise JMX layer.
* Also tracks whether Solr is available, sending Spring events when its availability changes.
*
* @since 4.0
*
*/
public class SOLRAdminClient implements ApplicationEventPublisherAware, DisposableBean
{
private String solrHost;
private int solrPort;
private int solrSSLPort;
private String solrUrl;
private String solrUser;
private String solrPassword;
private String solrPingCronExpression;
private String baseUrl;
private CommonsHttpSolrServer server;
private int solrConnectTimeout = 30000; // ms
private ApplicationEventPublisher applicationEventPublisher;
private SolrTracker solrTracker;
private HttpClientFactory httpClientFactory;
private Scheduler scheduler;
public SOLRAdminClient()
{
}
public void setSolrHost(String solrHost)
{
this.solrHost = solrHost;
}
public void setSolrPort(String solrPort)
{
this.solrPort = Integer.parseInt(solrPort);
}
public void setSolrsslPort(int solrSSLPort)
{
this.solrSSLPort = solrSSLPort;
}
public void setSolrUser(String solrUser)
{
this.solrUser = solrUser;
}
public void setSolrPassword(String solrPassword)
{
this.solrPassword = solrPassword;
}
public void setSolrConnectTimeout(String solrConnectTimeout)
{
this.solrConnectTimeout = Integer.parseInt(solrConnectTimeout);
}
@Override
public void setApplicationEventPublisher(ApplicationEventPublisher applicationEventPublisher)
{
this.applicationEventPublisher = applicationEventPublisher;
}
public void setSolrPingCronExpression(String solrPingCronExpression)
{
this.solrPingCronExpression = solrPingCronExpression;
}
public void setHttpClientFactory(HttpClientFactory httpClientFactory)
{
this.httpClientFactory = httpClientFactory;
}
public void setBaseUrl(String baseUrl)
{
this.baseUrl = baseUrl;
}
/**
* @param scheduler the scheduler to set
*/
public void setScheduler(Scheduler scheduler)
{
this.scheduler = scheduler;
}
public void init()
{
ParameterCheck.mandatory("solrHost", solrHost);
ParameterCheck.mandatory("solrPort", solrPort);
ParameterCheck.mandatory("solrUser", solrUser);
ParameterCheck.mandatory("solrPassword", solrPassword);
ParameterCheck.mandatory("solrPingCronExpression", solrPingCronExpression);
ParameterCheck.mandatory("solrConnectTimeout", solrConnectTimeout);
try
{
StringBuilder sb = new StringBuilder();
sb.append(httpClientFactory.isSSL() ? "https://" : "http://");
sb.append(solrHost);
sb.append(":");
sb.append(httpClientFactory.isSSL() ? solrSSLPort: solrPort);
sb.append(baseUrl);
this.solrUrl = sb.toString();
HttpClient httpClient = httpClientFactory.getHttpClient();
server = new CommonsHttpSolrServer(solrUrl, httpClient);
server.setParser(new XMLResponseParser());
// TODO remove credentials because we're using SSL?
Credentials defaultcreds = new UsernamePasswordCredentials(solrUser, solrPassword);
server.getHttpClient().getState().setCredentials(new AuthScope(solrHost, solrPort, AuthScope.ANY_REALM),
defaultcreds);
server.setConnectionTimeout(solrConnectTimeout);
server.setSoTimeout(20000);
this.solrTracker = new SolrTracker(scheduler);
}
catch(MalformedURLException e)
{
throw new AlfrescoRuntimeException("Cannot initialise Solr admin http client", e);
}
}
public QueryResponse basicQuery(ModifiableSolrParams params)
{
try
{
QueryResponse response = server.query(params);
return response;
}
catch(SolrServerException e)
{
return null;
}
}
public QueryResponse query(ModifiableSolrParams params) throws SolrServerException
{
try
{
QueryResponse response = server.query(params);
if(response.getStatus() != 0)
{
solrTracker.setSolrActive(false);
}
return response;
}
catch(SolrServerException e)
{
solrTracker.setSolrActive(false);
throw e;
}
}
public List<String> getRegisteredCores()
{
return solrTracker.getRegisteredCores();
}
/**
* Tracks the availability of Solr.
*
* @since 4.0
*
*/
class SolrTracker
{
private final WriteLock writeLock;
private boolean solrActive = false;
private Scheduler scheduler = null;
private Trigger trigger;
private List<String> cores;
SolrTracker(Scheduler scheduler)
{
this.scheduler = scheduler;
ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
writeLock = lock.writeLock();
cores = new ArrayList<String>(5);
setupTimer();
}
protected void pingSolr()
{
ModifiableSolrParams params = new ModifiableSolrParams();
params.set("qt", "/admin/cores");
params.set("action", "STATUS");
QueryResponse response = basicQuery(params);
if(response != null && response.getStatus() == 0)
{
NamedList<Object> results = response.getResponse();
@SuppressWarnings("unchecked")
NamedList<Object> report = (NamedList<Object>)results.get("status");
Iterator<Map.Entry<String, Object>> coreIterator = report.iterator();
List<String> cores = new ArrayList<String>(report.size());
while(coreIterator.hasNext())
{
Map.Entry<String, Object> core = coreIterator.next();
cores.add(core.getKey());
}
registerCores(cores);
setSolrActive(true);
}
else
{
setSolrActive(false);
}
}
void setSolrActive(boolean active)
{
boolean statusChanged = false;
try
{
writeLock.lock();
try
{
if(solrActive != active)
{
solrActive = active;
statusChanged = true;
}
}
finally
{
writeLock.unlock();
}
if(statusChanged)
{
// do this outside the write lock
if(solrActive)
{
stopTimer();
applicationEventPublisher.publishEvent(new SolrActiveEvent(this));
}
else
{
startTimer();
applicationEventPublisher.publishEvent(new SolrInactiveEvent(this));
}
}
}
catch(Exception e)
{
throw new AlfrescoRuntimeException("", e);
}
}
boolean isSolrActive()
{
return solrActive;
}
protected void setupTimer()
{
try
{
final String jobName = "SolrWatcher";
final String jobGroup = "Solr";
// If a Quartz job already exists with this name and group then we want to replace it.
// It is not expected that this will occur during production, but it is possible during automated testing
// where application contexts could be rebuilt between test cases, leading to multiple creations of
// equivalent Quartz jobs. Quartz disallows the scheduling of multiple jobs with the same name and group.
JobDetail existingJob = scheduler.getJobDetail(jobName, jobGroup);
if (existingJob != null)
{
scheduler.deleteJob(jobName, jobGroup);
}
JobDetail job = new JobDetail(jobName, jobGroup, SOLRWatcherJob.class);
JobDataMap jobDataMap = new JobDataMap();
jobDataMap.put("SOLR_TRACKER", this);
job.setJobDataMap(jobDataMap);
trigger = new CronTrigger("SolrWatcherTrigger", jobGroup, solrPingCronExpression);
scheduler.scheduleJob(job, trigger);
}
catch(Exception e)
{
throw new AlfrescoRuntimeException("Unable to set up SOLRTracker timer", e);
}
}
protected void startTimer() throws SchedulerException
{
scheduler.resumeTrigger(trigger.getName(), trigger.getGroup());
}
protected void stopTimer() throws SchedulerException
{
scheduler.pauseTrigger(trigger.getName(), trigger.getGroup());
}
void registerCores(List<String> cores)
{
writeLock.lock();
try
{
this.cores = cores;
}
finally
{
writeLock.unlock();
}
}
@SuppressWarnings("unchecked")
List<String> getRegisteredCores()
{
writeLock.lock();
try
{
return (cores != null ? cores : Collections.EMPTY_LIST);
}
finally
{
writeLock.unlock();
}
}
}
/* (non-Javadoc)
* @see org.springframework.beans.factory.DisposableBean#destroy()
*/
@Override
public void destroy() throws Exception
{
solrTracker.stopTimer();
}
}
package org.alfresco.repo.solr;
import java.net.MalformedURLException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.concurrent.locks.ReentrantReadWriteLock;
import java.util.concurrent.locks.ReentrantReadWriteLock.WriteLock;
import org.alfresco.error.AlfrescoRuntimeException;
import org.alfresco.httpclient.HttpClientFactory;
import org.alfresco.util.ParameterCheck;
import org.apache.commons.httpclient.Credentials;
import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.UsernamePasswordCredentials;
import org.apache.commons.httpclient.auth.AuthScope;
import org.apache.solr.client.solrj.SolrServerException;
import org.apache.solr.client.solrj.impl.CommonsHttpSolrServer;
import org.apache.solr.client.solrj.impl.XMLResponseParser;
import org.apache.solr.client.solrj.response.QueryResponse;
import org.apache.solr.common.params.ModifiableSolrParams;
import org.apache.solr.common.util.NamedList;
import org.quartz.CronTrigger;
import org.quartz.JobDataMap;
import org.quartz.JobDetail;
import org.quartz.Scheduler;
import org.quartz.SchedulerException;
import org.quartz.Trigger;
import org.springframework.beans.factory.DisposableBean;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.context.ApplicationEventPublisherAware;
/**
* Provides an interface to the Solr admin APIs, used by the Alfresco Enterprise JMX layer.
* Also tracks whether Solr is available, sending Spring events when its availability changes.
*
* @since 4.0
*
*/
public class SOLRAdminClient implements ApplicationEventPublisherAware, DisposableBean
{
private String solrHost;
private int solrPort;
private int solrSSLPort;
private String solrUrl;
private String solrUser;
private String solrPassword;
private String solrPingCronExpression;
private String baseUrl;
private CommonsHttpSolrServer server;
private int solrConnectTimeout = 30000; // ms
private ApplicationEventPublisher applicationEventPublisher;
private SolrTracker solrTracker;
private HttpClientFactory httpClientFactory;
private Scheduler scheduler;
public SOLRAdminClient()
{
}
public void setSolrHost(String solrHost)
{
this.solrHost = solrHost;
}
public void setSolrPort(String solrPort)
{
this.solrPort = Integer.parseInt(solrPort);
}
public void setSolrsslPort(int solrSSLPort)
{
this.solrSSLPort = solrSSLPort;
}
public void setSolrUser(String solrUser)
{
this.solrUser = solrUser;
}
public void setSolrPassword(String solrPassword)
{
this.solrPassword = solrPassword;
}
public void setSolrConnectTimeout(String solrConnectTimeout)
{
this.solrConnectTimeout = Integer.parseInt(solrConnectTimeout);
}
@Override
public void setApplicationEventPublisher(ApplicationEventPublisher applicationEventPublisher)
{
this.applicationEventPublisher = applicationEventPublisher;
}
public void setSolrPingCronExpression(String solrPingCronExpression)
{
this.solrPingCronExpression = solrPingCronExpression;
}
public void setHttpClientFactory(HttpClientFactory httpClientFactory)
{
this.httpClientFactory = httpClientFactory;
}
public void setBaseUrl(String baseUrl)
{
this.baseUrl = baseUrl;
}
/**
* @param scheduler the scheduler to set
*/
public void setScheduler(Scheduler scheduler)
{
this.scheduler = scheduler;
}
public void init()
{
ParameterCheck.mandatory("solrHost", solrHost);
ParameterCheck.mandatory("solrPort", solrPort);
ParameterCheck.mandatory("solrUser", solrUser);
ParameterCheck.mandatory("solrPassword", solrPassword);
ParameterCheck.mandatory("solrPingCronExpression", solrPingCronExpression);
ParameterCheck.mandatory("solrConnectTimeout", solrConnectTimeout);
try
{
StringBuilder sb = new StringBuilder();
sb.append(httpClientFactory.isSSL() ? "https://" : "http://");
sb.append(solrHost);
sb.append(":");
sb.append(httpClientFactory.isSSL() ? solrSSLPort: solrPort);
sb.append(baseUrl);
this.solrUrl = sb.toString();
HttpClient httpClient = httpClientFactory.getHttpClient();
server = new CommonsHttpSolrServer(solrUrl, httpClient);
server.setParser(new XMLResponseParser());
// TODO remove credentials because we're using SSL?
Credentials defaultcreds = new UsernamePasswordCredentials(solrUser, solrPassword);
server.getHttpClient().getState().setCredentials(new AuthScope(solrHost, solrPort, AuthScope.ANY_REALM),
defaultcreds);
server.setConnectionTimeout(solrConnectTimeout);
server.setSoTimeout(20000);
this.solrTracker = new SolrTracker(scheduler);
}
catch(MalformedURLException e)
{
throw new AlfrescoRuntimeException("Cannot initialise Solr admin http client", e);
}
}
public QueryResponse basicQuery(ModifiableSolrParams params)
{
try
{
QueryResponse response = server.query(params);
return response;
}
catch(SolrServerException e)
{
return null;
}
}
public QueryResponse query(ModifiableSolrParams params) throws SolrServerException
{
try
{
QueryResponse response = server.query(params);
if(response.getStatus() != 0)
{
solrTracker.setSolrActive(false);
}
return response;
}
catch(SolrServerException e)
{
solrTracker.setSolrActive(false);
throw e;
}
}
public List<String> getRegisteredCores()
{
return solrTracker.getRegisteredCores();
}
/**
* Tracks the availability of Solr.
*
* @since 4.0
*
*/
class SolrTracker
{
private final WriteLock writeLock;
private boolean solrActive = false;
private Scheduler scheduler = null;
private Trigger trigger;
private List<String> cores;
SolrTracker(Scheduler scheduler)
{
this.scheduler = scheduler;
ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
writeLock = lock.writeLock();
cores = new ArrayList<String>(5);
setupTimer();
}
protected void pingSolr()
{
ModifiableSolrParams params = new ModifiableSolrParams();
params.set("qt", "/admin/cores");
params.set("action", "STATUS");
QueryResponse response = basicQuery(params);
if(response != null && response.getStatus() == 0)
{
NamedList<Object> results = response.getResponse();
@SuppressWarnings("unchecked")
NamedList<Object> report = (NamedList<Object>)results.get("status");
Iterator<Map.Entry<String, Object>> coreIterator = report.iterator();
List<String> cores = new ArrayList<String>(report.size());
while(coreIterator.hasNext())
{
Map.Entry<String, Object> core = coreIterator.next();
cores.add(core.getKey());
}
registerCores(cores);
setSolrActive(true);
}
else
{
setSolrActive(false);
}
}
void setSolrActive(boolean active)
{
boolean statusChanged = false;
try
{
writeLock.lock();
try
{
if(solrActive != active)
{
solrActive = active;
statusChanged = true;
}
}
finally
{
writeLock.unlock();
}
if(statusChanged)
{
// do this outside the write lock
if(solrActive)
{
stopTimer();
applicationEventPublisher.publishEvent(new SolrActiveEvent(this));
}
else
{
startTimer();
applicationEventPublisher.publishEvent(new SolrInactiveEvent(this));
}
}
}
catch(Exception e)
{
throw new AlfrescoRuntimeException("", e);
}
}
boolean isSolrActive()
{
return solrActive;
}
protected void setupTimer()
{
try
{
final String jobName = "SolrWatcher";
final String jobGroup = "Solr";
// If a Quartz job already exists with this name and group then we want to replace it.
// It is not expected that this will occur during production, but it is possible during automated testing
// where application contexts could be rebuilt between test cases, leading to multiple creations of
// equivalent Quartz jobs. Quartz disallows the scheduling of multiple jobs with the same name and group.
JobDetail existingJob = scheduler.getJobDetail(jobName, jobGroup);
if (existingJob != null)
{
scheduler.deleteJob(jobName, jobGroup);
}
JobDetail job = new JobDetail(jobName, jobGroup, SOLRWatcherJob.class);
JobDataMap jobDataMap = new JobDataMap();
jobDataMap.put("SOLR_TRACKER", this);
job.setJobDataMap(jobDataMap);
trigger = new CronTrigger("SolrWatcherTrigger", jobGroup, solrPingCronExpression);
scheduler.scheduleJob(job, trigger);
}
catch(Exception e)
{
throw new AlfrescoRuntimeException("Unable to set up SOLRTracker timer", e);
}
}
protected void startTimer() throws SchedulerException
{
scheduler.resumeTrigger(trigger.getName(), trigger.getGroup());
}
protected void stopTimer() throws SchedulerException
{
scheduler.pauseTrigger(trigger.getName(), trigger.getGroup());
}
void registerCores(List<String> cores)
{
writeLock.lock();
try
{
this.cores = cores;
}
finally
{
writeLock.unlock();
}
}
@SuppressWarnings("unchecked")
List<String> getRegisteredCores()
{
writeLock.lock();
try
{
return (cores != null ? cores : Collections.EMPTY_LIST);
}
finally
{
writeLock.unlock();
}
}
}
/* (non-Javadoc)
* @see org.springframework.beans.factory.DisposableBean#destroy()
*/
@Override
public void destroy() throws Exception
{
solrTracker.stopTimer();
}
}

View File

@@ -1,31 +1,31 @@
package org.alfresco.repo.solr;
import org.alfresco.repo.solr.SOLRAdminClient.SolrTracker;
import org.quartz.Job;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
/**
* A Quartz job that pings Solr to determine if it is alive
*
* @since 4.0
*
*/
public class SOLRWatcherJob implements Job
{
public SOLRWatcherJob()
{
super();
}
/*
* (non-Javadoc)
* @see org.quartz.Job#execute(org.quartz.JobExecutionContext)
*/
@Override
public void execute(JobExecutionContext jec) throws JobExecutionException
{
SolrTracker solrTracker = (SolrTracker)jec.getJobDetail().getJobDataMap().get("SOLR_TRACKER");
solrTracker.pingSolr();
}
}
package org.alfresco.repo.solr;
import org.alfresco.repo.solr.SOLRAdminClient.SolrTracker;
import org.quartz.Job;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
/**
* A Quartz job that pings Solr to determine if it is alive
*
* @since 4.0
*
*/
public class SOLRWatcherJob implements Job
{
public SOLRWatcherJob()
{
super();
}
/*
* (non-Javadoc)
* @see org.quartz.Job#execute(org.quartz.JobExecutionContext)
*/
@Override
public void execute(JobExecutionContext jec) throws JobExecutionException
{
SolrTracker solrTracker = (SolrTracker)jec.getJobDetail().getJobDataMap().get("SOLR_TRACKER");
solrTracker.pingSolr();
}
}

View File

@@ -1,16 +1,16 @@
package org.alfresco.repo.solr;
/**
*
* @since 4.0
*
*/
public class SolrActiveEvent extends SolrEvent
{
private static final long serialVersionUID = -7361024456694701653L;
public SolrActiveEvent(Object source) {
super(source);
}
}
package org.alfresco.repo.solr;
/**
*
* @since 4.0
*
*/
public class SolrActiveEvent extends SolrEvent
{
private static final long serialVersionUID = -7361024456694701653L;
public SolrActiveEvent(Object source) {
super(source);
}
}

View File

@@ -1,18 +1,18 @@
package org.alfresco.repo.solr;
import org.springframework.context.ApplicationEvent;
/**
*
* @since 4.0
*
*/
public abstract class SolrEvent extends ApplicationEvent
{
private static final long serialVersionUID = 1L;
public SolrEvent(Object source)
{
super(source);
}
}
package org.alfresco.repo.solr;
import org.springframework.context.ApplicationEvent;
/**
*
* @since 4.0
*
*/
public abstract class SolrEvent extends ApplicationEvent
{
private static final long serialVersionUID = 1L;
public SolrEvent(Object source)
{
super(source);
}
}

View File

@@ -1,16 +1,16 @@
package org.alfresco.repo.solr;
/**
*
* @since 4.0
*
*/
public class SolrInactiveEvent extends SolrEvent
{
private static final long serialVersionUID = 376796464819899697L;
public SolrInactiveEvent(Object source) {
super(source);
}
}
package org.alfresco.repo.solr;
/**
*
* @since 4.0
*
*/
public class SolrInactiveEvent extends SolrEvent
{
private static final long serialVersionUID = 376796464819899697L;
public SolrInactiveEvent(Object source) {
super(source);
}
}