diff --git a/assets/config/couchdb.properties b/assets/config/couchdb.properties index 849574625b..b9a831f2a6 100644 --- a/assets/config/couchdb.properties +++ b/assets/config/couchdb.properties @@ -1,3 +1,4 @@ +#this file is used by motech host=localhost port=5984 maxConnections=20 diff --git a/assets/config/opensrp.properties b/assets/config/opensrp.properties index 5964f09f7b..ff773174dd 100644 --- a/assets/config/opensrp.properties +++ b/assets/config/opensrp.properties @@ -20,7 +20,7 @@ mcts-report-delay-in-days=10 mcts.poll.time.interval.in.minutes=10 # OpenMRS configuration -openmrs.url=http://localhost:8181/openmrs/ +openmrs.url=http://localhost:8080/openmrs/ openmrs.username=admin openmrs.password=Admin123 openmrs.idgen.url=/module/idgen/exportIdentifiers.form @@ -51,7 +51,7 @@ jdbc.backend=MYSQL jdbc.driverClassName=com.mysql.jdbc.Driver jdbc.username=root jdbc.password=VA1913wm -jdbc.url=jdbc:mysql://localhost:3306/opensrp_tbreach?createDatabaseIfNotExist=true +jdbc.url=jdbc:mysql://localhost:3306/opensrp?createDatabaseIfNotExist=true ##jdbc url with server and port but without database jdbc.url-wo-db=jdbc:mysql://localhost:3306 @@ -98,4 +98,4 @@ opensrp.authencation.cache.ttl=600 redis.host=localhost redis.port=6379 redis.password=RedI$P@S5 -redis.pool.max.connections=25 \ No newline at end of file +redis.pool.max.connections=25 diff --git a/assets/config/schedule_tracking.properties b/assets/config/schedule_tracking.properties index e5de3c178a..8526c88542 100644 --- a/assets/config/schedule_tracking.properties +++ b/assets/config/schedule_tracking.properties @@ -1 +1,2 @@ +#this file is used by motech schedule.definitions.directory=/schedules \ No newline at end of file diff --git a/assets/migrations/environments/development.properties b/assets/migrations/environments/development.properties index 3e8e71d1de..770eb8f34b 100644 --- a/assets/migrations/environments/development.properties +++ b/assets/migrations/environments/development.properties @@ -82,4 +82,4 @@ core_tablespace_location='/opt/postgres/core' error_tablespace_location ='/opt/postgres/error' schedule_tablespace_location='/opt/postgres/schedule' feed_tablespace_location='/opt/postgres/feed' -form_tablespace_location='/opt/postgres/form' \ No newline at end of file +form_tablespace_location='/opt/postgres/form' diff --git a/build/maven.properties b/build/maven.properties index 41a4367a9c..68d6a6d379 100644 --- a/build/maven.properties +++ b/build/maven.properties @@ -1,16 +1,16 @@ #database configuration that is not likely to change unless massive refactoring -couchdb.db.opensrp=opensrp_tbreach -couchdb.db.form=opensrp-form_tbreach -couchdb.db.atomfeed=atomfeed_tbreach -couchdb.db.mcts=opensrp-mcts_tbreach -couchdb.db.motech-scheduletracking=motech-scheduletracking-api_tbreach -couchdb.db.error=opensrp-errortrace_tbreach +couchdb.db.opensrp=opensrp +couchdb.db.form=opensrp-form +couchdb.db.atomfeed=atomfeed +couchdb.db.mcts=opensrp-mcts +couchdb.db.motech-scheduletracking=motech-scheduletracking-api +couchdb.db.error=opensrp-errortrace -db.quartz=motechquartz_tbreach -db.reporting=opensrp_tbreach -db.reporting.report=report_tbreach -db.reporting.anm=anm_report_tbreach +db.quartz=motechquartz +db.reporting=opensrp +db.reporting.report=report +db.reporting.anm=anm_report #selenium diff --git a/opensrp-common/pom.xml b/opensrp-common/pom.xml index 85ba887814..afcbafe31f 100644 --- a/opensrp-common/pom.xml +++ b/opensrp-common/pom.xml @@ -120,6 +120,10 @@ 2.3 test - + + org.apache.httpcomponents + httpclient + 4.5.2 + diff --git a/opensrp-common/src/main/java/org/opensrp/common/util/CustomCertificateSSLSocketFactory.java b/opensrp-common/src/main/java/org/opensrp/common/util/CustomCertificateSSLSocketFactory.java index 1beda5bff4..04aff2d300 100644 --- a/opensrp-common/src/main/java/org/opensrp/common/util/CustomCertificateSSLSocketFactory.java +++ b/opensrp-common/src/main/java/org/opensrp/common/util/CustomCertificateSSLSocketFactory.java @@ -30,7 +30,7 @@ public CustomCertificateSSLSocketFactory(KeyStore truststore) throws NoSuchAlgor super(truststore); System.setProperty("disable_bad_sslciphers", "yes"); - System.setProperty("jsse.enableSNIExtension", "false"); + System.setProperty("jsse.enableSNIExtension", "true"); TrustManager tm = new X509TrustManager() { public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException { diff --git a/opensrp-common/src/main/java/org/opensrp/common/util/HostNameSetter.java b/opensrp-common/src/main/java/org/opensrp/common/util/HostNameSetter.java new file mode 100644 index 0000000000..c0b8f37c3d --- /dev/null +++ b/opensrp-common/src/main/java/org/opensrp/common/util/HostNameSetter.java @@ -0,0 +1,77 @@ +package org.opensrp.common.util; + +import java.lang.ref.WeakReference; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.util.concurrent.atomic.AtomicReference; + +import javax.net.ssl.SSLSocket; + +public class HostNameSetter { + + private static final AtomicReference CURRENT = new AtomicReference<>(); + + private final WeakReference cls; + private final WeakReference setter; + + private HostNameSetter(Class clazz, Method setter) { + this.cls = new WeakReference<>(clazz); + this.setter = setter == null ? null : new WeakReference<>(setter); + } + + private static Method init(Class cls) { + Method s = null; + try { + s = cls.getMethod("setHost", String.class); + } catch (Exception e) { + initFail(e); + } + CURRENT.set(new HostNameSetter(cls, s)); + return s; + } + + private static void initFail(Exception e) { + // ignore + } + + private Method reuse(Class cls) { + final boolean wrongClass = this.cls.get() != cls; + if (wrongClass) { + return init(cls); + } + + final boolean setterNotSupported = this.setter == null; + if (setterNotSupported) { + return null; + } + + final Method s = setter.get(); + final boolean setterLost = s == null; + return setterLost ? init(cls) : s; + } + + /** + * Invokes the {@code #setName(String)} method if one is present. + * + * @param hostname + * the name to set + * @param sslsock + * the socket + */ + public static void setServerNameIndication(String hostname, SSLSocket sslsock) { + final Class cls = sslsock.getClass(); + final HostNameSetter current = CURRENT.get(); + final Method setter = (current == null) ? init(cls) : current.reuse(cls); + if (setter != null) { + try { + setter.invoke(sslsock, hostname); + } catch (IllegalArgumentException | IllegalAccessException | InvocationTargetException e) { + setServerNameIndicationFail(e); + } + } + } + + private static void setServerNameIndicationFail(Exception e) { + // ignore + } +} \ No newline at end of file diff --git a/opensrp-common/src/main/java/org/opensrp/common/util/HttpUtil.java b/opensrp-common/src/main/java/org/opensrp/common/util/HttpUtil.java index 318ce544b9..112a582aba 100644 --- a/opensrp-common/src/main/java/org/opensrp/common/util/HttpUtil.java +++ b/opensrp-common/src/main/java/org/opensrp/common/util/HttpUtil.java @@ -1,185 +1,177 @@ package org.opensrp.common.util; +import java.io.IOException; +import java.net.URI; +import java.net.URISyntaxException; + import org.apache.commons.codec.binary.Base64; import org.apache.commons.io.IOUtils; import org.apache.commons.lang.StringUtils; -import org.apache.http.client.methods.*; -import org.apache.http.conn.ClientConnectionManager; -import org.apache.http.conn.scheme.PlainSocketFactory; -import org.apache.http.conn.scheme.Scheme; -import org.apache.http.conn.scheme.SchemeRegistry; +import org.apache.http.client.methods.HttpDelete; +import org.apache.http.client.methods.HttpGet; +import org.apache.http.client.methods.HttpPost; +import org.apache.http.client.methods.HttpPut; +import org.apache.http.client.methods.HttpRequestBase; import org.apache.http.entity.StringEntity; -import org.apache.http.impl.client.DefaultHttpClient; -import org.apache.http.impl.conn.tsccm.ThreadSafeClientConnManager; -import org.apache.http.params.BasicHttpParams; -import org.apache.http.params.HttpConnectionParams; +import org.apache.http.impl.client.CloseableHttpClient; +import org.apache.http.impl.client.DefaultRedirectStrategy; +import org.apache.http.impl.client.HttpClientBuilder; import org.apache.http.protocol.HTTP; import org.springframework.stereotype.Component; -import java.io.IOException; -import java.net.URI; -import java.net.URISyntaxException; -import java.security.KeyStore; - @Component public class HttpUtil { - - private HttpUtil() { - - } - - public enum AuthType { - BASIC, TOKEN, NONE - } - - private final static DefaultHttpClient httpClient = init(); - - public static DefaultHttpClient init() { - try { - //TODO add option to ignore cetificate validation in opensrp.prop - KeyStore trustStore = KeyStore.getInstance(KeyStore.getDefaultType()); - trustStore.load(null, null); - CustomCertificateSSLSocketFactory sf = new CustomCertificateSSLSocketFactory(trustStore); - sf.setHostnameVerifier(CustomCertificateSSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER); - - BasicHttpParams basicHttpParams = new BasicHttpParams(); - HttpConnectionParams.setConnectionTimeout(basicHttpParams, 30000); - HttpConnectionParams.setSoTimeout(basicHttpParams, 60000); - - SchemeRegistry registry = new SchemeRegistry(); - registry.register(new Scheme("http", PlainSocketFactory.getSocketFactory(), 80)); - registry.register(new Scheme("https", sf, 443)); - - ClientConnectionManager connectionManager = new ThreadSafeClientConnManager(basicHttpParams, registry); - return new DefaultHttpClient(connectionManager, basicHttpParams); - } catch (Exception e) { - e.printStackTrace(); - throw new RuntimeException(e); - } - } - - public static HttpResponse post(String url, String payload, String data, String username, String password) { - return post(url, payload, data, "application/json", AuthType.BASIC, username + ":" + password); - } - - public static HttpResponse post(String url, String payload, String data) { - return post(url, payload, data, "application/json", AuthType.NONE, ""); - } - - public static HttpResponse postWithToken(String url, String payload, String data, String token) { - return post(url, payload, data, "application/json", AuthType.TOKEN, token); - } - - //TODO: Move setting content type in makeConnection function. - public static HttpResponse post(String url, String payload, String data, String contentType, AuthType authType, String authString) { - try { - HttpPost request = (HttpPost) makeConnection(url, payload, RequestMethod.POST, authType, authString); - request.setHeader(HTTP.CONTENT_TYPE, contentType); - StringEntity entity = new StringEntity(data == null ? "" : data); - System.out.println(data); - entity.setContentEncoding(contentType); - request.setEntity(entity); - org.apache.http.HttpResponse response = httpClient.execute(request); - return createCustomResponseFrom(response); - } catch (Exception e) { - e.printStackTrace(); - throw new RuntimeException(e); - } - } - - public static HttpResponse get(String url, String payload, String username, String password) { - return get(url, payload, AuthType.BASIC, username + ":" + password); - } - - public static HttpResponse delete(String url, String payload, String username, String password) { - return delete(url, payload, AuthType.BASIC, username + ":" + password); - } - - public static HttpResponse get(String url, String payload) { - return get(url, payload, AuthType.NONE, ""); - } - - public static HttpResponse getWithToken(String url, String payload, String token) { - return get(url, payload, AuthType.BASIC, token); - } - - public static HttpResponse get(String url, String payload, AuthType authType, String authString) { - try { - HttpGet request = (HttpGet) makeConnection(url, payload, RequestMethod.GET, authType, authString); - org.apache.http.HttpResponse response = httpClient.execute(request); - return createCustomResponseFrom(response); - } catch (Exception e) { - throw new RuntimeException(e); - } - } - - public static HttpResponse delete(String url, String payload, AuthType authType, String authString) { - try { - HttpDelete request = (HttpDelete) makeConnection(url, payload, RequestMethod.DELETE, authType, authString); - org.apache.http.HttpResponse response = httpClient.execute(request); - return createCustomResponseFrom(response); - } catch (Exception e) { - throw new RuntimeException(e); - } - } - - static HttpResponse createCustomResponseFrom(org.apache.http.HttpResponse response) throws IOException { - int statusCode = response.getStatusLine().getStatusCode(); - String entity = ""; - if (response.getEntity() != null) { - entity = IOUtils.toString(response.getEntity().getContent()); - } - - return new HttpResponse(checkSuccessBasedOnHttpCode(statusCode), statusCode, entity); - } - - static boolean checkSuccessBasedOnHttpCode(int httpCode) { - if (httpCode >= 400 && httpCode <= 599) { - return false; - } else { - return true; - } - } - - static HttpRequestBase makeConnection(String url, String payload, RequestMethod method, AuthType authType, String authString) throws URISyntaxException { - String charset = "UTF-8"; - - if (url.endsWith("/")) { - url = url.substring(0, url.lastIndexOf("/")); - } - url = (url + (StringUtils.isBlank(payload) ? "" : ("?" + payload))).replaceAll(" ", "%20"); - URI urlo = new URI(url); - - HttpRequestBase requestBase = null; - if (method.equals(RequestMethod.GET)) { - requestBase = new HttpGet(urlo); - } else if (method.equals(RequestMethod.POST)) { - requestBase = new HttpPost(urlo); - } else if (method.equals(RequestMethod.PUT)) { - requestBase = new HttpPut(urlo); - } else if (method.equals(RequestMethod.DELETE)) { - requestBase = new HttpDelete(urlo); - } - requestBase.setURI(urlo); - requestBase.addHeader("Accept-Charset", charset); - - if (authType.name().equalsIgnoreCase("basic")) { - String encoded = authString.matches(".+:.+") ? new String(Base64.encodeBase64(authString.getBytes())) : authString; - requestBase.addHeader("Authorization", "Basic " + encoded); - } else if (authType.name().equalsIgnoreCase("token")) { - requestBase.addHeader("Authorization", "Token " + authString); - } - - System.out.println(url); - return requestBase; - } - - public static String removeEndingSlash(String str) { - return str.endsWith("/") ? str.substring(0, str.lastIndexOf("/")) : str; - } - - public static String removeTrailingSlash(String str) { - return str.startsWith("/") ? str.substring(1) : str; - } + private HttpUtil() { + + } + + public enum AuthType { + BASIC, TOKEN, NONE + } + + private static CloseableHttpClient init(String host) { + try { + + HttpClientBuilder clientBuilder = HttpClientBuilder.create(); + ServerNameIndicationSSLContext ctx = new ServerNameIndicationSSLContext( + host, 443); + clientBuilder.setSSLContext(ctx); + clientBuilder.setRedirectStrategy(new DefaultRedirectStrategy()); + return clientBuilder.build(); + + } catch (Exception e) { + e.printStackTrace(); + throw new RuntimeException(e); + } + } + + public static HttpResponse post(String url, String payload, String data, String username, String password) { + return post(url, payload, data, "application/json", AuthType.BASIC, username + ":" + password); + } + + public static HttpResponse post(String url, String payload, String data) { + return post(url, payload, data, "application/json", AuthType.NONE, ""); + } + + public static HttpResponse postWithToken(String url, String payload, String data, String token) { + return post(url, payload, data, "application/json", AuthType.TOKEN, token); + } + + public static HttpResponse post(String url, String payload, String data, String contentType, AuthType authType, + String authString) { + try { + HttpPost request = (HttpPost) makeConnection(url, payload, RequestMethod.POST, authType, authString); + request.setHeader(HTTP.CONTENT_TYPE, contentType); + StringEntity entity = new StringEntity(data == null ? "" : data); + System.out.println(data); + entity.setContentEncoding(contentType); + request.setEntity(entity); + CloseableHttpClient httpClient = init(request.getURI().getHost()); + org.apache.http.HttpResponse response = httpClient.execute(request); + return createCustomResponseFrom(response); + } catch (Exception e) { + e.printStackTrace(); + throw new RuntimeException(e); + } + } + + public static HttpResponse get(String url, String payload, String username, String password) { + return get(url, payload, AuthType.BASIC, username + ":" + password); + } + + public static HttpResponse delete(String url, String payload, String username, String password) { + return delete(url, payload, AuthType.BASIC, username + ":" + password); + } + + public static HttpResponse get(String url, String payload) { + return get(url, payload, AuthType.NONE, ""); + } + + public static HttpResponse getWithToken(String url, String payload, String token) { + return get(url, payload, AuthType.BASIC, token); + } + + public static HttpResponse get(String url, String payload, AuthType authType, String authString) { + try { + HttpGet request = (HttpGet) makeConnection(url, payload, RequestMethod.GET, authType, authString); + CloseableHttpClient httpClient = init(request.getURI().getHost()); + org.apache.http.HttpResponse response = httpClient.execute(request); + return createCustomResponseFrom(response); + } catch (Exception e) { + throw new RuntimeException(e); + } + } + + public static HttpResponse delete(String url, String payload, AuthType authType, String authString) { + try { + HttpDelete request = (HttpDelete) makeConnection(url, payload, RequestMethod.DELETE, authType, authString); + CloseableHttpClient httpClient = init(request.getURI().getHost()); + org.apache.http.HttpResponse response = httpClient.execute(request); + return createCustomResponseFrom(response); + } catch (Exception e) { + throw new RuntimeException(e); + } + } + + static HttpResponse createCustomResponseFrom(org.apache.http.HttpResponse response) throws IOException { + int statusCode = response.getStatusLine().getStatusCode(); + String entity = ""; + if (response.getEntity() != null) { + entity = IOUtils.toString(response.getEntity().getContent()); + } + + return new HttpResponse(checkSuccessBasedOnHttpCode(statusCode), statusCode, entity); + } + + static boolean checkSuccessBasedOnHttpCode(int httpCode) { + if (httpCode >= 400 && httpCode <= 599) { + return false; + } else { + return true; + } + } + + static HttpRequestBase makeConnection(String url, String payload, RequestMethod method, AuthType authType, + String authString) throws URISyntaxException { + String charset = "UTF-8"; + + if (url.endsWith("/")) { + url = url.substring(0, url.lastIndexOf("/")); + } + url = (url + (StringUtils.isBlank(payload) ? "" : ("?" + payload))).replaceAll(" ", "%20"); + URI urlo = new URI(url); + + HttpRequestBase requestBase = null; + if (method.equals(RequestMethod.GET)) { + requestBase = new HttpGet(urlo); + } else if (method.equals(RequestMethod.POST)) { + requestBase = new HttpPost(urlo); + } else if (method.equals(RequestMethod.PUT)) { + requestBase = new HttpPut(urlo); + } else if (method.equals(RequestMethod.DELETE)) { + requestBase = new HttpDelete(urlo); + } + requestBase.setURI(urlo); + requestBase.addHeader("Accept-Charset", charset); + + if (authType.name().equalsIgnoreCase("basic")) { + String encoded = authString.matches(".+:.+") ? new String(Base64.encodeBase64(authString.getBytes())) + : authString; + requestBase.addHeader("Authorization", "Basic " + encoded); + } else if (authType.name().equalsIgnoreCase("token")) { + requestBase.addHeader("Authorization", "Token " + authString); + } + + System.out.println(url); + return requestBase; + } + + public static String removeEndingSlash(String str) { + return str.endsWith("/") ? str.substring(0, str.lastIndexOf("/")) : str; + } + + public static String removeTrailingSlash(String str) { + return str.startsWith("/") ? str.substring(1) : str; + } } diff --git a/opensrp-common/src/main/java/org/opensrp/common/util/ServerNameIndicationSSLContext.java b/opensrp-common/src/main/java/org/opensrp/common/util/ServerNameIndicationSSLContext.java new file mode 100644 index 0000000000..ce9dcd6640 --- /dev/null +++ b/opensrp-common/src/main/java/org/opensrp/common/util/ServerNameIndicationSSLContext.java @@ -0,0 +1,36 @@ +package org.opensrp.common.util; + +import java.security.NoSuchAlgorithmException; +import java.util.ArrayList; +import java.util.List; + +import javax.net.ssl.SNIHostName; +import javax.net.ssl.SNIServerName; +import javax.net.ssl.SSLContext; +import javax.net.ssl.SSLParameters; + +public class ServerNameIndicationSSLContext extends SSLContext { + + String hostname; + + public ServerNameIndicationSSLContext(String hostname, int port) { + super(new ServerNameIndicationSSLContextSpi(hostname, port), null, "Default"); + this.hostname = hostname; + } + + public SSLParameters getParametersForSNI() { + SSLParameters params = null; + try { + params = SSLContext.getDefault().getDefaultSSLParameters(); + } catch (NoSuchAlgorithmException e) { + e.printStackTrace(); + } + + List sNIServerNameList = new ArrayList(); + sNIServerNameList.add(new SNIHostName(hostname)); + params.setServerNames(sNIServerNameList); + params.setEndpointIdentificationAlgorithm("HTTPS"); + return params; + } + +} \ No newline at end of file diff --git a/opensrp-common/src/main/java/org/opensrp/common/util/ServerNameIndicationSSLContextSpi.java b/opensrp-common/src/main/java/org/opensrp/common/util/ServerNameIndicationSSLContextSpi.java new file mode 100644 index 0000000000..c29913406d --- /dev/null +++ b/opensrp-common/src/main/java/org/opensrp/common/util/ServerNameIndicationSSLContextSpi.java @@ -0,0 +1,81 @@ +package org.opensrp.common.util; + +import java.security.KeyManagementException; +import java.security.NoSuchAlgorithmException; +import java.security.SecureRandom; + +import javax.net.ssl.KeyManager; +import javax.net.ssl.SSLContext; +import javax.net.ssl.SSLContextSpi; +import javax.net.ssl.SSLEngine; +import javax.net.ssl.SSLServerSocketFactory; +import javax.net.ssl.SSLSessionContext; +import javax.net.ssl.SSLSocketFactory; +import javax.net.ssl.TrustManager; + +public class ServerNameIndicationSSLContextSpi extends SSLContextSpi { + + private final String hostname; + private final int port; + + public ServerNameIndicationSSLContextSpi(String hostname, int port) { + this.hostname = hostname; + this.port = port; + } + + @Override + protected void engineInit(KeyManager[] keyManagers, TrustManager[] trustManagers, SecureRandom secureRandom) + throws KeyManagementException { + + } + + @Override + protected SSLSocketFactory engineGetSocketFactory() { + try { + return SSLContext.getDefault().getSocketFactory(); + } catch (NoSuchAlgorithmException e) { + e.printStackTrace(); + } + return null; + } + + @Override + protected SSLServerSocketFactory engineGetServerSocketFactory() { + try { + return SSLContext.getDefault().getServerSocketFactory(); + } catch (NoSuchAlgorithmException e) { + e.printStackTrace(); + } + return null; + } + + @Override + protected SSLEngine engineCreateSSLEngine() { + try { + return SSLContext.getDefault().createSSLEngine(hostname, port); + } catch (NoSuchAlgorithmException e) { + e.printStackTrace(); + } + return null; + } + + @Override + protected SSLEngine engineCreateSSLEngine(String host, int port) { + try { + return SSLContext.getDefault().createSSLEngine(host, port); + } catch (NoSuchAlgorithmException e) { + e.printStackTrace(); + } + return null; + } + + @Override + protected SSLSessionContext engineGetServerSessionContext() { + return null; + } + + @Override + protected SSLSessionContext engineGetClientSessionContext() { + return null; + } +} diff --git a/opensrp-connector/src/main/java/org/opensrp/connector/openmrs/service/EncounterService.java b/opensrp-connector/src/main/java/org/opensrp/connector/openmrs/service/EncounterService.java index e3116f50a6..fc09781a49 100644 --- a/opensrp-connector/src/main/java/org/opensrp/connector/openmrs/service/EncounterService.java +++ b/opensrp-connector/src/main/java/org/opensrp/connector/openmrs/service/EncounterService.java @@ -20,386 +20,417 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + import com.mysql.jdbc.StringUtils; @Service public class EncounterService extends OpenmrsService { - - public static final String OPENMRS_UUID_IDENTIFIER_TYPE = "OPENMRS_UUID"; - - private static final String ENCOUNTER_URL = "ws/rest/v1/encounter";//"ws/rest/emrapi/encounter"; - - private static final String OBS_URL = "ws/rest/v1/obs"; - - private static final String ENCOUNTER__TYPE_URL = "ws/rest/v1/encountertype"; - - private PatientService patientService; - - private OpenmrsUserService userService; - - private ClientService clientService; - - private OpenmrsLocationService openmrsLocationService; - - @Autowired - public EncounterService(PatientService patientService, OpenmrsUserService userService, ClientService clientService, - OpenmrsLocationService openmrsLocationService) { - this.patientService = patientService; - this.userService = userService; - this.clientService = clientService; - this.openmrsLocationService = openmrsLocationService; - } - - public EncounterService(String openmrsUrl, String user, String password) { - super(openmrsUrl, user, password); - } - - public PatientService getPatientService() { - return patientService; - } - - public void setPatientService(PatientService patientService) { - this.patientService = patientService; - } - - public OpenmrsUserService getUserService() { - return userService; - } - - public void setUserService(OpenmrsUserService userService) { - this.userService = userService; - } - - public JSONObject getEncounterByUuid(String uuid, boolean noRepresentationTag) throws JSONException { - return new JSONObject(HttpUtil.get(getURL() + "/" + ENCOUNTER_URL + "/" + uuid, noRepresentationTag ? "" : "v=full", - OPENMRS_USER, OPENMRS_PWD).body()); - } - - public JSONObject getObsByEncounterUuid(String encounterUuid) throws JSONException { - // The data format returned contains the obs uuid and concept uuids - return new JSONObject(HttpUtil.get(getURL() + "/" + ENCOUNTER_URL + "/" + encounterUuid, - "v=custom:(uuid,obs:(uuid,concept:(uuid)))", OPENMRS_USER, OPENMRS_PWD).body()); - } - - public JSONObject getObsUuidByParentObsUuid(String obsUuid) throws JSONException { - //The data format returned contains the children obs uuid and concept uuids - return new JSONObject(HttpUtil.get(getURL() + "/" + OBS_URL + "/" + obsUuid, - "v=custom:(groupMembers:(uuid,concept:(uuid)))", OPENMRS_USER, OPENMRS_PWD).body()); - } - - public JSONObject getEncounterType(String encounterType) throws JSONException { - // we have to use this ugly approach because identifier not found throws exception and - // its hard to find whether it was network error or object not found or server error - JSONObject resEncounterType = new JSONObject( - HttpUtil.get(getURL() + "/" + ENCOUNTER__TYPE_URL, "v=full", OPENMRS_USER, OPENMRS_PWD).body()); - - if (resEncounterType.has("results") && resEncounterType.get("results") instanceof JSONArray) { - JSONArray res = resEncounterType.getJSONArray("results"); - for (int i = 0; i < res.length(); i++) { - if (res.getJSONObject(i).getString("display").equalsIgnoreCase(encounterType)) { - return res.getJSONObject(i); - } - } - } - return null; - } - - public JSONObject createEncounterType(String name, String description) throws JSONException { - JSONObject o = convertEncounterToOpenmrsJson(name, description); - return new JSONObject( - HttpUtil.post(getURL() + "/" + ENCOUNTER__TYPE_URL, "", o.toString(), OPENMRS_USER, OPENMRS_PWD).body()); - } - - public JSONObject convertEncounterToOpenmrsJson(String name, String description) throws JSONException { - JSONObject a = new JSONObject(); - a.put("name", name); - a.put("description", description); - return a; - } - - public JSONObject createEncounter(Event e) throws JSONException { - String ptuuid = patientService.getPatientByIdentifierUUID(e.getBaseEntityId()); - if (ptuuid == null) { - return null; - } - JSONObject enc = new JSONObject(); - - String pruuid = userService.getPersonUUIDByUser(e.getProviderId()); - - enc.put("encounterDatetime", OPENMRS_DATE.format(e.getEventDate().toDate())); - // patient must be existing in OpenMRS before it submits an encounter. if it doesnot it would throw NPE - enc.put("patient", ptuuid); - //TODO enc.put("patientUuid", pt.getString("uuid")); - enc.put("encounterType", e.getEventType()); - //TODO enc.put("encounterTypeUuid", e.getEventType()); - enc.put("location", e.getLocationId()); - enc.put("provider", pruuid); - - List ol = e.getObs(); - Map p = new HashMap<>(); - Map pc = new HashMap<>(); - - if (ol != null) - for (Obs obs : ol) { - if (!StringUtils.isEmptyOrWhitespaceOnly(obs.getFieldCode()) - && (obs.getFieldType() == null || obs.getFieldType().equalsIgnoreCase("concept"))) { - // skipping empty obs and fields that don't have concepts if no parent simply make it root obs - - if (obs.getFieldType().equals("concept") && obs.getFormSubmissionField().equals("Birth_Facility_Name") - && obs.getValue() != null) { - Location location = openmrsLocationService.getLocation(obs.getValue().toString()); - if (location != null && location.getName() != null) { - obs.setValue(location.getName()); - } - } - if (StringUtils.isEmptyOrWhitespaceOnly(obs.getParentCode())) { - p.put(obs.getFieldCode(), convertObsToJson(obs)); - } else { - //find parent obs if not found search and fill or create one - JSONArray parentObs = p.get(obs.getParentCode()); - if (parentObs == null) { - p.put(obs.getParentCode(), convertObsToJson(getOrCreateParent(ol, obs))); - } - // find if any other exists with same parent if so add to the list otherwise create new list - JSONArray obl = pc.get(obs.getParentCode()); - if (obl == null) { - obl = new JSONArray(); - } - JSONArray addobs = convertObsToJson(obs); - for (int i = 0; i < addobs.length(); i++) { - obl.put(addobs.getJSONObject(i)); - } - pc.put(obs.getParentCode(), obl); - } - } - } - - JSONArray obar = new JSONArray(); - for (String ok : p.keySet()) { - for (int i = 0; i < p.get(ok).length(); i++) { - JSONObject obo = p.get(ok).getJSONObject(i); - - JSONArray cob = pc.get(ok); - if (cob != null && cob.length() > 0) { - obo.put("groupMembers", cob); - } - - obar.put(obo); - } - } - enc.put("obs", obar); - - HttpResponse op = HttpUtil.post(HttpUtil.removeEndingSlash(OPENMRS_BASE_URL) + "/" + ENCOUNTER_URL, "", - enc.toString(), OPENMRS_USER, OPENMRS_PWD); - return new JSONObject(op.body()); - } - - public JSONObject buildUpdateEncounter(Event e) throws JSONException { - String openmrsuuid = e.getIdentifier(OPENMRS_UUID_IDENTIFIER_TYPE); - JSONObject encounterObsUuids = getObsByEncounterUuid(openmrsuuid); - JSONArray obsUuids = encounterObsUuids.getJSONArray("obs"); - - System.out.print("[OBS-UUIDS]" + obsUuids); - - String ptuuid = patientService.getPatientByIdentifierUUID(e.getBaseEntityId());//TODO find by any identifier - JSONObject enc = new JSONObject(); - - String pruuid = userService.getPersonUUIDByUser(e.getProviderId()); - - enc.put("encounterDatetime", OPENMRS_DATE.format(e.getEventDate().toDate())); - // patient must be existing in OpenMRS before it submits an encounter. if it doesnot it would throw NPE - enc.put("patient", ptuuid); - //TODO enc.put("patientUuid", pt.getString("uuid")); - enc.put("encounterType", e.getEventType()); - enc.put("location", e.getLocationId()); - enc.put("provider", pruuid == null ? "" : pruuid); - - List ol = e.getObs(); - Map p = new HashMap<>(); - Map pc = new HashMap<>(); - - if (ol != null) - for (Obs obs : ol) { - if (!StringUtils.isEmptyOrWhitespaceOnly(obs.getFieldCode()) - && (obs.getFieldType() == null || obs.getFieldType().equalsIgnoreCase("concept"))) { - //skipping empty obs if no parent simply make it root obs - if (obs.getFieldType().equals("concept") && obs.getFormSubmissionField().equals("Birth_Facility_Name") - && obs.getValue() != null - && openmrsLocationService.getLocation(obs.getValue().toString()).getName() != null) { - obs.setValue(openmrsLocationService.getLocation(obs.getValue().toString()).getName()); - } - if (StringUtils.isEmptyOrWhitespaceOnly(obs.getParentCode())) { - p.put(obs.getFieldCode(), convertObsToJson(obs)); - } else { - //find parent obs if not found search and fill or create one - JSONArray parentObs = p.get(obs.getParentCode()); - if (parentObs == null) { - p.put(obs.getParentCode(), convertObsToJson(getOrCreateParent(ol, obs))); - } - // find if any other exists with same parent if so add to the list otherwise create new list - JSONArray obl = pc.get(obs.getParentCode()); - if (obl == null) { - obl = new JSONArray(); - } - JSONArray addobs = convertObsToJson(obs); - for (int i = 0; i < addobs.length(); i++) { - obl.put(addobs.getJSONObject(i)); - } - pc.put(obs.getParentCode(), obl); - } - } - } - - JSONArray obar = new JSONArray(); - for (String ok : p.keySet()) { - for (int i = 0; i < p.get(ok).length(); i++) { - JSONObject obo = p.get(ok).getJSONObject(i); - obo.put("uuid", getObsUuid(obo, obsUuids)); - - JSONArray cob = pc.get(ok); - if (cob != null && cob.length() > 0) { - // Fetch children obs uuids - JSONObject obsGroupUuids = getObsUuidByParentObsUuid(obo.getString("uuid")); - JSONArray groupUuids = obsGroupUuids.getJSONArray("groupMembers"); - // Add uuids to group members - for (int j = 0; j < cob.length(); j++) { - JSONObject cobObj = cob.getJSONObject(j); - cobObj.put("uuid", getObsUuid(cobObj, groupUuids)); - } - - obo.put("groupMembers", cob); - } - - obar.put(obo); - } - } - enc.put("obs", obar); - - return enc; - } - - public JSONObject updateEncounter(Event e) throws JSONException { - if (StringUtils.isEmptyOrWhitespaceOnly(e.getIdentifier(OPENMRS_UUID_IDENTIFIER_TYPE))) { - throw new IllegalArgumentException("Encounter was never pushed to OpenMRS as " + OPENMRS_UUID_IDENTIFIER_TYPE - + " is empty. Consider creating a new one"); - } - - String openmrsuuid = e.getIdentifier(OPENMRS_UUID_IDENTIFIER_TYPE); - - JSONObject enc = buildUpdateEncounter(e); - - HttpResponse op = HttpUtil.post( - HttpUtil.removeEndingSlash(OPENMRS_BASE_URL) + "/" + ENCOUNTER_URL + "/" + openmrsuuid, "", enc.toString(), - OPENMRS_USER, OPENMRS_PWD); - return new JSONObject(op.body()); - } - - private String getObsUuid(JSONObject obs, JSONArray obsUuids) throws JSONException { - String uuid = ""; - // obs = {"concept":"163137AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"} - // obsUuids = [{"concept":{"uuid":"163137AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"},"uuid":"b267b2f5-94be-43e8-85c4-4e36f2eb8471"}, {}] - - for (int i = 0; i < obsUuids.length(); i++) { - JSONObject obsUuid = obsUuids.getJSONObject(i); - JSONObject conceptObj = obsUuid.getJSONObject("concept"); - - if (conceptObj.get("uuid").equals(obs.get("concept"))) { - return obsUuid.getString("uuid"); - } - } - - return uuid; - } - - private JSONArray convertObsToJson(Obs o) throws JSONException { - JSONArray arr = new JSONArray(); - if (o.getValues() == null || o.getValues().size() == 0) {//must be parent of some obs - JSONObject obo = new JSONObject(); - obo.put("concept", o.getFieldCode()); - - arr.put(obo); - } else { - //OpenMRS can not handle multivalued obs so add obs with multiple values as two different obs - for (Object v : o.getValues()) { - JSONObject obo = new JSONObject(); - obo.put("concept", o.getFieldCode()); - obo.put("value", v); - - arr.put(obo); - } - } - return arr; - } - - private Obs getOrCreateParent(List obl, Obs o) { - for (Obs obs : obl) { - if (o.getParentCode().equalsIgnoreCase(obs.getFieldCode())) { - return obs; - } - } - return new Obs("concept", "parent", o.getParentCode(), null, null, null, null); - } - - // TODO needs review and refactor - public Event convertToEvent(JSONObject encounter) throws JSONException { - if (encounter.has("patient") == false) { - throw new IllegalStateException("No 'patient' object found in given encounter"); - } - Event e = new Event(); - String patientUuid = encounter.getJSONObject("patient").getString("uuid"); - Client c = clientService.find(patientUuid); - if (c == null || c.getBaseEntityId() == null) { - //try to get the client from openmrs based on the uuid - JSONObject openmrsPatient = patientService.getPatientByUuid(patientUuid, false); - c = patientService.convertToClient(openmrsPatient); - if (c == null || c.getBaseEntityId() == null) { - throw new IllegalStateException( - "Client was not found registered while converting Encounter to an Event in OpenSRP"); - } else { - clientService.addClient(c); - } - } - - JSONObject creator = encounter.getJSONObject("auditInfo").getJSONObject("creator"); - e.withBaseEntityId(c.getBaseEntityId()) - .withCreator(new User(creator.getString("uuid"), creator.getString("display"), null, null)) - .withDateCreated(DateTime.now()); - - e.withEventDate(new DateTime(encounter.getString("encounterDatetime"))) - //.withEntityType(entityType) //TODO - .withEventType(encounter.getJSONObject("encounterType").getString("name")) - //.withFormSubmissionId(formSubmissionId)//TODO - .withLocationId((encounter.has("location") && encounter.get("location") instanceof JSONObject) - ? encounter.getJSONObject("location").getString("name") - : "") - //TODO manage providers and uuid in couch - .withProviderId(creator.getString("display")).withVoided(encounter.getBoolean("voided")); - - e.addIdentifier(OPENMRS_UUID_IDENTIFIER_TYPE, encounter.getString("uuid")); - - JSONArray ol = encounter.getJSONArray("obs"); - for (int i = 0; i < ol.length(); i++) { - JSONObject o = ol.getJSONObject(i); - List values = new ArrayList(); - if (o.optJSONObject("value") != null) { - values.add(o.getJSONObject("value").getString("uuid")); - } else if (o.has("value")) { - values.add(o.getString("value")); - } - e.addObs(new Obs(null, null, o.getJSONObject("concept").getString("uuid"), null /*//TODO handle parent*/, values, - null/*comments*/, null/*formSubmissionField*/)); - } - - return e; - } - - public synchronized Event processUpdateEvents(Event event) throws JSONException { - if (event.getEventType().equals("Death")) { - patientService.updatePersonAsDeceased(event); - } else if (event.getEventType().equals("Update Birth Registration")) { - patientService.updatePersonAddressAndName(event); - } - - return event; - } + + public static final String OPENMRS_UUID_IDENTIFIER_TYPE = "OPENMRS_UUID"; + + private static final String ENCOUNTER_URL = "ws/rest/v1/encounter";//"ws/rest/emrapi/encounter"; + + private static final String OBS_URL = "ws/rest/v1/obs"; + + private static final String ENCOUNTER__TYPE_URL = "ws/rest/v1/encountertype"; + + private PatientService patientService; + + private OpenmrsUserService userService; + + private ClientService clientService; + + private OpenmrsLocationService openmrsLocationService; + + private static Logger logger = LoggerFactory.getLogger(EncounterService.class.toString()); + + private static final String CONCEPT_REMOVE_REASON_DEATH = "161641AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"; + + @Autowired + public EncounterService(PatientService patientService, OpenmrsUserService userService, ClientService clientService, + OpenmrsLocationService openmrsLocationService) { + this.patientService = patientService; + this.userService = userService; + this.clientService = clientService; + this.openmrsLocationService = openmrsLocationService; + } + + public EncounterService(String openmrsUrl, String user, String password) { + super(openmrsUrl, user, password); + } + + public PatientService getPatientService() { + return patientService; + } + + public void setPatientService(PatientService patientService) { + this.patientService = patientService; + } + + public OpenmrsUserService getUserService() { + return userService; + } + + public void setUserService(OpenmrsUserService userService) { + this.userService = userService; + } + + public JSONObject getEncounterByUuid(String uuid, boolean noRepresentationTag) throws JSONException { + return new JSONObject(HttpUtil.get(getURL() + "/" + ENCOUNTER_URL + "/" + uuid, noRepresentationTag ? "" : "v=full", + OPENMRS_USER, OPENMRS_PWD).body()); + } + + public JSONObject getObsByEncounterUuid(String encounterUuid) throws JSONException { + // The data format returned contains the obs uuid and concept uuids + return new JSONObject(HttpUtil.get(getURL() + "/" + ENCOUNTER_URL + "/" + encounterUuid, + "v=custom:(uuid,obs:(uuid,concept:(uuid)))", OPENMRS_USER, OPENMRS_PWD).body()); + } + + public JSONObject getObsUuidByParentObsUuid(String obsUuid) throws JSONException { + //The data format returned contains the children obs uuid and concept uuids + return new JSONObject(HttpUtil.get(getURL() + "/" + OBS_URL + "/" + obsUuid, + "v=custom:(groupMembers:(uuid,concept:(uuid)))", OPENMRS_USER, OPENMRS_PWD).body()); + } + + public JSONObject getEncounterType(String encounterType) throws JSONException { + // we have to use this ugly approach because identifier not found throws exception and + // its hard to find whether it was network error or object not found or server error + JSONObject resEncounterType = new JSONObject( + HttpUtil.get(getURL() + "/" + ENCOUNTER__TYPE_URL, "v=full", OPENMRS_USER, OPENMRS_PWD).body()); + + if (resEncounterType.has("results") && resEncounterType.get("results") instanceof JSONArray) { + JSONArray res = resEncounterType.getJSONArray("results"); + for (int i = 0; i < res.length(); i++) { + if (res.getJSONObject(i).getString("display").equalsIgnoreCase(encounterType)) { + return res.getJSONObject(i); + } + } + } + return null; + } + + public JSONObject createEncounterType(String name, String description) throws JSONException { + JSONObject o = convertEncounterToOpenmrsJson(name, description); + return new JSONObject( + HttpUtil.post(getURL() + "/" + ENCOUNTER__TYPE_URL, "", o.toString(), OPENMRS_USER, OPENMRS_PWD).body()); + } + + public JSONObject convertEncounterToOpenmrsJson(String name, String description) throws JSONException { + JSONObject a = new JSONObject(); + a.put("name", name); + a.put("description", description); + return a; + } + + public JSONObject createEncounter(Event e) throws JSONException { + String ptuuid = patientService.getPatientByIdentifierUUID(e.getBaseEntityId()); + if (ptuuid == null) { + return null; + } else { + if (e.getEventType().equals("Death")) { + patientService.updatePersonAsDeceased(e); + } + JSONObject enc = new JSONObject(); + + String pruuid = userService.getPersonUUIDByUser(e.getProviderId()); + + enc.put("encounterDatetime", OPENMRS_DATE.format(e.getEventDate().toDate())); + // patient must be existing in OpenMRS before it submits an encounter. if it doesnot it would throw NPE + enc.put("patient", ptuuid); + //TODO enc.put("patientUuid", pt.getString("uuid")); + enc.put("encounterType", e.getEventType()); + //TODO enc.put("encounterTypeUuid", e.getEventType()); + enc.put("location", e.getLocationId()); + enc.put("provider", pruuid); + + List ol = e.getObs(); + Map p = new HashMap<>(); + Map pc = new HashMap<>(); + + if (ol != null) + for (Obs obs : ol) { + if (!StringUtils.isEmptyOrWhitespaceOnly(obs.getFieldCode()) + && (obs.getFieldType() == null || obs.getFieldType().equalsIgnoreCase("concept"))) { + // skipping empty obs and fields that don't have concepts if no parent simply make it root obs + if (obs.getFieldType().equals("concept") && obs.getFieldCode() != null) { + + if (e.getEventType().equals("Remove") && obs.getFieldCode().equalsIgnoreCase(CONCEPT_REMOVE_REASON_DEATH)) { + + patientService.updatePersonAsDeceased(e); + } + } + generateObs(p, pc, obs, ol); + } + } + + JSONArray obar = new JSONArray(); + + for (String ok : p.keySet()) { + for (int i = 0; i < p.get(ok).length(); i++) { + JSONObject obo = p.get(ok).getJSONObject(i); + JSONArray cob = pc.get(ok); + if (cob != null && cob.length() > 0) { + //fix for vaccines wrong parent concept remove the if-condition once the right concepts are passed + if (e.getEventType().equals("Vaccination") || e.getEventType().equals("HPV Vaccination")) { + JSONObject vaccineParent = new JSONObject(); + vaccineParent.put("concept", ok); + cob.put(vaccineParent); + obar = concatArray(obar, cob); + } else { + obo.put("groupMembers", cob); + obar.put(obo); + } + } else { + obar.put(obo); + } + } + } + enc.put("obs", obar); + HttpResponse op = HttpUtil.post(HttpUtil.removeEndingSlash(OPENMRS_BASE_URL) + "/" + ENCOUNTER_URL, "", + enc.toString(), OPENMRS_USER, OPENMRS_PWD); + return new JSONObject(op.body()); + } + } + + private void generateObs(Map p, Map pc, Obs obs, List ol) { + try { + if (StringUtils.isEmptyOrWhitespaceOnly(obs.getParentCode())) { + + p.put(obs.getFieldCode(), convertObsToJson(obs)); + + } else { + //find parent obs if not found search and fill or create one + JSONArray parentObs = p.get(obs.getParentCode()); + if (parentObs == null) { + p.put(obs.getParentCode(), convertObsToJson(getOrCreateParent(ol, obs))); + } + // find if any other exists with same parent if so add to the list otherwise create new list + JSONArray obl = pc.get(obs.getParentCode()); + if (obl == null) { + obl = new JSONArray(); + } + JSONArray addobs = convertObsToJson(obs); + for (int i = 0; i < addobs.length(); i++) { + obl.put(addobs.getJSONObject(i)); + } + pc.put(obs.getParentCode(), obl); + } + } catch (Exception e) { + logger.error(e.getMessage(), e); + } + } + + public JSONObject buildUpdateEncounter(Event e) throws JSONException { + String openmrsuuid = e.getIdentifier(OPENMRS_UUID_IDENTIFIER_TYPE); + JSONObject encounterObsUuids = getObsByEncounterUuid(openmrsuuid); + JSONArray obsUuids = encounterObsUuids.getJSONArray("obs"); + + System.out.print("[OBS-UUIDS]" + obsUuids); + + String ptuuid = patientService.getPatientByIdentifierUUID(e.getBaseEntityId());//TODO find by any identifier + JSONObject enc = new JSONObject(); + + String pruuid = userService.getPersonUUIDByUser(e.getProviderId()); + + enc.put("encounterDatetime", OPENMRS_DATE.format(e.getEventDate().toDate())); + // patient must be existing in OpenMRS before it submits an encounter. if it doesnot it would throw NPE + enc.put("patient", ptuuid); + //TODO enc.put("patientUuid", pt.getString("uuid")); + enc.put("encounterType", e.getEventType()); + enc.put("location", e.getLocationId()); + enc.put("provider", pruuid == null ? "" : pruuid); + + List ol = e.getObs(); + Map p = new HashMap<>(); + Map pc = new HashMap<>(); + + if (ol != null) + for (Obs obs : ol) { + if (!StringUtils.isEmptyOrWhitespaceOnly(obs.getFieldCode()) + && (obs.getFieldType() == null || obs.getFieldType().equalsIgnoreCase("concept"))) { + //skipping empty obs if no parent simply make it root obs + if (obs.getFieldType().equals("concept") && obs.getFormSubmissionField().equals("Birth_Facility_Name") + && obs.getValue() != null + && openmrsLocationService.getLocation(obs.getValue().toString()).getName() != null) { + obs.setValue(openmrsLocationService.getLocation(obs.getValue().toString()).getName()); + } + if (StringUtils.isEmptyOrWhitespaceOnly(obs.getParentCode())) { + p.put(obs.getFieldCode(), convertObsToJson(obs)); + } else { + //find parent obs if not found search and fill or create one + JSONArray parentObs = p.get(obs.getParentCode()); + if (parentObs == null) { + p.put(obs.getParentCode(), convertObsToJson(getOrCreateParent(ol, obs))); + } + // find if any other exists with same parent if so add to the list otherwise create new list + JSONArray obl = pc.get(obs.getParentCode()); + if (obl == null) { + obl = new JSONArray(); + } + JSONArray addobs = convertObsToJson(obs); + for (int i = 0; i < addobs.length(); i++) { + obl.put(addobs.getJSONObject(i)); + } + pc.put(obs.getParentCode(), obl); + } + } + } + + JSONArray obar = new JSONArray(); + for (String ok : p.keySet()) { + for (int i = 0; i < p.get(ok).length(); i++) { + JSONObject obo = p.get(ok).getJSONObject(i); + obo.put("uuid", getObsUuid(obo, obsUuids)); + + JSONArray cob = pc.get(ok); + if (cob != null && cob.length() > 0) { + // Fetch children obs uuids + JSONObject obsGroupUuids = getObsUuidByParentObsUuid(obo.getString("uuid")); + JSONArray groupUuids = obsGroupUuids.getJSONArray("groupMembers"); + // Add uuids to group members + for (int j = 0; j < cob.length(); j++) { + JSONObject cobObj = cob.getJSONObject(j); + cobObj.put("uuid", getObsUuid(cobObj, groupUuids)); + } + + obo.put("groupMembers", cob); + } + + obar.put(obo); + } + } + enc.put("obs", obar); + + return enc; + } + + public JSONObject updateEncounter(Event e) throws JSONException { + if (StringUtils.isEmptyOrWhitespaceOnly(e.getIdentifier(OPENMRS_UUID_IDENTIFIER_TYPE))) { + throw new IllegalArgumentException("Encounter was never pushed to OpenMRS as " + OPENMRS_UUID_IDENTIFIER_TYPE + + " is empty. Consider creating a new one"); + } + + String openmrsuuid = e.getIdentifier(OPENMRS_UUID_IDENTIFIER_TYPE); + + JSONObject enc = buildUpdateEncounter(e); + + HttpResponse op = HttpUtil.post( + HttpUtil.removeEndingSlash(OPENMRS_BASE_URL) + "/" + ENCOUNTER_URL + "/" + openmrsuuid, "", enc.toString(), + OPENMRS_USER, OPENMRS_PWD); + return new JSONObject(op.body()); + } + + private String getObsUuid(JSONObject obs, JSONArray obsUuids) throws JSONException { + String uuid = ""; + // obs = {"concept":"163137AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"} + // obsUuids = [{"concept":{"uuid":"163137AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"},"uuid":"b267b2f5-94be-43e8-85c4-4e36f2eb8471"}, {}] + + for (int i = 0; i < obsUuids.length(); i++) { + JSONObject obsUuid = obsUuids.getJSONObject(i); + JSONObject conceptObj = obsUuid.getJSONObject("concept"); + + if (conceptObj.get("uuid").equals(obs.get("concept"))) { + return obsUuid.getString("uuid"); + } + } + + return uuid; + } + + private JSONArray convertObsToJson(Obs o) throws JSONException { + JSONArray arr = new JSONArray(); + if (o.getValues() == null || o.getValues().size() == 0) {//must be parent of some obs + JSONObject obo = new JSONObject(); + obo.put("concept", o.getFieldCode()); + + arr.put(obo); + } else { + //OpenMRS can not handle multivalued obs so add obs with multiple values as two different obs + for (Object v : o.getValues()) { + JSONObject obo = new JSONObject(); + obo.put("concept", o.getFieldCode()); + obo.put("value", v); + + arr.put(obo); + } + } + return arr; + } + + private Obs getOrCreateParent(List obl, Obs o) { + for (Obs obs : obl) { + if (o.getParentCode().equalsIgnoreCase(obs.getFieldCode())) { + return obs; + } + } + return new Obs("concept", "parent", o.getParentCode(), null, null, null, null); + } + + // TODO needs review and refactor + public Event convertToEvent(JSONObject encounter) throws JSONException { + if (encounter.has("patient") == false) { + throw new IllegalStateException("No 'patient' object found in given encounter"); + } + Event e = new Event(); + String patientUuid = encounter.getJSONObject("patient").getString("uuid"); + Client c = clientService.find(patientUuid); + if (c == null || c.getBaseEntityId() == null) { + //try to get the client from openmrs based on the uuid + JSONObject openmrsPatient = patientService.getPatientByUuid(patientUuid, false); + c = patientService.convertToClient(openmrsPatient); + if (c == null || c.getBaseEntityId() == null) { + throw new IllegalStateException( + "Client was not found registered while converting Encounter to an Event in OpenSRP"); + } else { + clientService.addClient(c); + } + } + + JSONObject creator = encounter.getJSONObject("auditInfo").getJSONObject("creator"); + e.withBaseEntityId(c.getBaseEntityId()) + .withCreator(new User(creator.getString("uuid"), creator.getString("display"), null, null)) + .withDateCreated(DateTime.now()); + + e.withEventDate(new DateTime(encounter.getString("encounterDatetime"))) + //.withEntityType(entityType) //TODO + .withEventType(encounter.getJSONObject("encounterType").getString("name")) + //.withFormSubmissionId(formSubmissionId)//TODO + .withLocationId((encounter.has("location") && encounter.get("location") instanceof JSONObject) + ? encounter.getJSONObject("location").getString("name") + : "") + //TODO manage providers and uuid in couch + .withProviderId(creator.getString("display")).withVoided(encounter.getBoolean("voided")); + + e.addIdentifier(OPENMRS_UUID_IDENTIFIER_TYPE, encounter.getString("uuid")); + + JSONArray ol = encounter.getJSONArray("obs"); + for (int i = 0; i < ol.length(); i++) { + JSONObject o = ol.getJSONObject(i); + List values = new ArrayList(); + if (o.optJSONObject("value") != null) { + values.add(o.getJSONObject("value").getString("uuid")); + } else if (o.has("value")) { + values.add(o.getString("value")); + } + e.addObs(new Obs(null, null, o.getJSONObject("concept").getString("uuid"), null /*//TODO handle parent*/, values, + null/*comments*/, null/*formSubmissionField*/)); + } + + return e; + } + + private JSONArray concatArray(JSONArray... arrs) throws JSONException { + JSONArray result = new JSONArray(); + for (JSONArray arr : arrs) { + if (arr != null && arr.length() > 0) { + for (int i = 0; i < arr.length(); i++) { + result.put(arr.get(i)); + } + } + + } + return result; + } } diff --git a/opensrp-connector/src/main/java/org/opensrp/connector/openmrs/service/OpenmrsLocationService.java b/opensrp-connector/src/main/java/org/opensrp/connector/openmrs/service/OpenmrsLocationService.java index 2614479b3a..1e1c629654 100644 --- a/opensrp-connector/src/main/java/org/opensrp/connector/openmrs/service/OpenmrsLocationService.java +++ b/opensrp-connector/src/main/java/org/opensrp/connector/openmrs/service/OpenmrsLocationService.java @@ -171,8 +171,8 @@ private void extractLocations(Map map, TreeNode map, TreeNode cl, String errorType) throws JSONException { if (cl != null && !cl.isEmpty()) for (Client c : cl) { try { - if (c.getRelationships() != null && !c.getRelationships().isEmpty() - && c.getRelationships().containsKey("mother") && c.getIdentifier("OPENMRS_UUID") != null) { + if (c.getRelationships() != null && !c.getRelationships().isEmpty() && c.getRelationships() + .containsKey("mother") && c.getIdentifier("OPENMRS_UUID") != null) { String motherBaseId = c.getRelationships().get("mother").get(0).toString(); - + String personUUID = getPatientByIdentifierPersonUUID(motherBaseId); if (personUUID != null) { createPatientRelationShip(c.getIdentifier("OPENMRS_UUID"), personUUID, - "8d91a210-c2cc-11de-8d13-0010c6dffd0f"); + "8d91a210-c2cc-11de-8d13-0010c6dffd0f"); } List siblings = clientService.findByRelationship(motherBaseId); if (!siblings.isEmpty() || siblings != null) { @@ -263,26 +269,27 @@ public void createRelationShip(List cl, String errorType) throws JSONExc String siblingUUID = getPatientByIdentifierPersonUUID(client.getBaseEntityId()); if (siblingUUID != null) { createPatientRelationShip(c.getIdentifier("OPENMRS_UUID"), siblingUUID, - "8d91a01c-c2cc-11de-8d13-0010c6dffd0f"); + "8d91a01c-c2cc-11de-8d13-0010c6dffd0f"); } } - + } } } } catch (Exception e) { logger.error("", e); - errorTraceService.log(errorType, Client.class.getName(), c.getBaseEntityId(), - ExceptionUtils.getStackTrace(e), ""); + errorTraceService + .log(errorType, Client.class.getName(), c.getBaseEntityId(), ExceptionUtils.getStackTrace(e), + ""); } } } - + public void processClients(List cl, JSONArray patientsJsonArray, OpenmrsConstants.SchedulerConfig schedulerConfig, String errorType) { JSONObject patient = new JSONObject();// only for test code purpose - + logger.info("Reprocessing_clients " + cl.size()); for (Client c : cl) { try { @@ -295,7 +302,7 @@ public void processClients(List cl, JSONArray patientsJsonArray, c.setGender("Female"); } String uuid = c.getIdentifier(PatientService.OPENMRS_UUID_IDENTIFIER_TYPE); - + if (uuid == null) { uuid = getPatientByIdentifierUUID(c.getBaseEntityId()); if (uuid == null) { @@ -306,7 +313,7 @@ public void processClients(List cl, JSONArray patientsJsonArray, } } } - + } if (uuid != null) { logger.info("Updating patient " + uuid); @@ -317,7 +324,7 @@ public void processClients(List cl, JSONArray patientsJsonArray, c.addIdentifier(PatientService.OPENMRS_UUID_IDENTIFIER_TYPE, uuid); clientService.addorUpdate(c, false); config.updateAppStateToken(schedulerConfig, c.getServerVersion()); - + } else { JSONObject patientJson = createPatient(c); patient = patientJson;//only for test code purpose @@ -326,24 +333,25 @@ public void processClients(List cl, JSONArray patientsJsonArray, clientService.addorUpdate(c, false); config.updateAppStateToken(schedulerConfig, c.getServerVersion()); } - + } } catch (Exception ex1) { logger.error("", ex1); - errorTraceService.log(errorType, Client.class.getName(), c.getBaseEntityId(), - ExceptionUtils.getStackTrace(ex1), ""); + errorTraceService + .log(errorType, Client.class.getName(), c.getBaseEntityId(), ExceptionUtils.getStackTrace(ex1), ""); } patientsJsonArray.put(patient); } - + } - + public String getPersonAttributeTypeUUID(String attributeName) throws JSONException { - JSONObject resAttributeType = new JSONObject(HttpUtil.get(getURL() + "/" + PERSON_ATTRIBUTE_TYPE_URL, - CUSTOM_UUID_PARAM + "&q=" + attributeName, OPENMRS_USER, OPENMRS_PWD).body()); + JSONObject resAttributeType = new JSONObject( + HttpUtil.get(getURL() + "/" + PERSON_ATTRIBUTE_TYPE_URL, CUSTOM_UUID_PARAM + "&q=" + attributeName, + OPENMRS_USER, OPENMRS_PWD).body()); if (resAttributeType.has(RESULTS_KEY) && resAttributeType.get(RESULTS_KEY) instanceof JSONArray) { - + JSONArray res = resAttributeType.getJSONArray(RESULTS_KEY); if (res.length() > 0) { JSONObject resJson = res.getJSONObject(0); @@ -354,14 +362,14 @@ public String getPersonAttributeTypeUUID(String attributeName) throws JSONExcept } return null; } - + public JSONObject createPerson(Client be) throws JSONException { JSONObject per = convertBaseEntityToOpenmrsJson(be, false); logger.info("PERSON TO CREATE " + per.toString()); String response = HttpUtil.post(getURL() + "/" + PERSON_URL, "", per.toString(), OPENMRS_USER, OPENMRS_PWD).body(); logger.info("PERSON TO CREATE RESPONSE ----" + response); JSONObject jsonResponse = new JSONObject(response); - + if (jsonResponse.has("error")) { JSONObject responseError = new JSONObject(jsonResponse.getString("error")); if (responseError.has("message") && responseError.getString("message").equals("User is not logged in")) { @@ -371,7 +379,7 @@ public JSONObject createPerson(Client be) throws JSONException { } return new JSONObject(response); } - + public JSONObject convertBaseEntityToOpenmrsJson(Client be, boolean update) throws JSONException { JSONObject per = new JSONObject(); per.put("gender", be.getGender()); @@ -380,34 +388,35 @@ public JSONObject convertBaseEntityToOpenmrsJson(Client be, boolean update) thro if (be.getDeathdate() != null) { per.put("deathDate", OPENMRS_DATE.format(be.getDeathdate().toDate())); } - - String fn = be.getFirstName() == null || StringUtils.isEmptyOrWhitespaceOnly(be.getFirstName()) ? "-" - : be.getFirstName(); + + String fn = be.getFirstName() == null || StringUtils.isEmptyOrWhitespaceOnly(be.getFirstName()) ? + "-" : + be.getFirstName(); if (!fn.equals("-")) { fn = fn.replaceAll("[^A-Za-z0-9\\s]+", ""); } fn = convertToOpenmrsString(fn); - + String mn = be.getMiddleName() == null ? "" : be.getMiddleName(); - + if (!mn.equals("-")) { mn = mn.replaceAll("[^A-Za-z0-9\\s]+", ""); } mn = convertToOpenmrsString(mn); - + String ln = (be.getLastName() == null || be.getLastName().equals(".")) ? "-" : be.getLastName(); if (!ln.equals("-")) { ln = ln.replaceAll("[^A-Za-z0-9\\s]+", ""); } ln = convertToOpenmrsString(ln); - + List registrationEvents = eventService.findByBaseEntityId(be.getBaseEntityId()); for (Event event : registrationEvents) { if (event.getEventType().equals("Birth Registration")) { List obs = event.getObs(); for (Obs obs2 : obs) { - if (obs2 != null && obs2.getFieldType().equals("formsubmissionField") - && obs2.getFormSubmissionField().equals("Home_Facility") && obs2.getValue() != null) { + if (obs2 != null && obs2.getFieldType().equals("formsubmissionField") && obs2.getFormSubmissionField() + .equals("Home_Facility") && obs2.getValue() != null) { String clientAddress4 = openmrsLocationService.getLocation(obs2.getValue().toString()).getName(); if (be.getAttribute("Home_Facility") != null) { be.removeAttribute("Home_Facility"); @@ -419,15 +428,15 @@ public JSONObject convertBaseEntityToOpenmrsJson(Client be, boolean update) thro break; } per.put("attributes", convertAttributesToOpenmrsJson(be.getAttributes())); - + if (!update) { per.put("names", new JSONArray( - "[{\"givenName\":\"" + fn + "\",\"middleName\":\"" + mn + "\", \"familyName\":\"" + ln + "\"}]")); + "[{\"givenName\":\"" + fn + "\",\"middleName\":\"" + mn + "\", \"familyName\":\"" + ln + "\"}]")); per.put("addresses", convertAddressesToOpenmrsJson(be)); } return per; } - + public JSONArray convertAttributesToOpenmrsJson(Map attributes) throws JSONException { if (CollectionUtils.isEmpty(attributes)) { return null; @@ -442,10 +451,10 @@ public JSONArray convertAttributesToOpenmrsJson(Map attributes) attrs.put(a); } } - + return attrs; } - + public JSONArray convertAddressesToOpenmrsJson(Client client) throws JSONException { List
adl = client.getAddresses(); if (CollectionUtils.isEmpty(adl)) { @@ -455,59 +464,52 @@ public JSONArray convertAddressesToOpenmrsJson(Client client) throws JSONExcepti for (Address ad : adl) { JSONObject jao = new JSONObject(); if (ad.getAddressFields() != null) { - jao.put("address1", convertToOpenmrsString( - ad.getAddressFieldMatchingRegex("(?i)(ADDRESS1|HOUSE_NUMBER|HOUSE|HOUSE_NO|UNIT|UNIT_NUMBER|UNIT_NO)"))); + jao.put("address1", convertToOpenmrsString(ad.getAddressFieldMatchingRegex( + "(?i)(ADDRESS1|HOUSE_NUMBER|HOUSE|HOUSE_NO|UNIT|UNIT_NUMBER|UNIT_NO)"))); jao.put("address2", convertToOpenmrsString( - ad.getAddressFieldMatchingRegex("(?i)(ADDRESS2|STREET|STREET_NUMBER|STREET_NO|LANE)"))); + ad.getAddressFieldMatchingRegex("(?i)(ADDRESS2|STREET|STREET_NUMBER|STREET_NO|LANE)"))); String address3 = ad.getAddressFieldMatchingRegex("(?i)(ADDRESS3|SECTOR|AREA)"); address3 = fetchLocationByUUID(address3); jao.put("address3", convertToOpenmrsString(address3)); - jao.put("address5", - convertToOpenmrsString(ad.getAddressFieldMatchingRegex("(?i)(ADDRESS5|OTHER_RESIDENTIAL_AREA)"))); - - List registrationEvents = eventService.findByBaseEntityAndType(client.getBaseEntityId(), - "Birth Registration"); - for (Event event : registrationEvents) { - - List obs = event.getObs(); - for (Obs obs2 : obs) { - - if (obs2 != null && obs2.getFieldType().equals("formsubmissionField") - && obs2.getFormSubmissionField().equals("Home_Facility") && obs2.getValue() != null) { - - String clientAddress4 = fetchLocationByUUID(obs2.getValue().toString()); - jao.put("address4", convertToOpenmrsString(clientAddress4)); - - try { - LocationTree locationTree = openmrsLocationService - .getLocationTreeWithUpperHierachyOf(obs2.getValue().toString()); - Map locationsHierarchyMap = openmrsLocationService - .getLocationsHierarchy(locationTree); - - jao.put("countyDistrict", - locationsHierarchyMap.containsKey(AllowedLevels.DISTRICT.toString()) - ? locationsHierarchyMap.get(AllowedLevels.DISTRICT.toString()) - : ""); - jao.put("stateProvince", - locationsHierarchyMap.containsKey(AllowedLevels.PROVINCE.toString()) - ? locationsHierarchyMap.get(AllowedLevels.PROVINCE.toString()) - : ""); - jao.put("country", - locationsHierarchyMap.containsKey(AllowedLevels.COUNTRY.toString()) - ? locationsHierarchyMap.get(AllowedLevels.COUNTRY.toString()) - : ""); - } - catch (Exception e) { - logger.error("", e); - } - break; - } + String address5 = convertToOpenmrsString( + ad.getAddressFieldMatchingRegex("(?i)(ADDRESS5|OTHER_RESIDENTIAL_AREA)")); + jao.put("address5", openmrsLocationService.getLocation(address5).getName()); + + + LocationTree locationTree = openmrsLocationService.getLocationTreeWithUpperHierachyOf(address5); + + try { + + Map locationsHierarchyMap = openmrsLocationService + .getLocationsHierarchy(locationTree); + + jao.put("country", locationsHierarchyMap.containsKey(AllowedLevels.COUNTRY.toString()) ? + locationsHierarchyMap.get(AllowedLevels.COUNTRY.toString()) : + ""); + + jao.put("countyDistrict", locationsHierarchyMap.containsKey(AllowedLevels.DISTRICT.toString()) ? + locationsHierarchyMap.get(AllowedLevels.DISTRICT.toString()) : + ""); + + jao.put("address2", locationsHierarchyMap.containsKey(AllowedLevels.COUNTY.toString()) ? + locationsHierarchyMap.get(AllowedLevels.COUNTY.toString()) : + ""); + jao.put("address3", locationsHierarchyMap.containsKey(AllowedLevels.SUB_COUNTY.toString()) ? + locationsHierarchyMap.get(AllowedLevels.SUB_COUNTY.toString()) : + ""); + + jao.put("address4", locationsHierarchyMap.containsKey(AllowedLevels.DISTRICT.toString()) ? + locationsHierarchyMap.get(AllowedLevels.HEALTH_FACILITY.toString()) : + ""); + } - - } - jao.put("cityVillage", convertToOpenmrsString(ad.getCityVillage())); - + catch (Exception e) { + logger.error("", e); + } + + } + jao.put("cityVillage", convertToOpenmrsString(ad.getCityVillage())); jao.put("address6", convertToOpenmrsString(ad.getAddressType())); jao.put("postalCode", convertToOpenmrsString(ad.getPostalCode())); jao.put("latitude", ad.getLatitude()); @@ -518,58 +520,65 @@ public JSONArray convertAddressesToOpenmrsJson(Client client) throws JSONExcepti if (ad.getEndDate() != null) { jao.put("endDate", OPENMRS_DATE.format(ad.getEndDate().toDate())); } - + jaar.put(jao); } - + return jaar; } - + public JSONObject createPatient(Client c) throws JSONException { JSONObject p = new JSONObject(); - + p.put("person", createPerson(c).getString("uuid")); JSONArray ids = new JSONArray(); if (c.getIdentifiers() != null) { for (Entry id : c.getIdentifiers().entrySet()) { - JSONObject jio = new JSONObject(); - jio.put("identifierType", fetchIndentifierTypeUUID(id.getKey())); - jio.put("identifier", id.getValue()); - Object cloc = c.getAttribute("Location"); - jio.put("location", cloc == null ? "Unknown Location" : cloc); - //jio.put("preferred", true); - - ids.put(jio); + if (id != null && id.getKey() != null && id.getValue() != null) { + JSONObject jio = new JSONObject(); + jio.put("identifierType", fetchIndentifierTypeUUID(id.getKey())); + if (id.getKey().equalsIgnoreCase(OPENSRP_ID_TYPE_KEY)) { + + jio.put("identifier", cleanIdentifierWithCheckDigit(id.getValue())); + } else { + jio.put("identifier", id.getValue()); + } + Object cloc = c.getAttribute("Location"); + jio.put("location", cloc == null ? "Unknown Location" : cloc); + //jio.put("preferred", true); + + ids.put(jio); + } } } - + JSONObject jio = new JSONObject(); jio.put("identifierType", fetchIndentifierTypeUUID(OPENSRP_IDENTIFIER_TYPE)); jio.put("identifier", c.getBaseEntityId()); Object cloc = c.getAttribute("Location"); jio.put("location", cloc == null ? "Unknown Location" : cloc); jio.put("preferred", true); - + ids.put(jio); - + p.put("identifiers", ids); String response = HttpUtil.post(getURL() + "/" + PATIENT_URL, "", p.toString(), OPENMRS_USER, OPENMRS_PWD).body(); return new JSONObject(response); } - + public JSONObject updatePatientIdentifier(String patientUUID, String identifierUUID, String newIdentifier) - throws JSONException { + throws JSONException { String url = "ws/rest/v1/patient/" + patientUUID + "/identifier/" + identifierUUID; JSONObject p = new JSONObject(); p.put("identifier", newIdentifier); - + return new JSONObject(HttpUtil.post(getURL() + "/" + url, "", p.toString(), OPENMRS_USER, OPENMRS_PWD).body()); - + } - + public JSONObject updatePatient(Client c, String uuid) throws JSONException { JSONObject p = new JSONObject(); - + p.put("person", convertBaseEntityToOpenmrsJson(c, true)); JSONArray ids = new JSONArray(); if (c.getIdentifiers() != null) { @@ -583,24 +592,25 @@ public JSONObject updatePatient(Client c, String uuid) throws JSONException { jio.put("location", cloc == null ? "Unknown Location" : cloc); jio.put("preferred", true); ids.put(jio); - + p.put("identifiers", ids); - return new JSONObject(HttpUtil - .post(getURL() + "/" + PATIENT_URL + "/" + uuid, "", p.toString(), OPENMRS_USER, OPENMRS_PWD).body()); + return new JSONObject( + HttpUtil.post(getURL() + "/" + PATIENT_URL + "/" + uuid, "", p.toString(), OPENMRS_USER, OPENMRS_PWD) + .body()); } - + public JSONObject addThriveId(String baseEntityId, JSONObject patient) throws JSONException { JSONObject jio = new JSONObject(); jio.put("identifierType", fetchIndentifierTypeUUID(OPENSRP_IDENTIFIER_TYPE)); jio.put("identifier", baseEntityId); jio.put("location", "Unknown Location"); jio.put("preferred", true); - + return new JSONObject( - HttpUtil.post(getURL() + "/" + PATIENT_URL + "/" + patient.getString("uuid") + "/" + PATIENT_IDENTIFIER_URL, - "", jio.toString(), OPENMRS_USER, OPENMRS_PWD).body()); + HttpUtil.post(getURL() + "/" + PATIENT_URL + "/" + patient.getString("uuid") + "/" + PATIENT_IDENTIFIER_URL, + "", jio.toString(), OPENMRS_USER, OPENMRS_PWD).body()); } - + public Client convertToClient(JSONObject patient) throws JSONException { Client c = new Client(null); JSONArray ar = patient.getJSONArray("identifiers"); @@ -612,22 +622,22 @@ public Client convertToClient(JSONObject patient) throws JSONException { c.addIdentifier(ji.getJSONObject("identifierType").getString("display"), ji.getString("identifier")); } } - + c.addIdentifier(OPENMRS_UUID_IDENTIFIER_TYPE, patient.getString("uuid")); - + JSONObject pr = patient.getJSONObject("person"); - - String mn = pr.getJSONObject("preferredName").has("middleName") - ? pr.getJSONObject("preferredName").getString("middleName") - : null; - DateTime dd = pr.has("deathDate") && !pr.getString("deathDate").equalsIgnoreCase("null") - ? new DateTime(pr.getString("deathDate")) - : null; + + String mn = pr.getJSONObject("preferredName").has("middleName") ? + pr.getJSONObject("preferredName").getString("middleName") : + null; + DateTime dd = pr.has("deathDate") && !pr.getString("deathDate").equalsIgnoreCase("null") ? + new DateTime(pr.getString("deathDate")) : + null; c.withFirstName(pr.getJSONObject("preferredName").getString("givenName")).withMiddleName(mn) - .withLastName(pr.getJSONObject("preferredName").getString("familyName")).withGender(pr.getString("gender")) - .withBirthdate(new DateTime(pr.getString("birthdate")), pr.getBoolean("birthdateEstimated")) - .withDeathdate(dd, false); - + .withLastName(pr.getJSONObject("preferredName").getString("familyName")).withGender(pr.getString("gender")) + .withBirthdate(new DateTime(pr.getString("birthdate")), pr.getBoolean("birthdateEstimated")) + .withDeathdate(dd, false); + if (pr.has("attributes")) { for (int i = 0; i < pr.getJSONArray("attributes").length(); i++) { JSONObject at = pr.getJSONArray("attributes").getJSONObject(i); @@ -635,52 +645,52 @@ public Client convertToClient(JSONObject patient) throws JSONException { c.addAttribute(at.getJSONObject("attributeType").getString("display"), at.getString("value")); } else { c.addAttribute(at.getJSONObject("attributeType").getString("display"), - at.getJSONObject("value").getString("display")); + at.getJSONObject("value").getString("display")); } } } - + if (pr.has("addresses")) { for (int i = 0; i < pr.getJSONArray("addresses").length(); i++) { JSONObject ad = pr.getJSONArray("addresses").getJSONObject(i); - DateTime startDate = ad.has("startDate") && !ad.getString("startDate").equalsIgnoreCase("null") - ? new DateTime(ad.getString("startDate")) - : null; - DateTime endDate = ad.has("startDate") && !ad.getString("endDate").equalsIgnoreCase("null") - ? new DateTime(ad.getString("endDate")) - : null; + DateTime startDate = ad.has("startDate") && !ad.getString("startDate").equalsIgnoreCase("null") ? + new DateTime(ad.getString("startDate")) : + null; + DateTime endDate = ad.has("startDate") && !ad.getString("endDate").equalsIgnoreCase("null") ? + new DateTime(ad.getString("endDate")) : + null; ; Address a = new Address(ad.getString("address6"), startDate, endDate, null, ad.getString("latitude"), - ad.getString("longitude"), ad.getString("postalCode"), ad.getString("stateProvince"), - ad.getString("country")); + ad.getString("longitude"), ad.getString("postalCode"), ad.getString("stateProvince"), + ad.getString("country")); //a.setGeopoint(geopoint); a.setSubTown(ad.getString("address2"));//TODO a.setTown(ad.getString("address3")); a.setSubDistrict(ad.getString("address4")); a.setCountyDistrict(ad.getString("countyDistrict")); a.setCityVillage(ad.getString("cityVillage")); - + c.addAddress(a); } - + } return c; } - + public void patientImageUpload(Multimedia multimedia) throws IOException { //String requestURL = "http://46.101.51.199:8080/openmrs/ws/rest/v1/patientimage/uploadimage"; - + try { File convFile = new File("/opt" + multimedia.getFilePath()); MultipartUtility multipart = new MultipartUtility(getURL() + "/" + PATIENT_IMAGE_URL, OPENMRS_USER, OPENMRS_PWD); multipart.addFormField("patientidentifier", multimedia.getCaseId()); multipart.addFormField("category", multimedia.getFileCategory()); multipart.addFilePart("file", convFile); - + List response = multipart.finish(); - + System.out.println("SERVER REPLIED:"); - + for (String line : response) { System.out.println(line); } @@ -689,129 +699,86 @@ public void patientImageUpload(Multimedia multimedia) throws IOException { logger.error("", ex); } } - + public JSONObject updatePersonAsDeceased(Event deathEvent) throws JSONException { + List ol = deathEvent.getObs(); + JSONObject obsBody = new JSONObject(); JSONObject requestBody = new JSONObject(); - String patientUUID = getPatientByIdentifierUUID(deathEvent.getBaseEntityId()); - + + if (ol == null || ol.isEmpty()) { + throw new IllegalArgumentException( + "Death Encounter does not have any observations for the required causeOfDeath "); + } + for (Obs obs : ol) { + if (obs.getFormSubmissionField().equals("Cause_Death") && obs.getValue() != null) { + obsBody.put("person", patientUUID); + obsBody.put("concept", PROBABLE_CAUSE_OF_DEATH_CONCEPT); + obsBody.put("obsDatetime", OPENMRS_DATE.format(deathEvent.getEventDate().toDate())); + obsBody.put("value", obs.getValue().toString()); + break; + } + } + requestBody.put("dead", true); requestBody.put("deathDate", OPENMRS_DATE.format(deathEvent.getEventDate().toDate())); - requestBody.put("causeOfDeath", PROBABLE_CAUSE_PARENT_CONCEPT); - - HttpResponse op = HttpUtil.post(HttpUtil.removeEndingSlash(OPENMRS_BASE_URL) + "/" + PERSON_URL + "/" + patientUUID, - "", requestBody.toString(), OPENMRS_USER, OPENMRS_PWD); - - return new JSONObject(op.body()); - - } - + requestBody.put("causeOfDeath", OTHER_NON_CODED_CONCEPT); + + HttpResponse op = HttpUtil + .post(HttpUtil.removeEndingSlash(OPENMRS_BASE_URL) + "/" + PERSON_URL + "/" + patientUUID, "", + requestBody.toString(), OPENMRS_USER, OPENMRS_PWD); + + if (new JSONObject(op.body()).has("uuid")) { + HttpResponse obsResponse = HttpUtil + .post(HttpUtil.removeEndingSlash(OPENMRS_BASE_URL) + "/" + OBS_URL, "", obsBody.toString(), OPENMRS_USER, + OPENMRS_PWD); + return new JSONObject(obsResponse.body()); + } + return null; + + } + public JSONObject updatePersonName(JSONObject patientObject, Client client) throws JSONException { - + JSONObject nameObject = patientObject.getJSONObject("preferredName"); - + String fn = client.getFirstName() == null || client.getFirstName().isEmpty() ? "-" : client.getFirstName(); if (!fn.equals("-")) { fn = fn.replaceAll("[^A-Za-z0-9\\s]+", ""); } - + String ln = (client.getLastName() == null || client.getLastName().equals(".")) ? "-" : client.getLastName(); if (!ln.equals("-")) { ln = ln.replaceAll("[^A-Za-z0-9\\s]+", ""); } - + if (fn.equals(nameObject.getString("givenName")) && ln.equals(nameObject.getString("givenName"))) { return null; } - + JSONObject requestBody = new JSONObject(); requestBody.put("givenName", fn); requestBody.put("familyName", ln); String url = "ws/rest/v1/person/" + patientObject.getString("uuid") + "/name/" + nameObject.getString("uuid"); - - return new JSONObject( - HttpUtil.post(getURL() + "/" + url, "", requestBody.toString(), OPENMRS_USER, OPENMRS_PWD).body()); - - } - - public JSONObject updatePersonAddressAndName(Event addressUpdateEvent) throws JSONException { - JSONObject patientObject = getPatientByIdentifierPerson(addressUpdateEvent.getBaseEntityId()); - Client client = clientService.getByBaseEntityId(addressUpdateEvent.getBaseEntityId()); - - //update person names if any changes were made - updatePersonName(patientObject, client); - - List
clientAddresses = client.getAddresses(); - - JSONObject addressObject = patientObject.getJSONObject("preferredAddress"); - String clientAddress4; - String clientAddress; - - JSONObject requestBody = new JSONObject(); - - Map addressMap = clientAddresses.get(0).getAddressFields(); - - for (Map.Entry entry : addressMap.entrySet()) { - clientAddress = entry.getValue(); - if (entry.getKey().equals("address3") && !clientAddress.equals("Other") && clientAddress != null - && !StringUtils.isEmptyOrWhitespaceOnly(clientAddress)) { - clientAddress = openmrsLocationService.getLocation(clientAddress).getName(); - - } - - if (!clientAddress.equals(addressObject.getString(entry.getKey()))) { - requestBody.put(entry.getKey(), clientAddress); - } - } - - List obs = addressUpdateEvent.getObs(); - for (Obs obs2 : obs) { - - if (obs2 != null && obs2.getFieldType().equals("formsubmissionField") - && obs2.getFormSubmissionField().equals("Home_Facility") && obs2.getValue() != null) { - - LocationTree locationTree = openmrsLocationService - .getLocationTreeWithUpperHierachyOf(obs2.getValue().toString()); - Map locationsHierarchyMap = openmrsLocationService.getLocationsHierarchy(locationTree); - - clientAddress4 = openmrsLocationService.getLocation(obs2.getValue().toString()).getName(); - if (!addressObject.getString("address4").equals(clientAddress4)) { - requestBody.put("address4", clientAddress4); - requestBody.put("countyDistrict", - locationsHierarchyMap.containsKey(AllowedLevels.DISTRICT.toString()) - ? locationsHierarchyMap.get(AllowedLevels.DISTRICT.toString()) - : ""); - requestBody.put("stateProvince", - locationsHierarchyMap.containsKey(AllowedLevels.PROVINCE.toString()) - ? locationsHierarchyMap.get(AllowedLevels.PROVINCE.toString()) - : ""); - requestBody.put("country", - locationsHierarchyMap.containsKey(AllowedLevels.COUNTRY.toString()) - ? locationsHierarchyMap.get(AllowedLevels.COUNTRY.toString()) - : ""); - } - - break; - } - } - - String url = "ws/rest/v1/person/" + patientObject.getString("uuid") + "/address/" + addressObject.getString("uuid"); + return new JSONObject( - HttpUtil.post(getURL() + "/" + url, "", requestBody.toString(), OPENMRS_USER, OPENMRS_PWD).body()); - + HttpUtil.post(getURL() + "/" + url, "", requestBody.toString(), OPENMRS_USER, OPENMRS_PWD).body()); + } - + + + public void updateIdentifiers(String personUUID, Client c) throws JSONException { JSONObject p = getPatientByUuid(personUUID, false); if (p.has("identifiers") && p.get("identifiers") instanceof JSONArray) { JSONArray identifiers = p.getJSONArray("identifiers"); Map idsMap = c.getIdentifiers(); - + for (int j = 0; j < identifiers.length(); j++) { JSONObject idObject = identifiers.getJSONObject(j); String identifierType = idObject.has("display") ? idObject.getString("display") : null; String identifierUuid = idObject.has("uuid") ? idObject.getString("uuid") : null; - + if (identifierType == null || identifierUuid == null) { continue; } @@ -826,30 +793,30 @@ public void updateIdentifiers(String personUUID, Client c) throws JSONException } } } - + private String convertToOpenmrsString(String s) { if (org.apache.commons.lang3.StringUtils.isEmpty(s)) { return s; } - + s = s.replaceAll("\t", ""); s = org.apache.commons.lang3.StringUtils.stripAccents(s); return s; - + } - + private Object convertToOpenmrsString(Object o) { if (o != null && o instanceof String) { return convertToOpenmrsString(o.toString()); } return o; - + } - + private String fetchLocationByUUID(String locationUUID) { try { - if (locationUUID == null || StringUtils.isEmptyOrWhitespaceOnly(locationUUID) - || locationUUID.equalsIgnoreCase("Other")) { + if (locationUUID == null || StringUtils.isEmptyOrWhitespaceOnly(locationUUID) || locationUUID + .equalsIgnoreCase("Other")) { return locationUUID; } Location location = openmrsLocationService.getLocation(locationUUID); @@ -864,7 +831,7 @@ private String fetchLocationByUUID(String locationUUID) { return "Unknown Location Id: " + locationUUID; } } - + private String fetchIndentifierTypeUUID(String identifierType) throws JSONException { String uuid = getIdentifierTypeUUID(identifierType); if (uuid == null) { @@ -873,4 +840,25 @@ private String fetchIndentifierTypeUUID(String identifierType) throws JSONExcept } return uuid; } + + private String cleanIdentifierWithCheckDigit(String rawId) { + + if (StringUtils.isNullOrEmpty(rawId)) { + return rawId; + } + + boolean containsHyphen = rawId.contains("-"); + + if (!containsHyphen) { + return formatId(rawId); + } else { + return rawId; + } + } + + private String formatId(String openmrsId) { + int lastIndex = openmrsId.length() - 1; + String tail = openmrsId.substring(lastIndex); + return openmrsId.substring(0, lastIndex) + "-" + tail; + } } diff --git a/opensrp-core/src/main/resources/applicationContext-opensrp.xml b/opensrp-core/src/main/resources/applicationContext-opensrp.xml index ae50fb0160..8a1ef6d0ff 100644 --- a/opensrp-core/src/main/resources/applicationContext-opensrp.xml +++ b/opensrp-core/src/main/resources/applicationContext-opensrp.xml @@ -1,15 +1,15 @@ + class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"> @@ -32,17 +32,17 @@ + fixed-delay="180000" /> + fixed-delay="300000" /> + fixed-delay="420000" /> + fixed-delay="600000" /> + fixed-delay="900000" /> + fixed-delay="120000" /> @@ -55,25 +55,25 @@ + p:max-total="${redis.pool.max.connections}" p:test-on-borrow="true" + p:test-on-return="true" /> + class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory" + p:host-name="${redis.host}" p:port="${redis.port}" p:password="${redis.password}" + p:use-pool="true"> + p:connection-factory-ref="jedisConnectionFactory" + p:enable-transaction-support="true" /> + class="org.springframework.data.redis.connection.lettuce.DefaultLettucePool"> @@ -81,18 +81,17 @@ + p:max-total="${redis.pool.max.connections}" p:test-on-borrow="true" + p:test-on-return="true" /> + class="org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory"> + p:connection-factory-ref="lettuceConnectionFactory" + p:enable-transaction-support="true" /> - diff --git a/opensrp-core/src/test/resources/form/pnc_reg_form/form_submission.json b/opensrp-core/src/test/resources/form/pnc_reg_form/form_submission.json index 849b39de30..5ec548d617 100644 --- a/opensrp-core/src/test/resources/form/pnc_reg_form/form_submission.json +++ b/opensrp-core/src/test/resources/form/pnc_reg_form/form_submission.json @@ -405,7 +405,7 @@ "instances": [ { "gender": "male", - "birthdate":2015-03-05", + "birthdate":"2015-03-05", "weight": "2", "bloodGroup": "a_negative", "immunizationsGiven": "bcg", @@ -421,7 +421,7 @@ }, { "gender": "male", - "birthdate":2015-04-05", + "birthdate":"2015-04-05", "weight": "", "bloodGroup": "a_negative", "immunizationsGiven": "bcg", @@ -437,7 +437,7 @@ }, { "gender": "female", - "birthdate":2015-05-05", + "birthdate":"2015-05-05", "weight": "", "bloodGroup": "a_negative", "immunizationsGiven": "bcg", diff --git a/opensrp-web/pom.xml b/opensrp-web/pom.xml index df9bab9384..8d9a16e2b8 100644 --- a/opensrp-web/pom.xml +++ b/opensrp-web/pom.xml @@ -67,6 +67,7 @@ spring-tx 3.1.1.RELEASE + @@ -338,6 +339,5 @@ spring-data-redis 1.3.6.RELEASE - diff --git a/opensrp-web/src/main/java/org/opensrp/web/GZipCompressionFilter.java b/opensrp-web/src/main/java/org/opensrp/web/GZipCompressionFilter.java new file mode 100644 index 0000000000..aa8ed6dbcb --- /dev/null +++ b/opensrp-web/src/main/java/org/opensrp/web/GZipCompressionFilter.java @@ -0,0 +1,39 @@ +package org.opensrp.web; + +import java.io.IOException; + +import javax.servlet.Filter; +import javax.servlet.FilterChain; +import javax.servlet.FilterConfig; +import javax.servlet.ServletException; +import javax.servlet.ServletRequest; +import javax.servlet.ServletResponse; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +/** + * @author samuelgithengi + */ +public class GZipCompressionFilter implements Filter { + + public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException { + if (req instanceof HttpServletRequest) { + HttpServletRequest request = (HttpServletRequest) req; + HttpServletResponse response = (HttpServletResponse) res; + String ae = request.getHeader("accept-encoding"); + if (ae != null && ae.indexOf("gzip") != -1) { + GzipResponseWrapper wrappedResponse = new GzipResponseWrapper(response); + chain.doFilter(req, wrappedResponse); + wrappedResponse.finishResponse(); + return; + } + chain.doFilter(req, res); + } + } + + public void init(FilterConfig filterConfig) {//do nothing + } + + public void destroy() {//do nothing + } +} diff --git a/opensrp-web/src/main/java/org/opensrp/web/GzipResponseStream.java b/opensrp-web/src/main/java/org/opensrp/web/GzipResponseStream.java new file mode 100644 index 0000000000..6b10d60c4f --- /dev/null +++ b/opensrp-web/src/main/java/org/opensrp/web/GzipResponseStream.java @@ -0,0 +1,79 @@ +package org.opensrp.web; + +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.util.zip.GZIPOutputStream; + +import javax.servlet.ServletOutputStream; +import javax.servlet.http.HttpServletResponse; + +/** + * @author samuelgithengi + */ +public class GzipResponseStream extends ServletOutputStream { + + protected ByteArrayOutputStream baos = null; + + protected GZIPOutputStream gzipstream = null; + + protected boolean closed = false; + + protected HttpServletResponse response = null; + + protected ServletOutputStream output = null; + + public GzipResponseStream(HttpServletResponse response) throws IOException { + super(); + closed = false; + this.response = response; + this.output = response.getOutputStream(); + baos = new ByteArrayOutputStream(); + gzipstream = new GZIPOutputStream(baos); + } + + public void close() throws IOException { + if (closed) { + throw new IOException("This output stream has already been closed"); + } + gzipstream.finish(); + + byte[] bytes = baos.toByteArray(); + + response.addHeader("Content-Length", Integer.toString(bytes.length)); + response.addHeader("Content-Encoding", "gzip"); + output.write(bytes); + output.flush(); + output.close(); + closed = true; + } + + public void flush() throws IOException { + if (closed) { + throw new IOException("Cannot flush a closed output stream"); + } + gzipstream.flush(); + } + + public void write(int b) throws IOException { + if (closed) { + throw new IOException("Cannot write to a closed output stream"); + } + gzipstream.write((byte) b); + } + + public void write(byte b[]) throws IOException { + write(b, 0, b.length); + } + + public void write(byte b[], int off, int len) throws IOException { + if (closed) { + throw new IOException("Cannot write to a closed output stream"); + } + gzipstream.write(b, off, len); + } + + public boolean closed() { + return (this.closed); + } + +} diff --git a/opensrp-web/src/main/java/org/opensrp/web/GzipResponseWrapper.java b/opensrp-web/src/main/java/org/opensrp/web/GzipResponseWrapper.java new file mode 100644 index 0000000000..723accaab9 --- /dev/null +++ b/opensrp-web/src/main/java/org/opensrp/web/GzipResponseWrapper.java @@ -0,0 +1,73 @@ +package org.opensrp.web; + +import java.io.IOException; +import java.io.OutputStreamWriter; +import java.io.PrintWriter; + +import javax.servlet.ServletOutputStream; +import javax.servlet.http.HttpServletResponse; +import javax.servlet.http.HttpServletResponseWrapper; + +/** + * @author samuelgithengi + */ +public class GzipResponseWrapper extends HttpServletResponseWrapper { + + protected HttpServletResponse origResponse = null; + + protected ServletOutputStream stream = null; + + protected PrintWriter writer = null; + + public GzipResponseWrapper(HttpServletResponse response) { + super(response); + origResponse = response; + } + + public ServletOutputStream createOutputStream() throws IOException { + return (new GzipResponseStream(origResponse)); + } + + public void finishResponse() { + try { + if (writer != null) { + writer.close(); + } else { + if (stream != null) { + stream.close(); + } + } + } + catch (IOException e) {} + } + + public void flushBuffer() throws IOException { + stream.flush(); + } + + public ServletOutputStream getOutputStream() throws IOException { + if (writer != null) { + throw new IllegalStateException("getWriter() has already been called!"); + } + + if (stream == null) + stream = createOutputStream(); + return (stream); + } + + public PrintWriter getWriter() throws IOException { + if (writer != null) { + return (writer); + } + + if (stream != null) { + throw new IllegalStateException("getOutputStream() has already been called!"); + } + + stream = createOutputStream(); + writer = new PrintWriter(new OutputStreamWriter(stream, "UTF-8")); + return (writer); + } + + +} diff --git a/opensrp-web/src/main/resources/quartz.properties b/opensrp-web/src/main/resources/quartz.properties index dfca673b4c..833f4c2bdf 100644 --- a/opensrp-web/src/main/resources/quartz.properties +++ b/opensrp-web/src/main/resources/quartz.properties @@ -9,7 +9,7 @@ org.quartz.jobStore.tablePrefix = QRTZ_ org.quartz.jobStore.misfireThreshold = 300000 org.quartz.dataSource.motechDS.driver = com.mysql.jdbc.Driver -org.quartz.dataSource.motechDS.URL = jdbc:mysql://localhost:3306/motechquartz_tbreach +org.quartz.dataSource.motechDS.URL = jdbc:mysql://localhost:3306/motechquartz org.quartz.dataSource.motechDS.user = root org.quartz.dataSource.motechDS.password = VA1913wm org.quartz.dataSource.motechDS.maxConnections = 30 diff --git a/opensrp-web/src/main/webapp/META-INF/context.xml b/opensrp-web/src/main/webapp/META-INF/context.xml index 2351b47a5c..69b0380ad2 100644 --- a/opensrp-web/src/main/webapp/META-INF/context.xml +++ b/opensrp-web/src/main/webapp/META-INF/context.xml @@ -21,4 +21,4 @@ url="jdbc:postgresql://localhost:5432/opensrp" /> - \ No newline at end of file + diff --git a/opensrp-web/src/main/webapp/WEB-INF/web.xml b/opensrp-web/src/main/webapp/WEB-INF/web.xml index d9951847a5..716c36bdbc 100644 --- a/opensrp-web/src/main/webapp/WEB-INF/web.xml +++ b/opensrp-web/src/main/webapp/WEB-INF/web.xml @@ -52,6 +52,11 @@ org.opensrp.web.AuthenticationFilter + + GZipFilter + org.opensrp.web.GZipCompressionFilter + + AuthenticationFilter /authenticate-user/ diff --git a/opensrp-web/src/main/webapp/index.html b/opensrp-web/src/main/webapp/index.html index 45d009ab47..272f10d147 100644 --- a/opensrp-web/src/main/webapp/index.html +++ b/opensrp-web/src/main/webapp/index.html @@ -1,7 +1,7 @@ - Welcome to OpenSRP TB-Reach! + Welcome to OpenSRP ANC! diff --git a/pom.xml b/pom.xml index 3a733fdccc..bed7d1d3dd 100644 --- a/pom.xml +++ b/pom.xml @@ -272,7 +272,7 @@ - couchDb + couchdb opensrp.database.type