Single Entry Point to EJB Layer pattern
This pattern forces the client to use a single entry point to perform the calls to EJBs.
Motivation:
Precisely manage the user access to an application with a dynamic verification of security and session state with full transparency for client’s developers.
This architecture was first designed to be used with a heavy client in Swing. It can easily be modified for a web based client.
Solution :
The main components of this architecture are :
User:
This entity represents a user of the application. It holds authorisation informations as well as session state.
SessionManagementService :
This stateless service is a factory of user sessions. Security can be plugged in to verify the authorization to a particular user to obtain a Session.
UserSession :
This stateful bean is the real facade of the application. Each client call is passed through its two main methods :
public Object invoke(EJBDefinition p_service, String p_methodName, Class[] p_paramTypes, Object[] p_args)
public Object invoke(ServiceKey p_serviceKey, String p_methodName,Class[] p_paramTypes ,Object[] p_args)
This facade can check the connection state of the user (an administrator can dynamically lock a user) and the user's authorization to perform this call using the User EJB.
This component holds a cache on the services ( stateful or stateless).
The first method is used for the call on SLSB services, the second for SFSB services.
Services :
The services are implemented as stateful or stateless EJB. SLSB services have a ejbCreate method without any argument. SFSB services are created through a call on a SLSB service.
All the SLSB are defined in an interface of constants.
public interface Services {
final static EJBDefinition MESSAGING_SERVICE =
newEJBDefinition("ejb/framework/MessagingService",
"org.z.framework.jms.MessagingServiceHome",
"org.z.framework.jms.MessagingService");
….
UserSessionClient :
This singleton is instantiated only on the client side.
It first asks the SessionManagementService to create a new UserSession and then maintains a reference on this Session to transmit all the client calls.
ClientServiceFactory :
When an object on the client side needs a service to perform a task it asks it to this factory through the call :
messageService = (MessaggingService)ClientServiceFactory.getService(Services.MESSAGGING_SERVICE);
The return of this call is the remote interface of the SLSB service. In fact the object is a dynamic proxy ( see java.lang.reflect.Proxy ) with a ServiceClient as InvocationHandler.
ServiceClient :
This class implements the java.lang.reflect.InvocationHandler and is beside all the remote interface of EJB on the client side.
Every time the client makes a call on an remote interface an instance of this class extracts the method called and the arguments and transmits it to the UserSessionClient.
Normal sequence :
1. A client JVM which needs remote services initiate the session with its UserSessionClient :
UserSessionClient.getInstance().init( userLogin, userPassword);
The SessionManagementService after security checking creates a new UserSession. The remote reference on it is kept in the UserSessionClient.
2. The client needs a service to perform a task. It asks it to the ServiceFactory.
messageService = (MessaggingService)ClientServiceFactory.getService(
Services.MESSAGGING_SERVICE);
A new dynamic proxy is created using the EJBDefinition. The InvocationHandler of this dynamic proxy is a new instance of ServiceClient.
3. The client makes a call on his remote interface.
MessageService.sendMessage("toto");
The ServiceClient transmits all the parameters (the EJBDefinition, the method name, the arguments ) of this call to the UserSessionClient.
The UserSessionClient transmits everything to the UserSession.
The UserSession which does not have any reference on the service performs a lookup to retrieve a reference on the Home of the service and call "create" on it.
Then using reflection it invokes the method.
Consequences :
·The client code to access remote service is extremely simple,
·Any kind of control can be plugged on the client calls.
2 replies in this thread
EJB Session Facade patternPosted By: Gal Binyamini on October 13, 2001 in response to this message.
First of all, I think this pattern is not a "session facade" pattern. This pattern suggests a way for inserting method interceptors in method calls. It does not give a user a simplified view of a collection of complex subsystems. The user still talks to each "service" seperately, and the fact that all these calls happen to go through some single session bean behind the scenes is irrelevant to the client. I do not mean to say that the client should talk to the UserSession itself, of course. The UserSession has a very weakly typed interface (maybe weaker than C typing) and it isn't a facade either.
As for the motivation, I don't think security should be a key reason for using this pattern. EJB has a security model and while it isn't perfect, I think it's beneficial to atleast conform with it. You can then add any additional required functionality through proprietary interfaces. Virtually all App servers have such (atleast, to my knowledge). The security model outlined here does not support propagation of user identities. EJB supports such propagations atleast internally within the server, and will hopefully support inter-server propagation as well (although this field requires more work).
As for verification of session state - I do not understand how that relates to this pattern. IMO state verification should occur in the specific components responsible for the state - not in some global interceptor. Some examples of such use could clear thing out for me :)
I can't think of any particularly important use of interception that would require this massive pattern. It seems to me that, if interception is required, it will be much easier to add directly by calling the interceptor in the facade methods. While this isn't as theoretically interesting as doing dynamic interception, I believe it will get the same job done with much less code and will execute faster as well.
I also think that this pattern imposes several arbitrary limitations on implementations (effectively eliminating use of home objects, requiring JVMs of versions 1.3 or higher on client side, ...) that will make any application using it virtually incompliant with the rest of the EJB world. EJB meta classes will not return any meaningful results, new EJB2.0 home methods will not be supported, and god knows what in EJB2.1.
As a final note, EJB2.0 lists method interceptors as a planned feature for future releases. I doubt we'll see it in EJB2.1 though, but maybe in 3.0...
Regards
Gal
1 replies in this thread
Single Entry Point to EJB LayerPosted By: Floyd Marinescu on October 14, 2001 in response to this message.
I agree that this pattern is misnames, Gaetan, I changed it to "Single Entry Point to EJB Layer" (let me know if you think a different name is appropriate). Please read the Session Facade pattern from EJB Design Patterns book project (http://www.theserverside.com/resources/patterns_review.jsp) for a concise explanation of the session facade pattern.
Floyd
0 replies in this thread
Single Entry point to EJB LayerPosted By: gaetan zoritchak on October 15, 2001 in response to this message.
The single entry point to EJB layer is indeed more appropriate.
I don't agree with you on using code based on the proprietary interfaces of the security App Server your work on. I prefer limit the proprietary code to the minimum I can.
>The security model outlined here does not support propagation of user identities.
No. We set the user identity ( proprietary App Server code ;-) ) with the first call to the UserSessionClient. The user identity is then normally delegated and we can call the EJBContext.getCallerPrincipal() at anytime to obtain the caller principal name.
>IMO state verification should occur in the specific components responsible for the state - not in some global interceptor.
The session state is not held by the UserSession. Only the verification of this state is called in a generic way by this "global interceptor". It allows a administator to lock a specific session or all the sessions for a maintenance work. But I agree this functionnality may not interest a lot of people. The main purpose for us of this pattern is the security checking based on dynamic settings.
>I also think that this pattern imposes several arbitrary limitations on implementations (effectively eliminating use of home objects, requiring JVMs of versions 1.3 or higher on client side, ...) that will make any application using it virtually incompliant with the rest of the EJB world. EJB meta classes will not return any meaningful results, new EJB2.0 home methods will not be supported, and god knows what in EJB2.1.
We strictly divide our server code in layers : session, service and business. Our client should never call directly an entity and therefore doesn't need home methods. JDK 1.3 is not so recent and I don't feel it like a limitation.
Regards,
Gaetan