Moving MW to 3-Tier Q&A

Q: For moving MW on 3 tier, we will be deploying XWSF war, MW application classes, MW view definition XMLs, hibernate property and mapping files, etc. things on tomcat.

A: Not really. We have all this developed (or are in the process of debugging and developing more). Nothing new needs to be developed. All we need to do is put the new 3-Tier XWSF into use and action for our existing MW code.

Q: Application will persist or load data directly using hibernate which will connect to any underlying database like PostgreSQL, Oracle, etc. So we won't be using hsqldb as well as Jetty server any more. Is it correct? Will this create any issue?

A: Jetty is more light weight than Tomcat and can do Servlets. So, I don't think we need to drag in Tomcat. HSQLDB is there for a simple rapid deploy and test use, never for any production. There is no need to cut HSQLDB out, it just won't be used for production. I personally would like to keep running our app on the Jetty thing because it is more light weight. But none of this should be a real issue. If you like Tomcat as the Servlet container for now, do use it. Once it works there it can be made to work through Jetty.

Q: Are there any issues in using various RDBMS like PostgreSQL and MySQL underneath hibernate (in place of hsqldb)?

A: None that you need to worry about at this point. These are entirely interchangeable as far as we are concerned. We don't bother with MySQL. PostgreSQL is our main target for any production use, HSQLDB is purely for quick and easy testing. Oracle is for proof of concept that it can be done. I have used PostgreSQL and Oracle for big data.

Q: In particular, is there a problem with mysql 5.0?

A: Do not spend even a second of thought on MySQL.

Q: Is HL7 JavaSIG the channel to persist data for MW?

A: In our MW application yes. Definitely. However, one can write XWSF applications entirely independent of MW and JavaSIG.

Q: What is the exact role of HL7 JavaSIG? To provide standardized interfaces for communication or to persist data? We would really like some explanation on this topic.

A: HL7 JavaSIG is the implementation of HL7 health care data types and Reference Information Model. The JavaSIG code is the Model in Model-View-Controller.

Q: What is the role of encumbered?

A: Some of the HL7 metadata is Intellectual property that can't be packaged with an open source distribution. We keep all that IP in the encumbered file. It can also be replaced by an officially purchased CD ROM release of HL7 metadata.

Q: At many places, an object is Cloneable and yet the call to clone() is tried for CloneNotSupportedException??. We are getting a compile error for it.

A: This is new. Someone convinced me that clone() throws CloneNotSupportedException? is part of the signature of clone() and should not be removed in an extending interface. Once I added the throws clause into the interface declaration, I had to add the catch blocks everywhere. This should not cause compile errors. Please report with exact message in the JavaSIG Trac.

Q: Are their any other hibernate mapping files except "mw.hbm.xml" and "all.hbm.xml" ? Or does these 2 hbm files cover all the required mappings for MW?

A: all.hbm.xml is generated from template.hbm.xml using the mif2hbm.xsl transform and the rim.coremif metadata file (encumbered). mw.hbm.xml is our MW extensions and imports the basic all.hbm.xml from JavaSIG. At this time there is no other hbm.xml file, although there could well be some in the future.

Q: What all is needed to run MW? Could you explain the prerequisites? We often get various exceptions while trying to bring it up.

A: All software and libraries are included. If you follow the steps on this wiki, it should work. If not, please open a bug showing what you did and the detailed error you have received.

Q: If any of these questions are already answered on the wiki, just point out the link.

A: No they are fine questions for you to ask. Hope this has helped.

Questions Regarding The Deployment of Jetty

Q: The official site is down.

A: The real site is is up. :)

Q: The material found at codehaus.org is quite different from what we have in our project. For example I can't find start.jar, jetty-web.xml or jetty.xml in our projects. In short, we don't know where to look for info on Jetty.

A: Do not worry. For now you should use whatever Servlet container you feel good with. It should work on Tomcat just as well as on Jetty, and deployment into Tomcat is very well the thing we'll do.

Q: The immediate problem is that our servlet is not being mapped to the url we specify in web.xml ( or that is what I think). We are able to up the server. It shows directory listing of xwsf in the absence of an index.html. But gives "404 - Not Found" error for our context path ie /xwsf.

A: Again, do not worry about Jetty quirks, try with Tomcat first. There is more important things to worry first.

Q: In order to use Tomcat, what do we need to know about the purpose of Jetty in 2-tier framework? Is there some JMX or JMS running which must be run along with the framework?

