mirror of
https://github.com/Alfresco/alfresco-community-repo.git
synced 2025-07-24 17:32:48 +00:00
SEARCH-2782 use current transaction timestamp instead of current time as event time (#371)
This commit is contained in:
@@ -27,12 +27,16 @@ package org.alfresco.repo.event2;
|
|||||||
|
|
||||||
import java.io.Serializable;
|
import java.io.Serializable;
|
||||||
import java.net.URI;
|
import java.net.URI;
|
||||||
|
import java.time.Instant;
|
||||||
|
import java.time.ZoneOffset;
|
||||||
import java.time.ZonedDateTime;
|
import java.time.ZonedDateTime;
|
||||||
import java.util.Deque;
|
import java.util.Deque;
|
||||||
import java.util.LinkedHashMap;
|
import java.util.LinkedHashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
|
||||||
|
import org.alfresco.repo.domain.node.NodeDAO;
|
||||||
|
import org.alfresco.repo.domain.node.Transaction;
|
||||||
import org.alfresco.repo.event.v1.model.EventType;
|
import org.alfresco.repo.event.v1.model.EventType;
|
||||||
import org.alfresco.repo.event.v1.model.RepoEvent;
|
import org.alfresco.repo.event.v1.model.RepoEvent;
|
||||||
import org.alfresco.repo.event2.filter.ChildAssociationTypeFilter;
|
import org.alfresco.repo.event2.filter.ChildAssociationTypeFilter;
|
||||||
@@ -94,6 +98,7 @@ public class EventGenerator extends AbstractLifecycleBean implements Initializin
|
|||||||
private TransactionService transactionService;
|
private TransactionService transactionService;
|
||||||
private PersonService personService;
|
private PersonService personService;
|
||||||
protected NodeResourceHelper nodeResourceHelper;
|
protected NodeResourceHelper nodeResourceHelper;
|
||||||
|
private NodeDAO nodeDAO;
|
||||||
|
|
||||||
private NodeTypeFilter nodeTypeFilter;
|
private NodeTypeFilter nodeTypeFilter;
|
||||||
private ChildAssociationTypeFilter childAssociationTypeFilter;
|
private ChildAssociationTypeFilter childAssociationTypeFilter;
|
||||||
@@ -113,6 +118,7 @@ public class EventGenerator extends AbstractLifecycleBean implements Initializin
|
|||||||
PropertyCheck.mandatory(this, "transactionService", transactionService);
|
PropertyCheck.mandatory(this, "transactionService", transactionService);
|
||||||
PropertyCheck.mandatory(this, "personService", personService);
|
PropertyCheck.mandatory(this, "personService", personService);
|
||||||
PropertyCheck.mandatory(this, "nodeResourceHelper", nodeResourceHelper);
|
PropertyCheck.mandatory(this, "nodeResourceHelper", nodeResourceHelper);
|
||||||
|
PropertyCheck.mandatory(this, "nodeDAO", nodeDAO);
|
||||||
|
|
||||||
this.nodeTypeFilter = eventFilterRegistry.getNodeTypeFilter();
|
this.nodeTypeFilter = eventFilterRegistry.getNodeTypeFilter();
|
||||||
this.childAssociationTypeFilter = eventFilterRegistry.getChildAssociationTypeFilter();
|
this.childAssociationTypeFilter = eventFilterRegistry.getChildAssociationTypeFilter();
|
||||||
@@ -145,6 +151,11 @@ public class EventGenerator extends AbstractLifecycleBean implements Initializin
|
|||||||
new JavaBehaviour(this, "beforeDeleteAssociation"));
|
new JavaBehaviour(this, "beforeDeleteAssociation"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setNodeDAO(NodeDAO nodeDAO)
|
||||||
|
{
|
||||||
|
this.nodeDAO = nodeDAO;
|
||||||
|
}
|
||||||
|
|
||||||
public void setPolicyComponent(PolicyComponent policyComponent)
|
public void setPolicyComponent(PolicyComponent policyComponent)
|
||||||
{
|
{
|
||||||
this.policyComponent = policyComponent;
|
this.policyComponent = policyComponent;
|
||||||
@@ -370,13 +381,22 @@ public class EventGenerator extends AbstractLifecycleBean implements Initializin
|
|||||||
|
|
||||||
private EventInfo getEventInfo(String user)
|
private EventInfo getEventInfo(String user)
|
||||||
{
|
{
|
||||||
return new EventInfo().setTimestamp(ZonedDateTime.now())
|
return new EventInfo().setTimestamp(getCurrentTransactionTimestamp())
|
||||||
.setId(UUID.randomUUID().toString())
|
.setId(UUID.randomUUID().toString())
|
||||||
.setTxnId(AlfrescoTransactionSupport.getTransactionId())
|
.setTxnId(AlfrescoTransactionSupport.getTransactionId())
|
||||||
.setPrincipal(user)
|
.setPrincipal(user)
|
||||||
.setSource(URI.create("/" + descriptorService.getCurrentRepositoryDescriptor().getId()));
|
.setSource(URI.create("/" + descriptorService.getCurrentRepositoryDescriptor().getId()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private ZonedDateTime getCurrentTransactionTimestamp()
|
||||||
|
{
|
||||||
|
Long currentTransactionId = nodeDAO.getCurrentTransactionId(false);
|
||||||
|
Transaction transaction = nodeDAO.getTxnById(currentTransactionId);
|
||||||
|
Instant commitTimeMs = Instant.ofEpochMilli(transaction.getCommitTimeMs());
|
||||||
|
ZonedDateTime timestamp = ZonedDateTime.ofInstant(commitTimeMs, ZoneOffset.UTC);
|
||||||
|
return timestamp;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onBootstrap(ApplicationEvent applicationEvent)
|
protected void onBootstrap(ApplicationEvent applicationEvent)
|
||||||
{
|
{
|
||||||
|
@@ -41,6 +41,7 @@
|
|||||||
<property name="event2MessageProducer" ref="event2MessageProducer"/>
|
<property name="event2MessageProducer" ref="event2MessageProducer"/>
|
||||||
<property name="transactionService" ref="transactionService"/>
|
<property name="transactionService" ref="transactionService"/>
|
||||||
<property name="personService" ref="personService"/>
|
<property name="personService" ref="personService"/>
|
||||||
|
<property name="nodeDAO" ref="nodeDAO"/>
|
||||||
</bean>
|
</bean>
|
||||||
|
|
||||||
<bean id="baseNodeResourceHelper" abstract="true">
|
<bean id="baseNodeResourceHelper" abstract="true">
|
||||||
|
@@ -26,9 +26,14 @@
|
|||||||
|
|
||||||
package org.alfresco.repo.event2;
|
package org.alfresco.repo.event2;
|
||||||
|
|
||||||
|
import java.time.Instant;
|
||||||
|
import java.time.ZoneOffset;
|
||||||
|
import java.time.ZonedDateTime;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import org.alfresco.model.ContentModel;
|
import org.alfresco.model.ContentModel;
|
||||||
|
import org.alfresco.repo.domain.node.NodeDAO;
|
||||||
|
import org.alfresco.repo.domain.node.Transaction;
|
||||||
import org.alfresco.repo.event.v1.model.EventData;
|
import org.alfresco.repo.event.v1.model.EventData;
|
||||||
import org.alfresco.repo.event.v1.model.EventType;
|
import org.alfresco.repo.event.v1.model.EventType;
|
||||||
import org.alfresco.repo.event.v1.model.NodeResource;
|
import org.alfresco.repo.event.v1.model.NodeResource;
|
||||||
@@ -38,6 +43,7 @@ import org.alfresco.service.namespace.QName;
|
|||||||
import org.alfresco.util.GUID;
|
import org.alfresco.util.GUID;
|
||||||
import org.alfresco.util.PropertyMap;
|
import org.alfresco.util.PropertyMap;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Iulian Aftene
|
* @author Iulian Aftene
|
||||||
@@ -45,6 +51,9 @@ import org.junit.Test;
|
|||||||
public class CreateRepoEventIT extends AbstractContextAwareRepoEvent
|
public class CreateRepoEventIT extends AbstractContextAwareRepoEvent
|
||||||
{
|
{
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private NodeDAO nodeDAO;
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testCreateEvent()
|
public void testCreateEvent()
|
||||||
{
|
{
|
||||||
@@ -149,9 +158,32 @@ public class CreateRepoEventIT extends AbstractContextAwareRepoEvent
|
|||||||
assertTrue("isFile flag should be TRUE for nodeType=cm:content. ", resource.isFile());
|
assertTrue("isFile flag should be TRUE for nodeType=cm:content. ", resource.isFile());
|
||||||
assertFalse("isFolder flag should be FALSE for nodeType=cm:content. ", resource.isFolder());
|
assertFalse("isFolder flag should be FALSE for nodeType=cm:content. ", resource.isFolder());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testEventTimestampEqualsToTransactionCommitTime()
|
||||||
|
{
|
||||||
|
String name = "TestFile-" + System.currentTimeMillis() + ".txt";
|
||||||
|
PropertyMap propertyMap = new PropertyMap();
|
||||||
|
propertyMap.put(ContentModel.PROP_NAME, name);
|
||||||
|
|
||||||
|
//create a node and return the transaction id required later
|
||||||
|
Long transactionId = retryingTransactionHelper.doInTransaction(() -> {
|
||||||
|
nodeService.createNode(rootNodeRef, ContentModel.ASSOC_CHILDREN,
|
||||||
|
QName.createQName(TEST_NAMESPACE, GUID.generate()), ContentModel.TYPE_CONTENT, propertyMap).getChildRef();
|
||||||
|
return nodeDAO.getCurrentTransactionId(false);
|
||||||
|
});
|
||||||
|
|
||||||
|
RepoEvent<EventData<NodeResource>> resultRepoEvent = getRepoEvent(1);
|
||||||
|
|
||||||
|
Transaction transaction = nodeDAO.getTxnById(transactionId);
|
||||||
|
Instant commitTimeMs = Instant.ofEpochMilli(transaction.getCommitTimeMs());
|
||||||
|
ZonedDateTime timestamp = ZonedDateTime.ofInstant(commitTimeMs, ZoneOffset.UTC);
|
||||||
|
|
||||||
|
assertEquals(timestamp, resultRepoEvent.getTime());
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testCteateMultipleNodesInTheSameTransaction()
|
public void testCreateMultipleNodesInTheSameTransaction()
|
||||||
{
|
{
|
||||||
retryingTransactionHelper.doInTransaction(() -> {
|
retryingTransactionHelper.doInTransaction(() -> {
|
||||||
for (int i = 0; i < 3; i++)
|
for (int i = 0; i < 3; i++)
|
||||||
|
Reference in New Issue
Block a user