diff --git a/api/src/main/java/org/openmrs/module/sync2/api/SyncAuditService.java b/api/src/main/java/org/openmrs/module/sync2/api/SyncAuditService.java index b1ae4cb7..4b354126 100644 --- a/api/src/main/java/org/openmrs/module/sync2/api/SyncAuditService.java +++ b/api/src/main/java/org/openmrs/module/sync2/api/SyncAuditService.java @@ -7,6 +7,7 @@ import org.openmrs.module.sync2.SyncModuleConfig; import org.openmrs.module.sync2.api.model.audit.AuditMessage; +import org.springframework.beans.factory.annotation.Autowired; import org.springframework.transaction.annotation.Transactional; public interface SyncAuditService extends OpenmrsService { @@ -24,12 +25,10 @@ public interface SyncAuditService extends OpenmrsService { String getPaginatedMessages(Integer page, Integer pageSize, Boolean success, String action, String resourceName) throws APIException; @Authorized(SyncModuleConfig.SYNC_AUDIT_PRIVILEGE) - AuditMessage saveSuccessfulAudit(String resourceName, String resourceUrl, String action, String error) throws APIException; + @Transactional + AuditMessage saveAuditMessage(AuditMessage auditMessage) throws APIException; - @Authorized(SyncModuleConfig.SYNC_AUDIT_PRIVILEGE) - AuditMessage saveFailedAudit(String resourceName, String resourceUrl, String action, String error) throws APIException; - @Authorized(SyncModuleConfig.SYNC_AUDIT_PRIVILEGE) @Transactional - AuditMessage saveAuditMessage(AuditMessage auditMessage); + AuditMessage setNextAudit(AuditMessage current, AuditMessage next) throws APIException; } \ No newline at end of file diff --git a/api/src/main/java/org/openmrs/module/sync2/api/SyncPullService.java b/api/src/main/java/org/openmrs/module/sync2/api/SyncPullService.java index 3b05189b..a918aea2 100644 --- a/api/src/main/java/org/openmrs/module/sync2/api/SyncPullService.java +++ b/api/src/main/java/org/openmrs/module/sync2/api/SyncPullService.java @@ -1,8 +1,10 @@ package org.openmrs.module.sync2.api; +import org.openmrs.module.sync2.api.model.audit.AuditMessage; + import java.util.Map; public interface SyncPullService { - void pullDataFromParentAndSave(String category, Map resourceLinks, String address, String action); + AuditMessage pullDataFromParentAndSave(String category, Map resourceLinks, String address, String action); } diff --git a/api/src/main/java/org/openmrs/module/sync2/api/SyncPushService.java b/api/src/main/java/org/openmrs/module/sync2/api/SyncPushService.java index 2798fd96..6031f17e 100644 --- a/api/src/main/java/org/openmrs/module/sync2/api/SyncPushService.java +++ b/api/src/main/java/org/openmrs/module/sync2/api/SyncPushService.java @@ -1,8 +1,10 @@ package org.openmrs.module.sync2.api; +import org.openmrs.module.sync2.api.model.audit.AuditMessage; + import java.util.Map; public interface SyncPushService { - void readDataAndPushToParent(String category, Map resourceLinks, String address, String action); + AuditMessage readDataAndPushToParent(String category, Map resourceLinks, String address, String action); } diff --git a/api/src/main/java/org/openmrs/module/sync2/api/SyncRetryService.java b/api/src/main/java/org/openmrs/module/sync2/api/SyncRetryService.java new file mode 100644 index 00000000..17dc61e9 --- /dev/null +++ b/api/src/main/java/org/openmrs/module/sync2/api/SyncRetryService.java @@ -0,0 +1,12 @@ +package org.openmrs.module.sync2.api; + +import org.openmrs.annotation.Authorized; +import org.openmrs.api.APIException; +import org.openmrs.module.sync2.SyncModuleConfig; +import org.openmrs.module.sync2.api.model.audit.AuditMessage; + +public interface SyncRetryService { + + @Authorized(SyncModuleConfig.SYNC_AUDIT_PRIVILEGE) + AuditMessage retryMessage(AuditMessage message) throws APIException; +} diff --git a/api/src/main/java/org/openmrs/module/sync2/api/dao/impl/SyncAuditDaoImpl.java b/api/src/main/java/org/openmrs/module/sync2/api/dao/impl/SyncAuditDaoImpl.java index d8db4042..00221aea 100644 --- a/api/src/main/java/org/openmrs/module/sync2/api/dao/impl/SyncAuditDaoImpl.java +++ b/api/src/main/java/org/openmrs/module/sync2/api/dao/impl/SyncAuditDaoImpl.java @@ -4,7 +4,6 @@ import org.hibernate.Criteria; import org.hibernate.Session; import org.hibernate.Transaction; -import org.hibernate.criterion.Order; import org.hibernate.criterion.Projections; import org.hibernate.criterion.Restrictions; import org.openmrs.api.db.hibernate.DbSession; @@ -15,7 +14,6 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Repository; -import java.time.LocalDate; import java.util.List; @@ -54,24 +52,7 @@ public Long getCountOfMessages() { } public AuditMessage saveItem(AuditMessage auditMessage) { - Session session = sessionFactory.getHibernateSessionFactory().openSession(); - Transaction tx = null; - try { - tx = session.beginTransaction(); - session.saveOrUpdate(auditMessage); - tx.commit(); - } - catch (Exception ex) { - if (tx != null) { - tx.rollback(); - } - throw ex; - } - finally { - if (session != null) { - session.close(); - } - } + getSession().saveOrUpdate(auditMessage); return auditMessage; } diff --git a/api/src/main/java/org/openmrs/module/sync2/api/impl/SyncAuditServiceImpl.java b/api/src/main/java/org/openmrs/module/sync2/api/impl/SyncAuditServiceImpl.java index 124cd411..0414e159 100644 --- a/api/src/main/java/org/openmrs/module/sync2/api/impl/SyncAuditServiceImpl.java +++ b/api/src/main/java/org/openmrs/module/sync2/api/impl/SyncAuditServiceImpl.java @@ -48,38 +48,6 @@ public String getPaginatedMessages(Integer page, Integer pageSize, Boolean succe AuditMessageList result = new AuditMessageList(dao.getCountOfMessages(), page, pageSize, auditMessageList); return serializeResults(result); } - - @Override - public AuditMessage saveSuccessfulAudit(String resourceName, String resourceUrl, String operation, String details) throws APIException { - if (configuration.getSyncConfiguration().getGeneral().isPersistSuccessAudit()) { - AuditMessage newItem = new AuditMessage(); - newItem.setSuccess(true); - newItem.setTimestamp(new Timestamp(System.currentTimeMillis())); - newItem.setResourceName(resourceName); - newItem.setUsedResourceUrl(resourceUrl); - newItem.setOperation(operation); - newItem.setDetails(details); - - return dao.saveItem(newItem); - } - return null; - } - - @Override - public AuditMessage saveFailedAudit(String resourceName, String resourceUrl, String operation, String details) throws APIException { - if (configuration.getSyncConfiguration().getGeneral().isPersistFailureAudit()) { - AuditMessage newItem = new AuditMessage(); - newItem.setSuccess(false); - newItem.setTimestamp(new Timestamp(System.currentTimeMillis())); - newItem.setResourceName(resourceName); - newItem.setUsedResourceUrl(resourceUrl); - newItem.setOperation(operation); - newItem.setDetails(details); - - return dao.saveItem(newItem); - } - return null; - } @Override public AuditMessage saveAuditMessage(AuditMessage auditMessage) { @@ -95,7 +63,16 @@ public AuditMessage saveAuditMessage(AuditMessage auditMessage) { } return null; } - + + @Override + public AuditMessage setNextAudit(AuditMessage current, AuditMessage next) throws APIException { + if (current == null || next == null) { + return null; + } + current.setNextMessage(next.getId()); + return dao.saveItem(current); + } + private String serializeResults(AuditMessageList results) { GsonBuilder gsonBuilder = new GsonBuilder().serializeNulls(); gsonBuilder.registerTypeAdapter(AuditMessage.class, new AuditMessage.AuditMessageSerializer()); diff --git a/api/src/main/java/org/openmrs/module/sync2/api/impl/SyncPullServiceImpl.java b/api/src/main/java/org/openmrs/module/sync2/api/impl/SyncPullServiceImpl.java index a4fd6f11..bb07b633 100644 --- a/api/src/main/java/org/openmrs/module/sync2/api/impl/SyncPullServiceImpl.java +++ b/api/src/main/java/org/openmrs/module/sync2/api/impl/SyncPullServiceImpl.java @@ -11,6 +11,7 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.stereotype.Component; import java.sql.Timestamp; @@ -18,6 +19,7 @@ import static org.openmrs.module.sync2.SyncConstants.PULL_OPERATION; import static org.openmrs.module.sync2.SyncConstants.PULL_SUCCESS_MESSAGE; +import static org.openmrs.module.sync2.api.utils.SyncUtils.getPreferredClient; import static org.openmrs.module.sync2.api.utils.SyncUtils.getPreferredUrl; @Component("sync2.syncPullService") @@ -29,20 +31,18 @@ public class SyncPullServiceImpl implements SyncPullService { private SyncConfigurationService configurationService; @Autowired - private SyncAuditService auditService; + private SyncAuditService syncAuditService; private SyncClient syncClient = new SyncClient(); private SyncPersistence syncPersistence = new SyncPersistence(); - public void pullDataFromParentAndSave(String category, Map resourceLinks, String address, String action) { + public AuditMessage pullDataFromParentAndSave(String category, Map resourceLinks, String address, String action) { LOGGER.info(String.format("Pull category: %s, address: %s, action: %s", category, address, action)); AuditMessage auditMessage = prepareBaseAuditMessage(); auditMessage.setResourceName(category); auditMessage.setUsedResourceUrl(getPreferredUrl(resourceLinks)); auditMessage.setAvailableResourceUrls(SyncUtils.serializeMap(resourceLinks)); - auditMessage.setParentUrl(getParentUri()); - auditMessage.setLocalUrl(getLocalUri()); auditMessage.setAction(action); try { @@ -56,8 +56,9 @@ public void pullDataFromParentAndSave(String category, Map resou auditMessage.setSuccess(false); auditMessage.setDetails(ExceptionUtils.getFullStackTrace(e)); } finally { - auditService.saveAuditMessage(auditMessage); + auditMessage = syncAuditService.saveAuditMessage(auditMessage); } + return auditMessage; } private String getParentUri() { @@ -72,6 +73,9 @@ private AuditMessage prepareBaseAuditMessage() { AuditMessage auditMessage = new AuditMessage(); auditMessage.setTimestamp(new Timestamp(System.currentTimeMillis())); auditMessage.setOperation(PULL_OPERATION); + auditMessage.setParentUrl(getParentUri()); + auditMessage.setLocalUrl(getLocalUri()); + auditMessage.setLinkType(getPreferredClient()); return auditMessage; } } diff --git a/api/src/main/java/org/openmrs/module/sync2/api/impl/SyncPushServiceImpl.java b/api/src/main/java/org/openmrs/module/sync2/api/impl/SyncPushServiceImpl.java index 127fb58c..41afa0f3 100644 --- a/api/src/main/java/org/openmrs/module/sync2/api/impl/SyncPushServiceImpl.java +++ b/api/src/main/java/org/openmrs/module/sync2/api/impl/SyncPushServiceImpl.java @@ -19,6 +19,7 @@ import static org.openmrs.module.sync2.SyncConstants.PUSH_OPERATION; import static org.openmrs.module.sync2.SyncConstants.PUSH_SUCCESS_MESSAGE; +import static org.openmrs.module.sync2.api.utils.SyncUtils.getPreferredClient; import static org.openmrs.module.sync2.api.utils.SyncUtils.getPreferredUrl; @Component("sync2.syncPushService") @@ -31,28 +32,25 @@ public class SyncPushServiceImpl implements SyncPushService { private SyncConfigurationService configurationService; @Autowired - private SyncAuditService auditService; + private SyncAuditService syncAuditService; private SyncClient syncClient = new SyncClient(); private SyncPersistence syncPersistence = new SyncPersistence(); @Override - public void readDataAndPushToParent(String category, Map resourceLinks, String address, String action) { + public AuditMessage readDataAndPushToParent(String category, Map resourceLinks, String address, String action) { LOGGER.info(String.format("SyncPushService category: %s, address: %s, action: %s", category, address, action)); - + AuditMessage auditMessage = prepareBaseAuditMessage(); auditMessage.setResourceName(category); auditMessage.setUsedResourceUrl(getPreferredUrl(resourceLinks)); auditMessage.setAvailableResourceUrls(SyncUtils.serializeMap(resourceLinks)); - auditMessage.setParentUrl(getParentUri()); - auditMessage.setLocalUrl(getLocalUri()); auditMessage.setAction(action); - try { String uuid = SyncUtils.extractUUIDFromResourceLinks(resourceLinks); Object data = syncPersistence.retrieveData(getPreferredClient(), category, uuid); syncClient.pushDataToParent(data, resourceLinks, getParentUri()); - + auditMessage.setSuccess(true); auditMessage.setDetails(PUSH_SUCCESS_MESSAGE); } catch (Exception e) { @@ -60,8 +58,9 @@ public void readDataAndPushToParent(String category, Map resourc auditMessage.setSuccess(false); auditMessage.setDetails(ExceptionUtils.getFullStackTrace(e)); } finally { - auditService.saveAuditMessage(auditMessage); + auditMessage = syncAuditService.saveAuditMessage(auditMessage); } + return auditMessage; } private String getPreferredClient() { @@ -80,6 +79,9 @@ private AuditMessage prepareBaseAuditMessage() { AuditMessage auditMessage = new AuditMessage(); auditMessage.setTimestamp(new Timestamp(System.currentTimeMillis())); auditMessage.setOperation(PUSH_OPERATION); + auditMessage.setParentUrl(getParentUri()); + auditMessage.setLocalUrl(getLocalUri()); + auditMessage.setLinkType(getPreferredClient()); return auditMessage; } } diff --git a/api/src/main/java/org/openmrs/module/sync2/api/impl/SyncRetryServiceImpl.java b/api/src/main/java/org/openmrs/module/sync2/api/impl/SyncRetryServiceImpl.java new file mode 100644 index 00000000..c18a4e6e --- /dev/null +++ b/api/src/main/java/org/openmrs/module/sync2/api/impl/SyncRetryServiceImpl.java @@ -0,0 +1,70 @@ +package org.openmrs.module.sync2.api.impl; + +import org.openmrs.api.APIException; +import org.openmrs.module.sync2.api.SyncAuditService; +import org.openmrs.module.sync2.api.SyncConfigurationService; +import org.openmrs.module.sync2.api.SyncPullService; +import org.openmrs.module.sync2.api.SyncPushService; +import org.openmrs.module.sync2.api.SyncRetryService; +import org.openmrs.module.sync2.api.model.audit.AuditMessage; +import org.openmrs.module.sync2.api.utils.SyncUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +import java.util.HashMap; +import java.util.Map; + +import static org.openmrs.module.sync2.SyncConstants.PULL_OPERATION; +import static org.openmrs.module.sync2.SyncConstants.PUSH_OPERATION; + + +@Component("sync2.SyncRetryService") +public class SyncRetryServiceImpl implements SyncRetryService { + + @Autowired + private SyncPullService syncPullService; + + @Autowired + private SyncPushService syncPushService; + + @Autowired + private SyncAuditService syncAuditService; + + @Autowired + private SyncConfigurationService configuration; + + @Override + public AuditMessage retryMessage(AuditMessage message) throws APIException { + switch(message.getOperation()) { + case PULL_OPERATION: + return retryPull(message); + case PUSH_OPERATION: + return retryPush(message); + } + return null; + } + + private AuditMessage retryPush(AuditMessage message) { + String parentAddress = configuration.getSyncConfiguration().getGeneral().getParentFeedLocation(); + parentAddress = SyncUtils.getBaseUrl(parentAddress); + + Map map = new HashMap<>(); + map.put(message.getLinkType(), message.getUsedResourceUrl()); + + AuditMessage newMesssage = syncPushService.readDataAndPushToParent(message.getResourceName(), map, parentAddress, message.getAction()); + syncAuditService.setNextAudit(message, newMesssage); + return newMesssage; + } + + private AuditMessage retryPull(AuditMessage message) { + String parentAddress = configuration.getSyncConfiguration().getGeneral().getParentFeedLocation(); + parentAddress = SyncUtils.getBaseUrl(parentAddress); + + Map map = new HashMap<>(); + map.put(message.getLinkType(), message.getUsedResourceUrl()); + + AuditMessage newMesssage = syncPullService.pullDataFromParentAndSave(message.getResourceName(), map, parentAddress, message.getAction()); + syncAuditService.setNextAudit(message, newMesssage); + return newMesssage; + } +} diff --git a/api/src/main/java/org/openmrs/module/sync2/api/model/audit/AuditMessage.java b/api/src/main/java/org/openmrs/module/sync2/api/model/audit/AuditMessage.java index 8ccfefef..889aa527 100644 --- a/api/src/main/java/org/openmrs/module/sync2/api/model/audit/AuditMessage.java +++ b/api/src/main/java/org/openmrs/module/sync2/api/model/audit/AuditMessage.java @@ -16,75 +16,37 @@ import org.hibernate.persister.entity.SingleTableEntityPersister; import org.openmrs.BaseOpenmrsData; -import javax.persistence.Basic; -import javax.persistence.Column; -import javax.persistence.Entity; -import javax.persistence.GeneratedValue; -import javax.persistence.Id; -import javax.persistence.Table; - - @Persister(impl = SingleTableEntityPersister.class) -@Entity -@Table(name = "sync_audit_message") public class AuditMessage extends BaseOpenmrsData { private static final long serialVersionUID = 6106269076155338045L; - @Id - @GeneratedValue - @Column(name = "sync_audit_message_id") private Integer id; - @Basic - @Column(name = "success") private Boolean success; - @Basic - @Column(name = "timestamp") private Date timestamp; - @Basic - @Column(name = "resource_name") private String resourceName; - @Basic - @Column(name = "used_resource_url") private String usedResourceUrl; - - @Basic - @Column(name = "available_resource_urls") + private String availableResourceUrls; - - @Basic - @Column(name = "parent_url") + private String parentUrl; - - @Basic - @Column(name = "local_url") + private String localUrl; - - @Basic - @Column(name = "action") + + private String details; + private String action; - - @Basic - @Column(name = "operation") + private String operation; - - @Basic - @Column(name = "details") - private String details; + private String linkType; - public AuditMessage() { - } + private Integer nextMessage; - public AuditMessage(Integer id, Boolean success, Date timestamp, String resourceName, String usedResourceUrl) { - this.id = id; - this.success = success; - this.timestamp = new Date(timestamp.getTime()); - this.resourceName = resourceName; - this.usedResourceUrl = usedResourceUrl; + public AuditMessage() { } @Override @@ -187,6 +149,22 @@ public void setOperation(String operation) { this.operation = operation; } + public String getLinkType() { + return linkType; + } + + public void setLinkType(String linkType) { + this.linkType = linkType; + } + + public Integer getNextMessage() { + return nextMessage; + } + + public void setNextMessage(Integer nextMessage) { + this.nextMessage = nextMessage; + } + @Override public boolean equals(Object o) { if (this == o) { @@ -207,13 +185,20 @@ public boolean equals(Object o) { && Objects.equals(this.localUrl, auditMessage.localUrl) && Objects.equals(this.action, auditMessage.action) && Objects.equals(this.operation, auditMessage.operation) - && Objects.equals(this.details, auditMessage.details); + && Objects.equals(this.details, auditMessage.details) + && Objects.equals(this.action, auditMessage.action) + && Objects.equals(this.operation, auditMessage.operation) + && Objects.equals(this.linkType, auditMessage.linkType) + && Objects.equals(this.nextMessage, auditMessage.nextMessage); } + + @Override public int hashCode() { + return Objects.hash(success, timestamp, resourceName, usedResourceUrl, availableResourceUrls, parentUrl, - localUrl, action, details, action); + localUrl, action, details, action, linkType, nextMessage); } public static class AuditMessageSerializer implements JsonSerializer { @@ -236,6 +221,8 @@ public JsonElement serialize(AuditMessage src, Type typeOfSrc, JsonSerialization object.addProperty("action", src.action); object.addProperty("operation", src.operation); object.addProperty("details", src.details); + object.addProperty("linkType", src.linkType); + object.addProperty("nextMessage", src.nextMessage); return object; } diff --git a/api/src/main/java/org/openmrs/module/sync2/api/utils/SyncUtils.java b/api/src/main/java/org/openmrs/module/sync2/api/utils/SyncUtils.java index 78a7223e..0a96aca7 100644 --- a/api/src/main/java/org/openmrs/module/sync2/api/utils/SyncUtils.java +++ b/api/src/main/java/org/openmrs/module/sync2/api/utils/SyncUtils.java @@ -141,8 +141,23 @@ private static HashMap parseTag(String tag) { } public static String getPreferredUrl(Map resourceLinks) { - String preferredClient = Context.getAdministrationService().getGlobalProperty(RESOURCE_PREFERRED_CLIENT); - return resourceLinks.get(preferredClient); + String preferredClient = getPreferredClient(); + String result = resourceLinks.get(preferredClient); + if (result == null && resourceLinks.size() > 0) { + result = getFirstResourceLink(resourceLinks); + } + return result; + } + + private static String getFirstResourceLink(Map resourceLinks) { + if (resourceLinks.size() > 0) { + return resourceLinks.values().iterator().next(); + } + return ""; + } + + public static String getPreferredClient() { + return Context.getAdministrationService().getGlobalProperty(RESOURCE_PREFERRED_CLIENT); } public static String extractUUIDFromResourceLinks(Map resourceLinks) { diff --git a/api/src/main/resources/SyncAuditMessage.hbm.xml b/api/src/main/resources/SyncAuditMessage.hbm.xml index 2f9fac61..d833cef3 100644 --- a/api/src/main/resources/SyncAuditMessage.hbm.xml +++ b/api/src/main/resources/SyncAuditMessage.hbm.xml @@ -19,8 +19,10 @@ - + + + diff --git a/api/src/main/resources/liquibase.xml b/api/src/main/resources/liquibase.xml index 3c81bc96..6c18185b 100644 --- a/api/src/main/resources/liquibase.xml +++ b/api/src/main/resources/liquibase.xml @@ -5,7 +5,7 @@ xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog/1.9 http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-1.9.xsd"> - + @@ -29,10 +29,11 @@ - - + + + diff --git a/api/src/main/resources/messages.properties b/api/src/main/resources/messages.properties index f4aa84a3..26e32f8b 100644 --- a/api/src/main/resources/messages.properties +++ b/api/src/main/resources/messages.properties @@ -42,7 +42,8 @@ sync2.log.header.details.messageNotFound=The message not found sync2.log.header.details.status.failure=Failure sync2.log.header.details.status.success=Success - +sync2.log.header.retry=Retry +sync2.log.header.nextMessage=Next message sync2.log.status.all=All sync2.log.status.success=Success @@ -56,4 +57,6 @@ sync2.log.resource.all=All sync2.log.resource.patient=patient sync2.details.label=Details -sync2.auditList.label=Audit Log \ No newline at end of file +sync2.auditList.label=Audit Log +sync2.audit.retry.success=Success retry operation +sync2.audit.retry.failed=Retry failed \ No newline at end of file diff --git a/api/src/test/java/org/openmrs/module/sync2/api/impl/SyncAuditServiceImplTest.java b/api/src/test/java/org/openmrs/module/sync2/api/impl/SyncAuditServiceImplTest.java index bc383eab..68dc2ebb 100644 --- a/api/src/test/java/org/openmrs/module/sync2/api/impl/SyncAuditServiceImplTest.java +++ b/api/src/test/java/org/openmrs/module/sync2/api/impl/SyncAuditServiceImplTest.java @@ -41,7 +41,9 @@ public class SyncAuditServiceImplTest { private static final String AUDIT_OPERATION = "testOperation"; private static final String AUDIT_PARENT_URL = "parentUrl"; private static final String AUDIT_LOCAL_URL = "localUrl"; - + private static final String AUDIT_LINK_TYPE = "test"; + private static final Integer AUDIT_NEXT_MESSAGE = 1; + @InjectMocks private SyncAuditServiceImpl auditService; @@ -97,54 +99,6 @@ public void getPaginatedMessages() throws Exception { Assert.assertEquals(expected, fetched); } - - @Test - public void saveFailedAudit_shouldSave() { - AuditMessage auditMessage = new AuditMessage(); - - when(dao.saveItem(any())).thenReturn(auditMessage); - when(configurationService.getSyncConfiguration().getGeneral().isPersistFailureAudit()).thenReturn(true); - - AuditMessage fetched = auditService.saveFailedAudit(AUDIT_NAME, AUDIT_USED_URL, AUDIT_ACTION, AUDIT_DETAILS); - - Assert.assertNotNull(fetched); - } - - @Test - public void saveFailedAudit_shouldNotSave() { - AuditMessage auditMessage = new AuditMessage(); - - when(dao.saveItem(any())).thenReturn(auditMessage); - when(configurationService.getSyncConfiguration().getGeneral().isPersistFailureAudit()).thenReturn(false); - - AuditMessage fetched = auditService.saveFailedAudit(AUDIT_NAME, AUDIT_USED_URL, AUDIT_ACTION, AUDIT_DETAILS); - - Assert.assertNull(fetched); - } - - @Test - public void saveSuccessfulAudit_shouldSave() { - AuditMessage auditMessage = new AuditMessage(); - - when(dao.saveItem(any())).thenReturn(auditMessage); - when(configurationService.getSyncConfiguration().getGeneral().isPersistSuccessAudit()).thenReturn(true); - - AuditMessage fetched = auditService.saveSuccessfulAudit(AUDIT_NAME, AUDIT_USED_URL, AUDIT_ACTION, AUDIT_DETAILS); - - Assert.assertNotNull(fetched); - } - - @Test - public void saveSuccessfulAudit_shouldNotSave() { - AuditMessage auditMessage = new AuditMessage(); - - when(dao.saveItem(any())).thenReturn(auditMessage); - when(configurationService.getSyncConfiguration().getGeneral().isPersistSuccessAudit()).thenReturn(false); - - AuditMessage fetched = auditService.saveSuccessfulAudit(AUDIT_NAME, AUDIT_USED_URL, AUDIT_ACTION, AUDIT_DETAILS); - - Assert.assertNull(fetched); - } @Test public void saveAuditMessage_shouldSaveSuccessfulAudit() { @@ -229,8 +183,7 @@ private String prepareDummyAvailableResourcesUrls() { return null; } } - - + private AuditMessage prepareAuditMessage(Boolean success) throws ParseException { ObjectMapper objectMapper = new ObjectMapper(); AuditMessage newMessage = new AuditMessage(); @@ -243,6 +196,8 @@ private AuditMessage prepareAuditMessage(Boolean success) throws ParseException newMessage.setParentUrl(AUDIT_PARENT_URL); newMessage.setLocalUrl(AUDIT_LOCAL_URL); newMessage.setUsedResourceUrl(AUDIT_USED_URL); + newMessage.setLinkType(AUDIT_LINK_TYPE); + newMessage.setNextMessage(AUDIT_NEXT_MESSAGE); newMessage.setSuccess(success); String createDate = "2017-12-07 00:00:00"; diff --git a/api/src/test/resources/audit/sampleAuditMessage.json b/api/src/test/resources/audit/sampleAuditMessage.json index 79be7bd0..365e9697 100644 --- a/api/src/test/resources/audit/sampleAuditMessage.json +++ b/api/src/test/resources/audit/sampleAuditMessage.json @@ -1 +1 @@ -{"id":1,"uuid":"9f3dccc9-6bc3-4a2b-862d-af4ce41caa28","success":false,"timestamp":"2017-12-07 00:00:00.000","resourceName":"test","usedResourceUrl":"/test/test","availableResourceUrls":"{\"rest\":\"testUrl2\",\"fhir\":\"testUrl1\"}","parentUrl":"parentUrl","localUrl":"localUrl","action":"testAction","operation":"testOperation","details":"testDetails"} \ No newline at end of file +{"id":1,"uuid":"9f3dccc9-6bc3-4a2b-862d-af4ce41caa28","success":false,"timestamp":"2017-12-07 00:00:00.000","resourceName":"test","usedResourceUrl":"/test/test","availableResourceUrls":"{\"rest\":\"testUrl2\",\"fhir\":\"testUrl1\"}","parentUrl":"parentUrl","localUrl":"localUrl","action":"testAction","operation":"testOperation","details":"testDetails","linkType":"test","nextMessage":1} \ No newline at end of file diff --git a/api/src/test/resources/audit/sampleAuditMessages.json b/api/src/test/resources/audit/sampleAuditMessages.json index 628b04f3..1225dac2 100644 --- a/api/src/test/resources/audit/sampleAuditMessages.json +++ b/api/src/test/resources/audit/sampleAuditMessages.json @@ -1 +1 @@ -{"itemsCount":2,"page":1,"pageSize":100,"data":[{"id":1,"uuid":"9f3dccc9-6bc3-4a2b-862d-af4ce41caa28","success":true,"timestamp":"2017-12-07 00:00:00.000","resourceName":"Test 1","usedResourceUrl":"/test/test","availableResourceUrls":"{\"rest\":\"testUrl2\",\"fhir\":\"testUrl1\"}","parentUrl":"parentUrl","localUrl":"localUrl","action":"testAction","operation":"testOperation","details":"testDetails"},{"id":1,"uuid":"74e75d4a-393c-4611-a903-883a0fd5fc6f","success":false,"timestamp":"2017-12-07 00:00:00.000","resourceName":"Test 2","usedResourceUrl":"/test/test","availableResourceUrls":"{\"rest\":\"testUrl2\",\"fhir\":\"testUrl1\"}","parentUrl":"parentUrl","localUrl":"localUrl","action":"testAction","operation":"testOperation","details":"testDetails"}]} \ No newline at end of file +{"itemsCount":2,"page":1,"pageSize":100,"data":[{"id":1,"uuid":"9f3dccc9-6bc3-4a2b-862d-af4ce41caa28","success":true,"timestamp":"2017-12-07 00:00:00.000","resourceName":"Test 1","usedResourceUrl":"/test/test","availableResourceUrls":"{\"rest\":\"testUrl2\",\"fhir\":\"testUrl1\"}","parentUrl":"parentUrl","localUrl":"localUrl","action":"testAction","operation":"testOperation","details":"testDetails","linkType":"test","nextMessage":1},{"id":1,"uuid":"74e75d4a-393c-4611-a903-883a0fd5fc6f","success":false,"timestamp":"2017-12-07 00:00:00.000","resourceName":"Test 2","usedResourceUrl":"/test/test","availableResourceUrls":"{\"rest\":\"testUrl2\",\"fhir\":\"testUrl1\"}","parentUrl":"parentUrl","localUrl":"localUrl","action":"testAction","operation":"testOperation","details":"testDetails","linkType":"test","nextMessage":1}]} \ No newline at end of file diff --git a/omod/src/main/java/org/openmrs/module/sync2/fragment/controller/AuditDetailsFragmentController.java b/omod/src/main/java/org/openmrs/module/sync2/fragment/controller/AuditDetailsFragmentController.java index 6dd58159..f9593f76 100644 --- a/omod/src/main/java/org/openmrs/module/sync2/fragment/controller/AuditDetailsFragmentController.java +++ b/omod/src/main/java/org/openmrs/module/sync2/fragment/controller/AuditDetailsFragmentController.java @@ -1,24 +1,53 @@ package org.openmrs.module.sync2.fragment.controller; import org.openmrs.module.sync2.api.SyncAuditService; -import org.openmrs.module.sync2.api.impl.SyncAuditServiceImpl; +import org.openmrs.module.sync2.api.SyncRetryService; import org.openmrs.module.sync2.api.model.audit.AuditMessage; +import org.openmrs.module.uicommons.util.InfoErrorMessageUtil; +import org.openmrs.ui.framework.SimpleObject; +import org.openmrs.ui.framework.UiUtils; import org.openmrs.ui.framework.annotation.FragmentParam; import org.openmrs.ui.framework.annotation.SpringBean; import org.openmrs.ui.framework.fragment.FragmentModel; import org.openmrs.ui.framework.fragment.FragmentRequest; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestParam; -import java.io.IOException; +import javax.servlet.http.HttpSession; public class AuditDetailsFragmentController { + private static final String RETRY_SUCCESS = "sync2.audit.retry.success"; + private static final String RETRY_FAILED = "sync2.audit.retry.failed"; + public void controller(FragmentModel model, FragmentRequest request, @SpringBean("syncAuditService") SyncAuditService syncAuditService, - @FragmentParam(value = "messageId", required = true) Integer messageId) throws IOException { + @FragmentParam(value = "messageId", required = true) Integer messageId){ AuditMessage message = syncAuditService.getMessageById(messageId); model.addAttribute("auditLog", message); request.setProviderName("sync2"); } + + @RequestMapping(value = "/sync2/retry") + public SimpleObject retry(@RequestParam(value = "retryLogId") Integer messageId, + @SpringBean("syncAuditService") SyncAuditService syncAuditService, + @SpringBean("sync2.SyncRetryService") SyncRetryService syncRetryService, + HttpSession session, UiUtils ui) { + AuditMessage message = syncAuditService.getMessageById(messageId); + message = syncRetryService.retryMessage(message); + SimpleObject result = new SimpleObject(); + + if (message != null && message.getSuccess()) { + InfoErrorMessageUtil.flashInfoMessage(session, ui.message(RETRY_SUCCESS)); + result.put("url", "/sync2/auditList.page"); + } else if (message != null && !message.getSuccess()) { + InfoErrorMessageUtil.flashInfoMessage(session, ui.message(RETRY_FAILED)); + String newMessageUrl = "/sync2/details.page?messageId=" + message.getId() + "&backPage=auditList" + "&backPageIndex=" + 1; + result.put("url", newMessageUrl); + } + + return result; + } } \ No newline at end of file diff --git a/omod/src/main/webapp/fragments/auditDetails.gsp b/omod/src/main/webapp/fragments/auditDetails.gsp index e0859b45..5d948509 100644 --- a/omod/src/main/webapp/fragments/auditDetails.gsp +++ b/omod/src/main/webapp/fragments/auditDetails.gsp @@ -1,5 +1,7 @@ <% def messagesPrefix = "sync2.log.header" + def detailViewProvider = "sync2" + ui.includeJavascript("sync2", "sync2.audit.retry.js") %>