You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@commons.apache.org by Luke Blanshard <lu...@blanshard.us> on 2004/04/02 18:05:54 UTC

[HiveMind] Separating service declarations from their implementations

Hi all,

  I have what I assume to be a common desire: to define a service in one
module, and plug in one of several possible implementations in a
different module.  Furthermore, I want to select the correct
implementation at run time based on system properties or other
externally specified configuration data.

  For example, I have a service that returns a list of customers.  This
service has 2 different implementations: an EJB-based one, and a local
demo/debug version that reads from a file.  I want to declare the
service in one module, and the implementations in another module.  And I
want to select the implementation (one of these two, or even a third one
written later provided by yet a third module) at run time.

  Here's how I've approached this.  I've created a service factory that
just returns a different service -- I call it ServiceReferenceFactory. 
So I declare my customer list service as being created by this factory,
and I pass in a variable reference as the name of the service to return.
 The hivemodule looks something like this:

<service-point id="Customers" interface="pkg.CustomersService">
  <invoke-factory service-id="example.ServiceReferenceFactory">
    <service-id="${customers-implementation}" />
  </invoke-factory>
</service-point>

  Then in the implementation module I provide a default definition for
"customers-implementation" that has the id of one of the
implementations.  And I arrange symbol sources so that I can override
this default at runtime.


  My question: Isn't this kind of overkill?  Since we already have the
ability to separate service-point declarations from their
implementations, wouldn't it be reasonable to build this kind of
indirection right in to HiveMind's core?  Or am I missing something, and
we can already do what I want without this somewhat bogus service factory?

Luke

---------------------------------------------------------------------
To unsubscribe, e-mail: commons-dev-unsubscribe@jakarta.apache.org
For additional commands, e-mail: commons-dev-help@jakarta.apache.org


Re: [HiveMind] Separating service declarations from their implementations

Posted by Christian Essl <ch...@yahoo.de>.
What I use is a custom RegistryBuilder, which loads modules based on a 
magic a configuration-point. It wraps a RegistryBuilder and pre-parses the 
ModuleDescriptors loaded from the default location 
(META-INF/hivemodule.xml) - Howard designed Hivemind realy cool modular 
:-).

The configuration has the following schema:
<contribution id="buildmagic.includemodule">
   <include path="pathInClassPath" (optional) setup-id=".."/>
   or
   <include-default module-id="...." path=""/>
</contribution>

The custom RegistryBuilder gets when constructed an setup-id matcher. 
Module-Descritpors defined in <include> are added to the wrapped 
RegistryBuilder if they have no setup-id or the setup-id matches. Modules 
defined in <include-default> are only added if no module with the given id 
has been added through the default location or through <include>. The 
<include-default> is for module designers to provide default services 
contributions.

This aproache has the major disadvantage that I have to maintain an extra 
module-xml for each different config/module pair - so I'd very apriciate 
Howards proposal. On the other side the aproache makes it possible to 
split modules in a 'Hivemind way' - no extra xmls or so - and additional 
to make the setup very flexible - not only service implementations but 
also contributions etc for different setups. It's more flexible and less 
resource intensive. By using a magic config point it also ahs the nice 
side affect that the way in which the different modules where loaded is 
directly reflected in the registry.




On Mon, 5 Apr 2004 16:32:08 -0400, Howard M. Lewis Ship 
<hl...@comcast.net> wrote:

