Archived

This forum has been archived. Please start a new discussion on GitHub.

Better way to use implicit context? / Sesson concept in Glacier2?

Hello,

in our ICE based system sessions are essential. I.e. a user first logs in and thus creates a session object at the server side. The client then holds a reference (proxy) to this session object. Subsequent remote calls must be executed in the context of the appropriate session. Hence the server must allocate incoming calls to previously created sessions.

Up to now we have to rely on Ice's context mechanism, using an implicit context (to make sure that the context is available in any remote call, even within locators and when using stringToProxy()). However, this implicit context is nasty as we must create it at every proxy we receive / create on the client side with code like this:
Ice::ObjectPrx obj = ic->stringToProxy(szConnString);
setSessionContext(obj,mySessionDescPtr);
CMyObjectPrx archiveFactPrx = CMyObjectPrx::checkedCast(obj);

That's really nasty code. Unfortunately there seems to be no way to generalize this into a function, except for the function setSessionContext():
void setSessionContext(::Ice::ObjectPrx& obj, const CMySessionDescPtr& sessionDescPtr)
{
::Ice::Context context = obj->ice_getContext();
context["SESSION_ID"] = sessionDescPtr->szId;
obj = obj->ice_newContext(context);
}

We really hate to type the three code lines shown above for any and every proxy we create. Hence first question: can ZeroC please please simplify the implicit context mechanism?

Second question: it would be even better if we could use a session mechanism provided by the Ice runtime, so that we do not need to worry at all about setting an implicit context. We are aware that Glacier2 and IcePack use a session mechanism, but neither from the documentation nor from the source code can we understand how it works and how we can retrieve the appropriate session for an incoming call on the server side. Can you shed some light on this? I.e.: is it possible to use the Ice session mechanisms for one's own session handling? If yes, how?

Yet another question in this context: also a role concept would be of great benefit. Does Ice provide anything here or are there any plans?

Thanks!

Robert.

