Setup a new patient with a date of death before date of birth
When you run your rule it should return one patient, and can even check the patient’s ID
Setting up the tests will require you to run your test, find an error, fix it, run again etc … Its a step by step process and you will be the better for it. Once the tests run then we can look into adding your module to a Ref App SDK to deal with the UI stuff.
@shivtej I think I may have misled you and which is causing all the confusion. So my suggestion is as follows:
Create a new Reference Application Module
Test Cases
Add a sample data file with a person whose death date is after the birth date - you may need to add dummy data for persons without death dates to ensure the rule ignores them
You do not need to mock anything in the test cases since they are very simple
Add the Invalid Death Date rule
The criteria query you had was correct by the way - you just need to compare the death date to birth date
Once you get a list of patients you transform the list into the RuleResult
The approach is to write the tests first so that they fail - I cannot stress this enough I spent 4 weeks trying to work without tests, but took only 2 days with tests (I am evangelical about this)
@ssmusoke, I have successfully created test and tried on the sample rule. The rule is working fine, the test is passing. I request you to check the code I have written. You can access the test I wrote here and respective class here .
Thanks for pointing me at this approach. I learned lots of things.
After successfully writing and testing the test, I tried to deploy the module in the server. The build was successful but both submodules (api and omod) was skipped. I’m not sure if it is a problem.
I’m getting the same error (ui framework error) , here is the fresh log: https://pastebin.com/y7f4p2VB
Please let me know about the next set of steps.
Thanks.
@ssmusoke, I updated the getRule method and again tried deploying it on the server. I’m still not able to see the rules if they aren’t in database. I guess I need to write unit test of getRule also. I’ve updated the source code accordingly, you can see it on the same repo.
Thanks @ssmusoke for your help and patience. I think we are very close to our target. I’ve made the some changes including the changes you suggested. Now, the test is passing.
I also dig through some DINT module code and understand the flow a little bit. I’m guessing, that the error (that UI error) is preventing us to saving the rule in the metadata.
I request you to review my progress. I’ve updated the code of custom module. And here is my config.xml which I’m using in root folder of DINT module.
config.xml (1.8 KB)
I still cannot build your project locally, the test errors are initializationError(org.openmrs.module.ruleshost.api.dao.RuleshostDaoTest): org/springframework/core/annotation/AnnotatedElementUtils initializationError(org.openmrs.module.ruleshost.dataintegrity.InvalidDateOfDeathTest): org/springframework/core/annotation/AnnotatedElementUtils
You do not need the test in RulesHostDaoTest
I am using Oracle JDK fails on both 7 and 8 - how are you able to build the module?
@ssmusoke, I removed all the tests except ‘InvalidDateOfDeathTest’ from the source code. Your local repo might not be updated. I’ve pushed all the changed in this repo: https://github.com/shivtej1505/ruleshost .
I also faced similar problem when I was using Java 8 with spring 3 version. I switched to java 7 and then it got built successfully. I read somewhere all spring modules should have same version and java 8 isn’t compatible with spring 3.
You should add your module to be watched by your server by typing mvn opnemrs-sdk:watch -DserverId=server in your module so that whenever you start a new server the module is compiled and deployed
It will also enable auto reloading of UI components so you do not have to redeploy the module to see UI changes
@ssmusoke, I followed the exact steps you wrote but now I’m getting a new error, the server can’t find RuleDefinition class. Here is the log file: https://pastebin.com/Mz05friW
@ssmusoke, I followed exact steps you told over the skype call. Hopefully I’m not getting that NoClassFoundError and InvalidCast error but now I’m getting another error. I tried different versions of hibernate but no luck.
UI Framework Error
Root Error
java.lang.NoSuchMethodError: org.hibernate.SessionFactory.getCurrentSession()Lorg/hibernate/classic/Session;
at org.openmrs.module.lite.dataintegrity.InvalidDateOfDeath.evaluate(InvalidDateOfDeath.java:22)
at org.openmrs.module.dataintegrity.rule.impl.DataIntegrityEvaluationServiceImpl.fireRules(DataIntegrityEvaluationServiceImpl.java:64)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:317)
at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:190)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:157)
at org.springframework.transaction.interceptor.TransactionInterceptor$1.proceedWithInvocation(TransactionInterceptor.java:99)
at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:281)
at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:96)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:207)
at com.sun.proxy.$Proxy198.fireRules(Unknown Source)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:317)
at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:190)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:157)
at org.openmrs.aop.LoggingAdvice.invoke(LoggingAdvice.java:121)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
at org.springframework.aop.framework.adapter.MethodBeforeAdviceInterceptor.invoke(MethodBeforeAdviceInterceptor.java:52)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
at org.springframework.aop.framework.adapter.MethodBeforeAdviceInterceptor.invoke(MethodBeforeAdviceInterceptor.java:52)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:207)
at com.sun.proxy.$Proxy199.fireRules(Unknown Source)
at org.openmrs.module.dataintegrity.page.controller.ResultsPageController.get(ResultsPageController.java:31)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.openmrs.ui.framework.UiFrameworkUtil.invokeMethodWithArguments(UiFrameworkUtil.java:112)
at org.openmrs.ui.framework.UiFrameworkUtil.executeControllerMethod(UiFrameworkUtil.java:71)
at org.openmrs.ui.framework.page.PageFactory.handleRequestWithController(PageFactory.java:219)
at org.openmrs.ui.framework.page.PageFactory.processThisFragment(PageFactory.java:160)
at org.openmrs.ui.framework.page.PageFactory.process(PageFactory.java:116)
at org.openmrs.ui.framework.page.PageFactory.handle(PageFactory.java:86)
at org.openmrs.module.uiframework.PageController.handlePath(PageController.java:116)
at org.openmrs.module.uiframework.PageController.handleUrlWithDotPage(PageController.java:83)
at sun.reflect.GeneratedMethodAccessor577.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.springframework.web.bind.annotation.support.HandlerMethodInvoker.invokeHandlerMethod(HandlerMethodInvoker.java:177)
at org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter.invokeHandlerMethod(AnnotationMethodHandlerAdapter.java:446)
at org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter.handle(AnnotationMethodHandlerAdapter.java:434)
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:943)
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:877)
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:966)
at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:857)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:624)
at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:842)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:731)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:303)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
at org.openmrs.module.web.filter.ForcePasswordChangeFilter.doFilter(ForcePasswordChangeFilter.java:60)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:241)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
at org.openmrs.module.web.filter.ModuleFilterChain.doFilter(ModuleFilterChain.java:72)
at org.openmrs.module.owa.filter.OwaFilter.doFilter(OwaFilter.java:57)
at org.openmrs.module.web.filter.ModuleFilterChain.doFilter(ModuleFilterChain.java:70)
at org.openmrs.module.web.filter.ModuleFilter.doFilter(ModuleFilter.java:54)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:241)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
at org.openmrs.web.filter.OpenmrsFilter.doFilterInternal(OpenmrsFilter.java:108)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:241)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
at org.springframework.orm.hibernate4.support.OpenSessionInViewFilter.doFilterInternal(OpenSessionInViewFilter.java:150)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:241)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
at org.openmrs.web.filter.StartupFilter.doFilter(StartupFilter.java:105)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:241)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
at org.openmrs.web.filter.StartupFilter.doFilter(StartupFilter.java:105)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:241)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
at org.openmrs.web.filter.StartupFilter.doFilter(StartupFilter.java:105)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:241)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:88)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:241)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:220)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:122)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:505)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:169)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:103)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:116)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:423)
at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1079)
at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:625)
at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:318)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
at java.lang.Thread.run(Thread.java:748)
@ssmusoke, I have created a new module hosted here: https://github.com/shivtej1505/lite
And I just wanted to start with small tickets to familiarize myself with the codebase but I think I have understood it decent enough by trying to setting it up.