> Seems like what we need is *one* extra layer of indirection.
>
> Currently, you can use the BuilderFactory to get a reference to a 
> particular service. That is,
> <set-service> means, "lookup service foo.Bar and assign it to this 
> property."
>
> I think, for these cases, we need to define a ServiceLookup interface 
> whose job is to provide the
> actual service to use.
>
> BuilderFactory could have a <set-indirect-service> element, perhaps, 
> that says: "go to service
> foo.Bar and ask it what service to plug into this property".
>
> It would then be simple to provide implementations of the ServiceLookup 
> interface that used whatever
> technique was appropriate to find the actual service.
>
> --
> Howard M. Lewis Ship
> Independent J2EE / Open-Source Java Consultant
> Creator, Tapestry: Java Web Components
> http://howardlewisship.com
>
>
>> -----Original Message-----
>> From: Achim Huegen [mailto:ahuegen@gmx-topmail.de]
>> Sent: Monday, April 05, 2004 3:56 PM
>> To: Jakarta Commons Developers List
>> Subject: Re: [HiveMind] Separating service declarations from
>> their implementations
>>
>>
>>
>> > You solution is pretty much what I've always envisioned.
>> >
>> > The problem isn't the indirection ... its the *selection*.
>> >
>> ...
>> > Putting any specific solution into the framework creates a
>> kind of lock
>> > that will be hard to break
>> > in the future. Providing a reasonably flexible solution in
>> the standard
>> > library or (the forthcoming)
>> > contributions library is a better approach ... the less in the core
>> > framework, the better. The
>> > HiveMind framework is supposed to be the bare minimum needed to
>> > construct more elaborate solutions
>> > ... the more that's in the framework itself, the more locked into a
>> > specific solution we become, and
>> > that's a trap to avoid!
>>
>> I regard switching of services as a very important feature
>> which shouldn't
>> be completely moved to the contributions library. I fear that without
>> direct
>> support in the core, it could be very expensive to setup in terms of
>> needed configurations, factories etc.
>> So I would suggest that the core libary at least
>> "acknowledges" that there
>> is the need to switch between different implementations, but
>> the selection
>> mechanism is left to the user.
>> For example we could allow the definition of multiple
>> implementations of
>> a service :
>>
>> 	<service-point id="Simple"
>> interface="hivemind.test.services.SimpleService">
>> 	</service-point>
>>
>> 	<implementation service-id="Simple" id="impl1" >
>> 	  <create-instance
>> class="hivemind.test.services.impl.SimpleServiceImpl1"/>
>> 	</implementation>
>>
>> 	<implementation service-id="Simple" id="impl2" >
>> 	  <create-instance
>> class="hivemind.test.services.impl.SimpleServiceImpl2"/>
>> 	</implementation>
>>
>> The first time this service is used, a special service broker
>> (you already
>> mentioned
>> this one in a previous mail) is used for selecting the right
>> implementation.
>> The default (core) implementation of the broker could just raise an
>> exception, or
>> select the first implementation found. This is the current
>> behaviour in
>> this case.
>> If there is a well defined interface for changing the
>> implementation of the
>> service broker itself, the user could choose from different selection
>> strategies
>> that are available in the contribution library. Properties,
>> configuration
>> or environment variable, choose whatever you want and
>> configure it at a
>> central location for all
>> of your services.
>>
>> This solution is not too specific but eases things a lot.
>>
>> Achim Huegen
>>
>>
>>
>>
>>
>>
>>
>>
>>
>> ---------------------------------------------------------------------
>> To unsubscribe, e-mail: commons-dev-unsubscribe@jakarta.apache.org
>> For additional commands, e-mail: commons-dev-help@jakarta.apache.org
>>
>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: commons-dev-unsubscribe@jakarta.apache.org
> For additional commands, e-mail: commons-dev-help@jakarta.apache.org



-- 
Christian Essl 

---------------------------------------------------------------------
To unsubscribe, e-mail: commons-dev-unsubscribe@jakarta.apache.org
For additional commands, e-mail: commons-dev-help@jakarta.apache.org


RE: [HiveMind] Separating service declarations from their implementations

Posted by "Howard M. Lewis Ship" <hl...@comcast.net>.
Seems like what we need is *one* extra layer of indirection.

Currently, you can use the BuilderFactory to get a reference to a particular service. That is,
<set-service> means, "lookup service foo.Bar and assign it to this property."

I think, for these cases, we need to define a ServiceLookup interface whose job is to provide the
actual service to use.

BuilderFactory could have a <set-indirect-service> element, perhaps, that says: "go to service
foo.Bar and ask it what service to plug into this property".

It would then be simple to provide implementations of the ServiceLookup interface that used whatever
technique was appropriate to find the actual service.

--
Howard M. Lewis Ship
Independent J2EE / Open-Source Java Consultant
Creator, Tapestry: Java Web Components 
http://howardlewisship.com


