Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.
Comment: Migration of unmigrated content due to installation of a new plugin

...

Panel
titleOn This Page
Table of Contents
indent2em
stylenone
typelist
separatorpipe

...

Overview

There is normally only one service class per app. The service class' job is to get data from the back end and perform some biz logic on it and return it to the front end (actions). There should be one service interface and one class that implements it, e.g. OasSkeletonService, and OasSkeletonServiceImpl. This allows us an easy method to swap the SAP implementation with a Mock implementation for testing purposes. See the applicationContext.xml for information on how to do this swapping.

For SAP apps, the service calls RFCs and converts their via sap2java using sap2java generated proxies. The service converts the proxy data into biz model objects. The service class should be a subclass of SAPServiceSupport which provides methods to call the back end and process errors. If an error message is returned from the SAP RFC at this point, processing will stop and the user will either stay on the same page displaying the error message if an action input has been defined correctly in the struts-config or they will be sent to the GlobalKeys.FAIL jsp page with a MessageRuntimeException. In the rare case that you don't want to stop processing and display the error message you should wrap your service call in a try...catch statement intercepting any MessageRuntimeException messages. See ApplicationResources for documentation on the error handling.

For Hibernate apps, the service calls the daos to get biz objects and performs whatever biz logic is necessary on them.

...

The service spring beans are configured in applicationContext.xml (not in action-servlet.xml) .

For SAP apps, there is a default applicationContext that sets up the proper service properties needed to connect to SAP. (There are also some extra property settings for doing mock services; see the file).

The service interface allows you to swap out implementations in the spring config so you can use a mock service instead for testing, etc.

Message Handling

Default message handling is configured in applicationContext.xml. Messages from the back end usually either come as a collection of messages from a table (e.g. ET_RETURN or ET_MESSAGES), or a single message stuffed into a field in the return output object. The SAPBaseAction and SAPServiceSupport classes in conjunction with the applicationContext.xml configuration file automatically handle
message processing so you don't have to. The only thing you need to do is configure what tables and/or properties the message/messages can be in based on what all its RFCs return. E.g.:

If some of your RFCs return messages in the ET_MESSAGES table and some return them in ET_RETURN, you would add both of these to the spring config for the messageKeys property. If some of your RFCs return a single message in the output object, say in the field E_RETURN, then you would specify e_RETURN in the messageKeys.

...

as singletons. Because of this, there should be no instance variables defined for your service other than static variables that you intend to be accessed across threads (users). For instance, in the example below, a static variable, log, is defined. This means all users will write to the same log file which is the behavior you want.

Image Added

More Info on SAPServiceSupport 

All of our services are subclasses of SAPServiceSupport which has 4 singleton instance variables (messageKeys, connectionMgr, messageMgr, packageName) which are all instantiated once with values from the applicationContext.xml config file when the Spring Framework instantiates the service.

  • The messageKeys are essentially strings for configuration to tell the framework what tables to look in for return messages.
  • The connectionManager allows you to generate connections. 
  • The messageManager is what holds all the messages from SAP. Now this might sound not "thread-safe", but the messageManager stores this data in a "ThreadLocal" which essentially binds the messages to the running Thread only.
  • The packageName, like messageKeys, is for configuration (apparently necessary for sap2java because of the way it utilizes reflection).

convertRFCMessage

If the message objects returned from the back end have both the TYPE and MESSAGE fields, then setting messageKeys is all the configuration you need to do (these are automatically dealt with)you do not need to modify the method convertRFCMessage. Error messages are automatically handled by mortar. However, if some other type of object is returned instead that doesn't have these fields, you will need to add code in the convertRFCMessage method in
your service implementation to convert these message objects to the RFCMessage type.

Message content can also be overridden and customized in the ApplicationResources.properties file.  Objects of class edu.mit.mortar.controller.action.SAPBaseAction attempt to first find and display messages configured in ApplicationResources.properties based on ID, NUMBER, MESSAGE_V1, MESSAGE_V2, MESSAGE_V3, and MESSAGE_V4.  If none are found then MESSAGE is used for display.  An example of message overrides in ApplicationResources.properties:

Image Removed

ZVP and 00 are examples of the ID.  032, 043, and 255 are examples of the NUMBER.  The variables are within the curlycue brackets (0, 1 ,2 3) and reference MESSAGE_V1 - MESSAGE_V4.In 99.9% of the cases this method is left alone: Image Added