Permalink
Browse files

Merge branch 'master' of github.com:motech/GHANA-National

  • Loading branch information...
2 parents 1607dc4 + 2840774 commit 92f1029961ad1f7b4383be8c040c646fc4f50408 @deepan deepan committed Apr 18, 2012
Showing with 375 additions and 22 deletions.
  1. +2 −1 ghana-national-common/src/main/resources/ghana-national.properties
  2. +1 −0 ghana-national-common/src/main/resources/textMessages.properties
  3. +1 −0 ghana-national-core/src/main/java/org/motechproject/ghana/national/domain/Constants.java
  4. +1 −0 ghana-national-core/src/main/java/org/motechproject/ghana/national/domain/SmsTemplateKeys.java
  5. +31 −0 ...a-national-core/src/main/java/org/motechproject/ghana/national/handler/DefaultMessageHandler.java
  6. +23 −0 ...-core/src/main/java/org/motechproject/ghana/national/handler/FacilitiesDefaultMessageHandler.java
  7. +26 −6 ...ional-core/src/main/java/org/motechproject/ghana/national/repository/AggregationStrategyImpl.java
  8. +13 −6 ghana-national-core/src/main/java/org/motechproject/ghana/national/repository/AllFacilities.java
  9. +4 −0 ghana-national-core/src/main/java/org/motechproject/ghana/national/repository/SMSGateway.java
  10. +35 −0 ...re/src/main/java/org/motechproject/ghana/national/schedule/FacilitiesDefaultMessageScheduler.java
  11. +1 −0 ghana-national-core/src/main/java/org/motechproject/ghana/national/service/FacilityService.java
  12. +45 −0 ...tional-core/src/test/java/org/motechproject/ghana/national/handler/DefaultMessageHandlerTest.java
  13. +48 −0 ...e/src/test/java/org/motechproject/ghana/national/handler/FacilitiesDefaultMessageHandlerTest.java
  14. +64 −6 ...l-core/src/test/java/org/motechproject/ghana/national/repository/AggregationStrategyImplTest.java
  15. +30 −2 ghana-national-core/src/test/java/org/motechproject/ghana/national/repository/AllFacilitiesTest.java
  16. +48 −0 ...rc/test/java/org/motechproject/ghana/national/schedule/FacilitiesDefaultMessageSchedulerTest.java
  17. +2 −1 ghana-national-core/src/test/resources/ghana-national.properties
