diff --git a/api/pom.xml b/api/pom.xml index 15b22416..cfb1405e 100644 --- a/api/pom.xml +++ b/api/pom.xml @@ -32,9 +32,16 @@ org.openmrs.module - webservices.rest-omod-common + webservices.rest-omod + ${webservices.restVersion} provided + + + org.openmrs.module + webservices.rest-omod-common ${webservices.restVersion} + tests + test diff --git a/api/src/main/java/org/openmrs/module/sync2/api/model/audit/AuditMessageResource2_0.java b/api/src/main/java/org/openmrs/module/sync2/api/model/audit/AuditMessageResource2_0.java new file mode 100644 index 00000000..8ebb7885 --- /dev/null +++ b/api/src/main/java/org/openmrs/module/sync2/api/model/audit/AuditMessageResource2_0.java @@ -0,0 +1,122 @@ +package org.openmrs.module.sync2.api.model.audit; + +import org.openmrs.api.context.Context; +import org.openmrs.module.webservices.rest.web.RequestContext; +import org.openmrs.module.webservices.rest.web.RestConstants; +import org.openmrs.module.webservices.rest.web.annotation.PropertyGetter; +import org.openmrs.module.webservices.rest.web.annotation.Resource; +import org.openmrs.module.webservices.rest.web.representation.DefaultRepresentation; +import org.openmrs.module.webservices.rest.web.representation.FullRepresentation; +import org.openmrs.module.webservices.rest.web.representation.Representation; +import org.openmrs.module.webservices.rest.web.resource.impl.DataDelegatingCrudResource; +import org.openmrs.module.webservices.rest.web.resource.impl.DelegatingResourceDescription; +import org.openmrs.module.webservices.rest.web.response.ResourceDoesNotSupportOperationException; +import org.openmrs.module.webservices.rest.web.response.ResponseException; + + +/** + * {@link Resource} for {@link AuditMessage}, supporting standard CRUD operations + */ +@Resource(name = RestConstants.VERSION_1 + "/auditmessage", supportedClass = AuditMessage.class, supportedOpenmrsVersions = { + "2.0.*", "2.1.*", "2.2.*" }) +public class AuditMessageResource2_0 extends DataDelegatingCrudResource { + + /** + * @see org.openmrs.module.sync2.web.controller.rest.SyncAuditRestController + */ + @Override + public AuditMessage getByUniqueId(String s) { + throw new ResourceDoesNotSupportOperationException(); + } + + /** + * @see org.openmrs.module.sync2.web.controller.rest.SyncAuditRestController + */ + @Override + protected void delete(AuditMessage auditMessage, String s, RequestContext requestContext) throws ResponseException { + throw new ResourceDoesNotSupportOperationException(); + } + + /** + * @see org.openmrs.module.sync2.web.controller.rest.SyncAuditRestController + */ + @Override + public AuditMessage newDelegate() { + throw new ResourceDoesNotSupportOperationException(); + } + + /** + * @see org.openmrs.module.sync2.web.controller.rest.SyncAuditRestController + */ + @Override + public AuditMessage save(AuditMessage auditMessage) { + throw new ResourceDoesNotSupportOperationException(); + } + + /** + * @see org.openmrs.module.sync2.web.controller.rest.SyncAuditRestController + */ + @Override + public void purge(AuditMessage auditMessage, RequestContext requestContext) throws ResponseException { + throw new ResourceDoesNotSupportOperationException(); + } + + @Override + public DelegatingResourceDescription getRepresentationDescription(Representation rep) { + if (rep instanceof DefaultRepresentation) { + DelegatingResourceDescription description = new DelegatingResourceDescription(); + description.addProperty("uuid"); + description.addProperty("display"); + description.addProperty("voided"); + description.addProperty("success"); + description.addProperty("timestamp"); + description.addProperty("resourceName"); + description.addProperty("usedResourceUrl"); + description.addProperty("availableResourceUrls"); + description.addProperty("parentUrl"); + description.addProperty("localUrl"); + description.addProperty("details"); + description.addProperty("action"); + description.addProperty("operation"); + description.addProperty("linkType"); + description.addProperty("nextMessageUuid"); + description.addSelfLink(); + description.addLink("full", ".?v=" + RestConstants.REPRESENTATION_FULL); + return description; + } else if (rep instanceof FullRepresentation) { + DelegatingResourceDescription description = new DelegatingResourceDescription(); + description.addProperty("uuid"); + description.addProperty("display"); + description.addProperty("voided"); + description.addProperty("auditInfo"); + description.addProperty("success"); + description.addProperty("timestamp"); + description.addProperty("resourceName"); + description.addProperty("usedResourceUrl"); + description.addProperty("availableResourceUrls"); + description.addProperty("parentUrl"); + description.addProperty("localUrl"); + description.addProperty("details"); + description.addProperty("action"); + description.addProperty("operation"); + description.addProperty("linkType"); + description.addProperty("nextMessageUuid"); + description.addSelfLink(); + return description; + } + return null; + } + + /** + * @param auditMessage + * @return auditMessage's resourceName and date + */ + @PropertyGetter("display") + public String getDisplayString(AuditMessage auditMessage) { + String ret = auditMessage.getResourceName() == null ? "?" : auditMessage.getResourceName(); + ret += " "; + ret += auditMessage.getTimestamp() == null ? "?" : Context.getDateFormat().format( + auditMessage.getTimestamp()); + return ret; + } +} diff --git a/api/src/main/java/org/openmrs/module/sync2/api/model/enums/CategoryEnum.java b/api/src/main/java/org/openmrs/module/sync2/api/model/enums/CategoryEnum.java new file mode 100644 index 00000000..f95e4a3e --- /dev/null +++ b/api/src/main/java/org/openmrs/module/sync2/api/model/enums/CategoryEnum.java @@ -0,0 +1,94 @@ +package org.openmrs.module.sync2.api.model.enums; + +import org.openmrs.Allergy; +import org.openmrs.Cohort; + +import org.openmrs.DrugOrder; +import org.openmrs.Encounter; +import org.openmrs.Form; +import org.openmrs.Location; +import org.openmrs.Obs; +import org.openmrs.Patient; +import org.openmrs.PatientProgram; +import org.openmrs.Person; +import org.openmrs.Privilege; +import org.openmrs.Program; +import org.openmrs.Provider; +import org.openmrs.Relationship; +import org.openmrs.TestOrder; +import org.openmrs.User; +import org.openmrs.Visit; +import org.openmrs.VisitType; +import org.openmrs.module.fhir.api.util.FHIRConstants; +import org.openmrs.module.sync2.api.model.audit.AuditMessage; + +import java.util.HashMap; +import java.util.Map; + +public enum CategoryEnum { + LOCATION(FHIRConstants.CATEGORY_LOCATION, Location.class), + OBSERVATION(FHIRConstants.CATEGORY_OBSERVATION, Obs.class), + ENCOUNTER(FHIRConstants.CATEGORY_ENCOUNTER, Encounter.class), + VISIT(FHIRConstants.CATEGORY_VISIT, Visit.class), + PROVIDER(FHIRConstants.CATEGORY_PROVIDER, Provider.class), + DRUG_ORDER(FHIRConstants.CATEGORY_DRUG_ORDER, DrugOrder.class), + TEST_ORDER(FHIRConstants.CATEGORY_TEST_ORDER, TestOrder.class), + FORM("form", Form.class), + PATIENT_PROGRAM("patient_program", PatientProgram.class), + PERSON(FHIRConstants.CATEGORY_PERSON, Person.class), + PATIENT(FHIRConstants.CATEGORY_PATIENT, Patient.class), + RELATIONSHIP("relationship", Relationship.class), + COHORT(FHIRConstants.CATEGORY_COHORT, Cohort.class), + VISIT_TYPE("visit_type", VisitType.class), + USER("user", User.class), + PROGRAM("program", Program.class), + PRIVILEGE("privilege", Privilege.class), + AUDIT_MESSAGE("audit_message", AuditMessage.class), + ALLERGY(FHIRConstants.CATEGORY_ALLERGY, Allergy.class); + + private static final Map MAP; + + private final String category; + + private final Class clazz; + + CategoryEnum(String category, Class clazz) { + this.category = category; + this.clazz = clazz; + } + + public String getCategory() { + return category; + } + + public Class getClazz() { + return clazz; + } + + static { + MAP = new HashMap<>(); + MAP.put(LOCATION.getCategory(), LOCATION); + MAP.put(OBSERVATION.getCategory(), OBSERVATION); + MAP.put(ENCOUNTER.getCategory(), ENCOUNTER); + MAP.put(VISIT.getCategory(), VISIT); + MAP.put(PROVIDER.getCategory(), PROVIDER); + MAP.put(DRUG_ORDER.getCategory(), DRUG_ORDER); + MAP.put(TEST_ORDER.getCategory(), TEST_ORDER); + MAP.put(FORM.getCategory(), FORM); + MAP.put(PATIENT_PROGRAM.getCategory(), PATIENT_PROGRAM); + MAP.put(PERSON.getCategory(), PERSON); + MAP.put(PATIENT.getCategory(), PATIENT); + MAP.put(RELATIONSHIP.getCategory(), RELATIONSHIP); + MAP.put(COHORT.getCategory(), COHORT); + MAP.put(VISIT_TYPE.getCategory(), VISIT_TYPE); + MAP.put(USER.getCategory(), USER); + MAP.put(PROGRAM.getCategory(), PROGRAM); + MAP.put(PRIVILEGE.getCategory(), PRIVILEGE); + MAP.put(AUDIT_MESSAGE.getCategory(), AUDIT_MESSAGE); + MAP.put(ALLERGY.getCategory(), ALLERGY); + } + + public static CategoryEnum getByCategory(String category) { + return MAP.get(category); + } +} diff --git a/api/src/main/java/org/openmrs/module/sync2/api/service/UnifyService.java b/api/src/main/java/org/openmrs/module/sync2/api/service/UnifyService.java new file mode 100644 index 00000000..2fb37109 --- /dev/null +++ b/api/src/main/java/org/openmrs/module/sync2/api/service/UnifyService.java @@ -0,0 +1,8 @@ +package org.openmrs.module.sync2.api.service; + +import javax.transaction.NotSupportedException; + +public interface UnifyService { + + Object unifyObject(Object object, String category, String clientName) throws NotSupportedException; +} diff --git a/api/src/main/java/org/openmrs/module/sync2/api/service/impl/UnifyServiceImpl.java b/api/src/main/java/org/openmrs/module/sync2/api/service/impl/UnifyServiceImpl.java new file mode 100644 index 00000000..9f8c093b --- /dev/null +++ b/api/src/main/java/org/openmrs/module/sync2/api/service/impl/UnifyServiceImpl.java @@ -0,0 +1,44 @@ +package org.openmrs.module.sync2.api.service.impl; + +import org.openmrs.module.fhir.api.helper.FHIRClientHelper; +import org.openmrs.module.sync2.SyncConstants; +import org.openmrs.module.sync2.api.model.audit.AuditMessage; +import org.openmrs.module.sync2.api.model.enums.CategoryEnum; +import org.openmrs.module.sync2.api.service.UnifyService; +import org.openmrs.module.webservices.rest.SimpleObject; +import org.openmrs.module.webservices.rest.web.ConversionUtil; +import org.openmrs.module.webservices.rest.web.representation.Representation; +import org.springframework.stereotype.Service; + +import javax.transaction.NotSupportedException; + +@Service("sync2.unifyService") +public class UnifyServiceImpl implements UnifyService { + + @Override + public Object unifyObject(Object object, String category, String clientName) throws NotSupportedException { + Object result = null; + + if (isObjectAlreadyUnified(object)) { + result = object; + } else { + CategoryEnum cat = CategoryEnum.getByCategory(category); + + if (SyncConstants.FHIR_CLIENT.equals(clientName)) { + FHIRClientHelper helper = new FHIRClientHelper(); + result = helper.convertToOpenMrsObject(object, category); + result = ConversionUtil.convertToRepresentation(result, Representation.FULL); + } else if (AuditMessage.class.isAssignableFrom(cat.getClazz())) { + result = ConversionUtil.convertToRepresentation(object, Representation.FULL); + } else { + throw new NotSupportedException(String.format("Category %s not supported.", category)); + } + } + + return result; + } + + private boolean isObjectAlreadyUnified(Object object) { + return object instanceof SimpleObject; + } +} diff --git a/api/src/main/java/org/openmrs/module/sync2/client/rest/RESTClientHelper.java b/api/src/main/java/org/openmrs/module/sync2/client/rest/RESTClientHelper.java index d231157c..eee30d1c 100644 --- a/api/src/main/java/org/openmrs/module/sync2/client/rest/RESTClientHelper.java +++ b/api/src/main/java/org/openmrs/module/sync2/client/rest/RESTClientHelper.java @@ -1,14 +1,19 @@ package org.openmrs.module.sync2.client.rest; +import org.openmrs.Patient; import org.openmrs.api.context.Context; import org.openmrs.module.fhir.api.client.BasicAuthInterceptor; import org.openmrs.module.fhir.api.client.HeaderClientHttpRequestInterceptor; import org.openmrs.module.fhir.api.helper.ClientHelper; import org.openmrs.module.sync2.api.model.audit.AuditMessage; +import org.openmrs.module.sync2.api.model.enums.CategoryEnum; import org.openmrs.module.sync2.client.RestHttpMessageConverter; import org.openmrs.module.sync2.client.SimpleObjectMessageConverter; import org.openmrs.module.sync2.client.rest.resource.RestResource; import org.openmrs.module.webservices.rest.SimpleObject; +import org.openmrs.module.webservices.rest.web.ConversionUtil; +import org.openmrs.module.webservices.rest.web.api.RestService; +import org.openmrs.module.webservices.rest.web.v1_0.resource.openmrs1_9.PatientResource1_9; import org.springframework.http.HttpHeaders; import org.springframework.http.HttpMethod; import org.springframework.http.MediaType; @@ -17,10 +22,12 @@ import org.springframework.http.converter.HttpMessageConverter; import org.springframework.http.converter.StringHttpMessageConverter; +import javax.transaction.NotSupportedException; import java.net.URI; import java.net.URISyntaxException; import java.util.Arrays; import java.util.List; +import java.util.Optional; import static org.openmrs.module.sync2.SyncCategoryConstants.CATEGORY_AUDIT_MESSAGE; @@ -125,6 +132,24 @@ public String convertToFormattedData(Object object) { } } + @Override + public Object convertToOpenMrsObject(Object o, String category) throws NotSupportedException { + Optional opt2 = Optional.ofNullable(CategoryEnum.getByCategory(category)); + CategoryEnum cat = opt2.orElseThrow(() -> getNotSupportedCategory(category)); + + // This case should be removed as soon as + // @see org.openmrs.module.webservices.rest.web.v1_0.resource.openmrs1_8.PatientResource1_8#getPerson() + // will be implemented. + // Please check also PatientResource1_9 or any other @Resource class which supports current platform version. + if (cat.getClazz().equals(Patient.class) && o instanceof SimpleObject) { + PatientResource1_9 resource = (PatientResource1_9 ) Context.getService(RestService.class) + .getResourceBySupportedClass(Patient.class); + return resource.getPatient((SimpleObject) o); + } else { + return ConversionUtil.convert(o, cat.getClazz()); + } + } + private RestResourceConverter getRestResourceConverter() { return Context.getRegisteredComponent("sync2.RestResourceConverter", RestResourceConverter.class); } @@ -140,4 +165,8 @@ private boolean voidedObject(SimpleObject simpleObject) { private String getNotSupportedClassMsg(String className) { return String.format("Class %s is not supported", className); } + + private NotSupportedException getNotSupportedCategory(String category) { + return new NotSupportedException(String.format("Category %s is not supported", category)); + } } diff --git a/pom.xml b/pom.xml index 81517925..935e7d17 100644 --- a/pom.xml +++ b/pom.xml @@ -1,11 +1,12 @@ - + 4.0.0 - - org.openmrs.maven.parents - maven-parent-openmrs-module - 1.1.1 - + + org.openmrs.maven.parents + maven-parent-openmrs-module + 1.1.1 + org.openmrs.module sync2 @@ -31,8 +32,8 @@ scm:git:git@github.com:openmrs/openmrs-module-sync2.git scm:git:git@github.com:openmrs/openmrs-module-sync2.git https://github.com/openmrs/openmrs-module-sync2/ - HEAD - + HEAD + api @@ -196,9 +197,9 @@ - + 1.8 - 2.0.5 + 2.0.5 1.3.1 3.11.0 2.3.0 @@ -209,17 +210,17 @@ 2.23.0-SNAPSHOT - - - openmrs-repo-modules - Modules - http://mavenrepo.openmrs.org/nexus/content/repositories/modules/ - - - openmrs-repo-snapshots - OpenMRS Snapshots - http://mavenrepo.openmrs.org/nexus/content/repositories/snapshots - - + + + openmrs-repo-modules + Modules + http://mavenrepo.openmrs.org/nexus/content/repositories/modules/ + + + openmrs-repo-snapshots + OpenMRS Snapshots + http://mavenrepo.openmrs.org/nexus/content/repositories/snapshots + +