> -----Original Message-----
> From: Achim Huegen [mailto:ahuegen@gmx-topmail.de] 
> Sent: Monday, April 05, 2004 3:56 PM
> To: Jakarta Commons Developers List
> Subject: Re: [HiveMind] Separating service declarations from 
> their implementations
> 
> 
> 
> > You solution is pretty much what I've always envisioned.
> >
> > The problem isn't the indirection ... its the *selection*.
> >
> ...
> > Putting any specific solution into the framework creates a 
> kind of lock 
> > that will be hard to break
> > in the future. Providing a reasonably flexible solution in 
> the standard 
> > library or (the forthcoming)
> > contributions library is a better approach ... the less in the core 
> > framework, the better. The
> > HiveMind framework is supposed to be the bare minimum needed to 
> > construct more elaborate solutions
> > ... the more that's in the framework itself, the more locked into a 
> > specific solution we become, and
> > that's a trap to avoid!
> 
> I regard switching of services as a very important feature 
> which shouldn't
> be completely moved to the contributions library. I fear that without 
> direct
> support in the core, it could be very expensive to setup in terms of
> needed configurations, factories etc.
> So I would suggest that the core libary at least 
> "acknowledges" that there
> is the need to switch between different implementations, but 
> the selection
> mechanism is left to the user.
> For example we could allow the definition of multiple 
> implementations of
> a service :
> 
> 	<service-point id="Simple" 
> interface="hivemind.test.services.SimpleService">
> 	</service-point>
> 
> 	<implementation service-id="Simple" id="impl1" >
> 	  <create-instance 
> class="hivemind.test.services.impl.SimpleServiceImpl1"/>
> 	</implementation>
> 
> 	<implementation service-id="Simple" id="impl2" >
> 	  <create-instance 
> class="hivemind.test.services.impl.SimpleServiceImpl2"/>
> 	</implementation>
> 
> The first time this service is used, a special service broker 
> (you already 
> mentioned
> this one in a previous mail) is used for selecting the right 
> implementation.
> The default (core) implementation of the broker could just raise an 
> exception, or
> select the first implementation found. This is the current 
> behaviour in 
> this case.
> If there is a well defined interface for changing the 
> implementation of the
> service broker itself, the user could choose from different selection 
> strategies
> that are available in the contribution library. Properties, 
> configuration 
> or environment variable, choose whatever you want and 
> configure it at a 
> central location for all
> of your services.
> 
> This solution is not too specific but eases things a lot.
> 
> Achim Huegen
> 
> 
> 
> 
> 
> 
> 
> 
> 
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: commons-dev-unsubscribe@jakarta.apache.org
> For additional commands, e-mail: commons-dev-help@jakarta.apache.org
> 


---------------------------------------------------------------------
To unsubscribe, e-mail: commons-dev-unsubscribe@jakarta.apache.org
For additional commands, e-mail: commons-dev-help@jakarta.apache.org


Re: [HiveMind] Separating service declarations from their implementations

Posted by Achim Huegen <ah...@gmx-topmail.de>.
> You solution is pretty much what I've always envisioned.
>
> The problem isn't the indirection ... its the *selection*.
>
...
> Putting any specific solution into the framework creates a kind of lock 
> that will be hard to break
> in the future. Providing a reasonably flexible solution in the standard 
> library or (the forthcoming)
> contributions library is a better approach ... the less in the core 
> framework, the better. The
> HiveMind framework is supposed to be the bare minimum needed to 
> construct more elaborate solutions
> ... the more that's in the framework itself, the more locked into a 
> specific solution we become, and
> that's a trap to avoid!

I regard switching of services as a very important feature which shouldn't
be completely moved to the contributions library. I fear that without 
direct
support in the core, it could be very expensive to setup in terms of
needed configurations, factories etc.
So I would suggest that the core libary at least "acknowledges" that there
is the need to switch between different implementations, but the selection
mechanism is left to the user.
For example we could allow the definition of multiple implementations of
a service :

	<service-point id="Simple" 
interface="hivemind.test.services.SimpleService">
	</service-point>

	<implementation service-id="Simple" id="impl1" >
	  <create-instance 
class="hivemind.test.services.impl.SimpleServiceImpl1"/>
	</implementation>

	<implementation service-id="Simple" id="impl2" >
	  <create-instance 
class="hivemind.test.services.impl.SimpleServiceImpl2"/>
	</implementation>

