Module does not work on platform without Leagacy-UI

Hello to everyone. I am not very experience in Spring or OpenMRS development, so please bear with me.

I am working on a module that does some flexible/approximate search on the OpenMRS database.

My first issue is that the module I currently have works when I have the Legacy UI Installed. But it does not work without it.

I built the Legacy UI from github on 12/12/2014, and am currently using the platform 2.0.0 war on tomcat.

I built the module using the maven archetype, and the changes I have made are the following

The resultSet is a POJO which is currently set to hardcoded values for testing.

The following code works in when the UI is installed and the module is hit from: openmrs/module/flexiblesearch/search.form

directory structure: omod\src\main\java\org\openmrs\module\flexiblesearch\controller Controller Class

public class FlexibleSearchManageController {

protected final Log log = LogFactory.getLog(getClass());

@RequestMapping(value = "/module/flexiblesearch/search", method = RequestMethod.GET)
public void showForm(){
	//since this method has not been implemented
	// Spring MVC will look for the last part in the above mapping
	// in the webapp folder appended with a jsp
	// in this case it would look for search.jsp
	
	// also need to create a link in the admin list
}

@ModelAttribute
public ResultSet getSearchResults(@RequestParam(required=false, value="searchQuery") ResultSet resultSet){
	resultSet = new ResultSet();
	return resultSet;
}

}

dir: \omod\src\main\webapp JSP Page: …includes for footer and header are in the jsp

Enter Your Search Query:
First Name ${resultSet.firstName}
Last Name ${resultSet.lastName}
Telephone ${resultSet.telephone}
Address ${resultSet.address}
Patient ID ${resultSet.patientID}

AdminList.java public Map<String, String> getLinks() { LinkedHashMap<String, String> map = new LinkedHashMap<String, String>(); map.put("/module/flexiblesearch/search", “Flexible Search”); return map; }

Quick Note: Can the admin list extension point cause this dependency?

I have not modified the config.xml file yet. Do I need to add a servlet name/class mapping in there? I am working under the assumption that the request mapping from spring takes care of that.

The reason I cannot test is something that arose just recently. My teammate installed platform 2.0.0 and then installed the legacy UI on top of that and it ran without problem. I deleted my OpenMRS installation completed (deleted from tomcat webapp folder as well as the app data directory) and reinstalled and added the legacy UI module I ran into this problem:

ERROR - ModuleFactory.startModules(228) |2016-12-13 04:53:30,907| Could not start some modules because they depend on others which are not started. Please first start them or use the “Start All” button on the “Manage Modules” page: [owa->legacyui, fhir->legacyui, webservices.rest->legacyui] org.openmrs.util.CycleException: [owa->legacyui, fhir->legacyui, webservices.rest->legacyui] at org.openmrs.util.Graph.topologicalSort(Graph.java:170) at org.openmrs.module.ModuleFactory.getModulesInStartupOrder(ModuleFactory.java:336) at org.openmrs.module.ModuleFactory.startModules(ModuleFactory.java:224) at org.openmrs.module.ModuleUtil.startup(ModuleUtil.java:128) at org.openmrs.api.context.Context.startup(Context.java:830) at org.openmrs.web.Listener.startOpenmrs(Listener.java:245) at org.openmrs.web.WebDaemon$1.run(WebDaemon.java:42)

My second question is, how can I use the service layer to directly access the openmrs database?

I appreciate any help you can give me. Thank You.

I hope someone can help with some, if not all of the problems. I would be very grateful.

Thanks,

@kmat a number of classes were moved from the platfrom into the legacyui module. So if you are using or depending on any of such, you need the legacyui module to be installed.

If you used the OpenMRS SDK to create a module, it has a wizard with an option to automatically create for you a service layer to access the database. https://wiki.openmrs.org/display/docs/OpenMRS+SDK

@dkayiwa Thank you for your reply. I will look into the SDK for the database thing.

As for the dependencies, the only one I have is OpenMRS core in my module:

		<!-- Begin OpenMRS core -->
		
		<dependency>
			<groupId>org.openmrs.api</groupId>
			<artifactId>openmrs-api</artifactId>
			<version>${openMRSVersion}</version>
			<type>jar</type>
			<scope>provided</scope>
		</dependency>

		<dependency>
			<groupId>org.openmrs.web</groupId>
			<artifactId>openmrs-web</artifactId>
			<version>${openMRSVersion}</version>
			<type>jar</type>
			<scope>provided</scope>
		</dependency>
					
		<dependency>
			<groupId>org.openmrs.api</groupId>
			<artifactId>openmrs-api</artifactId>
			<version>${openMRSVersion}</version>
			<type>test-jar</type>
			<scope>test</scope>
		</dependency>
		
		<dependency>
			<groupId>org.openmrs.web</groupId>
			<artifactId>openmrs-web</artifactId>
			<version>${openMRSVersion}</version>
			<type>test-jar</type>
			<scope>test</scope>
		</dependency>
		
		<dependency>
			<groupId>org.openmrs.test</groupId>
			<artifactId>openmrs-test</artifactId>
			<version>${openMRSVersion}</version>
			<type>pom</type>
			<scope>test</scope>
		</dependency>
					
		<!-- End OpenMRS core -->

