Services are divided into two sets so pods do not have full access to the framework. This is for security, and also help with building pods, and implementing framework services. The main idea is that services for pods are intended to be easy to use. while services for the framework are intended to be easy to implement. So the framework provides a bridge between these two sets of services.
The runtime environment is a collection of:
Environment components
These components are independent of a particular session.
- portal - used to access usernames from userids, and portal based role information. This is currently handled by the SessionDataService.
example implementations:- wise
- microportal
- local file based "portal"
- generic soap interface to portal (requires implementing other side of soap on the portal)
- launch mechanism - this is the how the runtime enivronment is started up, it does not need to know exactly how it was started but it each startup mechanism needs to provide information to the environment. The main thing it provides is service configuration: which implementations of services should be used, and configuration info for those service implementations. The service configuration code should be independent of the launch mechanism. But it is up to the launch mechanism to supply the state for this configuration. This launch mechanism will also need to handle at least handle the session lifecycle event terminate. And it will also need to provide the offering. This is currently partially handled by the combination of SessionFactory, SessionConfiguration, SessionContext.
example implementations:- jnlp
- command line, basic eclipse launcher
- preview from authoring enivonrment
- preview from userdata monitor
- userdata - a service that takes offering id, userid, and rims ids and can provide agents and socks. This handled by the AgentService right now.
example implementations:- direct jdbc
- soap
- emf
- xml files
Session components
These components are specific to a session, and most likely to one implementation of an environment component above.
- portalsession - who is currently logged into the portal
this needs to be provided by the portal component above. It - launch settings - a offering id (uri, url, ...)
Use cases connecting services
Messaging
There is currently messaging component that sends out messages as session events happen. This is currently hooked into both the Sail Framework and the Pas LR. Instead this could be handled as an environment configuration. This messaging "plugin" can be added to the runtime environment, and when it is initialized, it requests the session component/service. It then adds itself as a listener to the session and sends out its messages. Inorder to do this correctly the message plugin might need more than just the session service.
Example configs
Environment config, could be embedded in a jar file in a jnlp launch enivronment, because it doesn't need to change for each session. This format is for the case where the bundles are responsible for registering their own services. This model should be close to how osgi works, but it doesn't include the classloading and security aspects. One reason for this, is that isn't clear how osgi would work with jnlp, and at least right now those aspects don't seem crucial.
<bundle type="net.sf.sail.jnlp.Launcher">
<!-- some config here perhaps a resource path to find the curnit, this would assume the curnit was in a jnlp jar and it was
in the same place for each deployment with this config file -->
</bundle>
<bundle type="net.sf.sail.DefaultSessionManager"/>
<bundle type="org.telscenter.pas.wise.Portal">
<!-- some config info here, perhaps url of wise server -->
</bundle>
<bundle type="org.telscenter.pas.db.JdbcPersistence">
<!-- some config here -->
</bundle>
<bundle type="org.telscenter.pas.service.MantarayMessagingService" />
<bundle type="org.telscenter.pas.messaging.SessionMessager" />
<bundle type="org.telscenter.pas.SessionLoadMonitor"/>
In this case the bundles could have a common interface that provided methods: registerServices(context), initialize(context)
An example launch sequence would be:
- jnlp.Launcher main method gets the url from this file perhaps based on a system property
- it calls the framework to launch method with this url
- the file is unmarshalled by xml decoder
- a first pass is made through all the bundles calling registerServices
- a second pass is made through all the bundles call initialize
- the SessionLoadMonitor adds a listener to the SessionManager service on initialize
- the SessionMessager adds registers a listener with the SessionManager, so that the SessionManager can add it to the Session when it is created
- the framework gets the SessionManager service and calls start on it. The SessionManager then:
- notifies all its listeners that is going to start
- the SessionLoadMonitor opens a progress dialog
- creates the SessionContext which will be available to the pods
- gets the portal service and adds it or some delegating class to the SessionContext
- gets the offering from the LaunchServices
- adds this offering to the SessionContext
- gets the current users from the PortalService
- request the curnit from the offering and assembles it
- gets the root pod from the curnit and adds it to the SessionContext
- nofifies listeners session is created
- SessionLaunchMonitor updates
- calls session.initiate
- session registers service provides with SessionContext
- notifies listeners session is initialized
- adds all registered listeners to the SessionContext
- calls session.start
...
- notifies all its listeners that is going to start
This is a different style that has more of a declaritive service and monitor binding. Perhaps we'll want to go this way, it is a little closer to eclipses extension point and extension design.
<service class="net.sf.sail.core.services.LauncerService">
<instance type="net.sf.sail.jnlp.Launcher">
<!-- some config here perhaps a resource path to find the curnit, this would assume the curnit was in a jnlp jar and it was
in the same place for each deployment with this config file -->
</instance>
</service>
<service class="net.sf.sail.core.services.SessionManager">
<instance type="net.sf.sail.DefaultSessionManager"/>
</service>
<service class="net.sf.sail.core.services.Portal">
<instance type="org.telscenter.pas.wise.Portal">
<!-- some config info here, perhaps url of wise server -->
</instance>
</service>
<service class="net.sf.sail.core.services.UserData">
<instance type="org.telscenter.pas.db.JdbcPersistence">
<!-- some config here -->
</instance>
</service>
<service class="org.telscenter.pas.service.IMessagingService">
<instance type="org.telscenter.pas.service.MantarayMessagingService" />
</service>
<monitor serviceClass="net.sf.sail.core.services.SessionManager"
listenerInterface="net.sf.sail.core.services.SessionLifeCycleListener">
<instance type="org.telscenter.pas.messaging.SessionMessager" />
</monitor>
<monitor serviceClass="net.sf.sail.core.services.SessionManager"
listenerInterface="net.sf.sail.core.services.SessionLoadListener">
<instance type="org.telscenter.pas.SessionLoadMonitor"/>
</monitor>
An example launch sequence would be:
- jnlp.Launcher main method gets the url from this file perhaps based on a system property
- it calls the framework to launch method with this url
- the framework creates a BeanContext and addes the ServiceMonitor service
- the file is unmarshalled by xml decoder
- during the unmarshalling process, or perhaps in a second step each service in the file registers itself with a context.
- at least the init method on each plugin is called so it can register listeners on the services it needs.
- the framework gets the SessionManager service and calls start on it. The SessionManager then:
- gets all monitors that are registered for it and the SessionLoadListener interface and addes them as listeners
- notifies all its listeners that is going to start
- the SessionLaunchMonitor opens a progress dialog
- creates the SessionContext which will be available to the pods
- gets the portal service and adds it or some delegating class to the SessionContext
- gets the offering from the LaunchServices
- adds this offering to the SessionContext
- gets the current users from the PortalService
- request the curnit from the offering and assembles it
- gets the root pod from the curnit and adds it to the SessionContext
- nofifies listeners session is created
- SessionLaunchMonitor updates
- calls session.initiate
- session registers service provides with context
- notifies listeners session is initialized
- gets all monitors that are registered for it and the SessionLifeCycleListener interface and addes them as listeners
to the session. - calls session.start
...
Service view
Pod Services
- RimService
- SessionService
Framework Services
- SessionLifecycleService - (parts of SessionContext)
the framework calls this service to init, start and terminate a session - LaunchEnvironmentService - (SessionConfiguration)
provides the
this provides the framework with information about the context in which it was started
the set of logged in users, a way to access the offering to run (perhaps this is just),
Abstract View of implementors and consumers
There will be several types of implementors and consumers of these services. If the types are distinct then it is best if the interfaces used by these types are distinct as well. So who are these actors in this environment?
Portal Connection - implementation and consumer
In the environment where sail is launched from a portal. The portal provides:
- a list of logged in users
...