I need to implement after AOP advice to void module entities like Lab Tests when ever OpenMRS Order entity is voided. (Our module entity Lab Test has a one to one mapping to OpenMRS Orders entity.) In OpenMRS, whenever an encounter is voided, its all linked Orders are also voided and this will eventually trigger voidOrder(…) method. Therefore, I’m implementing After advice on “voidOrder” method. And this does not work.
<!-- APO Support -->
<advice>
<point>org.openmrs.api.OrderService</point>
<class>org.openmrs.module.commonlabtest.aop.AfterOrderVoidAdvice</class>
</advice>
I have written advice as below by implementing AfterReturningAdvice.
public class AfterOrderVoidAdvice implements AfterReturningAdvice {
private Log log = LogFactory.getLog(this.getClass());
/*
* (non-Javadoc) * @see
* org.springframework.aop.AfterReturningAdvice#afterReturning(java.lang.Object,
* java.lang.reflect.Method, java.lang.Object[], java.lang.Object)
*
* depends on org.openmrs.api.impl.OrderServiceImpl
*/
@Override
public void afterReturning(Object returnValue, Method method, Object[] args, Object target) throws Throwable {
log.info("======== in After Advice " + method.getName() + "========");
if (method.getName().equalsIgnoreCase("voidOrder")) {
log.info("<<<<<<< Method: " + method.getName() + ". After advice called. >>>>>>>>");
if (returnValue != null)
log.info(returnValue.toString());
}
}
When I replace the point with EncounterService, it works but setting point to OrderService does not invoke advice.
Can anyone please suggest how to solve this problem?
Can you make sure that the encounters have unvoided orders while your are pointing to OrderService? OrderService.voidOrder() will be called if there are any unvoided orders for encounter - See here
@dkayiwa@darius@wyclif Please help me resolve this issue. Its quite weird that the same advice works for Encounter Service (method name: saveEncounter) but not for OrderService (method name: voidOrder)?
I’m actually unable to debug module api, I have set the configuration settings as localhost and port 1045 which I specified while setting up OpenMRS SDK server.
@dkayiwa I have verified that it never executes the line which @suthagar23 had pointed earlier.
Now, my question at this point is how does Encounter object holds orders that have already voided properties set to true? Is there an AOP implemented? @dkayiwa can you please explain why it has all linked orders already voided?
I have also tried to set the advice to saveEncounter method, and then checking the orders on returned Encounter object that if they are voided or not. But in this scenario, the sequence is a problem. If I void encounter, it first fetches the already voided orders and then executes the advice which is obviously something which is not required.
@Override
public void afterReturning(Object returnValue, Method method, Object[] args, Object target) throws Throwable {
log.info("======== in After Advice " + method.getName() + "========");
if (method.getName().equalsIgnoreCase("saveEncounter")) {
if (returnValue != null) {
Encounter encounter = (Encounter) returnValue;
Set<Order> orders = (Set<Order>) encounter.getOrders();
for (Order o : orders) {
if (!o.isVoided())
log.info(" ==== > Order # " + o.getOrderId() + " is voided.");
// void corresponding LabTest entity that has one to one mapping to this Order
}
}
}
}
My problem is solved. I have implemented Advice on voidEncounter and unvoidEncounter methods. I am catching the returned encounter and fetching its orders and I’m then able to void/unvoid Lab Test objects that are mapped to those OpenMRS Order objects.