Discussions

J2EE patterns: Single Entry Point to EJB Layer

  1. Single Entry Point to EJB Layer (6 messages)

    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.

    Threaded Messages (6)

  2. EJB Session Facade pattern[ Go to top ]

    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
  3. Single Entry point to EJB Layer[ Go to top ]

    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
  4. Single Entry point to EJB Layer[ Go to top ]

    Hi.
    "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."

    I understand what you mean, but my point is not that the pattern will directly keep you from doing something right now. The point is that it makes your code less compliant with the "EJB world". One day you may want to use an EJB testing tool, and each of these limitations could make it impossible for you to do so. That's the kind of thing I ment.

    If, as you said, the main purpose of this pattern is to handle security checking based on dynamic settings, I would go with the App server's proprietary interfaces. I agree that you should try to keep your code portable. However, the real world isn't this black and white. If you use a "bridge" pattern for instance you can make the non-portable code go down in a single class, probably not more than a hundred lines. If the alternative is a big refactoring into a less standard model that affects each and every client request, I would go ahead and write this one class.
    Of course, you may be using this model of "services" in your entire application regardless to this pattern. That sort of thing would make a seperate pattern, with seperate goals and probably a seperate context. This specific pattern doesn't justify this non-standard model, IMHO.

    I do think that this pattern is "theoretically" interesting and demonstrates the power of Java well. I just don't think it is appropriate in this particular context.

    Regards
    Gal
  5. Single Entry point to EJB Layer[ Go to top ]

    Hello,

    I like this pattern and I implemented it on a project I have been working last year. It is really nice, although can be quite complex to maintain,

    I would prefer, if I had to do it again, to post-process all my EJBs and overload the method setEntityContext or setSessionContext. (This can be achieve using an ANT task for example)

    Using the context, I would be able to use getCallerIdentity() and getCallerPrincipal() and invoke a method through a Session Bean or whatever in order to check the Security for the user.

    Therefore, the database that you would use could contain complex business rules and so on and is not tied to the business code.

    Best regards,

    Thierry Janaudy

    Jyperion
  6. 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
  7. Single Entry Point to EJB Layer[ Go to top ]

    Of course, if you were using JBoss you could write your own interceptor...