A: Jetty has so far had no purpose for the actual end-user application. It is only used in a messaging service which is entirely unrelated to the user application. So, you do not have to worry about Jetty. If you receive interaction due to the presence of the Jetty libraries, then delete them in your branch.

Scheme for Deployment of Framework and Application

- We have separated application from the XWSF framework code. Here is our idea for their deployment.

- Most of the framework code will go in xwsf.jar which will be placed in shared/lib directory of Tomcat, along with the dependencies

- A nominal xwsf.war having web.xml and ApplicationController? (the servlet) will be deployed as the web application. This bifurcation was necessitated by classloader issues of Tomcat

- The application is only required to put its jar along with the dependencies in the shared/lib folder of Tomcat and it will run.

- The limitation is that this Tomcat instance should not be used for other type of web applications as classes in the shared folder will be available to all the web apps.

- This is the scheme we are using as of now. The other option is that we provide the web.xml, the servlet and the xwsf.jar to the application developer and let them build an integrated war which contains the application code. In this case we can provide them with an ant target to build the war

Changes required for integrating MW with 3 tier XWSF

1. Deployment (as described above)

2. Changes in view definition xmls

- Modify data tags. Use aspect instead of SWT method names.

- Modify DnD syntax

- Change action tags. Remove SWT specific method names and use event attribute for generic event names

- Other syntax changes, which have been done to remove SWT specific things and introduce generic terms.

3. Controllers and Actions refactoring :

- For 2 tier, actions were directly bind to widgets as event listener. (so they were having method such as widgetSelected, shellClosed, etc.).

For 3 tier, Every action is supposed to implement following method only :

public void handleEvent(XWSFEvent event)

- Since Action classes are registered as event listeners, they access the event source widget and other SWT related stuff. This needs to be refactored.

Eventually the System Bootstrapping Should work like this
  • mw.ApplicationRuntime? corresponds to the main Servlet that is invoked when a client initiates a connection by one fixed URL.
  • Remember, the URL will not choose the xwsf XML page to render, it is, the application which will display content in its DialogViewPort?. XWSF ViewFactory? does the displaying.
  1. I figure xwsf code could just be bundled with mw code in the same war file. It should be really simple in the end.
  2. It should be deployable into a tomcat instance along with many other web apps.
  3. It should also be deployable from Jetty.

BUT YOU DO NOT HAVE TO TAKE ANY POSITIVE STEPS bothering with the three numbered items. Just go ahead as expediently as you can and focus on the overall functioning. Only be sure that the present functioning with the ViewFactory?, ViewPlaceholders?, and ApplicationActs with their dialogViewports is not destroyed. That was a pretty important design.

More Q&A

Q: The URL will not choose the xwsf XML page to render, but at least for the first time, don't we need to mention it? Otherwise server won't be able to figure which view should be pushed to the client? (Specially if there are multiple XWSF applications hosted on the same server and multiple clients accessing them).

A: That is why the XWSF is not the main Servlet. The Servlet code belongs to MW. The web.xml would be configured to use some class like org.regenstrief.mw.app.ApplicationServletImpl? extends ApplicationActImpl? implements ApplicationAct?. Now there is the URL, such as http://aurora.regenstrief.org/mw/app which would start that servlet. XWSF is not going to be a manager of applications. Many XWSF based applications could run at the same time on the same tomcat instance. Each would use the XWSF code, but each would have their own Servlet and URL.

Of course, any general functions that all XWSF applications need to run would be implemented in an org.regenstrief.xwsf.AbstractUIServlet or something like that, so that the org.regenstrief.mw.app.ApplicationServletImpl? would be very simple and only deal with implementing the ApplicationAct? functions ... oops ... that wouldn't work as that would be multiple inheritance. So then there would be no abstract UI servlet, but instead a org.regenstrief.xwsf.AbstractUIServletTool which would be used by org.regenstrief.mw.app.ApplicationServletImpl? via delegation. But that can be factored later.

Q: But ApplicationRuntime? is not a servlet now. Shouldn't the servlets be in the framework and not in the application?