The first problem I am trying to solve is how to get legacy UI working when it is was working a day ago but but apprently now its not after using the latest one from the github repo.

ERROR - ModuleFactory.startModules(228) |2016-12-13 04:53:30,907| Could not start some modules because they depend on others which are not started. Please first start them or use the “Start All” button on the “Manage Modules” page: [owa->legacyui, fhir->legacyui, webservices.rest->legacyui] org.openmrs.util.CycleException: [owa->legacyui, fhir->legacyui, webservices.rest->legacyui]?

Can you please advise how to get around this error because that is the only thing the log is showing. BTW, if I take out the legacy UI mod, then the other 3 (fhir, owa and webservices) work fine but with the legacy UI even they break.:

Is there any way of forcefully starting these modules without the UI installed? And is there any directory other than tomcat webapps and the app data directory where openmrs might store any config or old files that might cause such a problem?

Thanks,

You can go to the global_property table and look for “moduleid.started” where moduleid is in this set [owa->legacyui, fhir->legacyui, webservices.rest->legacyui] Then set each value to true and restart your servlet container.

@dkayiwa Thank you again for the info. I was able to get the modules working.

I used the maven archetype to create the module and not the SDK. I am currently looking into the SDK module creation to learn how to do the database connections.

But if I wanted to work without the SDK, would I be correct in assuming that I would explicitly have to create a connection using JDBC drivers in Java code or can I somehow go through OpenMRS core while still using the maven archetype created module?

@kmat, behind the scenes, the SDK uses the maven archetype module creation functionality. Therefore if you run the maven archetype module creation wizard again, you will see that it has an option where you choose whether to have the service and data access layer classes automatically created for you.

@dkayiwa Alright, thanks for clearing that up.

I am sorry if I am asking questions that might seem trivial, but I am trying to work through this as best as I can.

Two more questions,

  1. After the Legacy UI starts, I expect to see the module in the admin list. I have the following code in AdminList.java public Map<String, String> getLinks() { LinkedHashMap<String, String> map = new LinkedHashMap<String, String>(); map.put("/module/flexiblesearch/search", “Flexible Search”); return map; }

When I created the module using maven, I said yes to both link on admin page and the service layer.

  1. From what I have read from the documentation, the service layer requires Hibernate (please correct me if I am wrong) to access the database. Now, since I don’t know Hibernate at all, I want to ask the following question before I start learning it.

Traditionally, in Java I would do something like define the JDBC driver, give it the URL, user, pass etc… and then write the queries.

Using the service layer with Hibernate, would I need to do the same (in which case I can simply do the above) or does Hibernate allow me to skip that part using drivers and settings already in the OpenMRS core/properties?

And I want to clarify, I do not want to change or create any new data in the DB. I only need raw access to the DB to run queries and procedures.

Thank You for all your prompt help so far.

Regards,

The service layer does not require hibernate. It uses the data access layer. It is the data access layer which may use hibernate, JDBC, or something else. For just running database procedures, another possible option is Context.getAdministrationService().executeSQL(). You would make this call from your data access layer class.

@dkayiwa Another extension on the previous question.

I attempted to use

AdministrationService adminService = Context.getAdministrationService(); adminService.executeSQL(sqlQuery, false); (also tried with true for the second arg. I believe it means Select Only?)

from one of my java controller objects. (Probably not a good idea, I know.) The query itself is a simple select * from statement for testing. I tested it on the database directly beforehand.

The issue I faced was that the query apparently ran, but returned zero results when it should have returned some number of records. My question is, where do I run this query to get the correct results?

There are quite a few classes in the API project, which is why I don’t want to go through each of them one by one to test.

my project directory structure is attached below:

Thanks Again in advance,

Which openmrs platform version are you running?

I am using Platform 2.0.0 downloaded from old releases here: https://sourceforge.net/projects/openmrs/files/releases/OpenMRS_Platform_2.0.0/

The only other modules installed on it right now are the bundled ones (fhir, owa, webservices.rest) and legacy-ui which I built from the git v1.2.4

Here is one of the many examples where it is used to return results https://github.com/openmrs/openmrs-core/blob/master/api/src/main/java/org/openmrs/util/databasechange/ConvertOrderersToProviders.java#L52 Is your module anywhere like on github to look at?

@dkayiwa Currently I don’t have the module in a git repo.

I was able to get the code to work. The reason Context.getAdministrationService().executeSQL() wasn’t working was my own fault due to a minor logical error in the code.

Next Issue. They keep coming unfortunately.

In the API project service layer, I have defined some methods in the Interface FlexibleSearchService, and Implemented them in the FlexibleSearchServiceImpl.java.

I am currently not using the DAO or Hibernate classes. If I try to call a method using:

Context.getService(FlexibleSearchService.class)).searchFirstName(queryString);

I get the following error: The method searchFirstName(String) is undefined for the type FlexibleSearchService

The bean for the Impl class is included in the moduleApplicationContext with the bean name target. Do I need to make chagnes here or do some startup logic?

Thanks,

Please ignore the above post. Figured out how to get around it. Thanks for all your help.