Commit 1164cb86 authored by Matija Obreza's avatar Matija Obreza
Browse files

AccessionTriggers: using aggregated AuditLogs to record Accession changes

parent a7307d6f
......@@ -17,21 +17,28 @@ package org.gringlobal.service.triggers;
import java.util.Collection;
import java.util.Date;
import java.util.HashMap;
import java.util.Objects;
import java.util.Set;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.collections4.IterableUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.tuple.Pair;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.gringlobal.component.GGCE;
import org.genesys.blocks.auditlog.model.AuditAction;
import org.genesys.blocks.auditlog.model.AuditLog;
import org.genesys.blocks.auditlog.service.ClassPKService;
import org.genesys.blocks.model.ClassPK;
import org.gringlobal.model.Accession;
import org.gringlobal.model.AccessionAction;
import org.gringlobal.model.AccessionInvAnnotation;
import org.gringlobal.model.AccessionInvName;
import org.gringlobal.model.Inventory;
import org.gringlobal.model.NameGroup;
import org.gringlobal.model.QAccessionInvName;
import org.gringlobal.model.QInventory;
import org.gringlobal.model.TaxonomySpecies;
import org.gringlobal.model.community.CommunityCodeValues;
......@@ -44,15 +51,15 @@ import org.gringlobal.service.AccessionInvAnnotationService;
import org.gringlobal.service.AccessionInvNameService;
import org.gringlobal.service.AccessionService;
import org.gringlobal.service.InventoryService;
import org.gringlobal.spring.TransactionHelper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
@Aspect
@Component("accessionTriggers")
public class AccessionTriggers {
public class AccessionTriggers implements InitializingBean {
/** The Constant LOG. */
private static final Logger LOG = LoggerFactory.getLogger(AccessionTriggers.class);
......@@ -84,6 +91,53 @@ public class AccessionTriggers {
@Autowired
private AccessionInvAnnotationService accessionInvAnnotationService;
@Autowired
private ClassPKService classPKService;
private ClassPK accessionClassPk;
@Override
public void afterPropertiesSet() throws Exception {
accessionClassPk = classPKService.getClassPk(Accession.class);
}
@Before(value = "execution(* org.genesys.blocks.auditlog.persistence.AuditLogRepository.saveAll(Iterable)) && args(auditLogs)")
public void beforeSaveAuditLogs(final JoinPoint joinPoint, final Collection<AuditLog> auditLogs) throws Throwable {
var changedAccessions = new HashMap<Long, HashMap<String, Pair<Object, Object>>>();
auditLogs.stream().filter(this::isAccessionChangeLog).forEach(auditLog -> {
var changes = changedAccessions.get(auditLog.getEntityId());
if (changes == null) {
changedAccessions.put(auditLog.getEntityId(), changes = new HashMap<String, Pair<Object, Object>>());
}
changes.put(auditLog.getPropertyName(), Pair.of(auditLog.getPreviousEntity(), auditLog.getNewEntity()));
});
changedAccessions.forEach((accessionId, changes) -> {
perhapsRecordChanges(accessionId, changes);
});
}
// Utility
private boolean isAccessionChangeLog(final AuditLog auditLog) {
return auditLog != null && auditLog.getAction() == AuditAction.UPDATE && auditLog.getClassPk().equals(this.accessionClassPk);
}
private void perhapsRecordChanges(Long accessionId, HashMap<String, Pair<Object, Object>> changes) {
var taxonmySpeciesChange = changes.get("taxonomySpecies");
if (taxonmySpeciesChange != null) {
recordAccessionSpeciesChangesIfNeeded(accessionId, (TaxonomySpecies) taxonmySpeciesChange.getKey(), (TaxonomySpecies) taxonmySpeciesChange.getValue());
}
var accessionNumberChange = changes.get("accessionNumber");
if (accessionNumberChange != null) {
// We need accessionNumberPart1
var accessionNumberPart1Change = changes.get("accessionNumberPart1");
if (accessionNumberPart1Change != null) {
recordAccessionNumberIfNeeded(accessionId, (String) accessionNumberChange.getKey(), (String) accessionNumberChange.getValue(), (String) accessionNumberPart1Change.getKey(), (String) accessionNumberPart1Change.getValue());
} else {
recordAccessionNumberIfNeeded(accessionId, (String) accessionNumberChange.getKey(), (String) accessionNumberChange.getValue(), null, null);
}
}
}
@Around(value = "(execution(* org.gringlobal.persistence.AccessionRepository.save(..)) || execution(* org.gringlobal.persistence.AccessionRepository.saveAndFlush(..))) && args(accession)")
public Object aroundAccessionSave(final ProceedingJoinPoint joinPoint, final Accession accession) throws Throwable {
......@@ -91,9 +145,6 @@ public class AccessionTriggers {
assignAccessionNumberPart2IfNeeded(accession);
if (!accession.isNew()) {
Accession before = TransactionHelper.executeInTransaction(true, () -> accessionRepository.findById(accession.getId()).orElse(null));
recordAccessionNumberIfNeeded(accession, before);
recordAccessionSpeciesChangesIfNeeded(accession, before.getTaxonomySpecies().getId());
// it's updating, no need to assure systemInventory
Accession updatedAccession = (Accession) joinPoint.proceed();
// rename system inventories after updating
......@@ -105,8 +156,8 @@ public class AccessionTriggers {
LOG.info("Assure system inventory for {}", createdAccession);
inventoryService.assureSystemInventory(createdAccession);
recordAccessionNumber(createdAccession);
recordAccessionNumber(createdAccession.getId(), createdAccession.getAccessionNumber(), createdAccession.getAccessionNumberPart1());
recordReceivedAccessionSpecies(createdAccession);
return createdAccession;
}
......@@ -137,7 +188,7 @@ public class AccessionTriggers {
*
* @param accession the accession
*/
public void renameInventories(final Accession accession) {
private void renameInventories(final Accession accession) {
if (accession.getInventories() != null) {
LOG.info("Renaming accession SYSTEM inventories for updated accession {}", accession.getId());
inventoryRepository.findAll(QInventory.inventory.accession.eq(accession).and(QInventory.inventory.formTypeCode.eq(Inventory.SYSTEM_INVENTORY_FTC)))
......@@ -151,65 +202,86 @@ public class AccessionTriggers {
}
}
void recordAccessionNumberIfNeeded(Accession accession, Accession before) {
assert accession.getId() != null;
if (before != null && !GGCE.accessionNumber(accession).equals(before.getAccessionNumber())) {
if (CollectionUtils.isEmpty(accessionInvNameRepository.findAllByPlantName(before.getAccessionNumber()))) {
private void recordAccessionNumberIfNeeded(long accessionId, String oldNumber, String newNumber, String oldNumberPart1, String newNumberPart1) {
LOG.trace("Recording name change aid={} {}/{} -> {}/{}", accessionId, oldNumberPart1, oldNumber, newNumberPart1, newNumber);
if (oldNumber != null && !newNumber.equals(oldNumber)) {
LOG.debug("Recording name change aid={} {}/{} -> {}/{}", accessionId, oldNumberPart1, oldNumber, newNumberPart1, newNumber);
var accession = new Accession(accessionId);
var qAIN = QAccessionInvName.accessionInvName;
if (IterableUtils.isEmpty(accessionInvNameRepository.findAll(
// system inventory of accession
qAIN.inventory.formTypeCode.eq(Inventory.SYSTEM_INVENTORY_FTC).and(qAIN.inventory.accession.eq(accession))
// name type
.and(qAIN.categoryCode.eq(CommunityCodeValues.ACCESSION_NAME_TYPE_SITE.value))))) {
// previous accession number isn't yet registered, do it now
recordAccessionNumber(before);
recordAccessionNumber(accessionId, oldNumber, oldNumberPart1);
}
// register changed accession number
recordAccessionNumber(accession);
recordAccessionNumber(accessionId, newNumber, newNumberPart1);
// register new accession action
var actionData = new AccessionActionService.AccessionActionRequest();
actionData.id = Set.of(accession.getId());
actionData.webVisible = accession.getIsWebVisible();
actionData.actionNameCode = CommunityCodeValues.ACCESSION_ACTION_ACCNUMBERD.value;
actionData.note = "Changed " + before.getAccessionNumber() + " to " + GGCE.accessionNumber(accession);
actionService.startAction(actionData);
actionService.completeAction(actionData);
var action = new AccessionAction();
action.setAccession(accession);
action.setIsWebVisible("N");
action.setActionNameCode(CommunityCodeValues.ACCESSION_ACTION_ACCNUMBERD.value);
action.setNote("Changed " + oldNumber + " to " + newNumber);
action.setStartedDate(new Date());
action.setCompletedDate(action.getStartedDate());
action.setStartedDateCode(CommunityCodeValues.DATE_FORMAT_DATETIME.value);
action.setCompletedDateCode(CommunityCodeValues.DATE_FORMAT_DATETIME.value);
action = actionService.create(action);
assert (action != null);
} else {
LOG.trace("Not recording name change {} {}", oldNumber, newNumber);
}
}
void recordAccessionNumber(Accession accession) {
LOG.info("Registering new accession number: {}", accession.getAccessionNumber());
private void recordAccessionNumber(long accessionId, String accessionNumber, String accessionNumberPart1) {
LOG.debug("Registering accession number: {}", accessionNumber);
AccessionInvName invName = new AccessionInvName();
invName.setPlantName(GGCE.accessionNumber(accession));
invName.setPlantName(accessionNumber);
invName.setPlantNameRank(1080);
invName.setCategoryCode(CommunityCodeValues.ACCESSION_NAME_TYPE_SITE.value);
invName.setInventory(inventoryRepository.getSystemInventory(accession));
invName.setInventory(inventoryRepository.getSystemInventory(new Accession(accessionId)));
NameGroup groupName = nameGroupRepository.findByGroupName(accession.getAccessionNumberPart1());
if (groupName != null) {
if (StringUtils.isNotBlank(accessionNumberPart1)) {
// link it with the name group
NameGroup groupName = nameGroupRepository.findByGroupName(accessionNumberPart1);
LOG.trace("Name group {} {}", accessionNumberPart1, groupName);
invName.setNameGroup(groupName);
}
accessionInvNameService.create(invName);
var ain = accessionInvNameService.create(invName);
assert(ain != null);
}
void recordAccessionSpeciesChangesIfNeeded(Accession accession, Long originalTaxonomySpeciesId) {
assert accession.getId() != null;
if (originalTaxonomySpeciesId != null && !Objects.equals(originalTaxonomySpeciesId, accession.getTaxonomySpecies().getId())) {
private void recordAccessionSpeciesChangesIfNeeded(long accessionId, TaxonomySpecies oldTs, TaxonomySpecies newTs) {
LOG.debug("recordAccessionSpeciesChangesIfNeeded: orig.id={} curr=", oldTs, newTs);
if (oldTs != null && !Objects.equals(oldTs.getId(), newTs.getId())) {
AccessionInvAnnotation annotation = new AccessionInvAnnotation();
annotation.setAnnotationTypeCode(CommunityCodeValues.ANNOTATION_TYPE_RE_IDENT.value);
annotation.setInventory(inventoryRepository.getSystemInventory(accession));
annotation.setOldTaxonomySpecies(new TaxonomySpecies(originalTaxonomySpeciesId));
annotation.setNewTaxonomySpecies(accession.getTaxonomySpecies());
annotation.setInventory(inventoryRepository.getSystemInventory(new Accession(accessionId)));
annotation.setOldTaxonomySpecies(oldTs);
annotation.setNewTaxonomySpecies(newTs);
annotation.setAnnotationDate(new Date());
annotation.setAnnotationDateCode(CommunityCodeValues.DATE_FORMAT_DATETIME.value);
accessionInvAnnotationService.create(annotation);
var aia = accessionInvAnnotationService.create(annotation);
assert(aia != null);
} else {
LOG.trace("No change detected old={} new={}", oldTs, newTs);
}
}
void recordReceivedAccessionSpecies(Accession accession) {
private void recordReceivedAccessionSpecies(Accession accession) {
assert(accession.getId() != null);
AccessionInvAnnotation annotation = new AccessionInvAnnotation();
annotation.setAnnotationTypeCode(CommunityCodeValues.ANNOTATION_TYPE_RECEIVED.value);
annotation.setInventory(inventoryRepository.getSystemInventory(accession));
annotation.setAnnotationDate(new Date());
annotation.setAnnotationDateCode(CommunityCodeValues.DATE_FORMAT_DATETIME.value);
annotation.setNewTaxonomySpecies(accession.getTaxonomySpecies());
accessionInvAnnotationService.create(annotation);
var aia = accessionInvAnnotationService.create(annotation);
assert(aia != null);
}
}
......@@ -215,7 +215,7 @@ public class AccessionServiceTest extends AbstractServicesTest {
updated.setAccessionNumberPart1("TMe");
updated.setAccessionNumberPart2(-1l);
var newUpdated = accessionService.update(accession);
var newUpdated = accessionService.update(updated);
assertThat(accessionInvNameRepository.count(), is(3L));
allNames = accessionInvNameRepository.findAll();
......
......@@ -39,7 +39,8 @@ log4j.category.org.springframework.web.client=trace
log4j.category.org.elasticsearch.client=error
# Debug print JSON
#log4j.category.org.gringlobal.application.config.ElasticsearchConfig=trace
#log4j.category.org.genesys.blocks.auditlog=trace
#log4j.category.org.gringlobal.service.triggers=trace
# Debug GGCE-SEC
#log4j.category.org.gringlobal.application.config.GGCESecurityConfig=trace
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment