mirror of
https://github.com/Alfresco/alfresco-community-repo.git
synced 2025-07-31 17:39:05 +00:00
Merged SWIFT to HEAD
25250: SWIFT branch moved to 4.0.0 schema 5000 25435: Initial checkin for ALF-7069 25450: ALF-7069: - add maxResults to SOLR DAO - refactoring 25480: ALF-7069: further enhancements + unit tests - include/exclude aspects, store protocol + identifier git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@27999 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
@@ -253,4 +253,9 @@
|
||||
<property name="controlDAO" ref="controlDAO"/>
|
||||
</bean>
|
||||
|
||||
<bean id="solrDAO" class="org.alfresco.repo.domain.solr.ibatis.SOLRDAOImpl" init-method="init">
|
||||
<property name="sqlMapClientTemplate" ref="solrSqlMapClientTemplate"/>
|
||||
<property name="qNameDAO" ref="qnameDAO"/>
|
||||
</bean>
|
||||
|
||||
</beans>
|
||||
|
@@ -41,6 +41,7 @@
|
||||
<sqlMap resource="alfresco/ibatis/#resource.dialect#/permissions-insert-SqlMap.xml"/>
|
||||
<sqlMap resource="alfresco/ibatis/#resource.dialect#/usage-common-SqlMap.xml"/>
|
||||
<sqlMap resource="alfresco/ibatis/#resource.dialect#/usage-insert-SqlMap.xml"/>
|
||||
<sqlMap resource="alfresco/ibatis/#resource.dialect#/solr-common-SqlMap.xml"/>
|
||||
|
||||
<!-- Canned queries -->
|
||||
<sqlMap resource="alfresco/ibatis/#resource.dialect#/query-test-common-SqlMap.xml"/>
|
||||
|
@@ -78,5 +78,7 @@
|
||||
<bean id="avmSqlMapClientTemplate" class="org.springframework.orm.ibatis.SqlMapClientTemplate">
|
||||
<property name="sqlMapClient" ref="alfrescoSqlMapClient"/>
|
||||
</bean>
|
||||
|
||||
<bean id="solrSqlMapClientTemplate" class="org.springframework.orm.ibatis.SqlMapClientTemplate">
|
||||
<property name="sqlMapClient" ref="alfrescoSqlMapClient"/>
|
||||
</bean>
|
||||
</beans>
|
||||
|
@@ -0,0 +1,116 @@
|
||||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
|
||||
<!DOCTYPE sqlMap
|
||||
PUBLIC "-//ibatis.apache.org//DTD SQL Map 2.0//EN"
|
||||
"http://ibatis.apache.org/dtd/sql-map-2.dtd">
|
||||
|
||||
<sqlMap namespace="alfresco.solr">
|
||||
|
||||
<typeAlias alias="SOLRTransaction" type="org.alfresco.repo.domain.solr.TransactionEntity"/>
|
||||
<typeAlias alias="Node" type="org.alfresco.repo.domain.node.NodeEntity"/>
|
||||
<typeAlias alias="SOLRTransactionParameters" type="org.alfresco.repo.domain.solr.SOLRTransactionParameters"/>
|
||||
<typeAlias alias="NodeParameters" type="org.alfresco.repo.domain.solr.NodeParameters"/>
|
||||
|
||||
<resultMap id="result_Node" class="Node">
|
||||
<result property="id" column="id" jdbcType="BIGINT" javaType="java.lang.Long"/>
|
||||
<result property="deleted" column="node_deleted" jdbcType="BIT" javaType="java.lang.Boolean" />
|
||||
<result property="transaction.id" column="txn_id" jdbcType="BIGINT" javaType="java.lang.Long"/>
|
||||
</resultMap>
|
||||
|
||||
<resultMap id="result_Transaction" class="SOLRTransaction">
|
||||
<result property="id" column="id" jdbcType="BIGINT" javaType="java.lang.Long"/>
|
||||
<result property="commitTimeMs" column="commit_time_ms" jdbcType="BIGINT" javaType="java.lang.Long"/>
|
||||
<result property="updates" column="updates" jdbcType="BIGINT" javaType="java.lang.Long"/>
|
||||
<result property="deletes" column="deletes" jdbcType="BIGINT" javaType="java.lang.Long"/>
|
||||
</resultMap>
|
||||
|
||||
<select id="select_Txns" parameterClass="SOLRTransactionParameters" resultMap="result_Transaction">
|
||||
select
|
||||
txn.id as id,
|
||||
txn.commit_time_ms as commit_time_ms,
|
||||
(select
|
||||
count(node.id)
|
||||
from
|
||||
alf_node node
|
||||
where
|
||||
txn.id = node.transaction_id and
|
||||
node.node_deleted = 0
|
||||
) as updates,
|
||||
(select
|
||||
count(node.id)
|
||||
from
|
||||
alf_node node
|
||||
where
|
||||
txn.id = node.transaction_id and
|
||||
node.node_deleted = 1
|
||||
) as deletes
|
||||
from
|
||||
alf_transaction txn
|
||||
<dynamic prepend="where">
|
||||
<isNotNull property="txnFromCommitTime" prepend="and">
|
||||
<![CDATA[txn.commit_time_ms >= #txnFromCommitTime#]]>
|
||||
</isNotNull>
|
||||
<isNotNull property="minTxnId" prepend="and">
|
||||
<![CDATA[txn.id >= #minTxnId#]]>
|
||||
</isNotNull>
|
||||
</dynamic>
|
||||
order by txn.commit_time_ms ASC, txn.id ASC
|
||||
</select>
|
||||
|
||||
<select id="select_Txn_Nodes" parameterClass="NodeParameters" resultMap="result_Node">
|
||||
select
|
||||
node.id as id,
|
||||
node.node_deleted as node_deleted,
|
||||
node.transaction_id as txn_id
|
||||
from
|
||||
alf_transaction txn
|
||||
join alf_node node on (txn.id = node.transaction_id)
|
||||
<dynamic>
|
||||
<isEqual property="storeFilter" compareValue="true">
|
||||
join alf_store store on (store.id = node.store_id)
|
||||
</isEqual>
|
||||
</dynamic>
|
||||
<dynamic prepend="where">
|
||||
<isNotNull property="transactionIds" prepend="and">
|
||||
txn.id in <iterate property="transactionIds" open="(" close=")" conjunction=", ">#transactionIds[]#</iterate>
|
||||
</isNotNull>
|
||||
<isNotNull property="fromNodeId" prepend="and">
|
||||
<![CDATA[node.id >= #fromNodeId#]]>
|
||||
</isNotNull>
|
||||
<isNotNull property="toNodeId" prepend="and">
|
||||
<![CDATA[node.id <= #toNodeId#]]>
|
||||
</isNotNull>
|
||||
<isNotNull property="storeProtocol" prepend="and">
|
||||
store.protocol = #storeProtocol#
|
||||
</isNotNull>
|
||||
<isNotNull property="storeIdentifier" prepend="and">
|
||||
store.identifier = #storeIdentifier#
|
||||
</isNotNull>
|
||||
<isNotNull property="includeTypeIds" prepend="and">
|
||||
node.type_qname_id in <iterate property="includeTypeIds" open="(" close=")" conjunction=", ">#includeTypeIds[]#</iterate>
|
||||
</isNotNull>
|
||||
<isNotNull property="excludeTypeIds" prepend="and">
|
||||
node.type_qname_id not in <iterate property="excludeTypeIds" open="(" close=")" conjunction=", ">#excludeTypeIds[]#</iterate>
|
||||
</isNotNull>
|
||||
<isNotNull property="includeAspectIds" prepend="and">
|
||||
exists (
|
||||
select *
|
||||
from alf_node_aspects aspects
|
||||
where
|
||||
aspects.node_id = node.id
|
||||
and aspects.qname_id in <iterate property="includeAspectIds" open="(" close=")" conjunction=", ">#includeAspectIds[]#</iterate>
|
||||
)
|
||||
</isNotNull>
|
||||
<isNotNull property="excludeAspectIds" prepend="and">
|
||||
not exists (
|
||||
select *
|
||||
from alf_node_aspects aspects
|
||||
where
|
||||
aspects.node_id = node.id
|
||||
and aspects.qname_id in <iterate property="excludeAspectIds" open="(" close=")" conjunction=", ">#excludeAspectIds[]#</iterate>
|
||||
)
|
||||
</isNotNull>
|
||||
</dynamic>
|
||||
order by node.id ASC
|
||||
</select>
|
||||
</sqlMap>
|
@@ -4,10 +4,10 @@
|
||||
|
||||
# Version label
|
||||
|
||||
version.major=3
|
||||
version.minor=5
|
||||
version.major=4
|
||||
version.minor=0
|
||||
version.revision=0
|
||||
version.label=a
|
||||
version.label=
|
||||
|
||||
# Edition label
|
||||
|
||||
@@ -19,4 +19,4 @@ version.build=@build-number@
|
||||
|
||||
# Schema number
|
||||
|
||||
version.schema=4306
|
||||
version.schema=5000
|
||||
|
167
source/java/org/alfresco/repo/domain/solr/NodeParameters.java
Normal file
167
source/java/org/alfresco/repo/domain/solr/NodeParameters.java
Normal file
@@ -0,0 +1,167 @@
|
||||
package org.alfresco.repo.domain.solr;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import org.alfresco.service.namespace.QName;
|
||||
|
||||
/**
|
||||
* Stores node parameters for use in SOLR DAO queries
|
||||
*
|
||||
* @since 4.0
|
||||
*/
|
||||
public class NodeParameters
|
||||
{
|
||||
private List<Long> transactionIds;
|
||||
private Long fromNodeId;
|
||||
private Long toNodeId;
|
||||
|
||||
private String storeProtocol;
|
||||
private String storeIdentifier;
|
||||
|
||||
private Set<QName> includeNodeTypes;
|
||||
private Set<QName> excludeNodeTypes;
|
||||
private List<Long> includeTypeIds;
|
||||
private List<Long> excludeTypeIds;
|
||||
|
||||
private Set<QName> includeAspects;
|
||||
private Set<QName> excludeAspects;
|
||||
private List<Long> includeAspectIds;
|
||||
private List<Long> excludeAspectIds;
|
||||
|
||||
public boolean getStoreFilter()
|
||||
{
|
||||
return (storeProtocol != null || storeIdentifier != null);
|
||||
}
|
||||
|
||||
public void setStoreProtocol(String storeProtocol)
|
||||
{
|
||||
this.storeProtocol = storeProtocol;
|
||||
}
|
||||
|
||||
public String getStoreProtocol()
|
||||
{
|
||||
return storeProtocol;
|
||||
}
|
||||
|
||||
public void setStoreIdentifier(String storeIdentifier)
|
||||
{
|
||||
this.storeIdentifier = storeIdentifier;
|
||||
}
|
||||
|
||||
public String getStoreIdentifier()
|
||||
{
|
||||
return storeIdentifier;
|
||||
}
|
||||
|
||||
public void setTransactionIds(List<Long> txnIds)
|
||||
{
|
||||
this.transactionIds = txnIds;
|
||||
}
|
||||
|
||||
public List<Long> getTransactionIds()
|
||||
{
|
||||
return transactionIds;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
public Set<QName> getIncludeNodeTypes()
|
||||
{
|
||||
return includeNodeTypes;
|
||||
}
|
||||
|
||||
public Set<QName> getExcludeNodeTypes()
|
||||
{
|
||||
return excludeNodeTypes;
|
||||
}
|
||||
|
||||
public Set<QName> getIncludeAspects()
|
||||
{
|
||||
return includeAspects;
|
||||
}
|
||||
|
||||
public Set<QName> getExcludeAspects()
|
||||
{
|
||||
return excludeAspects;
|
||||
}
|
||||
|
||||
public void setIncludeNodeTypes(Set<QName> includeNodeTypes)
|
||||
{
|
||||
this.includeNodeTypes = includeNodeTypes;
|
||||
}
|
||||
|
||||
public void setExcludeNodeTypes(Set<QName> excludeNodeTypes)
|
||||
{
|
||||
this.excludeNodeTypes = excludeNodeTypes;
|
||||
}
|
||||
|
||||
public void setIncludeAspects(Set<QName> includeAspects)
|
||||
{
|
||||
this.includeAspects = includeAspects;
|
||||
}
|
||||
|
||||
public void setExcludeAspects(Set<QName> excludeAspects)
|
||||
{
|
||||
this.excludeAspects = excludeAspects;
|
||||
}
|
||||
|
||||
public List<Long> getIncludeAspectIds()
|
||||
{
|
||||
return includeAspectIds;
|
||||
}
|
||||
|
||||
public void setIncludeAspectIds(List<Long> includeAspectIds)
|
||||
{
|
||||
this.includeAspectIds = includeAspectIds;
|
||||
}
|
||||
|
||||
public List<Long> getExcludeAspectIds()
|
||||
{
|
||||
return excludeAspectIds;
|
||||
}
|
||||
|
||||
public void setExcludeAspectIds(List<Long> excludeAspectIds)
|
||||
{
|
||||
this.excludeAspectIds = excludeAspectIds;
|
||||
}
|
||||
|
||||
public List<Long> getIncludeTypeIds()
|
||||
{
|
||||
return includeTypeIds;
|
||||
}
|
||||
|
||||
public void setIncludeTypeIds(List<Long> includeTypeIds)
|
||||
{
|
||||
this.includeTypeIds = includeTypeIds;
|
||||
}
|
||||
|
||||
public List<Long> getExcludeTypeIds()
|
||||
{
|
||||
return excludeTypeIds;
|
||||
}
|
||||
|
||||
public void setExcludeTypeIds(List<Long> excludeTypeIds)
|
||||
{
|
||||
this.excludeTypeIds = excludeTypeIds;
|
||||
}
|
||||
|
||||
}
|
31
source/java/org/alfresco/repo/domain/solr/SOLRDAO.java
Normal file
31
source/java/org/alfresco/repo/domain/solr/SOLRDAO.java
Normal file
@@ -0,0 +1,31 @@
|
||||
package org.alfresco.repo.domain.solr;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.alfresco.repo.domain.node.Node;
|
||||
|
||||
/**
|
||||
* DAO support for SOLR web scripts.
|
||||
*
|
||||
* @since 4.0
|
||||
*/
|
||||
// TODO - permit shortened form of QNames for e.g. aspects i.e. cm:content vs {http://www.alfresco.org/model/content/1.0}content?
|
||||
public interface SOLRDAO
|
||||
{
|
||||
public List<Transaction> getTransactions(Long minTxnId, Long fromCommitTime, int maxResults);
|
||||
public void getNodes(NodeParameters nodeParameters, int maxResults, NodeQueryCallback callback);
|
||||
|
||||
/**
|
||||
* The interface that will be used to give query results to the calling code.
|
||||
*/
|
||||
public static interface NodeQueryCallback
|
||||
{
|
||||
/**
|
||||
* Handle a node.
|
||||
*
|
||||
* @param node the node
|
||||
* @return Return <tt>true</tt> to continue processing rows or <tt>false</tt> to stop
|
||||
*/
|
||||
boolean handleNode(Node node);
|
||||
}
|
||||
}
|
250
source/java/org/alfresco/repo/domain/solr/SOLRDAOTest.java
Normal file
250
source/java/org/alfresco/repo/domain/solr/SOLRDAOTest.java
Normal file
@@ -0,0 +1,250 @@
|
||||
package org.alfresco.repo.domain.solr;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
|
||||
import org.alfresco.model.ContentModel;
|
||||
import org.alfresco.repo.domain.node.Node;
|
||||
import org.alfresco.repo.domain.solr.SOLRDAO.NodeQueryCallback;
|
||||
import org.alfresco.repo.security.authentication.AuthenticationComponent;
|
||||
import org.alfresco.repo.transaction.RetryingTransactionHelper;
|
||||
import org.alfresco.repo.transaction.RetryingTransactionHelper.RetryingTransactionCallback;
|
||||
import org.alfresco.service.ServiceRegistry;
|
||||
import org.alfresco.service.cmr.model.FileFolderService;
|
||||
import org.alfresco.service.cmr.model.FileInfo;
|
||||
import org.alfresco.service.cmr.repository.NodeRef;
|
||||
import org.alfresco.service.cmr.repository.NodeService;
|
||||
import org.alfresco.service.cmr.repository.StoreRef;
|
||||
import org.alfresco.service.transaction.TransactionService;
|
||||
import org.alfresco.util.ApplicationContextHelper;
|
||||
import org.alfresco.util.PropertyMap;
|
||||
import org.springframework.context.ConfigurableApplicationContext;
|
||||
|
||||
public class SOLRDAOTest extends TestCase
|
||||
{
|
||||
private ConfigurableApplicationContext ctx = (ConfigurableApplicationContext) ApplicationContextHelper.getApplicationContext();
|
||||
|
||||
private AuthenticationComponent authenticationComponent;
|
||||
private TransactionService transactionService;
|
||||
private RetryingTransactionHelper txnHelper;
|
||||
private NodeService nodeService;
|
||||
private FileFolderService fileFolderService;
|
||||
private SOLRDAO solrDAO;
|
||||
|
||||
private StoreRef storeRef;
|
||||
private NodeRef rootNodeRef;
|
||||
private NodeRef container1;
|
||||
private NodeRef content1;
|
||||
private NodeRef content2;
|
||||
|
||||
@Override
|
||||
public void setUp() throws Exception
|
||||
{
|
||||
ServiceRegistry serviceRegistry = (ServiceRegistry) ctx.getBean(ServiceRegistry.SERVICE_REGISTRY);
|
||||
transactionService = serviceRegistry.getTransactionService();
|
||||
txnHelper = transactionService.getRetryingTransactionHelper();
|
||||
|
||||
solrDAO = (SOLRDAO)ctx.getBean("solrDAO");
|
||||
nodeService = (NodeService)ctx.getBean("NodeService");
|
||||
fileFolderService = (FileFolderService)ctx.getBean("FileFolderService");
|
||||
authenticationComponent = (AuthenticationComponent)ctx.getBean("authenticationComponent");
|
||||
|
||||
authenticationComponent.setSystemUserAsCurrentUser();
|
||||
|
||||
storeRef = nodeService.createStore(StoreRef.PROTOCOL_WORKSPACE, getName() + System.currentTimeMillis());
|
||||
rootNodeRef = nodeService.getRootNode(storeRef);
|
||||
}
|
||||
|
||||
private void buildTransactions1()
|
||||
{
|
||||
txnHelper.doInTransaction(new RetryingTransactionCallback<Void>()
|
||||
{
|
||||
public Void execute() throws Throwable
|
||||
{
|
||||
PropertyMap props = new PropertyMap();
|
||||
props.put(ContentModel.PROP_NAME, "Container1");
|
||||
container1 = nodeService.createNode(
|
||||
rootNodeRef,
|
||||
ContentModel.ASSOC_CHILDREN,
|
||||
ContentModel.ASSOC_CHILDREN,
|
||||
ContentModel.TYPE_FOLDER,
|
||||
props).getChildRef();
|
||||
|
||||
System.out.println("container1 = " + container1);
|
||||
|
||||
FileInfo content1Info = fileFolderService.create(container1, "Content1", ContentModel.TYPE_CONTENT);
|
||||
content1 = content1Info.getNodeRef();
|
||||
|
||||
System.out.println("content1 = " + content1);
|
||||
|
||||
return null;
|
||||
}
|
||||
});
|
||||
|
||||
txnHelper.doInTransaction(new RetryingTransactionCallback<Void>()
|
||||
{
|
||||
public Void execute() throws Throwable
|
||||
{
|
||||
FileInfo content2Info = fileFolderService.create(container1, "Content2", ContentModel.TYPE_CONTENT);
|
||||
content2 = content2Info.getNodeRef();
|
||||
|
||||
System.out.println("content2 = " + content2);
|
||||
|
||||
fileFolderService.delete(content1);
|
||||
|
||||
return null;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void buildTransactions2()
|
||||
{
|
||||
txnHelper.doInTransaction(new RetryingTransactionCallback<Void>()
|
||||
{
|
||||
public Void execute() throws Throwable
|
||||
{
|
||||
PropertyMap props = new PropertyMap();
|
||||
props.put(ContentModel.PROP_NAME, "Container1");
|
||||
container1 = nodeService.createNode(
|
||||
rootNodeRef,
|
||||
ContentModel.ASSOC_CHILDREN,
|
||||
ContentModel.ASSOC_CHILDREN,
|
||||
ContentModel.TYPE_FOLDER,
|
||||
props).getChildRef();
|
||||
|
||||
System.out.println("container1 = " + container1);
|
||||
|
||||
FileInfo content1Info = fileFolderService.create(container1, "Content1", ContentModel.TYPE_CONTENT);
|
||||
content1 = content1Info.getNodeRef();
|
||||
|
||||
System.out.println("content1 = " + content1);
|
||||
|
||||
return null;
|
||||
}
|
||||
});
|
||||
|
||||
txnHelper.doInTransaction(new RetryingTransactionCallback<Void>()
|
||||
{
|
||||
public Void execute() throws Throwable
|
||||
{
|
||||
FileInfo content2Info = fileFolderService.create(container1, "Content2", ContentModel.TYPE_CONTENT);
|
||||
content2 = content2Info.getNodeRef();
|
||||
|
||||
System.out.println("content2 = " + content2);
|
||||
|
||||
fileFolderService.delete(content1);
|
||||
|
||||
return null;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public void testQueryTransactions1()
|
||||
{
|
||||
long startTime = System.currentTimeMillis();
|
||||
|
||||
buildTransactions1();
|
||||
|
||||
List<Transaction> txns = solrDAO.getTransactions(null, startTime, 0);
|
||||
assertEquals("Number of transactions is incorrect", 2, txns.size());
|
||||
|
||||
int[] updates = new int[] {1, 1};
|
||||
int[] deletes = new int[] {0, 1};
|
||||
List<Long> txnIds = new ArrayList<Long>(txns.size());
|
||||
int i = 0;
|
||||
for(Transaction txn : txns)
|
||||
{
|
||||
assertEquals("Number of deletes is incorrect", deletes[i], txn.getDeletes());
|
||||
assertEquals("Number of updates is incorrect", updates[i], txn.getUpdates());
|
||||
i++;
|
||||
|
||||
txnIds.add(txn.getId());
|
||||
}
|
||||
|
||||
TestNodeQueryCallback nodeQueryCallback = new TestNodeQueryCallback(container1, content1, content2);
|
||||
NodeParameters nodeParameters = new NodeParameters();
|
||||
nodeParameters.setTransactionIds(txnIds);
|
||||
solrDAO.getNodes(nodeParameters, 0, nodeQueryCallback);
|
||||
|
||||
assertEquals("Unxpected nodes", 3, nodeQueryCallback.getSuccessCount());
|
||||
}
|
||||
|
||||
public void testQueryTransactions2()
|
||||
{
|
||||
long startTime = System.currentTimeMillis();
|
||||
|
||||
buildTransactions2();
|
||||
|
||||
List<Transaction> txns = solrDAO.getTransactions(null, startTime, 0);
|
||||
assertEquals("Number of transactions is incorrect", 2, txns.size());
|
||||
|
||||
int[] updates = new int[] {1, 1};
|
||||
int[] deletes = new int[] {0, 1};
|
||||
List<Long> txnIds = new ArrayList<Long>(txns.size());
|
||||
int i = 0;
|
||||
for(Transaction txn : txns)
|
||||
{
|
||||
assertEquals("Number of deletes is incorrect", deletes[i], txn.getDeletes());
|
||||
assertEquals("Number of updates is incorrect", updates[i], txn.getUpdates());
|
||||
i++;
|
||||
|
||||
txnIds.add(txn.getId());
|
||||
}
|
||||
|
||||
TestNodeQueryCallback nodeQueryCallback = new TestNodeQueryCallback(container1, content1, content2);
|
||||
NodeParameters nodeParameters = new NodeParameters();
|
||||
nodeParameters.setTransactionIds(txnIds);
|
||||
solrDAO.getNodes(nodeParameters, 0, nodeQueryCallback);
|
||||
|
||||
assertEquals("Unxpected nodes", 3, nodeQueryCallback.getSuccessCount());
|
||||
}
|
||||
|
||||
|
||||
private static class TestNodeQueryCallback implements NodeQueryCallback
|
||||
{
|
||||
private int successCount = 0;
|
||||
private NodeRef container1;
|
||||
private NodeRef content1;
|
||||
private NodeRef content2;
|
||||
|
||||
public TestNodeQueryCallback(NodeRef container1,
|
||||
NodeRef content1, NodeRef content2) {
|
||||
super();
|
||||
this.container1 = container1;
|
||||
this.content1 = content1;
|
||||
this.content2 = content2;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean handleNode(Node node) {
|
||||
NodeRef nodeRef = node.getNodeRef();
|
||||
Boolean isDeleted = node.getDeleted();
|
||||
|
||||
System.out.println("Node: " + node.toString());
|
||||
|
||||
if(nodeRef.equals(container1) && !isDeleted)
|
||||
{
|
||||
successCount++;
|
||||
}
|
||||
|
||||
if(nodeRef.equals(content1) && isDeleted)
|
||||
{
|
||||
successCount++;
|
||||
}
|
||||
|
||||
if(nodeRef.equals(content2) && !isDeleted)
|
||||
{
|
||||
successCount++;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public int getSuccessCount()
|
||||
{
|
||||
return successCount;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@@ -0,0 +1,14 @@
|
||||
package org.alfresco.repo.domain.solr;
|
||||
|
||||
/**
|
||||
* Interface for SOLR transaction objects.
|
||||
*
|
||||
* @since 4.0
|
||||
*/
|
||||
public interface SOLRTransaction
|
||||
{
|
||||
public Long getId();
|
||||
public Long getCommitTimeMs();
|
||||
public int getUpdates();
|
||||
public int getDeletes();
|
||||
}
|
@@ -0,0 +1,76 @@
|
||||
package org.alfresco.repo.domain.solr;
|
||||
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Holds parameters for SOLR DAO calls
|
||||
*
|
||||
* @since 4.0
|
||||
*/
|
||||
public class SOLRTransactionParameters {
|
||||
private Long minTxnId;
|
||||
private Long txnFromCommitTime;
|
||||
private List<Long> transactionIds;
|
||||
private Long fromNodeId;
|
||||
private Long toNodeId;
|
||||
|
||||
public SOLRTransactionParameters()
|
||||
{
|
||||
}
|
||||
|
||||
public void setMinTxnId(Long minTxnId)
|
||||
{
|
||||
this.minTxnId = minTxnId;
|
||||
}
|
||||
|
||||
public Long getMinTxnId()
|
||||
{
|
||||
return minTxnId;
|
||||
}
|
||||
|
||||
public void setTxnFromCommitTime(Long txnFromCommitTime) {
|
||||
this.txnFromCommitTime = txnFromCommitTime;
|
||||
}
|
||||
|
||||
public Long getTxnFromCommitTime() {
|
||||
return txnFromCommitTime;
|
||||
}
|
||||
|
||||
public void setTransactionIds(List<Long> txnIds) {
|
||||
this.transactionIds = txnIds;
|
||||
}
|
||||
|
||||
public List<Long> getTransactionIds() {
|
||||
return transactionIds;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString()
|
||||
{
|
||||
StringBuilder sb = new StringBuilder(512);
|
||||
sb.append("SOLRTransactionParameters")
|
||||
.append(", txnFromCommitTime").append(txnFromCommitTime == null ? null : new Date(txnFromCommitTime))
|
||||
.append(", fromNodeId").append(fromNodeId == null ? null : fromNodeId)
|
||||
.append(", toNodeId").append(toNodeId == null ? null : toNodeId)
|
||||
.append(", txnIds").append(transactionIds == null ? null : transactionIds.size())
|
||||
.append("]");
|
||||
return sb.toString();
|
||||
}
|
||||
}
|
14
source/java/org/alfresco/repo/domain/solr/Transaction.java
Normal file
14
source/java/org/alfresco/repo/domain/solr/Transaction.java
Normal file
@@ -0,0 +1,14 @@
|
||||
package org.alfresco.repo.domain.solr;
|
||||
|
||||
/**
|
||||
* Interface for SOLR transaction objects.
|
||||
*
|
||||
* @since 4.0
|
||||
*/
|
||||
public interface Transaction
|
||||
{
|
||||
public Long getId();
|
||||
public Long getCommitTimeMs();
|
||||
public int getUpdates();
|
||||
public int getDeletes();
|
||||
}
|
@@ -0,0 +1,75 @@
|
||||
package org.alfresco.repo.domain.solr;
|
||||
|
||||
/**
|
||||
* Bean to represent SOLR transaction data.
|
||||
*
|
||||
* @since 4.0
|
||||
*/
|
||||
public class TransactionEntity implements Transaction
|
||||
{
|
||||
private Long id;
|
||||
private Long commitTimeMs;
|
||||
private int updates;
|
||||
private int deletes;
|
||||
|
||||
/**
|
||||
* Required default constructor
|
||||
*/
|
||||
public TransactionEntity()
|
||||
{
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString()
|
||||
{
|
||||
StringBuilder sb = new StringBuilder(512);
|
||||
sb.append("TransactionEntity")
|
||||
.append("[ ID=").append(id)
|
||||
.append(", updates=").append(updates)
|
||||
.append(", deletes=").append(deletes)
|
||||
.append(", commitTimeMs=").append(commitTimeMs)
|
||||
.append("]");
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
public Long getId()
|
||||
{
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(Long id)
|
||||
{
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public int getUpdates()
|
||||
{
|
||||
return updates;
|
||||
}
|
||||
|
||||
public void setUpdates(int updates)
|
||||
{
|
||||
this.updates = updates;
|
||||
}
|
||||
|
||||
public int getDeletes()
|
||||
{
|
||||
return deletes;
|
||||
}
|
||||
|
||||
public void setDeletes(int deletes)
|
||||
{
|
||||
this.deletes = deletes;
|
||||
}
|
||||
|
||||
public Long getCommitTimeMs()
|
||||
{
|
||||
return commitTimeMs;
|
||||
}
|
||||
|
||||
public void setCommitTimeMs(Long commitTimeMs)
|
||||
{
|
||||
this.commitTimeMs = commitTimeMs;
|
||||
}
|
||||
}
|
||||
|
@@ -0,0 +1,147 @@
|
||||
package org.alfresco.repo.domain.solr.ibatis;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import org.alfresco.repo.domain.node.Node;
|
||||
import org.alfresco.repo.domain.node.NodeEntity;
|
||||
import org.alfresco.repo.domain.qname.QNameDAO;
|
||||
import org.alfresco.repo.domain.solr.NodeParameters;
|
||||
import org.alfresco.repo.domain.solr.SOLRDAO;
|
||||
import org.alfresco.repo.domain.solr.SOLRTransactionParameters;
|
||||
import org.alfresco.repo.domain.solr.Transaction;
|
||||
import org.springframework.orm.ibatis.SqlMapClientTemplate;
|
||||
|
||||
/**
|
||||
* DAO support for SOLR web scripts.
|
||||
*
|
||||
* @since 4.0
|
||||
*/
|
||||
public class SOLRDAOImpl implements SOLRDAO
|
||||
{
|
||||
private static final String SELECT_TRANSACTIONS = "alfresco.solr.select_Txns";
|
||||
private static final String SELECT_NODES = "alfresco.solr.select_Txn_Nodes";
|
||||
|
||||
private QNameDAO qnameDAO;
|
||||
private SqlMapClientTemplate template;
|
||||
|
||||
public void setSqlMapClientTemplate(SqlMapClientTemplate sqlMapClientTemplate)
|
||||
{
|
||||
this.template = sqlMapClientTemplate;
|
||||
}
|
||||
|
||||
public SqlMapClientTemplate getSqlMapClientTemplate()
|
||||
{
|
||||
return this.template;
|
||||
}
|
||||
|
||||
public void setQNameDAO(QNameDAO qnameDAO)
|
||||
{
|
||||
this.qnameDAO = qnameDAO;
|
||||
}
|
||||
|
||||
/*
|
||||
* Initialize
|
||||
*/
|
||||
public void init()
|
||||
{
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public List<Transaction> getTransactions(Long minTxnId, Long fromCommitTime, int maxResults)
|
||||
{
|
||||
if(minTxnId == null && fromCommitTime == null && (maxResults == 0 || maxResults == Integer.MAX_VALUE))
|
||||
{
|
||||
throw new IllegalArgumentException("Must specify at least one parameter");
|
||||
}
|
||||
|
||||
List<Transaction> txns = null;
|
||||
SOLRTransactionParameters params = new SOLRTransactionParameters();
|
||||
params.setMinTxnId(minTxnId);
|
||||
params.setTxnFromCommitTime(fromCommitTime);
|
||||
|
||||
if(maxResults != 0 && maxResults != Integer.MAX_VALUE)
|
||||
{
|
||||
txns = (List<Transaction>)template.queryForList(SELECT_TRANSACTIONS, params, 0, maxResults);
|
||||
}
|
||||
else
|
||||
{
|
||||
txns = (List<Transaction>)template.queryForList(SELECT_TRANSACTIONS, params);
|
||||
}
|
||||
|
||||
return txns;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
// TODO should create qnames if don't exist?
|
||||
public void getNodes(NodeParameters nodeParameters, int maxResults, NodeQueryCallback callback)
|
||||
{
|
||||
List<NodeEntity> nodes = null;
|
||||
NodeQueryRowHandler rowHandler = new NodeQueryRowHandler(callback);
|
||||
|
||||
if(nodeParameters.getIncludeTypeIds() == null && nodeParameters.getIncludeNodeTypes() != null)
|
||||
{
|
||||
Set<Long> qnamesIds = qnameDAO.convertQNamesToIds(nodeParameters.getIncludeNodeTypes(), false);
|
||||
nodeParameters.setIncludeTypeIds(new ArrayList<Long>(qnamesIds));
|
||||
}
|
||||
|
||||
if(nodeParameters.getExcludeTypeIds() == null && nodeParameters.getExcludeNodeTypes() != null)
|
||||
{
|
||||
Set<Long> qnamesIds = qnameDAO.convertQNamesToIds(nodeParameters.getExcludeNodeTypes(), false);
|
||||
nodeParameters.setExcludeTypeIds(new ArrayList<Long>(qnamesIds));
|
||||
}
|
||||
|
||||
if(nodeParameters.getExcludeAspectIds() == null && nodeParameters.getExcludeAspects() != null)
|
||||
{
|
||||
Set<Long> qnamesIds = qnameDAO.convertQNamesToIds(nodeParameters.getExcludeAspects(), false);
|
||||
nodeParameters.setExcludeAspectIds(new ArrayList<Long>(qnamesIds));
|
||||
}
|
||||
|
||||
if(nodeParameters.getIncludeAspectIds() == null && nodeParameters.getIncludeAspects() != null)
|
||||
{
|
||||
Set<Long> qnamesIds = qnameDAO.convertQNamesToIds(nodeParameters.getIncludeAspects(), false);
|
||||
nodeParameters.setIncludeAspectIds(new ArrayList<Long>(qnamesIds));
|
||||
}
|
||||
|
||||
if(maxResults != 0 && maxResults != Integer.MAX_VALUE)
|
||||
{
|
||||
nodes = (List<NodeEntity>)template.queryForList(SELECT_NODES, nodeParameters, 0, maxResults);
|
||||
}
|
||||
else
|
||||
{
|
||||
nodes = (List<NodeEntity>)template.queryForList(SELECT_NODES, nodeParameters);
|
||||
}
|
||||
|
||||
for(NodeEntity node : nodes)
|
||||
{
|
||||
rowHandler.processResult(node);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Class that passes results from a result entity into the client callback
|
||||
*/
|
||||
protected class NodeQueryRowHandler
|
||||
{
|
||||
private final NodeQueryCallback callback;
|
||||
private boolean more;
|
||||
|
||||
private NodeQueryRowHandler(NodeQueryCallback callback)
|
||||
{
|
||||
this.callback = callback;
|
||||
this.more = true;
|
||||
}
|
||||
|
||||
public void processResult(Node row)
|
||||
{
|
||||
if (!more)
|
||||
{
|
||||
// No more results required
|
||||
return;
|
||||
}
|
||||
|
||||
more = callback.handleNode(row);
|
||||
}
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user