Skip to content

Commit

Permalink
[Ritesh] [BAH-3191] Fix issue occured during openmrs version upgrade (#…
Browse files Browse the repository at this point in the history
…12)

* [ Ritesh ] | BAH-3086 - Segregate bahmni patient create and update events and Adding meta info of publishing openmrs object in event header.

* [ Ritesh ] | BAH-3086 - Changes as per review comments

* [ Ritesh ] | BAH-3086 - Replaces Header keys with Enum

* [ Ritesh ] | BAH-3086 - Minor fix

* [ Ritesh ] | BAH-3086 - Added non-null check in JMSMessageCreatorTest

* Added workflow dispatch for publishing omod

* [ Ritesh ] | BAH-3191 - Fix issue of publishing event after openmrs base image change to 2.5.12.

* [ Ritesh ] | BAH-3191 - PR Feedback incorporated.

* [ Ritesh ] | BAH-3191 - PR Feedback incorporated for test

---------

Co-authored-by: Kavitha S <[email protected]>
Co-authored-by: kavitha-sundararajan <[email protected]>
  • Loading branch information
3 people authored Sep 4, 2023
1 parent a67910b commit 8b30205
Show file tree
Hide file tree
Showing 16 changed files with 457 additions and 304 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package org.bahmni.module.events.api.configuration;

import org.bahmni.module.events.api.publisher.BahmniEventPublisher;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class BahmniEventPublisherConfiguration {

@Bean
public BahmniEventPublisher bahmniEventPublisher() {
return new BahmniEventPublisher();
}
}

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
package org.bahmni.module.events.api.configuration;

import com.fasterxml.jackson.databind.ObjectMapper;
import org.bahmni.module.events.api.publisher.JMSEventPublisher;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Conditional;
import org.springframework.context.annotation.Configuration;
import org.springframework.jms.core.JmsTemplate;
import org.springframework.jms.support.destination.DynamicDestinationResolver;
import org.springframework.jndi.JndiObjectFactoryBean;

import javax.jms.ConnectionFactory;