Comments

  • Re: Better way to use implicit context? / Sesson concept in Glacier2?
    Originally posted by robert
    [...]
    We really hate to type the three code lines shown above for any and every proxy we create. Hence first question: can ZeroC please please simplify the implicit context mechanism?

    What kind of mechanism would you exactly like to have? Perhaps a per-communicator default context?
    Originally posted by robert
    Second question: it would be even better if we could use a session mechanism provided by the Ice runtime, so that we do not need to worry at all about setting an implicit context. We are aware that Glacier2 and IcePack use a session mechanism, but neither from the documentation nor from the source code can we understand how it works and how we can retrieve the appropriate session for an incoming call on the server side. Can you shed some light on this? I.e.: is it possible to use the Ice session mechanisms for one's own session handling? If yes, how?

    With Glacier, you can provide your own session manager. When a new client connects, a session is created for the given ID, and SessionManager::create(id) is called. In this function you can create objects that are specific to the client with the given ID. When the session is destroyed (either because the client destroys it explicitly, or because it times out), then Session::destroy() is called for the session object that was created by SessionManager::create(id). At this point, you can clean up all the objects for the client.

    What kind of objects you create heavily depends on your application's needs. One example is to create a facade object for each client, and to give this facade object the client's ID as Ice object identity. You can then configure Glacier so that it only allows calls from the client with the given ID to this facade object. This gives you security (because you can be sure that only the authorized client can call the facade), and it provides implicit client identity.

    Other approaches include passing the client identity in the context. There is no single solution that is appropriate for all applications.
    Originally posted by robert
    Yet another question in this context: also a role concept would be of great benefit. Does Ice provide anything here or are there any plans?

    Do you mean that different clients have different access rights? This can be done in many ways. One of them is to use the facade approach outlined above. For different client IDs, you would create different facades, depending on what roles the clients have. Or you could use the same facade type, but add a role parameter. Another approach is to use different Glacier instances, which provide different levels of access to the backend server.

    It is difficult to give advice without knowing your application in detail. Note that we can provide you with consulting services to discuss the needs of your specific application and to propose potential solutions. If you are interested, please contact us at info@zeroc.com.
  • Re: Re: Better way to use implicit context? / Sesson concept in Glacier2?
    Originally posted by marc
    What kind of mechanism would you exactly like to have? Perhaps a per-communicator default context?

    A per-communicator default context would really be cool! To make us happy it would however be enough if the assignment of a new implicit context to a proxy could be done with one line of code. For example if the proxy would receive a new context or just a new context entry without giving back a new proxy but rather by modifying the existing proxy.
    Originally posted by marc
    With Glacier, you can provide your own session manager. When a new client connects, a session is created for the given ID, and SessionManager::create(id) is called. In this function you can create objects that are specific to the client with the given ID. When the session is destroyed (either because the client destroys it explicitly, or because it times out), then Session::destroy() is called for the session object that was created by SessionManager::create(id). At this point, you can clean up all the objects for the client.

    This means that Ice binds the proxy to the TCP connection with the client, right? Sure enough convenient for the client as it doesn't need to pass any Session ID. On the other hand this means that the Session is bound to one server process, right? Do you see any chance to find out about the current Glacier2 - session in our own servants?
    Originally posted by marc
    What kind of objects you create heavily depends on your application's needs. One example is to create a facade object for each client, and to give this facade object the client's ID as Ice object identity. You can then configure Glacier so that it only allows calls from the client with the given ID to this facade object. This gives you security (because you can be sure that only the authorized client can call the facade), and it provides implicit client identity.

    Hope my question is not naive: what is the "client's ID"?
    Originally posted by marc
    Do you mean that different clients have different access rights? This can be done in many ways. One of them is to use the facade approach outlined above. For different client IDs, you would create different facades, depending on what roles the clients have. Or you could use the same facade type, but add a role parameter. Another approach is to use different Glacier instances, which provide different levels of access to the backend server.

    It is difficult to give advice without knowing your application in detail. Note that we can provide you with consulting services to discuss the needs of your specific application and to propose potential solutions. If you are interested, please contact us at info@zeroc.com.

    Thanks, we will consider your offer of specific consulting. I will have to check with my project partners about the role concept.
  • Re: Re: Re: Better way to use implicit context? / Sesson concept in Glacier2?
    Originally posted by robert
    A per-communicator default context would really be cool! To make us happy it would however be enough if the assignment of a new implicit context to a proxy could be done with one line of code. For example if the proxy would receive a new context or just a new context entry without giving back a new proxy but rather by modifying the existing proxy.

    I guess we can add a per-communicator default context. This seems like a nice and clean solution. Consider it added to our todo list :)
    Originally posted by robert
    This means that Ice binds the proxy to the TCP connection with the client, right? Sure enough convenient for the client as it doesn't need to pass any Session ID. On the other hand this means that the Session is bound to one server process, right? Do you see any chance to find out about the current Glacier2 - session in our own servants?

    Yes, with Glacier2, sessions are bound to connections (SSL or plain TCP) from clients. (With Glacier1, sessions are bound to connections with a temporary SSL certificate - more flexible, but also a more complicated and heavy-weight.)

    A session is definitely not bound to a single server process. Your server can consist of many different processes, implementing a multitude of Ice objects. Glacier2's job is to control the access to these Ice objects, and to notify your server processes when a client connects or disconnects.

    As for how to pass client identity to your various servants, there are many different strategies, including the ones I outlined in my previous posts.
    Originally posted by robert
    Hope my question is not naive: what is the "client's ID"?

    Client IDs can be anything you want them to be. For example, the most common client ID is a user-id, like one that you use if you log into a Web page or into a Unix account. Glacier2 can also check passwords for you. All you have to do is to configure your own PermissionVerifier object with Glacier2.
  • Re: Re: Re: Re: Better way to use implicit context? / Sesson concept in Glacier2?
    Originally posted by marc
    I guess we can add a per-communicator default context. This seems like a nice and clean solution. Consider it added to our todo list :)

    Maybe, together with this solution, adding something like a ContextProvider
    could be very powerful.
    Well, in multi-threaded client (e.g., servlet container) a default context
    could be useless.

    It could be

    interface ContextProvider {
    void setContext(Object *pxy, Context ctx);
    boolean useDefaultContext(Object *pxy);
    }

    I think that some assumption on threading should be made too.

    (OK, I know, it looks like CORBA client interceptor)

    Guido.
  • I've added per-communicator default contexts to the code, so this will be available with Ice 2.1.

    Cheers,

    Michi.