Hi Marcel,

2011/10/4 Marcel Offermans <[email protected]>:
> Hello Bram,
> On Oct 4, 2011, at 9:06 PM, Bram de Kruijff wrote:
>
> On Tue, Oct 4, 2011 at 2:40 PM, Marcel Offermans
> <[email protected]> wrote:
>
> Summarizing, I hope we can agree that:
>
> a) ultimately, a multi-container model is what we aim for
>
> yup
>
> b) for now, we need to carefully plan a migration strategy
>
> I have no clue how to do this (make it optional) in a non
> multi-container model. Do you have an idea?
>
> Yes. Let's start with the assumption that our service implementations are
> POJOs, that implement some service interface (I left out the import
> statements on purpose):
> package api;
> public interface MyService {
> }
> package impl;
> public class MyServiceImpl implements MyService {
> }
> The OSGi "glue" we need to make this work is:
> package impl.osgi;
> public class Activator extends DependencyActivatorBase {
> public void init(BundleContext context, DependencyManager manager) throws
> Exception {
> manager.add(createComponent()
> .setInterface(MyService.class.getName(), null)
> .setImplementation(MyServiceImpl.class)
> );
> }
> public void destroy(BundleContext context, DependencyManager manager) throws
> Exception {
> }
> }
> Now in general, our tenant aware version of this service uses a different
> activator (because it's based on an adapter) and the POJO is slightly
> extended with a bit of extra code (we could even argue here that this code
> does not belong in the POJO at all, but I'll leave that for now). So we get
> an implementation that looks like this:
> package impl.tenant;
> public class MyServiceTenantImpl extends MyServiceImpl {
> volatile Tenant m_tenant;
>
> public void init(Component component) {
>
> // setup tenant specific dependencies and code here
> }
> }
> The code in the init method usually adds dependencies to the component, and
> bases them on the injected Tenant. Finally, our activator looks like this:
> package impl.tenant.osgi;
> public class Activator extends DependencyActivatorBase {
> public void init(BundleContext context, DependencyManager manager) throws
> Exception {
> manager.add(createAdapterService(Tenant.class, null)
> .setInterface(MyService.class.getName(), null)
> .setImplementation(MyServiceTenantImpl.class)
> );
> }
> public void destroy(BundleContext context, DependencyManager manager) throws
> Exception {
> }
> }
> So now we have all the code we need to create both alternatives, and we
> could package this as two separate bundles. One is completely unaware of
> tenants, and can therefore be used in any OSGi container. The other uses our
> current tenant model and is very similar to what we have now. My gut feeling
> is that 95% of the work will go into MyServiceImpl where maybe the only
> location where we might have a bit of duplication is in the definition of
> the dependencies (which for the tenant aware service will be in the init and
> for the tenant unaware one be in the Activator).

The notion of seperating osgi/dm plumbing from the pojo is something
I'd really like! Using inheritance and being forced to manage seperate
artifacts not so much. Two thoughts:

1) The DM adaptor is part of the problem as it has a fixed strategy. I
could do the work myself with a custom factory component that can have
multiple strategies based on <any condition> like configuration,
system property or whatever. Eg.

{code}
  class MyServiceFactoryImpl implements MyServiceFactory {
        void init(Component component){
                if(m_strategy == Strategy.ADAPTOR)
                        // start tracking services
        }
        void start(Component component){
                if(m_strategy == Strategy.SINGLETON)
                        // create/configure new MyService singleton
        }
        void stop(Component component){
                // remove MyService instances                   
        }
        void serviceAdded(ServiceReference ref){
                // create/configure new MyService instance
        }
        void serviceRemoved(ServiceReference ref){
                // removed new MyService instance
        }
  }
{code}

Now I have one implementation that can do both. Not sure if we could
internalize this in DM? With some fancy generics and a base factory
the default case would be simple.

2) Using the DM is still invasive in that I still have an
init(component c) in my POJO service for all but the simplest cases.
Again I think the factory could help in it where allowed to handle the
DM callbacks/lifecycle. This is kind of similar to what I requested
for configuration at https://issues.apache.org/jira/browse/FELIX-2706.
It kind of like DS I guess.


Obviously, you will still have the <adapted class> compile dependency
even if you don't use the adapter strategy...

No answers, just thoughts :)

grz
Bram


> On the bright side any code now using the mt adaptor pattern should
> work transparently in a multi-container as long as we make sure the
> correct (and only) Tenant service is published.
>
> That is true, so for the short term that is definitely the quickest way to
> get going. The solution above could be our "next step".
> Greetings, Marcel
>
> _______________________________________________
> Amdatu-developers mailing list
> [email protected]
> http://lists.amdatu.org/mailman/listinfo/amdatu-developers
>
>
_______________________________________________
Amdatu-developers mailing list
[email protected]
http://lists.amdatu.org/mailman/listinfo/amdatu-developers

Reply via email to