The first time this service is used, a special service broker (you already 
mentioned
this one in a previous mail) is used for selecting the right 
implementation.
The default (core) implementation of the broker could just raise an 
exception, or
select the first implementation found. This is the current behaviour in 
this case.
If there is a well defined interface for changing the implementation of the
service broker itself, the user could choose from different selection 
strategies
that are available in the contribution library. Properties, configuration 
or environment variable, choose whatever you want and configure it at a 
central location for all
of your services.

This solution is not too specific but eases things a lot.

Achim Huegen









---------------------------------------------------------------------
To unsubscribe, e-mail: commons-dev-unsubscribe@jakarta.apache.org
For additional commands, e-mail: commons-dev-help@jakarta.apache.org


RE: [HiveMind] Separating service declarations from their implementations

Posted by "Howard M. Lewis Ship" <hl...@comcast.net>.
You solution is pretty much what I've always envisioned.

The problem isn't the indirection ... its the *selection*. 

For example, perhaps you are creating a DAO system, and you have different implementations based on
database type (oracle vs. db2 vs. postgres vs. mysql). 

I can imagine something like:

<contribution configuration-id="foo.DAOImplementations">
  <dao database="mysql" service-id="foo.MySQLDAO"/>
  <dao database="db2" service-id="foo.DB2DAO"/>
  (etc)
</contribution>

<contribution configuration-id="hivemind.ApplicationDefaults">
  <default symbol="foo.active-database" value="db2"/>
</contribution>

And of course, if different parts of the system use different databases, it gets more complicated.

Putting any specific solution into the framework creates a kind of lock that will be hard to break
in the future. Providing a reasonably flexible solution in the standard library or (the forthcoming)
contributions library is a better approach ... the less in the core framework, the better. The
HiveMind framework is supposed to be the bare minimum needed to construct more elaborate solutions
... the more that's in the framework itself, the more locked into a specific solution we become, and
that's a trap to avoid!


--
Howard M. Lewis Ship
Independent J2EE / Open-Source Java Consultant
Creator, Tapestry: Java Web Components 
http://howardlewisship.com


> -----Original Message-----
> From: Luke Blanshard [mailto:luke@blanshard.us] 
> Sent: Friday, April 02, 2004 11:06 AM
> To: commons-dev@jakarta.apache.org
> Subject: [HiveMind] Separating service declarations from 
> their implementations
> 
> 
> Hi all,
> 
>   I have what I assume to be a common desire: to define a 
> service in one
> module, and plug in one of several possible implementations in a
> different module.  Furthermore, I want to select the correct
> implementation at run time based on system properties or other
> externally specified configuration data.
> 
>   For example, I have a service that returns a list of 
> customers.  This
> service has 2 different implementations: an EJB-based one, and a local
> demo/debug version that reads from a file.  I want to declare the
> service in one module, and the implementations in another 
> module.  And I
> want to select the implementation (one of these two, or even 
> a third one
> written later provided by yet a third module) at run time.
> 
>   Here's how I've approached this.  I've created a service 
> factory that
> just returns a different service -- I call it 
> ServiceReferenceFactory. 
> So I declare my customer list service as being created by 
> this factory,
> and I pass in a variable reference as the name of the service 
> to return.
>  The hivemodule looks something like this:
> 
> <service-point id="Customers" interface="pkg.CustomersService">
>   <invoke-factory service-id="example.ServiceReferenceFactory">
>     <service-id="${customers-implementation}" />
>   </invoke-factory>
> </service-point>
> 
>   Then in the implementation module I provide a default definition for
> "customers-implementation" that has the id of one of the
> implementations.  And I arrange symbol sources so that I can override
> this default at runtime.
> 
> 
>   My question: Isn't this kind of overkill?  Since we already have the
> ability to separate service-point declarations from their
> implementations, wouldn't it be reasonable to build this kind of
> indirection right in to HiveMind's core?  Or am I missing 
> something, and
> we can already do what I want without this somewhat bogus 
> service factory?
> 
> Luke
> 
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: commons-dev-unsubscribe@jakarta.apache.org
> For additional commands, e-mail: commons-dev-help@jakarta.apache.org
> 


---------------------------------------------------------------------
To unsubscribe, e-mail: commons-dev-unsubscribe@jakarta.apache.org
For additional commands, e-mail: commons-dev-help@jakarta.apache.org