A: I think the servlets should be in the application. You may think its a quirk, but I love my ApplicationAct? design. I want all instances of "computation" to be represented by an ApplicationAct? object, starting with the Servlet, HttpSession?, ApplicationRuntime?, Session, PatientSession?, Command, etc.

  1. It's the ApplicationAct? / ApplicationContext? idea. A web servlet is initialized when the server starts or webapp is reloaded. This would already be an MW ApplicationActImpl? which leaves its mark in the database.
  2. Then, when a request comes in, either a new or existing session will handle that request. So, the web session is represented by another MW ApplicationActImpl?. That now corresponds with what exists as ApplicationRuntimeImpl? in the 2-tier system.
  3. That ApplicationRuntimeImpl? or WebSessionImpl? will then initialize the view through a method similar as the ViewFactory? bootstrap.
  4. From then on, there is a DialogViewport? (and in future perhaps other viewports) to push content to the client.
  5. Now everything else works unchanged. I.e., the WebSessionImpl? will launch the UserAuthenticateCommand? which will display the authentication screen via the DialogViewport?.
  6. Then when that completes it will start a UserSession?, which, in turn, pushes its User Perspective gui to the WebSessionImpl?'s DialogViewport?.
  7. And so on, on selecting a patient, the PatientSession? would be launched which again pushes its Patient Session Perspective. Now most commands that are launched go into the DialogViewPort? there, which now is a tabFolder and causes multiple Command (tasks) to be shown in different tabs in parallel.

I think the primary point of your changes in MW should be the controllers and wherever we are scheduling Runnables into the UI thread. However, ALL the creation of views should still go through ViewFactory?, pushed by the application server (not pulled via URL parameters) and using the ViewPort? approach.

Q: Can you explain the rationale behind all this ApplicationAct? stuff? Is the idea of ServletContexts? used as a pattern here?

A: The design was developed while gaining experience with writing the system. A ViewPort? is a communication channel to a user. Applications can render ViewStuff? on ViewPorts?. ViewStuff? is put on a queue and the queue is displayed in a ViewPlaceholder?. This can be immediately in a stacked window or in a tab folder or some other organizer.

ViewStuff? is like instant noodlesoup (just add water): a view just about ready to be displayed, but not yet displayed because it can only be displayed (in SWT specifically) when the parent widget has been determined (just add a parent). But the application component that wants to talk to the user does not know where it should put its content. Managing that is the job of the Perspective.

Therefore, the application component (e.g., a Command, better word might be Task) will send ViewStuff? into the ViewPort? queue. Where it will be rendered in the proper ViewPlaceholder? as determined by the Perspective. Now, a Perspective too is rendered in a ViewPort?, and because that is recursive, you have the bootstrap problem, where an initial view has to be spit out somehow differently. ViewPlaceholder? has this bootstrap view method.

Question regarding actions

In 2 tier all actions act as event listners, implementing appropriate event listner interfaces.

And now in 3 tier, we have removed all SWT specific code from actions and they simply implement single method "handleEvent( XWSFEvent event)

When a particular event occurs , client simply pass all event information through xml message. Then the application controller simply forms XWSFEvent object according to event type, finds appropriate controller responsible for that view. And then the view controller maps that event to appropriate action, executing its handleEvent method.

Now the issue is: the generic event types may have sub events / types.

e.g. Focus event may indicate focus loss or gain.

For 2 tier, actions directly implement 2 separate methods "focusGained(FocusEvent? arg0)" and "focusLost(FocusEvent? arg0)".

Now for 3 tier, we will have to pass this sub event type information to server, where it will be set into XWSF event.

Now the question is, Should we expect the actions to check this sub type using if-else blocks OR Should we define generic listener interfaces on server and force actions to implement them?

Even though 2nd approach may take some time for implementation, action code will be much more clearer. But I am not really sure whether to bind actions with event listener interfaces?

Good Question

Actions can be mind boggling, messy. I am not 100% happy with the way they have evolved.

I doubt that Actions should be considered event handlers at all. The UI events should be handled on the client, actions will be invoked, but are independent of events. E.g., FocusLostEvent? would be mapped to the DataInputHandler?.UpdateAction?.

The argument to the Action call would only sometimes be required if there are any arguments of note to communicate. For instance, key event listeners might need this to handle, e.g., ESC key specially to reset a data input field to its original content. But even that might be handled on the UI side. My reasoning is that Actions should be independent of how a user might invoke them, a hot key or mouse gesture, and key strokes or mouse gestures should be UI issues and not server side issues.

So, I think I push back on both suggested options and consider refining the abstract event names on UI side. There would be no FocusEvent?, only FocusLossEvent? and FocusGainEvent?. KeyEvent? would have a parameter to determine which key.