From d28246b42d35d99f2a4c35e6b8d9e7e784c2b54d Mon Sep 17 00:00:00 2001 From: Maimoona Kausar Date: Wed, 11 May 2016 15:54:15 +0500 Subject: [PATCH 1/2] MK: Fixed failing test cases; Added ssh support; --- opensrp-connector/pom.xml | 10 ++ .../java/org/opensrp/connector/HttpUtil.java | 70 +++++++++++- .../connector/SecureSocketFactory.java | 75 +++++++++++++ .../scheduler/FormEventListenerTest.java | 9 +- opensrp-web/doc/schedules/child-measles.html | 8 +- .../doc/schedules/child-pentavalent-2.html | 6 +- .../doc/schedules/child-pentavalent-3.html | 6 +- .../integration/ChildImmunizationFields.java | 4 +- .../it/DrishtiSchedulesIntegrationTest.java | 24 ++-- .../web/rest/it/ProviderResourceTest.java | 5 +- .../test/resources/schedules/child-bcg.json | 29 +++++ .../resources/schedules/child-boosters.json | 23 ++++ .../schedules/child-dpt-booster1.json | 35 ++++++ .../schedules/child-dpt-booster2.json | 22 ++++ .../schedules/child-measles-booster.json | 35 ++++++ .../resources/schedules/child-measles.json | 35 ++++++ .../schedules/child-opv-0-and-1.json | 51 +++++++++ .../test/resources/schedules/child-opv-2.json | 35 ++++++ .../test/resources/schedules/child-opv-3.json | 35 ++++++ .../schedules/child-opv-booster.json | 29 +++++ .../schedules/child-pentavalent-1.json | 35 ++++++ .../schedules/child-pentavalent-2.json | 35 ++++++ .../schedules/child-pentavalent-3.json | 35 ++++++ .../resources/schedules/delivery-plan.json | 35 ++++++ .../resources/schedules/ec-condom-refill.json | 29 +++++ .../schedules/ec-dmpa-injectable-refill.json | 35 ++++++ .../ec-female-sterilization-followup.json | 75 +++++++++++++ .../resources/schedules/ec-fp-followup.json | 35 ++++++ .../schedules/ec-fp-referral-followup.json | 35 ++++++ .../resources/schedules/ec-iud-followup.json | 58 ++++++++++ .../ec-male-sterilization-followup.json | 52 +++++++++ .../resources/schedules/ec-ocp-refill.json | 29 +++++ .../schedules/mother-anc-normal.json | 104 ++++++++++++++++++ .../schedules/mother-auto-close-pnc.json | 20 ++++ .../mother-expected-date-of-delivery.json | 35 ++++++ .../schedules/mother-hb-followup-test.json | 35 ++++++ .../resources/schedules/mother-hb-test-1.json | 29 +++++ .../resources/schedules/mother-hb-test-2.json | 29 +++++ .../resources/schedules/mother-ifa-1.json | 35 ++++++ .../resources/schedules/mother-ifa-2.json | 35 ++++++ .../resources/schedules/mother-ifa-3.json | 35 ++++++ .../schedules/mother-lab-reminder.json | 29 +++++ .../test/resources/schedules/mother-tt-1.json | 29 +++++ .../test/resources/schedules/mother-tt-2.json | 35 ++++++ 44 files changed, 1451 insertions(+), 33 deletions(-) create mode 100644 opensrp-connector/src/main/java/org/opensrp/connector/SecureSocketFactory.java create mode 100644 opensrp-web/src/test/resources/schedules/child-bcg.json create mode 100644 opensrp-web/src/test/resources/schedules/child-boosters.json create mode 100644 opensrp-web/src/test/resources/schedules/child-dpt-booster1.json create mode 100644 opensrp-web/src/test/resources/schedules/child-dpt-booster2.json create mode 100644 opensrp-web/src/test/resources/schedules/child-measles-booster.json create mode 100644 opensrp-web/src/test/resources/schedules/child-measles.json create mode 100644 opensrp-web/src/test/resources/schedules/child-opv-0-and-1.json create mode 100644 opensrp-web/src/test/resources/schedules/child-opv-2.json create mode 100644 opensrp-web/src/test/resources/schedules/child-opv-3.json create mode 100644 opensrp-web/src/test/resources/schedules/child-opv-booster.json create mode 100644 opensrp-web/src/test/resources/schedules/child-pentavalent-1.json create mode 100644 opensrp-web/src/test/resources/schedules/child-pentavalent-2.json create mode 100644 opensrp-web/src/test/resources/schedules/child-pentavalent-3.json create mode 100644 opensrp-web/src/test/resources/schedules/delivery-plan.json create mode 100644 opensrp-web/src/test/resources/schedules/ec-condom-refill.json create mode 100644 opensrp-web/src/test/resources/schedules/ec-dmpa-injectable-refill.json create mode 100644 opensrp-web/src/test/resources/schedules/ec-female-sterilization-followup.json create mode 100644 opensrp-web/src/test/resources/schedules/ec-fp-followup.json create mode 100644 opensrp-web/src/test/resources/schedules/ec-fp-referral-followup.json create mode 100644 opensrp-web/src/test/resources/schedules/ec-iud-followup.json create mode 100644 opensrp-web/src/test/resources/schedules/ec-male-sterilization-followup.json create mode 100644 opensrp-web/src/test/resources/schedules/ec-ocp-refill.json create mode 100644 opensrp-web/src/test/resources/schedules/mother-anc-normal.json create mode 100644 opensrp-web/src/test/resources/schedules/mother-auto-close-pnc.json create mode 100644 opensrp-web/src/test/resources/schedules/mother-expected-date-of-delivery.json create mode 100644 opensrp-web/src/test/resources/schedules/mother-hb-followup-test.json create mode 100644 opensrp-web/src/test/resources/schedules/mother-hb-test-1.json create mode 100644 opensrp-web/src/test/resources/schedules/mother-hb-test-2.json create mode 100644 opensrp-web/src/test/resources/schedules/mother-ifa-1.json create mode 100644 opensrp-web/src/test/resources/schedules/mother-ifa-2.json create mode 100644 opensrp-web/src/test/resources/schedules/mother-ifa-3.json create mode 100644 opensrp-web/src/test/resources/schedules/mother-lab-reminder.json create mode 100644 opensrp-web/src/test/resources/schedules/mother-tt-1.json create mode 100644 opensrp-web/src/test/resources/schedules/mother-tt-2.json diff --git a/opensrp-connector/pom.xml b/opensrp-connector/pom.xml index bc38e8b384..02c9212004 100644 --- a/opensrp-connector/pom.xml +++ b/opensrp-connector/pom.xml @@ -190,6 +190,16 @@ atomfeed-client 1.9.1 + + org.bouncycastle + bcprov-jdk15on + 1.54 + + + org.bouncycastle + bcprov-ext-jdk15on + 1.54 + diff --git a/opensrp-connector/src/main/java/org/opensrp/connector/HttpUtil.java b/opensrp-connector/src/main/java/org/opensrp/connector/HttpUtil.java index c078618e79..bd13bb00a1 100644 --- a/opensrp-connector/src/main/java/org/opensrp/connector/HttpUtil.java +++ b/opensrp-connector/src/main/java/org/opensrp/connector/HttpUtil.java @@ -7,10 +7,25 @@ import java.io.PrintWriter; import java.net.HttpURLConnection; import java.net.URL; +import java.net.URLConnection; +import java.security.KeyManagementException; +import java.security.NoSuchAlgorithmException; +import java.security.Security; +import java.security.cert.CertificateException; +import java.security.cert.X509Certificate; + +import javax.net.ssl.HostnameVerifier; +import javax.net.ssl.HttpsURLConnection; +import javax.net.ssl.SSLContext; +import javax.net.ssl.SSLSession; +import javax.net.ssl.SSLSocketFactory; +import javax.net.ssl.TrustManager; +import javax.net.ssl.X509TrustManager; import org.apache.commons.codec.binary.Base64; import org.apache.commons.httpclient.HttpStatus; import org.apache.commons.io.IOUtils; +import org.bouncycastle.jce.provider.BouncyCastleProvider; import org.opensrp.common.util.HttpResponse; import org.springframework.http.HttpMethod; import org.springframework.stereotype.Component; @@ -38,7 +53,7 @@ public HttpUtil() { */ public static HttpResponse post(String url, String payload, String data, String username,String password) { try { - HttpURLConnection con = makeConnection(url, payload, HttpMethod.POST, true, username, password); + HttpsURLConnection con = makeConnection(url, payload, HttpMethod.POST, true, username, password); con.setDoOutput(true); con.setRequestProperty("Content-Type", "application/json"); String charset = "utf-8"; @@ -66,7 +81,7 @@ public static HttpResponse post(String url, String payload, String data, String */ public static HttpResponse get(String url, String payload, String username, String password) { try { - HttpURLConnection con = makeConnection(url, payload, HttpMethod.GET, true, username, password); + HttpsURLConnection con = makeConnection(url, payload, HttpMethod.GET, true, username, password); System.out.println(url); HttpResponse resp = new HttpResponse(con.getResponseCode() == HttpStatus.SC_OK, IOUtils.toString(con.getInputStream())); System.out.println(resp); @@ -83,7 +98,7 @@ public static HttpResponse get(String url, String payload, String username, Stri } } - static HttpURLConnection makeConnection(String url, String payload, HttpMethod requestMethod, boolean useBasicAuth, String username, String password) throws IOException { + static HttpsURLConnection makeConnection(String url, String payload, HttpMethod requestMethod, boolean useBasicAuth, String username, String password) throws IOException { String charset = "UTF-8"; if(url.endsWith("/")){ @@ -91,7 +106,7 @@ static HttpURLConnection makeConnection(String url, String payload, HttpMethod r } url = (url+(StringUtils.isEmptyOrWhitespaceOnly(payload)?"":("?"+payload))).replaceAll(" ", "%20"); URL urlo = new URL(url); - HttpURLConnection conn = (HttpURLConnection) urlo.openConnection(); + HttpsURLConnection conn = (HttpsURLConnection) urlo.openConnection(); conn.setRequestProperty("Accept-Charset", charset); if(useBasicAuth){ @@ -110,4 +125,51 @@ public static String removeEndingSlash(String str){ public static String removeTrailingSlash(String str){ return str.startsWith("/")?str.substring(1):str; } + + static { + disableSslVerification(); + } + + private static void disableSslVerification() { + System.setProperty("disable_bad_sslciphers", "yes"); + System.setProperty("jsse.enableSNIExtension", "false"); + Security.addProvider(new BouncyCastleProvider()); + + try + { + // Create a trust manager that does not validate certificate chains + TrustManager[] trustAllCerts = new TrustManager[] {new X509TrustManager() { + public java.security.cert.X509Certificate[] getAcceptedIssuers() { + return null; + } + @Override + public void checkClientTrusted(X509Certificate[] arg0, String arg1) throws CertificateException { + } + @Override + public void checkServerTrusted(X509Certificate[] arg0, String arg1) throws CertificateException { + } + } + }; + + // Install the all-trusting trust manager + SSLContext sc = SSLContext.getInstance("TLS"); + sc.init(null, trustAllCerts, new java.security.SecureRandom()); + SSLSocketFactory sf = sc.getSocketFactory(); + HttpsURLConnection.setDefaultSSLSocketFactory(new SecureSocketFactory(sf)); + + // Create all-trusting host name verifier + HostnameVerifier allHostsValid = new HostnameVerifier() { + public boolean verify(String hostname, SSLSession session) { + return true; + } + }; + + // Install the all-trusting host verifier + HttpsURLConnection.setDefaultHostnameVerifier(allHostsValid); + } catch (NoSuchAlgorithmException e) { + e.printStackTrace(); + } catch (KeyManagementException e) { + e.printStackTrace(); + } + } } \ No newline at end of file diff --git a/opensrp-connector/src/main/java/org/opensrp/connector/SecureSocketFactory.java b/opensrp-connector/src/main/java/org/opensrp/connector/SecureSocketFactory.java new file mode 100644 index 0000000000..6d23292df1 --- /dev/null +++ b/opensrp-connector/src/main/java/org/opensrp/connector/SecureSocketFactory.java @@ -0,0 +1,75 @@ +package org.opensrp.connector; + +import java.io.IOException; +import java.net.InetAddress; +import java.net.Socket; +import java.net.UnknownHostException; +import java.util.LinkedList; +import java.util.List; + +import javax.net.ssl.SSLSocket; +import javax.net.ssl.SSLSocketFactory; + +public class SecureSocketFactory extends SSLSocketFactory { + + private final SSLSocketFactory delegate; + + public SecureSocketFactory(SSLSocketFactory delegate) { + + this.delegate = delegate; + } + + @Override + public String[] getDefaultCipherSuites() { + + return this.delegate.getDefaultCipherSuites(); + } + + @Override + public String[] getSupportedCipherSuites() { + + return this.delegate.getSupportedCipherSuites(); + } + + @Override + public Socket createSocket(String arg0, int arg1) throws IOException, UnknownHostException { + Socket socket = this.delegate.createSocket(arg0, arg1); + return handleSocket(socket); + } + + private Socket handleSocket(Socket socket){ + List limited = new LinkedList(); + for (String suite : ((SSLSocket) socket).getEnabledCipherSuites()) { + if (!suite.contains("_ECDHE_") && !suite.contains("_DH_") && !suite.contains("_DHE_")) { + limited.add(suite); + } + } + ((SSLSocket) socket).setEnabledCipherSuites(limited.toArray(new String[limited.size()])); + return socket; + } + + @Override + public Socket createSocket(InetAddress arg0, int arg1) throws IOException { + Socket socket = this.delegate.createSocket(arg0, arg1); + return handleSocket(socket); + } + + @Override + public Socket createSocket(Socket arg0, String arg1, int arg2, boolean arg3) throws IOException { + Socket socket = this.delegate.createSocket(arg0, arg1, arg2, arg3); + return handleSocket(socket); + } + + @Override + public Socket createSocket(String arg0, int arg1, InetAddress arg2, int arg3) throws IOException, UnknownHostException { + Socket socket = this.delegate.createSocket(arg0, arg1, arg2, arg3); + return handleSocket(socket); + } + + @Override + public Socket createSocket(InetAddress arg0, int arg1, InetAddress arg2, int arg3) throws IOException { + Socket socket = this.delegate.createSocket(arg0, arg1, arg2, arg3); + return handleSocket(socket); + } + +} \ No newline at end of file diff --git a/opensrp-core/src/test/java/org/opensrp/scheduler/FormEventListenerTest.java b/opensrp-core/src/test/java/org/opensrp/scheduler/FormEventListenerTest.java index d5ec2b8d05..8fa47f8308 100644 --- a/opensrp-core/src/test/java/org/opensrp/scheduler/FormEventListenerTest.java +++ b/opensrp-core/src/test/java/org/opensrp/scheduler/FormEventListenerTest.java @@ -4,11 +4,11 @@ import static org.mockito.Mockito.verify; import static org.mockito.Matchers.*; import static org.mockito.Mockito.*; -import static org.mockito.Mockito.when; import static org.mockito.MockitoAnnotations.initMocks; import static org.opensrp.common.util.EasyMap.mapOf; import java.text.Normalizer.Form; +import java.util.ArrayList; import java.util.Collections; import java.util.List; @@ -21,6 +21,9 @@ import org.opensrp.common.AllConstants.OpenSRPEvent; import org.opensrp.domain.AppStateToken; import org.opensrp.dto.form.FormSubmissionDTO; +import org.opensrp.form.domain.FormData; +import org.opensrp.form.domain.FormField; +import org.opensrp.form.domain.FormInstance; import org.opensrp.form.domain.FormSubmission; import org.opensrp.form.service.FormSubmissionService; import org.opensrp.service.ConfigService; @@ -61,8 +64,8 @@ public void shouldDelegateFormSubmissionToSubmissionService() throws Exception { @Test public void shouldFetchFormSubmissionsFromSubmissionService() throws Exception { - FormSubmission fs1 = new FormSubmission("anm id 1", "instance id 1", "form name", "entity id 1", "1.0", 0L, null), - fs2 = new FormSubmission("anm id 2", "instance id 2", "form name", "entity id 2", "1.0", 0L, null); + FormSubmission fs1 = new FormSubmission("anm id 1", "instance id 1", "form name", "entity id 1", "1.0", 0L, new FormInstance(new FormData("test","def/bindpath", new ArrayList(), null))), + fs2 = new FormSubmission("anm id 2", "instance id 2", "form name", "entity id 2", "1.0", 0L, new FormInstance(new FormData("test","def/bindpath", new ArrayList(), null))); List formSubmissions = asList(fs1,fs2); when(configService.getAppStateTokenByName(Config.FORM_ENTITY_PARSER_LAST_SYNCED_FORM_SUBMISSION)).thenReturn(new AppStateToken("token", 1L, 0)); when(formSubmissionService.getAllSubmissions(1L, null)).thenReturn(formSubmissions); diff --git a/opensrp-web/doc/schedules/child-measles.html b/opensrp-web/doc/schedules/child-measles.html index 548d91f658..999337c624 100644 --- a/opensrp-web/doc/schedules/child-measles.html +++ b/opensrp-web/doc/schedules/child-measles.html @@ -6,10 +6,10 @@ -
Measles Vaccination
\ No newline at end of file +
Measles 1
\ No newline at end of file diff --git a/opensrp-web/doc/schedules/child-pentavalent-2.html b/opensrp-web/doc/schedules/child-pentavalent-2.html index 07bdb06080..fc797abd9c 100644 --- a/opensrp-web/doc/schedules/child-pentavalent-2.html +++ b/opensrp-web/doc/schedules/child-pentavalent-2.html @@ -6,9 +6,9 @@ diff --git a/opensrp-web/doc/schedules/child-pentavalent-3.html b/opensrp-web/doc/schedules/child-pentavalent-3.html index a5c8fdd60b..51f2070d2e 100644 --- a/opensrp-web/doc/schedules/child-pentavalent-3.html +++ b/opensrp-web/doc/schedules/child-pentavalent-3.html @@ -6,9 +6,9 @@ diff --git a/opensrp-web/src/test/java/org/opensrp/integration/ChildImmunizationFields.java b/opensrp-web/src/test/java/org/opensrp/integration/ChildImmunizationFields.java index 69748a37c7..954c5f7d02 100644 --- a/opensrp-web/src/test/java/org/opensrp/integration/ChildImmunizationFields.java +++ b/opensrp-web/src/test/java/org/opensrp/integration/ChildImmunizationFields.java @@ -14,8 +14,8 @@ public class ChildImmunizationFields { public static final String HEPATITIS_0_VALUE = "hepb_0"; - public static final String MEASLES_VALUE = "measles"; - public static final String MEASLES_BOOSTER_VALUE = "measlesbooster"; + public static final String MEASLES_VALUE = "measles1"; + public static final String MEASLES_BOOSTER_VALUE = "measles2"; public static final String OPV_0_VALUE = "opv_0"; public static final String OPV_1_VALUE = "opv_1"; diff --git a/opensrp-web/src/test/java/org/opensrp/web/it/DrishtiSchedulesIntegrationTest.java b/opensrp-web/src/test/java/org/opensrp/web/it/DrishtiSchedulesIntegrationTest.java index d0bd4c7d5b..0ad76a3647 100644 --- a/opensrp-web/src/test/java/org/opensrp/web/it/DrishtiSchedulesIntegrationTest.java +++ b/opensrp-web/src/test/java/org/opensrp/web/it/DrishtiSchedulesIntegrationTest.java @@ -240,10 +240,10 @@ public void shouldProvideAlertForDPTBooster2Vaccination() throws Exception { public void shouldProvideAlertsForPentavalent1() throws Exception { schedule.enrollFor(CHILD_SCHEDULE_PENTAVALENT_1, newDate(2012, JANUARY, 1), new Time(14, 0)); - schedule.assertAlertsStartWith("penta1", earliest, date(1, JANUARY), date(2, JANUARY), date(3, JANUARY), date(4, JANUARY)); - schedule.assertAlertsStartWith("penta1", due, date(12, FEBRUARY), date(13, FEBRUARY), date(14, FEBRUARY), date(15, FEBRUARY)); - schedule.assertAlertsStartWith("penta1", late, date(26, FEBRUARY), date(27, FEBRUARY), date(28, FEBRUARY), date(29, FEBRUARY)); - schedule.assertNoAlerts("penta1", max); + schedule.assertAlertsStartWith("pentavalent_1", earliest, date(1, JANUARY), date(2, JANUARY), date(3, JANUARY), date(4, JANUARY)); + schedule.assertAlertsStartWith("pentavalent_1", due, date(12, FEBRUARY), date(13, FEBRUARY), date(14, FEBRUARY), date(15, FEBRUARY)); + schedule.assertAlertsStartWith("pentavalent_1", late, date(26, FEBRUARY), date(27, FEBRUARY), date(28, FEBRUARY), date(29, FEBRUARY)); + schedule.assertNoAlerts("pentavalent_1", max); visualization.outputTo("child-pentavalent-1.html", 1); } @@ -252,10 +252,10 @@ public void shouldProvideAlertsForPentavalent1() throws Exception { public void shouldProvideAlertsForPentavalent2() throws Exception { schedule.enrollFor(CHILD_SCHEDULE_PENTAVALENT_2, newDate(2012, JANUARY, 1), new Time(14, 0)); - schedule.assertAlertsStartWith("penta2", earliest, date(1, JANUARY), date(2, JANUARY), date(3, JANUARY), date(4, JANUARY)); - schedule.assertAlertsStartWith("penta2", due, date(29, JANUARY), date(30, JANUARY), date(31, JANUARY)); - schedule.assertAlertsStartWith("penta2", late, date(12, FEBRUARY), date(13, FEBRUARY), date(14, FEBRUARY), date(15, FEBRUARY)); - schedule.assertNoAlerts("penta2", max); + schedule.assertAlertsStartWith("pentavalent_2", earliest, date(1, JANUARY), date(2, JANUARY), date(3, JANUARY), date(4, JANUARY)); + schedule.assertAlertsStartWith("pentavalent_2", due, date(29, JANUARY), date(30, JANUARY), date(31, JANUARY)); + schedule.assertAlertsStartWith("pentavalent_2", late, date(12, FEBRUARY), date(13, FEBRUARY), date(14, FEBRUARY), date(15, FEBRUARY)); + schedule.assertNoAlerts("pentavalent_2", max); visualization.outputTo("child-pentavalent-2.html", 1); } @@ -264,10 +264,10 @@ public void shouldProvideAlertsForPentavalent2() throws Exception { public void shouldProvideAlertsForPentavalent3() throws Exception { schedule.enrollFor(CHILD_SCHEDULE_PENTAVALENT_3, newDate(2012, JANUARY, 1), new Time(14, 0)); - schedule.assertAlertsStartWith("penta3", earliest, date(1, JANUARY), date(2, JANUARY), date(3, JANUARY), date(4, JANUARY)); - schedule.assertAlertsStartWith("penta3", due, date(29, JANUARY), date(30, JANUARY), date(31, JANUARY)); - schedule.assertAlertsStartWith("penta3", late, date(12, FEBRUARY), date(13, FEBRUARY), date(14, FEBRUARY), date(15, FEBRUARY)); - schedule.assertNoAlerts("penta3", max); + schedule.assertAlertsStartWith("pentavalent_3", earliest, date(1, JANUARY), date(2, JANUARY), date(3, JANUARY), date(4, JANUARY)); + schedule.assertAlertsStartWith("pentavalent_3", due, date(29, JANUARY), date(30, JANUARY), date(31, JANUARY)); + schedule.assertAlertsStartWith("pentavalent_3", late, date(12, FEBRUARY), date(13, FEBRUARY), date(14, FEBRUARY), date(15, FEBRUARY)); + schedule.assertNoAlerts("pentavalent_3", max); visualization.outputTo("child-pentavalent-3.html", 1); } diff --git a/opensrp-web/src/test/java/org/opensrp/web/rest/it/ProviderResourceTest.java b/opensrp-web/src/test/java/org/opensrp/web/rest/it/ProviderResourceTest.java index aeed146245..ab6b835964 100644 --- a/opensrp-web/src/test/java/org/opensrp/web/rest/it/ProviderResourceTest.java +++ b/opensrp-web/src/test/java/org/opensrp/web/rest/it/ProviderResourceTest.java @@ -21,6 +21,7 @@ import org.opensrp.domain.Client; import org.opensrp.service.ClientService; import org.opensrp.web.rest.ClientResource; +import org.opensrp.web.rest.ProviderResource; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.converter.HttpMessageConverter; import org.springframework.http.converter.json.MappingJacksonHttpMessageConverter; @@ -47,7 +48,7 @@ public class ProviderResourceTest { @Autowired private ClientService cs; @Autowired - private ClientResource cr; + private ProviderResource pr; @Test public void testProviderSearch() throws Exception { @@ -64,7 +65,7 @@ public void testProviderSearch() throws Exception { handlerAdapter.setMessageConverters(messageConverters); MockHttpServletResponse mockResponse = new MockHttpServletResponse(); - handlerAdapter.handle(mockRequest, mockResponse, cr); + handlerAdapter.handle(mockRequest, mockResponse, pr); String actual = mockResponse.getContentAsString(); System.out.println(actual); diff --git a/opensrp-web/src/test/resources/schedules/child-bcg.json b/opensrp-web/src/test/resources/schedules/child-bcg.json new file mode 100644 index 0000000000..585f1d86d4 --- /dev/null +++ b/opensrp-web/src/test/resources/schedules/child-bcg.json @@ -0,0 +1,29 @@ +{ + "name": "BCG", + "absolute": true, + "milestones": [ + { + "name": "bcg", + "scheduleWindows": { + "earliest": ["0 Days"], + "due": ["2 Weeks"], + "late": ["1 Year"], + "max": ["1 Year"] + }, + "alerts": [ + { + "window": "due", + "offset": ["0 Days"], + "interval": ["1 Day"], + "count": "14" + }, + { + "window": "late", + "offset": ["2 Weeks"], + "interval": ["1 Day"], + "count": "350" + } + ] + } + ] +} diff --git a/opensrp-web/src/test/resources/schedules/child-boosters.json b/opensrp-web/src/test/resources/schedules/child-boosters.json new file mode 100644 index 0000000000..546d4229eb --- /dev/null +++ b/opensrp-web/src/test/resources/schedules/child-boosters.json @@ -0,0 +1,23 @@ +{ + "name": "Boosters", + "absolute": false, + "milestones": [ + { + "name": "REMINDER", + "scheduleWindows": { + "earliest": ["72 Weeks"], + "due": ["73 Weeks"], + "late": [""], + "max": [""] + }, + "alerts": [ + { + "window": "due", + "offset": ["0 Days"], + "interval": ["1 Week"], + "count": "1" + } + ] + } + ] +} diff --git a/opensrp-web/src/test/resources/schedules/child-dpt-booster1.json b/opensrp-web/src/test/resources/schedules/child-dpt-booster1.json new file mode 100644 index 0000000000..ac3930beb1 --- /dev/null +++ b/opensrp-web/src/test/resources/schedules/child-dpt-booster1.json @@ -0,0 +1,35 @@ +{ + "name": "DPT Booster 1", + "absolute": true, + "milestones": [ + { + "name": "dptbooster_1", + "scheduleWindows": { + "earliest": ["16 Months"], + "due": ["24 Months"], + "late": ["5 Years"], + "max": [""] + }, + "alerts": [ + { + "window": "earliest", + "offset": ["0 Days"], + "interval": ["1 Day"], + "count": "486" + }, + { + "window": "due", + "offset": ["16 Months"], + "interval": ["1 Day"], + "count": "243" + }, + { + "window": "late", + "offset": ["24 Months"], + "interval": ["1 Day"], + "count": "1095" + } + ] + } + ] +} diff --git a/opensrp-web/src/test/resources/schedules/child-dpt-booster2.json b/opensrp-web/src/test/resources/schedules/child-dpt-booster2.json new file mode 100644 index 0000000000..74f1a83bae --- /dev/null +++ b/opensrp-web/src/test/resources/schedules/child-dpt-booster2.json @@ -0,0 +1,22 @@ +{ + "name": "DPT Booster 2", + "absolute": true, + "milestones": [ + { + "name": "dptbooster_2", + "scheduleWindows": { + "earliest": ["5 Years"], + "due": ["7 Years"], + "max": ["7 Years"] + }, + "alerts": [ + { + "window": "due", + "offset": ["5 Years"], + "interval": ["1 Day"], + "count": "730" + } + ] + } + ] +} diff --git a/opensrp-web/src/test/resources/schedules/child-measles-booster.json b/opensrp-web/src/test/resources/schedules/child-measles-booster.json new file mode 100644 index 0000000000..f4fcc7fbf6 --- /dev/null +++ b/opensrp-web/src/test/resources/schedules/child-measles-booster.json @@ -0,0 +1,35 @@ +{ + "name": "Measles 2", + "absolute": true, + "milestones": [ + { + "name": "measles2", + "scheduleWindows": { + "earliest": ["16 Months"], + "due": ["24 Months"], + "late": ["5 Years"], + "max": ["5 Years"] + }, + "alerts": [ + { + "window": "earliest", + "offset": ["0 Days"], + "interval": ["1 Day"], + "count": "486" + }, + { + "window": "due", + "offset": ["16 Months"], + "interval": ["1 Day"], + "count": "243" + }, + { + "window": "late", + "offset": ["24 Months"], + "interval": ["1 Day"], + "count": "1095" + } + ] + } + ] +} diff --git a/opensrp-web/src/test/resources/schedules/child-measles.json b/opensrp-web/src/test/resources/schedules/child-measles.json new file mode 100644 index 0000000000..2d5eec6fba --- /dev/null +++ b/opensrp-web/src/test/resources/schedules/child-measles.json @@ -0,0 +1,35 @@ +{ + "name": "Measles 1", + "absolute": true, + "milestones": [ + { + "name": "measles1", + "scheduleWindows": { + "earliest": ["9 Months"], + "due": ["12 Months"], + "late": ["5 Years"], + "max": ["5 Years"] + }, + "alerts": [ + { + "window": "earliest", + "offset": ["0 Days"], + "interval": ["1 Day"], + "count": "273" + }, + { + "window": "due", + "offset": ["9 Months"], + "interval": ["1 Day"], + "count": "91" + }, + { + "window": "late", + "offset": ["12 Months"], + "interval": ["1 Day"], + "count": "1460" + } + ] + } + ] +} diff --git a/opensrp-web/src/test/resources/schedules/child-opv-0-and-1.json b/opensrp-web/src/test/resources/schedules/child-opv-0-and-1.json new file mode 100644 index 0000000000..8a5d992387 --- /dev/null +++ b/opensrp-web/src/test/resources/schedules/child-opv-0-and-1.json @@ -0,0 +1,51 @@ +{ + "name": "OPV_0_AND_1", + "absolute": true, + "milestones": [ + { + "name": "opv_0", + "scheduleWindows": { + "earliest": ["0 Days"], + "due": ["15 Days"], + "max": ["15 Days"] + }, + "alerts": [ + { + "window": "due", + "offset": ["0 Days"], + "interval": ["1 Day"], + "count": "15" + } + ] + }, + { + "name": "opv_1", + "scheduleWindows": { + "earliest": ["6 Weeks"], + "due": ["8 Weeks"], + "late": ["5 Years"], + "max": ["5 Years"] + }, + "alerts": [ + { + "window": "earliest", + "offset": ["15 Days"], + "interval": ["1 Day"], + "count": "27" + }, + { + "window": "due", + "offset": ["6 Weeks"], + "interval": ["1 Day"], + "count": "14" + }, + { + "window": "late", + "offset": ["8 Weeks"], + "interval": ["1 Day"], + "count": "1764" + } + ] + } + ] +} diff --git a/opensrp-web/src/test/resources/schedules/child-opv-2.json b/opensrp-web/src/test/resources/schedules/child-opv-2.json new file mode 100644 index 0000000000..40acb77cbc --- /dev/null +++ b/opensrp-web/src/test/resources/schedules/child-opv-2.json @@ -0,0 +1,35 @@ +{ + "name": "OPV 2", + "absolute": true, + "milestones": [ + { + "name": "opv_2", + "scheduleWindows": { + "earliest": ["4 Weeks"], + "due": ["6 Weeks"], + "late": ["5 Years"], + "max": ["5 Years"] + }, + "alerts": [ + { + "window": "earliest", + "offset": ["0 Days"], + "interval": ["1 Day"], + "count": "28" + }, + { + "window": "due", + "offset": ["4 Weeks"], + "interval": ["1 Day"], + "count": "14" + }, + { + "window": "late", + "offset": ["6 Weeks"], + "interval": ["1 Day"], + "count": "1778" + } + ] + } + ] +} diff --git a/opensrp-web/src/test/resources/schedules/child-opv-3.json b/opensrp-web/src/test/resources/schedules/child-opv-3.json new file mode 100644 index 0000000000..a9c1f3f8da --- /dev/null +++ b/opensrp-web/src/test/resources/schedules/child-opv-3.json @@ -0,0 +1,35 @@ +{ + "name": "OPV 3", + "absolute": true, + "milestones": [ + { + "name": "opv_3", + "scheduleWindows": { + "earliest": ["4 Weeks"], + "due": ["6 Weeks"], + "late": ["5 Years"], + "max": ["5 Years"] + }, + "alerts": [ + { + "window": "earliest", + "offset": ["0 Days"], + "interval": ["1 Day"], + "count": "28" + }, + { + "window": "due", + "offset": ["4 Weeks"], + "interval": ["1 Day"], + "count": "14" + }, + { + "window": "late", + "offset": ["6 Weeks"], + "interval": ["1 Day"], + "count": "1778" + } + ] + } + ] +} diff --git a/opensrp-web/src/test/resources/schedules/child-opv-booster.json b/opensrp-web/src/test/resources/schedules/child-opv-booster.json new file mode 100644 index 0000000000..1c4e122505 --- /dev/null +++ b/opensrp-web/src/test/resources/schedules/child-opv-booster.json @@ -0,0 +1,29 @@ +{ + "name": "OPV BOOSTER", + "absolute": true, + "milestones": [ + { + "name": "opvbooster", + "scheduleWindows": { + "earliest": ["16 Months"], + "due": ["24 Months"], + "late": ["5 Years"], + "max": ["5 Years"] + }, + "alerts": [ + { + "window": "due", + "offset": ["16 Months"], + "interval": ["1 Day"], + "count": "243" + }, + { + "window": "late", + "offset": ["24 Months"], + "interval": ["1 Day"], + "count": "1095" + } + ] + } + ] +} diff --git a/opensrp-web/src/test/resources/schedules/child-pentavalent-1.json b/opensrp-web/src/test/resources/schedules/child-pentavalent-1.json new file mode 100644 index 0000000000..50085c2d5e --- /dev/null +++ b/opensrp-web/src/test/resources/schedules/child-pentavalent-1.json @@ -0,0 +1,35 @@ +{ + "name": "PENTAVALENT 1", + "absolute": true, + "milestones": [ + { + "name": "pentavalent_1", + "scheduleWindows": { + "earliest": ["6 Weeks"], + "due": ["8 Weeks"], + "late": ["12 Months"], + "max": ["12 Months"] + }, + "alerts": [ + { + "window": "earliest", + "offset": ["0 Days"], + "interval": ["1 Day"], + "count": "42" + }, + { + "window": "due", + "offset": ["6 Weeks"], + "interval": ["1 Day"], + "count": "14" + }, + { + "window": "late", + "offset": ["8 Weeks"], + "interval": ["1 Day"], + "count": "308" + } + ] + } + ] +} diff --git a/opensrp-web/src/test/resources/schedules/child-pentavalent-2.json b/opensrp-web/src/test/resources/schedules/child-pentavalent-2.json new file mode 100644 index 0000000000..9bdc10d86e --- /dev/null +++ b/opensrp-web/src/test/resources/schedules/child-pentavalent-2.json @@ -0,0 +1,35 @@ +{ + "name": "PENTAVALENT 2", + "absolute": true, + "milestones": [ + { + "name": "pentavalent_2", + "scheduleWindows": { + "earliest": ["4 Weeks"], + "due": ["6 Weeks"], + "late": ["12 Months"], + "max": ["12 Months"] + }, + "alerts": [ + { + "window": "earliest", + "offset": ["0 Days"], + "interval": ["1 Day"], + "count": "28" + }, + { + "window": "due", + "offset": ["4 Weeks"], + "interval": ["1 Day"], + "count": "14" + }, + { + "window": "late", + "offset": ["6 Weeks"], + "interval": ["1 Day"], + "count": "322" + } + ] + } + ] +} \ No newline at end of file diff --git a/opensrp-web/src/test/resources/schedules/child-pentavalent-3.json b/opensrp-web/src/test/resources/schedules/child-pentavalent-3.json new file mode 100644 index 0000000000..9ffe531b92 --- /dev/null +++ b/opensrp-web/src/test/resources/schedules/child-pentavalent-3.json @@ -0,0 +1,35 @@ +{ + "name": "PENTAVALENT 3", + "absolute": true, + "milestones": [ + { + "name": "pentavalent_3", + "scheduleWindows": { + "earliest": ["4 Weeks"], + "due": ["6 Weeks"], + "late": ["12 Months"], + "max": ["12 Months"] + }, + "alerts": [ + { + "window": "earliest", + "offset": ["0 Days"], + "interval": ["1 Day"], + "count": "28" + }, + { + "window": "due", + "offset": ["4 Weeks"], + "interval": ["1 Day"], + "count": "14" + }, + { + "window": "late", + "offset": ["6 Weeks"], + "interval": ["1 Day"], + "count": "322" + } + ] + } + ] +} diff --git a/opensrp-web/src/test/resources/schedules/delivery-plan.json b/opensrp-web/src/test/resources/schedules/delivery-plan.json new file mode 100644 index 0000000000..a265d65154 --- /dev/null +++ b/opensrp-web/src/test/resources/schedules/delivery-plan.json @@ -0,0 +1,35 @@ +{ + "name": "Delivery Plan", + "absolute": true, + "milestones": [ + { + "name": "Delivery Plan", + "scheduleWindows": { + "earliest": ["34 Weeks"], + "due": ["36 Weeks"], + "late": ["300 Days"], + "max": ["5 Years"] + }, + "alerts": [ + { + "window": "earliest", + "offset": ["0 Days"], + "interval": ["1 Day"], + "count": "238" + }, + { + "window": "due", + "offset": ["34 Weeks"], + "interval": ["1 Day"], + "count": "14" + }, + { + "window": "late", + "offset": ["36 Weeks"], + "interval": ["1 Day"], + "count": "48" + } + ] + } + ] +} diff --git a/opensrp-web/src/test/resources/schedules/ec-condom-refill.json b/opensrp-web/src/test/resources/schedules/ec-condom-refill.json new file mode 100644 index 0000000000..cce9f98933 --- /dev/null +++ b/opensrp-web/src/test/resources/schedules/ec-condom-refill.json @@ -0,0 +1,29 @@ +{ + "name": "Condom Refill", + "absolute": true, + "milestones": [ + { + "name": "Condom Refill", + "scheduleWindows": { + "earliest": ["0 Weeks"], + "due": ["1 Weeks"], + "late": ["1 Year"], + "max": ["1 Year", "1 Day"] + }, + "alerts": [ + { + "window": "due", + "offset": ["0 Weeks"], + "interval": ["1 Day"], + "count": "7" + }, + { + "window": "late", + "offset": ["1 Weeks"], + "interval": ["1 Day"], + "count": "358" + } + ] + } + ] +} diff --git a/opensrp-web/src/test/resources/schedules/ec-dmpa-injectable-refill.json b/opensrp-web/src/test/resources/schedules/ec-dmpa-injectable-refill.json new file mode 100644 index 0000000000..d83b18ce80 --- /dev/null +++ b/opensrp-web/src/test/resources/schedules/ec-dmpa-injectable-refill.json @@ -0,0 +1,35 @@ +{ + "name": "DMPA Injectable Refill", + "absolute": true, + "milestones": [ + { + "name": "DMPA Injectable Refill", + "scheduleWindows": { + "earliest": ["12 Weeks"], + "due": ["13 Weeks"], + "late": ["1 Year"], + "max": ["1 Year", "1 Day"] + }, + "alerts": [ + { + "window": "earliest", + "offset": ["0 Weeks"], + "interval": ["1 Day"], + "count": "84" + }, + { + "window": "due", + "offset": ["12 Weeks"], + "interval": ["1 Day"], + "count": "7" + }, + { + "window": "late", + "offset": ["13 Weeks"], + "interval": ["1 Day"], + "count": "274" + } + ] + } + ] +} diff --git a/opensrp-web/src/test/resources/schedules/ec-female-sterilization-followup.json b/opensrp-web/src/test/resources/schedules/ec-female-sterilization-followup.json new file mode 100644 index 0000000000..2fe8f4c6db --- /dev/null +++ b/opensrp-web/src/test/resources/schedules/ec-female-sterilization-followup.json @@ -0,0 +1,75 @@ +{ + "name": "Female sterilization Followup", + "absolute": true, + "milestones": [ + { + "name": "Female sterilization Followup 1", + "scheduleWindows": { + "earliest": ["0 Weeks"], + "due": ["2 Days"], + "late": ["7 Days"], + "max": ["7 Days"] + }, + "alerts": [ + { + "window": "due", + "offset": ["0 Days"], + "interval": ["1 Day"], + "count": "2" + }, + { + "window": "late", + "offset": ["2 Days"], + "interval": ["1 Day"], + "count": "5" + } + ] + }, + { + "name": "Female sterilization Followup 2", + "scheduleWindows": { + "earliest": ["0 Weeks"], + "due": ["9 Days"], + "late": ["1 Month"], + "max": ["1 Month"] + }, + "alerts": [ + { + "window": "due", + "offset": ["7 Days"], + "interval": ["1 Day"], + "count": "2" + }, + { + "window": "late", + "offset": ["9 Days"], + "interval": ["1 Day"], + "count": "22" + } + ] + }, + { + "name": "Female sterilization Followup 3", + "scheduleWindows": { + "earliest": ["0 Weeks"], + "due": ["1 Month", "1 Week"], + "late": ["100 Weeks"], + "max": ["100 Weeks", "1 Day"] + }, + "alerts": [ + { + "window": "due", + "offset": ["1 Month"], + "interval": ["1 Day"], + "count": "7" + }, + { + "window": "late", + "offset": ["1 Month", "1 Week"], + "interval": ["1 Day"], + "count": "665" + } + ] + } + ] +} diff --git a/opensrp-web/src/test/resources/schedules/ec-fp-followup.json b/opensrp-web/src/test/resources/schedules/ec-fp-followup.json new file mode 100644 index 0000000000..092db43076 --- /dev/null +++ b/opensrp-web/src/test/resources/schedules/ec-fp-followup.json @@ -0,0 +1,35 @@ +{ + "name": "FP Followup", + "absolute": true, + "milestones": [ + { + "name": "FP Followup", + "scheduleWindows": { + "earliest": ["3 Days"], + "due": ["7 Days"], + "late": ["100 Weeks"], + "max": ["100 Weeks", "1 Day"] + }, + "alerts": [ + { + "window": "earliest", + "offset": ["0 Days"], + "interval": ["1 Day"], + "count": "3" + }, + { + "window": "due", + "offset": ["3 Days"], + "interval": ["1 Day"], + "count": "4" + }, + { + "window": "late", + "offset": ["7 Days"], + "interval": ["1 Day"], + "count": "693" + } + ] + } + ] +} diff --git a/opensrp-web/src/test/resources/schedules/ec-fp-referral-followup.json b/opensrp-web/src/test/resources/schedules/ec-fp-referral-followup.json new file mode 100644 index 0000000000..3c36c7dc9c --- /dev/null +++ b/opensrp-web/src/test/resources/schedules/ec-fp-referral-followup.json @@ -0,0 +1,35 @@ +{ + "name": "FP Referral Followup", + "absolute": true, + "milestones": [ + { + "name": "FP Referral Followup", + "scheduleWindows": { + "earliest": ["1 Day"], + "due": ["2 Days"], + "late": ["100 Weeks"], + "max": ["100 Weeks", "1 Day"] + }, + "alerts": [ + { + "window": "earliest", + "offset": ["0 Days"], + "interval": ["1 Day"], + "count": "1" + }, + { + "window": "due", + "offset": ["1 Day"], + "interval": ["1 Day"], + "count": "1" + }, + { + "window": "late", + "offset": ["2 Days"], + "interval": ["1 Day"], + "count": "698" + } + ] + } + ] +} diff --git a/opensrp-web/src/test/resources/schedules/ec-iud-followup.json b/opensrp-web/src/test/resources/schedules/ec-iud-followup.json new file mode 100644 index 0000000000..5e39cdaf8c --- /dev/null +++ b/opensrp-web/src/test/resources/schedules/ec-iud-followup.json @@ -0,0 +1,58 @@ +{ + "name": "IUD Followup", + "absolute": true, + "milestones": [ + { + "name": "IUD Followup 1", + "scheduleWindows": { + "earliest": ["1 Month"], + "due": ["1 Month", "1 Week"], + "late": ["4 Months"], + "max": ["4 Months"] + }, + "alerts": [ + { + "window": "earliest", + "offset": ["0 Days"], + "interval": ["1 Day"], + "count": "30" + }, + { + "window": "due", + "offset": ["1 Month"], + "interval": ["1 Day"], + "count": "7" + }, + { + "window": "late", + "offset": ["1 Month", "1 Week"], + "interval": ["1 Day"], + "count": "84" + } + ] + }, + { + "name": "IUD Followup 2", + "scheduleWindows": { + "earliest": ["0 Weeks"], + "due": ["4 Months", "1 Week"], + "late": ["100 Weeks"], + "max": ["100 Weeks", "1 Day"] + }, + "alerts": [ + { + "window": "due", + "offset": ["4 Months"], + "interval": ["1 Day"], + "count": "7" + }, + { + "window": "late", + "offset": ["4 Months", "1 Week"], + "interval": ["1 Day"], + "count": "572" + } + ] + } + ] +} diff --git a/opensrp-web/src/test/resources/schedules/ec-male-sterilization-followup.json b/opensrp-web/src/test/resources/schedules/ec-male-sterilization-followup.json new file mode 100644 index 0000000000..72d095e489 --- /dev/null +++ b/opensrp-web/src/test/resources/schedules/ec-male-sterilization-followup.json @@ -0,0 +1,52 @@ +{ + "name": "Male sterilization Followup", + "absolute": true, + "milestones": [ + { + "name": "Male sterilization Followup 1", + "scheduleWindows": { + "earliest": ["0 Weeks"], + "due": ["2 Days"], + "late": ["3 Months"], + "max": ["3 Months"] + }, + "alerts": [ + { + "window": "due", + "offset": ["0 Days"], + "interval": ["1 Day"], + "count": "2" + }, + { + "window": "late", + "offset": ["2 Days"], + "interval": ["1 Day"], + "count": "89" + } + ] + }, + { + "name": "Male sterilization Followup 2", + "scheduleWindows": { + "earliest": ["0 Weeks"], + "due": ["3 Months", "1 Week"], + "late": ["100 Weeks"], + "max": ["100 Weeks", "1 Day"] + }, + "alerts": [ + { + "window": "due", + "offset": ["3 Months"], + "interval": ["1 Day"], + "count": "7" + }, + { + "window": "late", + "offset": ["3 Months", "1 Week"], + "interval": ["1 Day"], + "count": "602" + } + ] + } + ] +} diff --git a/opensrp-web/src/test/resources/schedules/ec-ocp-refill.json b/opensrp-web/src/test/resources/schedules/ec-ocp-refill.json new file mode 100644 index 0000000000..e5b0c4556b --- /dev/null +++ b/opensrp-web/src/test/resources/schedules/ec-ocp-refill.json @@ -0,0 +1,29 @@ +{ + "name": "OCP Refill", + "absolute": true, + "milestones": [ + { + "name": "OCP Refill", + "scheduleWindows": { + "earliest": ["0 Weeks"], + "due": ["1 Week"], + "late": ["1 Year"], + "max": ["1 Year", "1 Day"] + }, + "alerts": [ + { + "window": "due", + "offset": ["0 Week"], + "interval": ["1 Day"], + "count": "7" + }, + { + "window": "late", + "offset": ["1 Weeks"], + "interval": ["1 Day"], + "count": "358" + } + ] + } + ] +} diff --git a/opensrp-web/src/test/resources/schedules/mother-anc-normal.json b/opensrp-web/src/test/resources/schedules/mother-anc-normal.json new file mode 100644 index 0000000000..7032989b45 --- /dev/null +++ b/opensrp-web/src/test/resources/schedules/mother-anc-normal.json @@ -0,0 +1,104 @@ +{ + "name": "Ante Natal Care - Normal", + "absolute": true, + "milestones": [ + { + "name": "ANC 1", + "scheduleWindows": { + "earliest": ["0 Weeks"], + "due": ["12 Weeks"], + "late": ["14 Weeks"], + "max": ["14 weeks"] + }, + "alerts": [ + { + "window": "due", + "offset": ["0 Weeks"], + "interval": ["1 Day"], + "count": "84" + }, + { + "window": "late", + "offset": ["12 Weeks"], + "interval": ["1 Day"], + "count": "14" + }, + { + "window": "max", + "offset": ["14 Weeks"], + "interval": ["1 Day"], + "count": "2" + } + ] + }, + { + "name": "ANC 2", + "scheduleWindows": { + "earliest": ["14 Weeks"], + "due": ["26 Weeks"], + "late": ["28 Weeks"], + "max": ["28 Weeks"] + }, + "alerts": [ + { + "window": "due", + "offset": ["14 Weeks"], + "interval": ["1 Day"], + "count": "84" + }, + { + "window": "late", + "offset": ["26 Weeks"], + "interval": ["1 Day"], + "count": "14" + } + ] + }, + { + "name": "ANC 3", + "scheduleWindows": { + "earliest": ["28 Weeks"], + "due": ["34 Weeks"], + "late": ["36 Weeks"], + "max": ["36 Weeks"] + }, + "alerts": [ + { + "window": "due", + "offset": ["28 Weeks"], + "interval": ["1 Day"], + "count": "42" + }, + { + "window": "late", + "offset": ["34 Weeks"], + "interval": ["1 Day"], + "count": "14" + } + ] + }, + { + "name": "ANC 4", + "scheduleWindows": { + "earliest": ["36 Weeks"], + "due": ["39 Weeks"], + "late": ["100 Weeks"], + "max": ["100 Weeks", "1 Day"] + }, + "alerts": [ + { + "window": "due", + "offset": ["36 Weeks"], + "interval": ["1 Day"], + "count": "21" + }, + { + "window": "late", + "offset": ["39 Weeks"], + "interval": ["1 Day"], + "count": "427" + } + ] + } + ] +} diff --git a/opensrp-web/src/test/resources/schedules/mother-auto-close-pnc.json b/opensrp-web/src/test/resources/schedules/mother-auto-close-pnc.json new file mode 100644 index 0000000000..e73b24f8ba --- /dev/null +++ b/opensrp-web/src/test/resources/schedules/mother-auto-close-pnc.json @@ -0,0 +1,20 @@ +{ + "name": "Auto Close PNC", + "absolute": false, + "milestones": [ + { + "name": "Auto Close PNC", + "scheduleWindows": { + "due": ["8 Weeks", "4 Day"] + }, + "alerts": [ + { + "window": "due", + "offset": ["8 Weeks"], + "interval": ["1 Day"], + "count": "4" + } + ] + } + ] +} \ No newline at end of file diff --git a/opensrp-web/src/test/resources/schedules/mother-expected-date-of-delivery.json b/opensrp-web/src/test/resources/schedules/mother-expected-date-of-delivery.json new file mode 100644 index 0000000000..adf0921335 --- /dev/null +++ b/opensrp-web/src/test/resources/schedules/mother-expected-date-of-delivery.json @@ -0,0 +1,35 @@ +{ + "name": "Expected Date Of Delivery", + "absolute": false, + "milestones": [ + { + "name": "EDD", + "scheduleWindows": { + "earliest": ["38 Weeks"], + "due": ["40 Weeks", "1 Day"], + "late": ["100 Weeks"], + "max": ["100 Weeks", "1 Day"] + }, + "alerts": [ + { + "window": "due", + "offset": ["0 Days"], + "interval": ["1 Weeks"], + "count": "3" + }, + { + "window": "late", + "offset": ["2 Days"], + "interval": ["1 Weeks"], + "count": "100" + }, + { + "window": "late", + "offset": ["6 Days"], + "interval": ["1 Weeks"], + "count": "100" + } + ] + } + ] +} diff --git a/opensrp-web/src/test/resources/schedules/mother-hb-followup-test.json b/opensrp-web/src/test/resources/schedules/mother-hb-followup-test.json new file mode 100644 index 0000000000..cceeeeb496 --- /dev/null +++ b/opensrp-web/src/test/resources/schedules/mother-hb-followup-test.json @@ -0,0 +1,35 @@ +{ + "name": "Hb Followup Test", + "absolute": true, + "milestones": [ + { + "name": "Hb Followup Test", + "scheduleWindows": { + "earliest": ["1 Month"], + "due": ["1 Month", "2 Weeks"], + "late": ["100 Weeks"], + "max": ["100 Weeks", "1 Day"] + }, + "alerts": [ + { + "window": "earliest", + "offset": ["0 Weeks"], + "interval": ["1 Day"], + "count": "30" + }, + { + "window": "due", + "offset": ["1 Month"], + "interval": ["1 Day"], + "count": "14" + }, + { + "window": "late", + "offset": ["1 Month", "2 Weeks"], + "interval": ["1 Day"], + "count": "655" + } + ] + } + ] +} diff --git a/opensrp-web/src/test/resources/schedules/mother-hb-test-1.json b/opensrp-web/src/test/resources/schedules/mother-hb-test-1.json new file mode 100644 index 0000000000..97f7b54267 --- /dev/null +++ b/opensrp-web/src/test/resources/schedules/mother-hb-test-1.json @@ -0,0 +1,29 @@ +{ + "name": "Hb Test 1", + "absolute": true, + "milestones": [ + { + "name": "Hb Test 1", + "scheduleWindows": { + "earliest": ["0 Weeks"], + "due": ["12 Weeks"], + "late": ["100 Weeks"], + "max": ["100 Weeks", "1 Day"] + }, + "alerts": [ + { + "window": "due", + "offset": ["0 Weeks"], + "interval": ["1 Day"], + "count": "84" + }, + { + "window": "late", + "offset": ["12 Weeks"], + "interval": ["1 Day"], + "count": "616" + } + ] + } + ] +} diff --git a/opensrp-web/src/test/resources/schedules/mother-hb-test-2.json b/opensrp-web/src/test/resources/schedules/mother-hb-test-2.json new file mode 100644 index 0000000000..70d2f18b48 --- /dev/null +++ b/opensrp-web/src/test/resources/schedules/mother-hb-test-2.json @@ -0,0 +1,29 @@ +{ + "name": "Hb Test 2", + "absolute": true, + "milestones": [ + { + "name": "Hb Test 2", + "scheduleWindows": { + "earliest": ["0 Weeks"], + "due": ["30 Weeks"], + "late": ["100 Weeks"], + "max": ["100 Weeks", "1 Day"] + }, + "alerts": [ + { + "window": "due", + "offset": ["28 Weeks"], + "interval": ["1 Day"], + "count": "14" + }, + { + "window": "late", + "offset": ["30 Weeks"], + "interval": ["1 Day"], + "count": "490" + } + ] + } + ] +} diff --git a/opensrp-web/src/test/resources/schedules/mother-ifa-1.json b/opensrp-web/src/test/resources/schedules/mother-ifa-1.json new file mode 100644 index 0000000000..027939ac58 --- /dev/null +++ b/opensrp-web/src/test/resources/schedules/mother-ifa-1.json @@ -0,0 +1,35 @@ +{ + "name": "IFA 1", + "absolute": true, + "milestones": [ + { + "name": "IFA 1", + "scheduleWindows": { + "earliest": ["14 Weeks"], + "due": ["16 Weeks"], + "late": ["100 Weeks"], + "max": ["100 Weeks", "1 Day"] + }, + "alerts": [ + { + "window": "earliest", + "offset": ["0 Weeks"], + "interval": ["1 Day"], + "count": "90" + }, + { + "window": "due", + "offset": ["14 Weeks"], + "interval": ["1 Day"], + "count": "14" + }, + { + "window": "late", + "offset": ["16 Weeks"], + "interval": ["1 Day"], + "count": "588" + } + ] + } + ] +} diff --git a/opensrp-web/src/test/resources/schedules/mother-ifa-2.json b/opensrp-web/src/test/resources/schedules/mother-ifa-2.json new file mode 100644 index 0000000000..e45e067ee8 --- /dev/null +++ b/opensrp-web/src/test/resources/schedules/mother-ifa-2.json @@ -0,0 +1,35 @@ +{ + "name": "IFA 2", + "absolute": true, + "milestones": [ + { + "name": "IFA 2", + "scheduleWindows": { + "earliest": ["1 Months"], + "due": ["1 Month", "2 Weeks"], + "late": ["100 Weeks"], + "max": ["100 Weeks", "1 Day"] + }, + "alerts": [ + { + "window": "earliest", + "offset": ["0 Weeks"], + "interval": ["1 Day"], + "count": "30" + }, + { + "window": "due", + "offset": ["1 Months"], + "interval": ["1 Day"], + "count": "14" + }, + { + "window": "late", + "offset": ["1 Month", "2 Weeks"], + "interval": ["1 Day"], + "count": "658" + } + ] + } + ] +} diff --git a/opensrp-web/src/test/resources/schedules/mother-ifa-3.json b/opensrp-web/src/test/resources/schedules/mother-ifa-3.json new file mode 100644 index 0000000000..206ede5e19 --- /dev/null +++ b/opensrp-web/src/test/resources/schedules/mother-ifa-3.json @@ -0,0 +1,35 @@ +{ + "name": "IFA 3", + "absolute": true, + "milestones": [ + { + "name": "IFA 3", + "scheduleWindows": { + "earliest": ["1 Months"], + "due": ["1 Month", "2 Weeks"], + "late": ["100 Weeks"], + "max": ["100 Weeks", "1 Day"] + }, + "alerts": [ + { + "window": "earliest", + "offset": ["0 Weeks"], + "interval": ["1 Day"], + "count": "30" + }, + { + "window": "due", + "offset": ["1 Months"], + "interval": ["1 Day"], + "count": "14" + }, + { + "window": "late", + "offset": ["1 Month", "2 Weeks"], + "interval": ["1 Day"], + "count": "658" + } + ] + } + ] +} diff --git a/opensrp-web/src/test/resources/schedules/mother-lab-reminder.json b/opensrp-web/src/test/resources/schedules/mother-lab-reminder.json new file mode 100644 index 0000000000..6738572b56 --- /dev/null +++ b/opensrp-web/src/test/resources/schedules/mother-lab-reminder.json @@ -0,0 +1,29 @@ +{ + "name": "Lab Reminders", + "absolute": false, + "milestones": [ + { + "name": "REMINDER", + "scheduleWindows": { + "earliest": ["10 Weeks"], + "due": ["30 Weeks"], + "late": ["40 Weeks", "1 Day"], + "max": ["41 Weeks"] + }, + "alerts": [ + { + "window": "late", + "offset": ["0 Days"], + "interval": ["1 Weeks"], + "count": "11" + }, + { + "window": "max", + "offset": ["1 Day"], + "interval": ["1 Day"], + "count": "3" + } + ] + } + ] +} diff --git a/opensrp-web/src/test/resources/schedules/mother-tt-1.json b/opensrp-web/src/test/resources/schedules/mother-tt-1.json new file mode 100644 index 0000000000..230b20d60f --- /dev/null +++ b/opensrp-web/src/test/resources/schedules/mother-tt-1.json @@ -0,0 +1,29 @@ +{ + "name": "TT 1", + "absolute": true, + "milestones": [ + { + "name": "TT 1", + "scheduleWindows": { + "earliest": ["0 Weeks"], + "due": ["12 Weeks"], + "late": ["1 Year"], + "max": ["1 Year", "1 Day"] + }, + "alerts": [ + { + "window": "due", + "offset": ["0 Weeks"], + "interval": ["1 Day"], + "count": "84" + }, + { + "window": "late", + "offset": ["12 Weeks"], + "interval": ["1 Day"], + "count": "280" + } + ] + } + ] +} diff --git a/opensrp-web/src/test/resources/schedules/mother-tt-2.json b/opensrp-web/src/test/resources/schedules/mother-tt-2.json new file mode 100644 index 0000000000..588fea88a8 --- /dev/null +++ b/opensrp-web/src/test/resources/schedules/mother-tt-2.json @@ -0,0 +1,35 @@ +{ + "name": "TT 2", + "absolute": true, + "milestones": [ + { + "name": "TT 2", + "scheduleWindows": { + "earliest": ["4 Weeks"], + "due": ["6 Weeks"], + "late": ["1 Year"], + "max": ["1 Year", "1 Day"] + }, + "alerts": [ + { + "window": "earliest", + "offset": ["0 Weeks"], + "interval": ["1 Day"], + "count": "28" + }, + { + "window": "due", + "offset": ["4 Weeks"], + "interval": ["1 Day"], + "count": "14" + }, + { + "window": "late", + "offset": ["6 Weeks"], + "interval": ["1 Day"], + "count": "322" + } + ] + } + ] +} From 5366ef4e4e1bafbf67f6d4876d4ce4cf9e089538 Mon Sep 17 00:00:00 2001 From: Maimoona Kausar Date: Thu, 9 Jun 2016 11:33:07 +0500 Subject: [PATCH 2/2] MK: Move to CE for scheduling --- .../org/opensrp/service/EventService.java | 1 + .../service/XlsFormDownloaderService.java | 2 + .../service/autosys/DataUpdateListener.java | 115 +++++++++++++ .../autosys/FormSubmissionProcessor.java | 159 ++++++++++++++++++ 4 files changed, 277 insertions(+) create mode 100644 opensrp-core/src/main/java/org/opensrp/service/autosys/DataUpdateListener.java create mode 100644 opensrp-core/src/main/java/org/opensrp/service/autosys/FormSubmissionProcessor.java diff --git a/opensrp-core/src/main/java/org/opensrp/service/EventService.java b/opensrp-core/src/main/java/org/opensrp/service/EventService.java index b15827ef17..715ec853d9 100644 --- a/opensrp-core/src/main/java/org/opensrp/service/EventService.java +++ b/opensrp-core/src/main/java/org/opensrp/service/EventService.java @@ -66,6 +66,7 @@ public synchronized Event addEvent(Event event) } event.setDateCreated(new Date()); + event.setDateEdited(new Date()); if(StringUtils.isEmptyOrWhitespaceOnly(event.getEventId())){ event.setEventId(System.currentTimeMillis()+""); } diff --git a/opensrp-core/src/main/java/org/opensrp/service/XlsFormDownloaderService.java b/opensrp-core/src/main/java/org/opensrp/service/XlsFormDownloaderService.java index c19b08ab26..e9d72a6498 100644 --- a/opensrp-core/src/main/java/org/opensrp/service/XlsFormDownloaderService.java +++ b/opensrp-core/src/main/java/org/opensrp/service/XlsFormDownloaderService.java @@ -41,6 +41,8 @@ public static void main(String[] args) { // } catch (IOException e) { // e.printStackTrace(); // } + + System.out.println(DateTime.now().toString("dd-MM-yyyy")); } public boolean downloadFormFiles(String directory,String username ,String formPath, String password,String formId, String formPk) throws IOException{ diff --git a/opensrp-core/src/main/java/org/opensrp/service/autosys/DataUpdateListener.java b/opensrp-core/src/main/java/org/opensrp/service/autosys/DataUpdateListener.java new file mode 100644 index 0000000000..83b3b5c486 --- /dev/null +++ b/opensrp-core/src/main/java/org/opensrp/service/autosys/DataUpdateListener.java @@ -0,0 +1,115 @@ +package org.opensrp.service.autosys; + +import static java.text.MessageFormat.format; +import static java.util.Collections.sort; +import static org.apache.commons.lang.exception.ExceptionUtils.getFullStackTrace; + +import java.text.MessageFormat; +import java.util.Comparator; +import java.util.Date; +import java.util.List; +import java.util.concurrent.locks.ReentrantLock; + +import org.joda.time.DateTime; +import org.motechproject.scheduler.domain.MotechEvent; +import org.motechproject.server.event.annotations.MotechListener; +import org.opensrp.common.AllConstants; +import org.opensrp.domain.AppStateToken; +import org.opensrp.domain.ErrorTrace; +import org.opensrp.domain.Event; +import org.opensrp.dto.form.FormSubmissionDTO; +import org.opensrp.form.domain.FormSubmission; +import org.opensrp.form.service.FormSubmissionService; +import org.opensrp.service.ClientService; +import org.opensrp.service.ConfigService; +import org.opensrp.service.ErrorTraceService; +import org.opensrp.service.EventService; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +import com.google.gson.Gson; +import com.google.gson.reflect.TypeToken; + +@Component +public class DataUpdateListener { + private static Logger logger = LoggerFactory.getLogger(DataUpdateListener.class.toString()); + private static final ReentrantLock lock = new ReentrantLock(); + private ClientService clientService; + private EventService eventService; + private ConfigService configService; + private FormSubmissionProcessor fsp; + private ErrorTraceService errorTraceService; + + @Autowired + public DataUpdateListener(ClientService clientService, EventService eventService, + FormSubmissionProcessor fsp, + ConfigService configService, ErrorTraceService errorTraceService) { + this.clientService = clientService; + this.eventService = eventService; + this.configService = configService; + this.errorTraceService = errorTraceService; + this.fsp = fsp; + this.configService.registerAppStateToken(AllConstants.Config.FORM_ENTITY_PARSER_LAST_SYNCED_FORM_SUBMISSION, + 0, "Token to keep track of forms processed for client n event parsing and schedule handling", true); + } + + @MotechListener(subjects = AllConstants.FORM_SCHEDULE_SUBJECT) + public void parseForms(MotechEvent event) { + if (!lock.tryLock()) { + logger.warn("Not fetching forms from Message Queue. It is already in progress."); + return; + } + try { + logger.info("Fetching Forms"); + long version = getVersion(); + + List events = eventService.findEventsBy(null, null, null, null, null, null, null, new DateTime(version) , DateTime.now()); + if (events.isEmpty()) { + logger.info("No new events found. Export token: " + version); + return; + } + + logger.info(format("Fetched {0} new forms found. Export token: {1}", events.size(), version)); + + sort(events, serverVersionComparator()); + + for (Event e : events) { + try{ + logger.info(format("Invoking save for form with instance Id: {0} and for entity Id: {1}", submission.instanceId(), submission.entityId())); + + if(submission.getField("no_client_event") == null || submission.getField("no_client_event").contains("false")){ + fsp.processFormSubmission(submission); + } + + configService.updateAppStateToken(AllConstants.Config.FORM_ENTITY_PARSER_LAST_SYNCED_FORM_SUBMISSION, submission.serverVersion()); + } + catch(Exception e){ + e.printStackTrace(); + errorTraceService.addError(new ErrorTrace(new Date(), "FormSubmissionProcessor", this.getClass().getName(), e.getStackTrace().toString(), "unsolved", FormSubmission.class.getName())); + } + } + } catch (Exception e) { + logger.error(MessageFormat.format("{0} occurred while trying to fetch forms. Message: {1} with stack trace {2}", + e.toString(), e.getMessage(), getFullStackTrace(e))); + } finally { + lock.unlock(); + } + } + + private long getVersion() { + AppStateToken token = configService.getAppStateTokenByName(AllConstants.Config.FORM_ENTITY_PARSER_LAST_SYNCED_FORM_SUBMISSION); + return token==null?0L:token.longValue(); + } + + private Comparator serverVersionComparator() { + return new Comparator() { + public int compare(Event first, Event second) { + long firstTimestamp = first.getDateCreated().getTime(); + long secondTimestamp = second.getDateCreated().getTime(); + return firstTimestamp == secondTimestamp ? 0 : firstTimestamp < secondTimestamp ? -1 : 1; + } + }; + } +} diff --git a/opensrp-core/src/main/java/org/opensrp/service/autosys/FormSubmissionProcessor.java b/opensrp-core/src/main/java/org/opensrp/service/autosys/FormSubmissionProcessor.java new file mode 100644 index 0000000000..53fd333362 --- /dev/null +++ b/opensrp-core/src/main/java/org/opensrp/service/autosys/FormSubmissionProcessor.java @@ -0,0 +1,159 @@ +package org.opensrp.service.autosys; + +import java.io.IOException; +import java.text.ParseException; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.joda.time.LocalDate; +import org.json.JSONException; +import org.json.JSONObject; +import org.opensrp.domain.Client; +import org.opensrp.domain.Event; +import org.opensrp.form.domain.FormSubmission; +import org.opensrp.form.domain.SubFormData; +import org.opensrp.scheduler.HealthSchedulerService; +import org.opensrp.scheduler.Schedule; +import org.opensrp.scheduler.Schedule.ActionType; +import org.opensrp.service.ClientService; +import org.opensrp.service.EventService; +import org.opensrp.service.formSubmission.handler.FormSubmissionRouter; +import org.opensrp.service.formSubmission.ziggy.ZiggyService; +import org.opensrp.util.Utils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import com.google.gson.Gson; +import com.mysql.jdbc.StringUtils; + +@Service +public class FormSubmissionProcessor{ + private static Logger logger = LoggerFactory.getLogger(DataUpdateListener.class.toString()); + + private ZiggyService ziggyService; + private FormSubmissionRouter formSubmissionRouter; + private FormEntityConverter formEntityConverter; + private ClientService clientService; + private EventService eventService; + private HealthSchedulerService scheduleService; + + @Autowired + public FormSubmissionProcessor(ZiggyService ziggyService, FormSubmissionRouter formSubmissionRouter, + FormEntityConverter formEntityConverter, HealthSchedulerService scheduleService, + ClientService clientService, EventService eventService) throws IOException { + this.ziggyService = ziggyService; + this.formSubmissionRouter = formSubmissionRouter; + this.formEntityConverter = formEntityConverter; + this.scheduleService = scheduleService; + this.clientService = clientService; + this.eventService = eventService; + } + + public void processFormSubmission(FormSubmission submission) throws Exception { + // ugly hack TODO + if(submission.bindType().equalsIgnoreCase("stock")) return; + + // parse and into client and event model + logger.info("Creating model entities"); + makeModelEntities(submission); + logger.info("Handling xls configured schedules"); + handleSchedules(submission); + if(ziggyService.isZiggyCompliant(submission.bindType())){ + passToZiggy(submission); + //and skip form submission routing as ziggy does it automatically + } + else {//if not ziggy entity call custom route handler explicitly + logger.info("Routing to custom handler"); + formSubmissionRouter.route(submission); + } + } + + void handleSchedules(FormSubmission submission) throws JSONException, IOException { + List schl = scheduleService.findAutomatedSchedules(submission.formName()); + for (Schedule sch : schl) { + Map entsch = getEntitiesQualifyingForSchedule(submission, sch); + System.out.println("creating schedule for : "+entsch); + for (String enid : entsch.keySet()) { + if(sch.action().equals(ActionType.enroll)){ + scheduleService.enrollIntoSchedule(enid, sch.schedule(), + sch.milestone(), entsch.get(enid), submission.instanceId()); + } + else if(sch.action().equals(ActionType.fulfill)){ + scheduleService.fullfillMilestoneAndCloseAlert(enid, submission.anmId(), sch.schedule() + , LocalDate.parse(entsch.get(enid)), submission.instanceId()); + } + else if(sch.action().equals(ActionType.unenroll)){ + scheduleService.unEnrollFromSchedule(enid, submission.anmId(), sch.schedule(), submission.instanceId()); + } + else if(sch.action().equals(ActionType.unenroll) && sch.schedule().equalsIgnoreCase("*")){ + scheduleService.unEnrollFromAllSchedules(enid, submission.instanceId()); + } + } + } + } + + Map getEntitiesQualifyingForSchedule(FormSubmission submission, Schedule schedule) throws JSONException { + Map entityIds = new HashMap(); + if(schedule.applicableForEntity(submission.bindType())){ + String res = evaluateScheduleFor(schedule, submission.instance().form().getFieldsAsMap()); + if(!StringUtils.isEmptyOrWhitespaceOnly(res)){ + entityIds.put(submission.entityId(), res); + } + } + + if(submission.subForms() != null) + for (SubFormData sbf : submission.subForms()) { + if(schedule.applicableForEntity(sbf.bindType())){ + for (Map inst : sbf.instances()) { + String res = evaluateScheduleFor(schedule, inst); + if(!StringUtils.isEmptyOrWhitespaceOnly(res)){ + entityIds.put(inst.get("id"), res); + } + } + } + } + return entityIds; + } + + String evaluateScheduleFor(Schedule schedule, Map flvl) { + //find first field in submission that qualifies triggerdate field and has a value + for (String tf : schedule.triggerDateFields()) { + String flv = flvl.get(tf); + // if field has value and schedule flag field is empty or has value 1 or true + if(!StringUtils.isEmptyOrWhitespaceOnly(flv) && schedule.passesValidations(flvl)){ + return flv; + } + } + return null; + } + + private void makeModelEntities(FormSubmission submission) throws JSONException { + Client c = formEntityConverter.getClientFromFormSubmission(submission); + Event e = formEntityConverter.getEventFromFormSubmission(submission); + Map> dep = formEntityConverter.getDependentClientsFromFormSubmission(submission); + + if(clientService.findClient(c) != null){ + clientService.mergeClient(c); + } + else clientService.addClient(c); + + eventService.addEvent(e); + // TODO relationships b/w entities + + for (Map cm : dep.values()) { + Client cin = (Client)cm.get("client"); + Event evin = (Event)cm.get("event"); + clientService.addClient(cin); + eventService.addEvent(evin); + } + } + + private void passToZiggy(FormSubmission submission) { + String params = Utils.getZiggyParams(submission); + ziggyService.saveForm(params, new Gson().toJson(submission.instance())); + } + +}