@Conditional(JMSEventPublishingToggleCondition.class)
@Configuration
public class JMSEventPublisherConfiguration {

@Bean
public JndiObjectFactoryBean eventJndiObjectFactoryBean() {
JndiObjectFactoryBean jndiObjectFactoryBean = new JndiObjectFactoryBean();

String jndiJMSResourceName = "jmsConnectionFactory";
jndiObjectFactoryBean.setJndiName("java:comp/env/" + jndiJMSResourceName);
jndiObjectFactoryBean.setProxyInterface(ConnectionFactory.class);
jndiObjectFactoryBean.setLookupOnStartup(true);

return jndiObjectFactoryBean;
}

@Bean
public DynamicDestinationResolver eventDestinationResolver() {
return new DynamicDestinationResolver();
}

@Bean
public JmsTemplate jmsTemplate(JndiObjectFactoryBean eventJndiObjectFactoryBean, DynamicDestinationResolver eventDestinationResolver) {
JmsTemplate jmsTemplate = new JmsTemplate();
jmsTemplate.setConnectionFactory((ConnectionFactory) eventJndiObjectFactoryBean.getObject());
jmsTemplate.setDestinationResolver(eventDestinationResolver);
jmsTemplate.setPubSubDomain(true);
return jmsTemplate;
}

@Bean
public JMSEventPublisher jmsEventPublisher(JmsTemplate jmsTemplate) {
return new JMSEventPublisher(jmsTemplate, new ObjectMapper());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
import org.springframework.stereotype.Component;

@Component
public class EventPublishingToggleCondition implements Condition {
public class JMSEventPublishingToggleCondition implements Condition {

@Override
public boolean matches(ConditionContext conditionContext, AnnotatedTypeMetadata annotatedTypeMetadata) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,62 +1,66 @@
package org.bahmni.module.events.api.listener;

import com.google.common.collect.Sets;
import org.bahmni.module.events.api.model.BahmniEventType;
import org.bahmni.module.events.api.model.Event;
import org.bahmni.module.events.api.publisher.BahmniEventPublisher;
import org.openmrs.api.context.Context;
import org.openmrs.module.appointments.model.Appointment;
import org.openmrs.module.appointments.web.mapper.AppointmentMapper;
import org.springframework.aop.AfterReturningAdvice;
import org.springframework.aop.MethodBeforeAdvice;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.context.ApplicationEventPublisherAware;
import org.springframework.lang.NonNull;

import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
import java.util.function.Supplier;

import static org.bahmni.module.events.api.model.BahmniEventType.*;
import static org.bahmni.module.events.api.model.BahmniEventType.BAHMNI_APPOINTMENT_CREATED;
import static org.bahmni.module.events.api.model.BahmniEventType.BAHMNI_APPOINTMENT_UPDATED;

public class AppointmentAdvice implements AfterReturningAdvice, ApplicationEventPublisherAware, MethodBeforeAdvice {

private ApplicationEventPublisher eventPublisher;
public class AppointmentAdvice implements AfterReturningAdvice, MethodBeforeAdvice {

private final BahmniEventPublisher eventPublisher;
private final ThreadLocal<Map<String,Integer>> threadLocal = new ThreadLocal<>();
private final String APPOINTMENT_ID_KEY = "appointmentId";
private final AppointmentMapper appointmentMapper;
private final Set<String> adviceMethodNames = Sets.newHashSet("validateAndSave");

private final ApplicationContext applicationContext;
public AppointmentAdvice() {
this.eventPublisher = Context.getRegisteredComponent("bahmniEventPublisher", BahmniEventPublisher.class);
this.appointmentMapper = Context.getRegisteredComponent("appointmentMapper", AppointmentMapper.class);
}

public AppointmentAdvice(ApplicationContext applicationContext) {
this.applicationContext = applicationContext;
public AppointmentAdvice(BahmniEventPublisher bahmniEventPublisher, AppointmentMapper appointmentMapper) {
this.eventPublisher = bahmniEventPublisher;
this.appointmentMapper = appointmentMapper;
}

@Override
public void afterReturning(Object returnValue, Method method, Object[] arguments, Object target) {
Map<String, Integer> appointmentInfo = threadLocal.get();
// TODO: This is a workaround to avoid publishing duplicate events because currently the event is getting called twice. Need to find out the reason and resolve it.
if (appointmentInfo != null) {
BahmniEventType eventType = appointmentInfo.get(APPOINTMENT_ID_KEY) == null ? BAHMNI_APPOINTMENT_CREATED : BAHMNI_APPOINTMENT_UPDATED;
threadLocal.remove();
Appointment appointment = (Appointment) returnValue;
AppointmentMapper appointmentMapper = applicationContext.getBean(AppointmentMapper.class);
Object representation = appointmentMapper.constructResponse(appointment);
Event event = new Event(eventType, representation, appointment.getUuid());
eventPublisher.publishEvent(event);
System.out.println("Successfully published event with uuid : " + appointment.getUuid());
if (adviceMethodNames.contains(method.getName())) {
Map<String, Integer> appointmentInfo = threadLocal.get();
// TODO: This is a workaround to avoid publishing duplicate events because currently the event is getting called twice. Need to find out the reason and resolve it.
if (appointmentInfo != null) {
BahmniEventType eventType = appointmentInfo.get(APPOINTMENT_ID_KEY) == null ? BAHMNI_APPOINTMENT_CREATED : BAHMNI_APPOINTMENT_UPDATED;
threadLocal.remove();
Appointment appointment = (Appointment) returnValue;
Object representation = appointmentMapper.constructResponse(appointment);
Event event = new Event(eventType, representation, appointment.getUuid());
eventPublisher.publishEvent(event);
System.out.println("Successfully published event with uuid : " + appointment.getUuid());
}
}
}

@Override
public void setApplicationEventPublisher(@NonNull ApplicationEventPublisher applicationEventPublisher) {
this.eventPublisher = applicationEventPublisher;
}

@Override
public void before(Method method, Object[] objects, Object o) {
Appointment appointment = ((Supplier<Appointment>) objects[0]).get();
Map<String, Integer> appointmentInfo = new HashMap<>(1);
appointmentInfo.put(APPOINTMENT_ID_KEY, appointment.getId());
threadLocal.set(appointmentInfo);
if (adviceMethodNames.contains(method.getName())) {
Appointment appointment = ((Supplier<Appointment>) objects[0]).get();
Map<String, Integer> appointmentInfo = new HashMap<>(1);
appointmentInfo.put(APPOINTMENT_ID_KEY, appointment.getId());
threadLocal.set(appointmentInfo);
}
}
}
Original file line number Diff line number Diff line change
@@ -1,10 +1,14 @@
package org.bahmni.module.events.api.listener;

import com.google.common.collect.Sets;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.bahmni.module.events.api.model.BahmniEventType;
import org.bahmni.module.events.api.model.Event;
import org.bahmni.module.events.api.publisher.BahmniEventPublisher;
import org.openmrs.Encounter;
import org.openmrs.api.context.Context;
import org.openmrs.module.appointments.web.mapper.AppointmentMapper;
import org.openmrs.module.webservices.rest.web.ConversionUtil;
import org.openmrs.module.webservices.rest.web.representation.Representation;
import org.springframework.aop.AfterReturningAdvice;
Expand All @@ -16,46 +20,53 @@
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;

import static org.bahmni.module.events.api.model.BahmniEventType.*;

public class EncounterAdvice implements AfterReturningAdvice, ApplicationEventPublisherAware, MethodBeforeAdvice {
public class EncounterAdvice implements AfterReturningAdvice, MethodBeforeAdvice {

private final Logger log = LogManager.getLogger(EncounterAdvice.class);

private ApplicationEventPublisher eventPublisher;

private final BahmniEventPublisher eventPublisher;
private final ThreadLocal<Map<String,Integer>> threadLocal = new ThreadLocal<>();
private final String ENCOUNTER_ID_KEY = "encounterId";
private final Set<String> adviceMethodNames = Sets.newHashSet("saveEncounter");

public EncounterAdvice() {
this.eventPublisher = Context.getRegisteredComponent("bahmniEventPublisher", BahmniEventPublisher.class);
}

@Override
public void afterReturning(Object returnValue, Method method, Object[] arguments, Object target) {
Map<String, Integer> encounterInfo = threadLocal.get();
// TODO: This is a workaround to avoid publishing duplicate events because currently the event is getting called twice. Need to find out the reason and resolve it.
if (encounterInfo != null) {
BahmniEventType eventType = encounterInfo.get(ENCOUNTER_ID_KEY) == null ? BAHMNI_ENCOUNTER_CREATED : BAHMNI_ENCOUNTER_UPDATED;
threadLocal.remove();
Encounter encounter = (Encounter) returnValue;

Object representation = ConversionUtil.convertToRepresentation(encounter, Representation.FULL);
Event event = new Event(eventType, representation, encounter.getUuid());
eventPublisher.publishEvent(event);

System.out.println("Successfully published event with uuid : " + encounter.getUuid());
}
public EncounterAdvice(BahmniEventPublisher bahmniEventPublisher) {
this.eventPublisher = bahmniEventPublisher;
}

@Override
public void setApplicationEventPublisher(@NonNull ApplicationEventPublisher applicationEventPublisher) {
this.eventPublisher = applicationEventPublisher;
public void afterReturning(Object returnValue, Method method, Object[] arguments, Object target) {
if (adviceMethodNames.contains(method.getName())) {
Map<String, Integer> encounterInfo = threadLocal.get();
// TODO: This is a workaround to avoid publishing duplicate events because currently the event is getting called twice. Need to find out the reason and resolve it.
if (encounterInfo != null) {
BahmniEventType eventType = encounterInfo.get(ENCOUNTER_ID_KEY) == null ? BAHMNI_ENCOUNTER_CREATED : BAHMNI_ENCOUNTER_UPDATED;
threadLocal.remove();
Encounter encounter = (Encounter) returnValue;

Object representation = ConversionUtil.convertToRepresentation(encounter, Representation.FULL);
Event event = new Event(eventType, representation, encounter.getUuid());
eventPublisher.publishEvent(event);

System.out.println("Successfully published event with uuid : " + encounter.getUuid());
}
}
}

@Override
public void before(Method method, Object[] objects, Object o) {
Encounter encounter = (Encounter) objects[0];
Map<String, Integer> encounterInfo = new HashMap<>(1);
encounterInfo.put(ENCOUNTER_ID_KEY, encounter.getId());
threadLocal.set(encounterInfo);
if (adviceMethodNames.contains(method.getName())) {
Encounter encounter = (Encounter) objects[0];
Map<String, Integer> encounterInfo = new HashMap<>(1);
encounterInfo.put(ENCOUNTER_ID_KEY, encounter.getId());
threadLocal.set(encounterInfo);
}
}
}
Loading

0 comments on commit 8b30205

Please sign in to comment.