@@ -2,4 +2,5 @@ omod.identifier.service.host=localhost
omod.identifier.service.port=${OPENMRS_PORT}
omod.identifier.service.path=openmrs/ms/identifier/
omod.user.name=admin
-omod.user.password=P@ssw0rd
+omod.user.password=P@ssw0rd
+facility.default.message.cron=0 0 8 ? * SUN
@@ -12,6 +12,7 @@ CWC_MEASLES_SMS_KEY=${window},${milestoneName},${motechId},${serialNumber},${fir
CWC_PENTA_SMS_KEY=${window},${milestoneName},${motechId},${serialNumber},${firstName},${lastName}
CWC_YF_SMS_KEY=${window},${milestoneName},${motechId},${serialNumber},${firstName},${lastName}
CWC_OPV_SMS_KEY=${window},${milestoneName},${motechId},${serialNumber},${firstName},${lastName}
+FACILITIES_DEFAULT_MESSAGE_KEY=alpha gamma
PREGNANT_CLIENT_QUERY_RESPONSE_SMS_KEY=MotechID=${motechId}, ${firstName} ${lastName}, Sex=${gender}, DoB=${dob}, Age=${age}, ${facility}, PhoneNo=${phoneNumber}, EDD=${date}
NON_PREGNANT_CLIENT_QUERY_RESPONSE_SMS_KEY=MotechID=${motechId}, ${firstName} ${lastName}, Sex=${gender}, DoB=${dob}, Age=${age}, ${facility}, PhoneNo=${phoneNumber}
@@ -90,4 +90,5 @@
public static final Integer CWC_PENTA_MAX_WEEK_FOR_REGISTRATION = 10;
public static final Integer CWC_MEASLES_MAX_AGE_WEEK_FOR_REGISTRATION = 5;
+ public static final String FACILITIES_DEFAULT_MESSAGE_SUBJECT = "org.motechproject.ghana.national.facilities.default";
}
@@ -14,4 +14,5 @@
public static final String CWC_IPTi_VACCINATION_SMS_KEY = "CWC_IPTi_VACCINATION_SMS_KEY";
public static final String PNC_MOTHER_SMS_KEY = "PNC_MOTHER_SMS_KEY";
public static final String PNC_CHILD_SMS_KEY = "PNC_CHILD_SMS_KEY";
+ public static final String FACILITIES_DEFAULT_MESSAGE_KEY = "FACILITIES_DEFAULT_MESSAGE_KEY";
}
@@ -0,0 +1,31 @@
+package org.motechproject.ghana.national.handler;
+
+import org.motechproject.ghana.national.domain.SmsTemplateKeys;
+import org.motechproject.ghana.national.repository.AllFacilities;
+import org.motechproject.ghana.national.repository.SMSGateway;
+import org.motechproject.openmrs.advice.ApiSession;
+import org.motechproject.openmrs.advice.LoginAsAdmin;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+
+import java.util.Set;
+
+@Component
+public class DefaultMessageHandler {
+
+ @Autowired
+ AllFacilities allFacilities;
+
+ @Autowired
+ SMSGateway smsGateway;
+
+ @LoginAsAdmin
+ @ApiSession
+ public void handleDefaultMessagesForFacility() {
+ Set<String> facilityPhoneNumbers = allFacilities.getAllPhoneNumbers();
+ for (String facilityPhoneNumber : facilityPhoneNumbers) {
+ smsGateway.dispatchSMSTextToAggregator(SmsTemplateKeys.FACILITIES_DEFAULT_MESSAGE_KEY,
+ facilityPhoneNumber, facilityPhoneNumber);
+ }
+ }
+}
@@ -0,0 +1,23 @@
+package org.motechproject.ghana.national.handler;
+
+import org.motechproject.ghana.national.domain.Constants;
+import org.motechproject.model.MotechEvent;
+import org.motechproject.server.event.annotations.MotechListener;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+
+/**
+ * Handles the message triggered by weekly cron job for sending 'DEFAULT' SMS to all facilities to aggregate
+ */
+@Component
+public class FacilitiesDefaultMessageHandler {
+
+ @Autowired
+ private DefaultMessageHandler messageHandler;
+
+
+ @MotechListener(subjects = {Constants.FACILITIES_DEFAULT_MESSAGE_SUBJECT})
+ public void handleAlert(MotechEvent motechEvent) {
+ messageHandler.handleDefaultMessagesForFacility();
+ }
+}
@@ -1,30 +1,50 @@
package org.motechproject.ghana.national.repository;
import ch.lambdaj.group.Group;
+import org.motechproject.cmslite.api.model.ContentNotFoundException;
+import org.motechproject.cmslite.api.model.StringContent;
+import org.motechproject.cmslite.api.service.CMSLiteService;
+import org.motechproject.ghana.national.domain.SmsTemplateKeys;
import org.motechproject.ghana.national.messagegateway.domain.AggregationStrategy;
import org.motechproject.ghana.national.messagegateway.domain.SMS;
import org.motechproject.ghana.national.messagegateway.domain.SMSDatum;
import org.motechproject.ghana.national.tools.Utility;
import org.motechproject.util.DateUtil;
+import org.springframework.beans.factory.annotation.Autowired;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Comparator;
-import java.util.List;
+import java.util.*;
import static ch.lambdaj.Lambda.*;
import static ch.lambdaj.group.Groups.by;
import static ch.lambdaj.group.Groups.group;
+import static org.hamcrest.Matchers.equalTo;
+import static org.hamcrest.core.IsNot.not;
public class AggregationStrategyImpl implements AggregationStrategy {
public static final String SMS_SEPARATOR = "%0A";
+ @Autowired
+ private CMSLiteService cmsLiteService;
+
@Override
public List<SMS> aggregate(List<SMS> smsMessages) {
+ try {
+ StringContent defaultMessage = cmsLiteService.getStringContent(Locale.getDefault().getLanguage(), SmsTemplateKeys.FACILITIES_DEFAULT_MESSAGE_KEY);
+ List<SMS> filteredMessages = filter(having(on(SMS.class).getText(), not(equalTo(defaultMessage.getValue()))), smsMessages);
+ return (filteredMessages.isEmpty()) ?
+ filter(having(on(SMS.class).getText(), equalTo(defaultMessage.getValue())), smsMessages) :
+ aggregateMessages(filteredMessages);
+
+ } catch (ContentNotFoundException e) {
+ e.printStackTrace();
+ return Collections.emptyList();
+ }
+ }
+
+ private List<SMS> aggregateMessages(List<SMS> smsMessages) {
final SMS firstSMS = Utility.nullSafe(smsMessages, 0, null);
final String phoneNumber = firstSMS != null ? firstSMS.getPhoneNumber() : null;
-
ArrayList<SMSDatum> smsData = getSMSData(smsMessages);
Comparator<String> alphabeticalOrder = new Comparator<String>() {
@@ -57,7 +77,7 @@ public int compare(String s, String s1) {
.append(", ").append(datum.getSerialNumber()).append(", ").append(joinFrom(all).getMilestone());
}
}
- messages.add(SMS.fromText(builder.toString(), phoneNumber, DateUtil.now(), null ,null));
+ messages.add(SMS.fromText(builder.toString(), phoneNumber, DateUtil.now(), null, null));
}
return messages;
}
@@ -15,13 +15,11 @@
import org.springframework.stereotype.Repository;
import java.util.ArrayList;
+import java.util.HashSet;
import java.util.List;
+import java.util.Set;
-import static ch.lambdaj.Lambda.convert;
-import static ch.lambdaj.Lambda.extract;
-import static ch.lambdaj.Lambda.having;
-import static ch.lambdaj.Lambda.on;
-import static ch.lambdaj.Lambda.selectUnique;
+import static ch.lambdaj.Lambda.*;
import static org.hamcrest.core.Is.is;
@Repository
@@ -117,7 +115,7 @@ public Facility findByMrsFacilityId(String facilityId) {
@View(name = "find_by_motech_facility_id", map = "function(doc) { if(doc.type === 'Facility') emit(doc.motechId, doc) }")
public Facility findByMotechFacilityId(String facilityId) {
- if(StringUtils.isEmpty(facilityId)) {
+ if (StringUtils.isEmpty(facilityId)) {
return null;
}
ViewQuery viewQuery = createQuery("find_by_motech_facility_id").key(facilityId).includeDocs(true);
@@ -129,4 +127,13 @@ public Facility getFacilityByMotechId(String motechFacilityId) {
Facility facility = findByMotechFacilityId(motechFacilityId);
return (facility != null) ? facility.mrsFacility(facilityAdapter.getFacility(facility.mrsFacilityId())) : null;
}
+
+ public Set<String> getAllPhoneNumbers() {
+ List<Facility> facilities = facilities();
+ Set<String> phoneNumbers = new HashSet<String>();
+ for (Facility facility : facilities) {
+ phoneNumbers.addAll(facility.getPhoneNumbers());
+ }
+ return phoneNumbers;
+ }
}
@@ -44,6 +44,10 @@ public void dispatchSMSToAggregator(String templateKey, Map<String, String> temp
messageGateway.dispatch(SMS.fromTemplate(getSMSTemplate(templateKey), templateValues, phoneNumber, DateUtil.now(), new NextMondayDispatcher(), new SMSTextComparator<String>()), identifier);
}
+ public void dispatchSMSTextToAggregator(String templateKey, String phoneNumber, String identifier) {
+ messageGateway.dispatch(SMS.fromText(getSMSTemplate(templateKey), phoneNumber, DateUtil.now(), new NextMondayDispatcher(), new SMSTextComparator<String>()), identifier);
+ }
+
public void dispatchSMS(String templateKey, Map<String, String> templateValues, String phoneNumber) {
smsService.sendSMS(phoneNumber, SMS.fill(getSMSTemplate(templateKey), templateValues));
}
@@ -0,0 +1,35 @@
+package org.motechproject.ghana.national.schedule;
+
+import org.motechproject.ghana.national.domain.Constants;
+import org.motechproject.model.CronSchedulableJob;
+import org.motechproject.model.MotechEvent;
+import org.motechproject.scheduler.MotechSchedulerService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.stereotype.Component;
+
+import javax.annotation.PostConstruct;
+import java.util.HashMap;
+
+/**
+ *
+ */
+@Component
+public class FacilitiesDefaultMessageScheduler {
+
+ @Autowired
+ MotechSchedulerService schedulerService;
+
+ @Value("#{ghanaNationalProperties['facility.default.message.cron']}")
+ private String defaultMessageCronExpression;
+ static String JOB_ID_KEY = "default-facility-message";
+
+ @PostConstruct
+ public void init() {
+ MotechEvent motechEvent = new MotechEvent(Constants.FACILITIES_DEFAULT_MESSAGE_SUBJECT, new HashMap<String, Object>() {{
+ put(MotechSchedulerService.JOB_ID_KEY, JOB_ID_KEY);
+ }});
+ CronSchedulableJob cronSchedulableJob = new CronSchedulableJob(motechEvent, defaultMessageCronExpression);
+ schedulerService.scheduleJob(cronSchedulableJob);
+ }
+}
@@ -14,6 +14,7 @@
import org.springframework.stereotype.Service;
import java.util.List;
+import java.util.Set;
import static ch.lambdaj.Lambda.filter;
import static ch.lambdaj.Lambda.having;
@@ -0,0 +1,45 @@
+package org.motechproject.ghana.national.handler;
+
+import org.junit.Test;
+import org.mockito.InjectMocks;
+import org.mockito.Mock;
+import org.motechproject.ghana.national.domain.SmsTemplateKeys;
+import org.motechproject.ghana.national.repository.AllFacilities;
+import org.motechproject.ghana.national.repository.SMSGateway;
+
+import java.util.HashSet;
+
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+import static org.mockito.MockitoAnnotations.initMocks;
+
+public class DefaultMessageHandlerTest {
+
+ @Mock
+ AllFacilities mockAllFacilities;
+
+ @Mock
+ SMSGateway mockSmsGateway;
+
+ @InjectMocks
+ DefaultMessageHandler handler = new DefaultMessageHandler();
+
+ @Test
+ public void shouldSendDefaultMessageToAllFacilitiesOnTrigger() {
+ initMocks(this);
+ final String phone1 = "phone1";
+ final String phone2 = "phone2";
+
+ when(mockAllFacilities.getAllPhoneNumbers()).thenReturn(new HashSet<String>() {{
+ add(phone1);
+ add(phone2);
+ }});
+ handler.handleDefaultMessagesForFacility();
+
+ verify(mockAllFacilities).getAllPhoneNumbers();
+ verify(mockSmsGateway).dispatchSMSTextToAggregator(SmsTemplateKeys.FACILITIES_DEFAULT_MESSAGE_KEY,
+ phone1, phone1);
+ verify(mockSmsGateway).dispatchSMSTextToAggregator(SmsTemplateKeys.FACILITIES_DEFAULT_MESSAGE_KEY,
+ phone2, phone2);
+ }
+}
@@ -0,0 +1,48 @@
+package org.motechproject.ghana.national.handler;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.mockito.InjectMocks;
+import org.mockito.Mock;
+import org.motechproject.ghana.national.domain.Constants;
+import org.motechproject.model.MotechEvent;
+import org.motechproject.server.event.annotations.MotechListener;
+
+import java.lang.annotation.Annotation;
+import java.lang.reflect.Method;
+
+import static junit.framework.Assert.assertEquals;
+import static junit.framework.Assert.assertTrue;
+import static org.hamcrest.Matchers.is;
+import static org.junit.Assert.assertThat;
+import static org.mockito.Mockito.verify;
+import static org.mockito.MockitoAnnotations.initMocks;
+
+public class FacilitiesDefaultMessageHandlerTest {
+
+ @Mock
+ DefaultMessageHandler defaultMessageHandler;
+
+ @InjectMocks
+ FacilitiesDefaultMessageHandler handler = new FacilitiesDefaultMessageHandler();
+
+ @Before
+ public void setUp() {
+ initMocks(this);
+ }
+
+ @Test
+ public void shouldListenToFacilityDefaultMessageSubject() throws NoSuchMethodException {
+ Method handleAlertMethod = handler.getClass().getMethod("handleAlert", MotechEvent.class);
+ Annotation[] annotations = handleAlertMethod.getDeclaredAnnotations();
+ assertEquals(1, annotations.length);
+ assertTrue(annotations[0] instanceof MotechListener);
+ assertThat(((MotechListener) annotations[0]).subjects(), is(new String[]{Constants.FACILITIES_DEFAULT_MESSAGE_SUBJECT}));
+ }
+
+ @Test
+ public void shouldHandleDefaultMessageDispatch(){
+ handler.handleAlert(null);
+ verify(defaultMessageHandler).handleDefaultMessagesForFacility();
+ }
+}
Oops, something went wrong. Retry.

0 comments on commit 92f1029

Please sign in to comment.