You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@felix.apache.org by Mark Richards <ma...@gmail.com> on 2013/06/12 17:56:44 UTC

Object versions in services

Hi,

I'm new to this list and hopefully this question isn't too long... please
let me know if you'd like further details.

Context: I'd like to create a service architecture that represents EIPs, a
bit like Camel but more OSGi friendly, however the safe wiring of objects
must ensure the producers are wired to consumers that provide and consumer
compatible versions of the objects.

Problem: How do you handle the versions dependencies of objects used a
layer beneath the services provided?

I believe this issue also affects the listener model, if you wanted to use
a generic listener model like so I'm hoping somebody has already solved it:

interface Listener<T> { //Listener class is handled by bundle resolution
    void Notify(T event); //but what about this T?
}


When you create an implementation you usually know T, so it's quite easy to
call "bundleContext.register(Listener.class, this, props)" where props
includes {"listenerOf":"t.class}" and to then filter the class. However,
I'm not sure where to get the version for T from (it may be an imported
class) and versions are ranges with different rules for import and export.

Any help advice or also, an idea of whether I'm the only one trying to do
this would be useful.

Thanks,
Mark


Ps: if it helps here is an example of the style of problem in semi-pseudo
code.
If you cannot filter the version of the Model through the services layer
ModelProvider will provide a Date object and ModelConsumer will try to read
a Long. The two shouldn't be allowed to bind to each other.


bundle A: wiring-api
    interface Provider<T> {
        T giveMeAnObject();
    }
    interface Consumer<T> {
        void hereIsAnObject(T object);
    }

bundle B: model version 1:
    class Model {
        long getDate();{ return (long) 99 }
    }

bundle C: model version 2:
    class Model {
        Date getDate() { return new Date(); }
    }

bundle D: model-provder version 2: import-packages wiring-api 1 and model 2
    class ModelProvider implements Provider <Model>  implements
BundleActivator { {
        void start(BundleContext context) {
            context.register(Provider.class, this, ???? )* // here you'd
need to specify it is model 2, but how do you get this*
       }
        Model giveMeAnObject() {
            return new Model();
        }
    }
bundle E: consumer imports wiring-api and model 1:
    class ModelConsumer implements Consumer<Model>, BundleActivator {
        void start(BundleContext context) {
            context.register(Consumer.class, this, ???? )* // here you'd
need to specify it is model 1, but how do you get this**
*        }*
*

        void hereIsAnObject(Model object) {
            System.out.println(Long.valueOf(model.getDate())); // if no
object version filtering this will fail as bundle D should not be connected
to bundle E
        }
    }

// here I envisage there should be a Provider Manager perhaps along the
lines of that could be exposed to have wiring done through a UI, interface
or config settings like WireAdmin
// this isn't too important at this point, except it would need some way to
manage this *version filtering/matching*!
bundle F: provider-service imports wiring-api
    class ProviderManager {
        Map<ClassVersion, Provider> providers;
        Map<ClassVersion, Consumer, consumers
        void registerProvider(ClassVersion<T> provided, Provider<T>
provider);
        void registerConsumer(ClassVersion<T> consumed, Consumer<T>
provider);

       // methods to lookup and match providers with consumers
    }

Re: Object versions in services

Posted by "Richard S. Hall" <he...@ungoverned.org>.
On 6/14/13 06:43 , Mark Richards wrote:
>   The WireAdmin Producer class has a polled method that is similar that just
> returns an Object. I've used Generics as a good programming practice, but
> I'm aware it doesn't solve this problem.
> There seems to be a use case for this nature of functionality. I've no idea
> how frameworks like Camel are solving this problem in OSGi... do they just
> hope for the best and push Objects are around and assume Producers and
> Consumers are using the same versions?
>
> I understand that the framework wouldn't know what T is, so I'd quite like
> to tell the framework what T is.
> Ie:
> Properties props ...
> props.put("providerClassName",Model.class.getName());
> props.put("providerClassVersion",*
> context.getImportVersion(Model.class.getPackage().getName()*); //this
> doesn't exist
> context.register(Provider.class,this,props);
>
> However, there doesn't seem to be an easy way to do this,  unless I've
> missed something.

Yes and no.

At the module level, if you know that the service API will always be 
exposing the model API, then your service API bundle should import the 
model package and list it as a "uses" constraint on the export of the 
service package. This will then ensure that any consumers of the service 
package will also be compatible with the service's model package.

If you want to have many providers of the service with different model 
versions being exposed, then different providers will likely have to 
export the service package and export it where they import a the 
specific version of the model they want so their exported service 
package is bound to their desired model version via the "uses" constraint.

It is not possible at the module level to maintain consistency with a 
single shared service package where each provider exposes different 
versions of downcastable classes from the service API. If you really 
need this, then you have to do it yourself at the service level.

For example, in your service registration you could add properties to 
indicate the bundle ID from which the provider gets its model package, 
then consumers would have to use a service filter that also matched the 
bundle ID from which they get the model package. This would work, but 
not very elegant.

In short, this whole situation results because of a lie being told in 
your API. The API gives the illusion that the service is indendent of 
the downcastable type, which makes you believe that you should have a 
single class space for all service providers, but in reality you don't 
have a single class space. You have one class space for each service + 
model combination.

No client in Java (with or without OSGi) can expect to downcast reliably 
in the scenario you are creating.

-> richard

>
> Many Thanks
> Mark
>
>
> On 14 June 2013 04:36, Richard S. Hall <he...@ungoverned.org> wrote:
>
>> On 6/13/13 20:55 , Mark Richards wrote:
>>
>>> I thought I'd implement an example of this and I get ClassCastExceptions
>>> in
>>> the Consumer.
>>> Please feel free to checkout:
>>> https://bitbucket.org/**markalanrichards/discussion-**points/overview<https://bitbucket.org/markalanrichards/discussion-points/overview>
>>> It's not that big (each bundle has only one Java class in it).
>>>
>>> When these start (in order) everything is fine: service-api, model10,
>>> model15, model20, model-provider10, model-provider15, model-provider20.
>>> However, when I start modelConsumer10, model 1.0 and model 1.5 are fine
>>> for
>>> the consumer, but model 2.0 hits the ClassCastException.
>>>
>>> What did I miss?
>>>
>> You are basically hiding package dependencies behind generic types. There
>> is no easy way for the framework to do a consistency check for "T
>> provide()" in a Provider<T>. It can't do it at resolve time because there
>> is no "uses" constraint on T since it doesn't know what it is; it
>> technically might be able to figure it out at run time when doing service
>> lookups, but that would be tricky and costly and still not complete since
>> incompatible stuff could still be passed back in Objects or supertypes and
>> accessed via downcasting.
>>
>> The only guarantees OSGi gives you are with respect to packages and their
>> associated "uses" constraints, your example expects it to analyze all
>> reachable types from a given service interface at run time. It doesn't do
>> that.
>>
>> You would have to create specific concrete versions of your generic
>> interface for each model type so that you could establish a "uses"
>> constraint between the service interface and the concrete model it provides.
>>
>> -> richard
>>
>>
>>
>>> Many Thanks
>>> Mark
>>>
>>> PS: If you don't wish to checkout/run this, but are interested in what
>>> happens, the output when I start model-consumer10 is:
>>> finding refs
>>> objectClass: [Ljava.lang.String;@df54977
>>> provides: com.example.markoffline.model.**Model
>>> service.id: 226
>>> TO STRING: Date: 1371160741853
>>> Description: null
>>> THE LONG: 1371160741853
>>> objectClass: [Ljava.lang.String;@11df24ba
>>> provides: com.example.markoffline.model.**Model
>>> service.id: 227
>>> TO STRING: Date: 1371160741856
>>> Description: The time now
>>> THE LONG: 1371160741856
>>> objectClass: [Ljava.lang.String;@373984fd
>>> provides: com.example.markoffline.model.**Model
>>> service.id: 228
>>> ---
>>> --- Here the bundle hits an exception trace, probably not too useful
>>> except
>>> for:
>>> ---
>>> Caused by: java.lang.ClassCastException:
>>> com.example.markoffline.model.**Model cannot be cast to
>>> com.example.markoffline.model.**Model
>>>       at
>>> com.example.markoffline.**consumer.ModelConsumer.start(**
>>> ModelConsumer.java:27)
>>>
>>>
>>>
>>>
>>>
>>>
>>> On 13 June 2013 11:27, Felix Meschberger <fm...@adobe.com> wrote:
>>>
>>>   Hi
>>>> Am 13.06.2013 um 12:18 schrieb Mark Richards:
>>>>
>>>>   Thanks...
>>>>> "In addition the service registry makes sure, that D only gets V1 Model
>>>>> service instances and E only gets V2 Model service instances."
>>>>> I assumed the registry would only care about the versions of Producer
>>>>> and
>>>>> Consumer, as the Models aren't bound directly to the service.
>>>>>
>>>> The service registry does not care for versions at all. It cares to make
>>>> sure a consumer (retrieving the service) can use the service by making
>>>> sure, the consumer and the service object see the same service object
>>>> class
>>>> objects and thus are compatible.
>>>>
>>>> Regards
>>>> Felix
>>>>
>>>>
>>>>> On 13 June 2013 09:56, Felix Meschberger <fm...@adobe.com> wrote:
>>>>>
>>>>>   Hi
>>>>>> OSGi wires API by import and export package version.
>>>>>>
>>>>>> In you example of two incompatible model classes, you might have bundle
>>>>>>
>>>>> B
>>>>> export the Model API at version 1.0 and bundle C export the Model API at
>>>>>> version 2.0.
>>>>>>
>>>>>> Your consumer bundles D and E would then import the appropriate Model
>>>>>>
>>>>> API
>>>>> versions such as [1,2) and [2,3).
>>>>>> The actual Model class objects are then different for D and E (even
>>>>>>
>>>>> though
>>>>> the fully qualified class name is the same). In addition the service
>>>>>> registry makes sure, that D only gets V1 Model service instances and E
>>>>>>
>>>>> only
>>>>> gets V2 Model service instances.
>>>>>> Hope this helps.
>>>>>>
>>>>>> Regards
>>>>>> Felix
>>>>>>
>>>>>> Am 12.06.2013 um 17:56 schrieb Mark Richards:
>>>>>>
>>>>>>   Hi,
>>>>>>> I'm new to this list and hopefully this question isn't too long...
>>>>>>>
>>>>>> please
>>>>> let me know if you'd like further details.
>>>>>>> Context: I'd like to create a service architecture that represents
>>>>>>>
>>>>>> EIPs,
>>>>> a
>>>>>>> bit like Camel but more OSGi friendly, however the safe wiring of
>>>>>>>
>>>>>> objects
>>>>> must ensure the producers are wired to consumers that provide and
>>>>>> consumer
>>>>>>
>>>>>>> compatible versions of the objects.
>>>>>>>
>>>>>>> Problem: How do you handle the versions dependencies of objects used a
>>>>>>> layer beneath the services provided?
>>>>>>>
>>>>>>> I believe this issue also affects the listener model, if you wanted to
>>>>>>>
>>>>>> use
>>>>>>
>>>>>>> a generic listener model like so I'm hoping somebody has already
>>>>>>> solved
>>>>>>>
>>>>>> it:
>>>>>>
>>>>>>> interface Listener<T> { //Listener class is handled by bundle
>>>>>>>
>>>>>> resolution
>>>>>     void Notify(T event); //but what about this T?
>>>>>>> }
>>>>>>>
>>>>>>>
>>>>>>> When you create an implementation you usually know T, so it's quite
>>>>>>>
>>>>>> easy
>>>>> to
>>>>>>> call "bundleContext.register(**Listener.class, this, props)" where
>>>>>>> props
>>>>>>> includes {"listenerOf":"t.class}" and to then filter the class.
>>>>>>>
>>>>>> However,
>>>>> I'm not sure where to get the version for T from (it may be an imported
>>>>>>> class) and versions are ranges with different rules for import and
>>>>>>>
>>>>>> export.
>>>>>>
>>>>>>> Any help advice or also, an idea of whether I'm the only one trying to
>>>>>>>
>>>>>> do
>>>>> this would be useful.
>>>>>>> Thanks,
>>>>>>> Mark
>>>>>>>
>>>>>>>
>>>>>>> Ps: if it helps here is an example of the style of problem in
>>>>>>>
>>>>>> semi-pseudo
>>>>> code.
>>>>>>> If you cannot filter the version of the Model through the services
>>>>>>>
>>>>>> layer
>>>>> ModelProvider will provide a Date object and ModelConsumer will try to
>>>>>> read
>>>>>>
>>>>>>> a Long. The two shouldn't be allowed to bind to each other.
>>>>>>>
>>>>>>>
>>>>>>> bundle A: wiring-api
>>>>>>>     interface Provider<T> {
>>>>>>>         T giveMeAnObject();
>>>>>>>     }
>>>>>>>     interface Consumer<T> {
>>>>>>>         void hereIsAnObject(T object);
>>>>>>>     }
>>>>>>>
>>>>>>> bundle B: model version 1:
>>>>>>>     class Model {
>>>>>>>         long getDate();{ return (long) 99 }
>>>>>>>     }
>>>>>>>
>>>>>>> bundle C: model version 2:
>>>>>>>     class Model {
>>>>>>>         Date getDate() { return new Date(); }
>>>>>>>     }
>>>>>>>
>>>>>>> bundle D: model-provder version 2: import-packages wiring-api 1 and
>>>>>>>
>>>>>> model 2
>>>>>>
>>>>>>>     class ModelProvider implements Provider <Model>  implements
>>>>>>> BundleActivator { {
>>>>>>>         void start(BundleContext context) {
>>>>>>>             context.register(Provider.**class, this, ???? )* // here
>>>>>>> you'd
>>>>>>> need to specify it is model 2, but how do you get this*
>>>>>>>        }
>>>>>>>         Model giveMeAnObject() {
>>>>>>>             return new Model();
>>>>>>>         }
>>>>>>>     }
>>>>>>> bundle E: consumer imports wiring-api and model 1:
>>>>>>>     class ModelConsumer implements Consumer<Model>, BundleActivator {
>>>>>>>         void start(BundleContext context) {
>>>>>>>             context.register(Consumer.**class, this, ???? )* // here
>>>>>>> you'd
>>>>>>> need to specify it is model 1, but how do you get this**
>>>>>>> *        }*
>>>>>>> *
>>>>>>>
>>>>>>>         void hereIsAnObject(Model object) {
>>>>>>>             System.out.println(Long.**valueOf(model.getDate())); //
>>>>>>> if no
>>>>>>> object version filtering this will fail as bundle D should not be
>>>>>>>
>>>>>> connected
>>>>>>
>>>>>>> to bundle E
>>>>>>>         }
>>>>>>>     }
>>>>>>>
>>>>>>> // here I envisage there should be a Provider Manager perhaps along
>>>>>>> the
>>>>>>> lines of that could be exposed to have wiring done through a UI,
>>>>>>>
>>>>>> interface
>>>>>>
>>>>>>> or config settings like WireAdmin
>>>>>>> // this isn't too important at this point, except it would need some
>>>>>>>
>>>>>> way
>>>>> to
>>>>>>> manage this *version filtering/matching*!
>>>>>>> bundle F: provider-service imports wiring-api
>>>>>>>     class ProviderManager {
>>>>>>>         Map<ClassVersion, Provider> providers;
>>>>>>>         Map<ClassVersion, Consumer, consumers
>>>>>>>         void registerProvider(ClassVersion<**T> provided, Provider<T>
>>>>>>> provider);
>>>>>>>         void registerConsumer(ClassVersion<**T> consumed, Consumer<T>
>>>>>>> provider);
>>>>>>>
>>>>>>>        // methods to lookup and match providers with consumers
>>>>>>>     }
>>>>>>>
>>>>>> ------------------------------**------------------------------**
>>>>>> ---------
>>>>>> To unsubscribe, e-mail: users-unsubscribe@felix.**apache.org<us...@felix.apache.org>
>>>>>> For additional commands, e-mail: users-help@felix.apache.org
>>>>>>
>>>>>>
>>>>>>
>>>> ------------------------------**------------------------------**
>>>> ---------
>>>> To unsubscribe, e-mail: users-unsubscribe@felix.**apache.org<us...@felix.apache.org>
>>>> For additional commands, e-mail: users-help@felix.apache.org
>>>>
>>>>
>>>>
>> ------------------------------**------------------------------**---------
>> To unsubscribe, e-mail: users-unsubscribe@felix.**apache.org<us...@felix.apache.org>
>> For additional commands, e-mail: users-help@felix.apache.org
>>
>>


---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@felix.apache.org
For additional commands, e-mail: users-help@felix.apache.org


Re: Object versions in services

Posted by Mark Richards <ma...@gmail.com>.
 The WireAdmin Producer class has a polled method that is similar that just
returns an Object. I've used Generics as a good programming practice, but
I'm aware it doesn't solve this problem.
There seems to be a use case for this nature of functionality. I've no idea
how frameworks like Camel are solving this problem in OSGi... do they just
hope for the best and push Objects are around and assume Producers and
Consumers are using the same versions?

I understand that the framework wouldn't know what T is, so I'd quite like
to tell the framework what T is.
Ie:
Properties props ...
props.put("providerClassName",Model.class.getName());
props.put("providerClassVersion",*
context.getImportVersion(Model.class.getPackage().getName()*); //this
doesn't exist
context.register(Provider.class,this,props);

However, there doesn't seem to be an easy way to do this,  unless I've
missed something.

Many Thanks
Mark


On 14 June 2013 04:36, Richard S. Hall <he...@ungoverned.org> wrote:

>
> On 6/13/13 20:55 , Mark Richards wrote:
>
>> I thought I'd implement an example of this and I get ClassCastExceptions
>> in
>> the Consumer.
>> Please feel free to checkout:
>> https://bitbucket.org/**markalanrichards/discussion-**points/overview<https://bitbucket.org/markalanrichards/discussion-points/overview>
>> It's not that big (each bundle has only one Java class in it).
>>
>> When these start (in order) everything is fine: service-api, model10,
>> model15, model20, model-provider10, model-provider15, model-provider20.
>> However, when I start modelConsumer10, model 1.0 and model 1.5 are fine
>> for
>> the consumer, but model 2.0 hits the ClassCastException.
>>
>> What did I miss?
>>
>
> You are basically hiding package dependencies behind generic types. There
> is no easy way for the framework to do a consistency check for "T
> provide()" in a Provider<T>. It can't do it at resolve time because there
> is no "uses" constraint on T since it doesn't know what it is; it
> technically might be able to figure it out at run time when doing service
> lookups, but that would be tricky and costly and still not complete since
> incompatible stuff could still be passed back in Objects or supertypes and
> accessed via downcasting.
>
> The only guarantees OSGi gives you are with respect to packages and their
> associated "uses" constraints, your example expects it to analyze all
> reachable types from a given service interface at run time. It doesn't do
> that.
>
> You would have to create specific concrete versions of your generic
> interface for each model type so that you could establish a "uses"
> constraint between the service interface and the concrete model it provides.
>
> -> richard
>
>
>
>> Many Thanks
>> Mark
>>
>> PS: If you don't wish to checkout/run this, but are interested in what
>> happens, the output when I start model-consumer10 is:
>> finding refs
>> objectClass: [Ljava.lang.String;@df54977
>> provides: com.example.markoffline.model.**Model
>> service.id: 226
>> TO STRING: Date: 1371160741853
>> Description: null
>> THE LONG: 1371160741853
>> objectClass: [Ljava.lang.String;@11df24ba
>> provides: com.example.markoffline.model.**Model
>> service.id: 227
>> TO STRING: Date: 1371160741856
>> Description: The time now
>> THE LONG: 1371160741856
>> objectClass: [Ljava.lang.String;@373984fd
>> provides: com.example.markoffline.model.**Model
>> service.id: 228
>> ---
>> --- Here the bundle hits an exception trace, probably not too useful
>> except
>> for:
>> ---
>> Caused by: java.lang.ClassCastException:
>> com.example.markoffline.model.**Model cannot be cast to
>> com.example.markoffline.model.**Model
>>      at
>> com.example.markoffline.**consumer.ModelConsumer.start(**
>> ModelConsumer.java:27)
>>
>>
>>
>>
>>
>>
>> On 13 June 2013 11:27, Felix Meschberger <fm...@adobe.com> wrote:
>>
>>  Hi
>>>
>>> Am 13.06.2013 um 12:18 schrieb Mark Richards:
>>>
>>>  Thanks...
>>>> "In addition the service registry makes sure, that D only gets V1 Model
>>>> service instances and E only gets V2 Model service instances."
>>>> I assumed the registry would only care about the versions of Producer
>>>> and
>>>> Consumer, as the Models aren't bound directly to the service.
>>>>
>>> The service registry does not care for versions at all. It cares to make
>>> sure a consumer (retrieving the service) can use the service by making
>>> sure, the consumer and the service object see the same service object
>>> class
>>> objects and thus are compatible.
>>>
>>> Regards
>>> Felix
>>>
>>>
>>>> On 13 June 2013 09:56, Felix Meschberger <fm...@adobe.com> wrote:
>>>>
>>>>  Hi
>>>>>
>>>>> OSGi wires API by import and export package version.
>>>>>
>>>>> In you example of two incompatible model classes, you might have bundle
>>>>>
>>>> B
>>>
>>>> export the Model API at version 1.0 and bundle C export the Model API at
>>>>> version 2.0.
>>>>>
>>>>> Your consumer bundles D and E would then import the appropriate Model
>>>>>
>>>> API
>>>
>>>> versions such as [1,2) and [2,3).
>>>>>
>>>>> The actual Model class objects are then different for D and E (even
>>>>>
>>>> though
>>>
>>>> the fully qualified class name is the same). In addition the service
>>>>> registry makes sure, that D only gets V1 Model service instances and E
>>>>>
>>>> only
>>>
>>>> gets V2 Model service instances.
>>>>>
>>>>> Hope this helps.
>>>>>
>>>>> Regards
>>>>> Felix
>>>>>
>>>>> Am 12.06.2013 um 17:56 schrieb Mark Richards:
>>>>>
>>>>>  Hi,
>>>>>>
>>>>>> I'm new to this list and hopefully this question isn't too long...
>>>>>>
>>>>> please
>>>
>>>> let me know if you'd like further details.
>>>>>>
>>>>>> Context: I'd like to create a service architecture that represents
>>>>>>
>>>>> EIPs,
>>>
>>>> a
>>>>>
>>>>>> bit like Camel but more OSGi friendly, however the safe wiring of
>>>>>>
>>>>> objects
>>>
>>>> must ensure the producers are wired to consumers that provide and
>>>>>>
>>>>> consumer
>>>>>
>>>>>> compatible versions of the objects.
>>>>>>
>>>>>> Problem: How do you handle the versions dependencies of objects used a
>>>>>> layer beneath the services provided?
>>>>>>
>>>>>> I believe this issue also affects the listener model, if you wanted to
>>>>>>
>>>>> use
>>>>>
>>>>>> a generic listener model like so I'm hoping somebody has already
>>>>>> solved
>>>>>>
>>>>> it:
>>>>>
>>>>>> interface Listener<T> { //Listener class is handled by bundle
>>>>>>
>>>>> resolution
>>>
>>>>    void Notify(T event); //but what about this T?
>>>>>> }
>>>>>>
>>>>>>
>>>>>> When you create an implementation you usually know T, so it's quite
>>>>>>
>>>>> easy
>>>
>>>> to
>>>>>
>>>>>> call "bundleContext.register(**Listener.class, this, props)" where
>>>>>> props
>>>>>> includes {"listenerOf":"t.class}" and to then filter the class.
>>>>>>
>>>>> However,
>>>
>>>> I'm not sure where to get the version for T from (it may be an imported
>>>>>> class) and versions are ranges with different rules for import and
>>>>>>
>>>>> export.
>>>>>
>>>>>> Any help advice or also, an idea of whether I'm the only one trying to
>>>>>>
>>>>> do
>>>
>>>> this would be useful.
>>>>>>
>>>>>> Thanks,
>>>>>> Mark
>>>>>>
>>>>>>
>>>>>> Ps: if it helps here is an example of the style of problem in
>>>>>>
>>>>> semi-pseudo
>>>
>>>> code.
>>>>>> If you cannot filter the version of the Model through the services
>>>>>>
>>>>> layer
>>>
>>>> ModelProvider will provide a Date object and ModelConsumer will try to
>>>>>>
>>>>> read
>>>>>
>>>>>> a Long. The two shouldn't be allowed to bind to each other.
>>>>>>
>>>>>>
>>>>>> bundle A: wiring-api
>>>>>>    interface Provider<T> {
>>>>>>        T giveMeAnObject();
>>>>>>    }
>>>>>>    interface Consumer<T> {
>>>>>>        void hereIsAnObject(T object);
>>>>>>    }
>>>>>>
>>>>>> bundle B: model version 1:
>>>>>>    class Model {
>>>>>>        long getDate();{ return (long) 99 }
>>>>>>    }
>>>>>>
>>>>>> bundle C: model version 2:
>>>>>>    class Model {
>>>>>>        Date getDate() { return new Date(); }
>>>>>>    }
>>>>>>
>>>>>> bundle D: model-provder version 2: import-packages wiring-api 1 and
>>>>>>
>>>>> model 2
>>>>>
>>>>>>    class ModelProvider implements Provider <Model>  implements
>>>>>> BundleActivator { {
>>>>>>        void start(BundleContext context) {
>>>>>>            context.register(Provider.**class, this, ???? )* // here
>>>>>> you'd
>>>>>> need to specify it is model 2, but how do you get this*
>>>>>>       }
>>>>>>        Model giveMeAnObject() {
>>>>>>            return new Model();
>>>>>>        }
>>>>>>    }
>>>>>> bundle E: consumer imports wiring-api and model 1:
>>>>>>    class ModelConsumer implements Consumer<Model>, BundleActivator {
>>>>>>        void start(BundleContext context) {
>>>>>>            context.register(Consumer.**class, this, ???? )* // here
>>>>>> you'd
>>>>>> need to specify it is model 1, but how do you get this**
>>>>>> *        }*
>>>>>> *
>>>>>>
>>>>>>        void hereIsAnObject(Model object) {
>>>>>>            System.out.println(Long.**valueOf(model.getDate())); //
>>>>>> if no
>>>>>> object version filtering this will fail as bundle D should not be
>>>>>>
>>>>> connected
>>>>>
>>>>>> to bundle E
>>>>>>        }
>>>>>>    }
>>>>>>
>>>>>> // here I envisage there should be a Provider Manager perhaps along
>>>>>> the
>>>>>> lines of that could be exposed to have wiring done through a UI,
>>>>>>
>>>>> interface
>>>>>
>>>>>> or config settings like WireAdmin
>>>>>> // this isn't too important at this point, except it would need some
>>>>>>
>>>>> way
>>>
>>>> to
>>>>>
>>>>>> manage this *version filtering/matching*!
>>>>>> bundle F: provider-service imports wiring-api
>>>>>>    class ProviderManager {
>>>>>>        Map<ClassVersion, Provider> providers;
>>>>>>        Map<ClassVersion, Consumer, consumers
>>>>>>        void registerProvider(ClassVersion<**T> provided, Provider<T>
>>>>>> provider);
>>>>>>        void registerConsumer(ClassVersion<**T> consumed, Consumer<T>
>>>>>> provider);
>>>>>>
>>>>>>       // methods to lookup and match providers with consumers
>>>>>>    }
>>>>>>
>>>>>
>>>>> ------------------------------**------------------------------**
>>>>> ---------
>>>>> To unsubscribe, e-mail: users-unsubscribe@felix.**apache.org<us...@felix.apache.org>
>>>>> For additional commands, e-mail: users-help@felix.apache.org
>>>>>
>>>>>
>>>>>
>>> ------------------------------**------------------------------**
>>> ---------
>>> To unsubscribe, e-mail: users-unsubscribe@felix.**apache.org<us...@felix.apache.org>
>>> For additional commands, e-mail: users-help@felix.apache.org
>>>
>>>
>>>
>
> ------------------------------**------------------------------**---------
> To unsubscribe, e-mail: users-unsubscribe@felix.**apache.org<us...@felix.apache.org>
> For additional commands, e-mail: users-help@felix.apache.org
>
>

Re: Object versions in services

Posted by "Richard S. Hall" <he...@ungoverned.org>.
On 6/13/13 20:55 , Mark Richards wrote:
> I thought I'd implement an example of this and I get ClassCastExceptions in
> the Consumer.
> Please feel free to checkout:
> https://bitbucket.org/markalanrichards/discussion-points/overview
> It's not that big (each bundle has only one Java class in it).
>
> When these start (in order) everything is fine: service-api, model10,
> model15, model20, model-provider10, model-provider15, model-provider20.
> However, when I start modelConsumer10, model 1.0 and model 1.5 are fine for
> the consumer, but model 2.0 hits the ClassCastException.
>
> What did I miss?

You are basically hiding package dependencies behind generic types. 
There is no easy way for the framework to do a consistency check for "T 
provide()" in a Provider<T>. It can't do it at resolve time because 
there is no "uses" constraint on T since it doesn't know what it is; it 
technically might be able to figure it out at run time when doing 
service lookups, but that would be tricky and costly and still not 
complete since incompatible stuff could still be passed back in Objects 
or supertypes and accessed via downcasting.

The only guarantees OSGi gives you are with respect to packages and 
their associated "uses" constraints, your example expects it to analyze 
all reachable types from a given service interface at run time. It 
doesn't do that.

You would have to create specific concrete versions of your generic 
interface for each model type so that you could establish a "uses" 
constraint between the service interface and the concrete model it provides.

-> richard

>
> Many Thanks
> Mark
>
> PS: If you don't wish to checkout/run this, but are interested in what
> happens, the output when I start model-consumer10 is:
> finding refs
> objectClass: [Ljava.lang.String;@df54977
> provides: com.example.markoffline.model.Model
> service.id: 226
> TO STRING: Date: 1371160741853
> Description: null
> THE LONG: 1371160741853
> objectClass: [Ljava.lang.String;@11df24ba
> provides: com.example.markoffline.model.Model
> service.id: 227
> TO STRING: Date: 1371160741856
> Description: The time now
> THE LONG: 1371160741856
> objectClass: [Ljava.lang.String;@373984fd
> provides: com.example.markoffline.model.Model
> service.id: 228
> ---
> --- Here the bundle hits an exception trace, probably not too useful except
> for:
> ---
> Caused by: java.lang.ClassCastException:
> com.example.markoffline.model.Model cannot be cast to
> com.example.markoffline.model.Model
>      at
> com.example.markoffline.consumer.ModelConsumer.start(ModelConsumer.java:27)
>
>
>
>
>
>
> On 13 June 2013 11:27, Felix Meschberger <fm...@adobe.com> wrote:
>
>> Hi
>>
>> Am 13.06.2013 um 12:18 schrieb Mark Richards:
>>
>>> Thanks...
>>> "In addition the service registry makes sure, that D only gets V1 Model
>>> service instances and E only gets V2 Model service instances."
>>> I assumed the registry would only care about the versions of Producer and
>>> Consumer, as the Models aren't bound directly to the service.
>> The service registry does not care for versions at all. It cares to make
>> sure a consumer (retrieving the service) can use the service by making
>> sure, the consumer and the service object see the same service object class
>> objects and thus are compatible.
>>
>> Regards
>> Felix
>>
>>>
>>> On 13 June 2013 09:56, Felix Meschberger <fm...@adobe.com> wrote:
>>>
>>>> Hi
>>>>
>>>> OSGi wires API by import and export package version.
>>>>
>>>> In you example of two incompatible model classes, you might have bundle
>> B
>>>> export the Model API at version 1.0 and bundle C export the Model API at
>>>> version 2.0.
>>>>
>>>> Your consumer bundles D and E would then import the appropriate Model
>> API
>>>> versions such as [1,2) and [2,3).
>>>>
>>>> The actual Model class objects are then different for D and E (even
>> though
>>>> the fully qualified class name is the same). In addition the service
>>>> registry makes sure, that D only gets V1 Model service instances and E
>> only
>>>> gets V2 Model service instances.
>>>>
>>>> Hope this helps.
>>>>
>>>> Regards
>>>> Felix
>>>>
>>>> Am 12.06.2013 um 17:56 schrieb Mark Richards:
>>>>
>>>>> Hi,
>>>>>
>>>>> I'm new to this list and hopefully this question isn't too long...
>> please
>>>>> let me know if you'd like further details.
>>>>>
>>>>> Context: I'd like to create a service architecture that represents
>> EIPs,
>>>> a
>>>>> bit like Camel but more OSGi friendly, however the safe wiring of
>> objects
>>>>> must ensure the producers are wired to consumers that provide and
>>>> consumer
>>>>> compatible versions of the objects.
>>>>>
>>>>> Problem: How do you handle the versions dependencies of objects used a
>>>>> layer beneath the services provided?
>>>>>
>>>>> I believe this issue also affects the listener model, if you wanted to
>>>> use
>>>>> a generic listener model like so I'm hoping somebody has already solved
>>>> it:
>>>>> interface Listener<T> { //Listener class is handled by bundle
>> resolution
>>>>>    void Notify(T event); //but what about this T?
>>>>> }
>>>>>
>>>>>
>>>>> When you create an implementation you usually know T, so it's quite
>> easy
>>>> to
>>>>> call "bundleContext.register(Listener.class, this, props)" where props
>>>>> includes {"listenerOf":"t.class}" and to then filter the class.
>> However,
>>>>> I'm not sure where to get the version for T from (it may be an imported
>>>>> class) and versions are ranges with different rules for import and
>>>> export.
>>>>> Any help advice or also, an idea of whether I'm the only one trying to
>> do
>>>>> this would be useful.
>>>>>
>>>>> Thanks,
>>>>> Mark
>>>>>
>>>>>
>>>>> Ps: if it helps here is an example of the style of problem in
>> semi-pseudo
>>>>> code.
>>>>> If you cannot filter the version of the Model through the services
>> layer
>>>>> ModelProvider will provide a Date object and ModelConsumer will try to
>>>> read
>>>>> a Long. The two shouldn't be allowed to bind to each other.
>>>>>
>>>>>
>>>>> bundle A: wiring-api
>>>>>    interface Provider<T> {
>>>>>        T giveMeAnObject();
>>>>>    }
>>>>>    interface Consumer<T> {
>>>>>        void hereIsAnObject(T object);
>>>>>    }
>>>>>
>>>>> bundle B: model version 1:
>>>>>    class Model {
>>>>>        long getDate();{ return (long) 99 }
>>>>>    }
>>>>>
>>>>> bundle C: model version 2:
>>>>>    class Model {
>>>>>        Date getDate() { return new Date(); }
>>>>>    }
>>>>>
>>>>> bundle D: model-provder version 2: import-packages wiring-api 1 and
>>>> model 2
>>>>>    class ModelProvider implements Provider <Model>  implements
>>>>> BundleActivator { {
>>>>>        void start(BundleContext context) {
>>>>>            context.register(Provider.class, this, ???? )* // here you'd
>>>>> need to specify it is model 2, but how do you get this*
>>>>>       }
>>>>>        Model giveMeAnObject() {
>>>>>            return new Model();
>>>>>        }
>>>>>    }
>>>>> bundle E: consumer imports wiring-api and model 1:
>>>>>    class ModelConsumer implements Consumer<Model>, BundleActivator {
>>>>>        void start(BundleContext context) {
>>>>>            context.register(Consumer.class, this, ???? )* // here you'd
>>>>> need to specify it is model 1, but how do you get this**
>>>>> *        }*
>>>>> *
>>>>>
>>>>>        void hereIsAnObject(Model object) {
>>>>>            System.out.println(Long.valueOf(model.getDate())); // if no
>>>>> object version filtering this will fail as bundle D should not be
>>>> connected
>>>>> to bundle E
>>>>>        }
>>>>>    }
>>>>>
>>>>> // here I envisage there should be a Provider Manager perhaps along the
>>>>> lines of that could be exposed to have wiring done through a UI,
>>>> interface
>>>>> or config settings like WireAdmin
>>>>> // this isn't too important at this point, except it would need some
>> way
>>>> to
>>>>> manage this *version filtering/matching*!
>>>>> bundle F: provider-service imports wiring-api
>>>>>    class ProviderManager {
>>>>>        Map<ClassVersion, Provider> providers;
>>>>>        Map<ClassVersion, Consumer, consumers
>>>>>        void registerProvider(ClassVersion<T> provided, Provider<T>
>>>>> provider);
>>>>>        void registerConsumer(ClassVersion<T> consumed, Consumer<T>
>>>>> provider);
>>>>>
>>>>>       // methods to lookup and match providers with consumers
>>>>>    }
>>>>
>>>> ---------------------------------------------------------------------
>>>> To unsubscribe, e-mail: users-unsubscribe@felix.apache.org
>>>> For additional commands, e-mail: users-help@felix.apache.org
>>>>
>>>>
>>
>> ---------------------------------------------------------------------
>> To unsubscribe, e-mail: users-unsubscribe@felix.apache.org
>> For additional commands, e-mail: users-help@felix.apache.org
>>
>>


---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@felix.apache.org
For additional commands, e-mail: users-help@felix.apache.org


Re: Object versions in services

Posted by Mark Richards <ma...@gmail.com>.
I thought I'd implement an example of this and I get ClassCastExceptions in
the Consumer.
Please feel free to checkout:
https://bitbucket.org/markalanrichards/discussion-points/overview
It's not that big (each bundle has only one Java class in it).

When these start (in order) everything is fine: service-api, model10,
model15, model20, model-provider10, model-provider15, model-provider20.
However, when I start modelConsumer10, model 1.0 and model 1.5 are fine for
the consumer, but model 2.0 hits the ClassCastException.

What did I miss?

Many Thanks
Mark

PS: If you don't wish to checkout/run this, but are interested in what
happens, the output when I start model-consumer10 is:
finding refs
objectClass: [Ljava.lang.String;@df54977
provides: com.example.markoffline.model.Model
service.id: 226
TO STRING: Date: 1371160741853
Description: null
THE LONG: 1371160741853
objectClass: [Ljava.lang.String;@11df24ba
provides: com.example.markoffline.model.Model
service.id: 227
TO STRING: Date: 1371160741856
Description: The time now
THE LONG: 1371160741856
objectClass: [Ljava.lang.String;@373984fd
provides: com.example.markoffline.model.Model
service.id: 228
---
--- Here the bundle hits an exception trace, probably not too useful except
for:
---
Caused by: java.lang.ClassCastException:
com.example.markoffline.model.Model cannot be cast to
com.example.markoffline.model.Model
    at
com.example.markoffline.consumer.ModelConsumer.start(ModelConsumer.java:27)






On 13 June 2013 11:27, Felix Meschberger <fm...@adobe.com> wrote:

> Hi
>
> Am 13.06.2013 um 12:18 schrieb Mark Richards:
>
> > Thanks...
> > "In addition the service registry makes sure, that D only gets V1 Model
> > service instances and E only gets V2 Model service instances."
> > I assumed the registry would only care about the versions of Producer and
> > Consumer, as the Models aren't bound directly to the service.
>
> The service registry does not care for versions at all. It cares to make
> sure a consumer (retrieving the service) can use the service by making
> sure, the consumer and the service object see the same service object class
> objects and thus are compatible.
>
> Regards
> Felix
>
> >
> >
> > On 13 June 2013 09:56, Felix Meschberger <fm...@adobe.com> wrote:
> >
> >> Hi
> >>
> >> OSGi wires API by import and export package version.
> >>
> >> In you example of two incompatible model classes, you might have bundle
> B
> >> export the Model API at version 1.0 and bundle C export the Model API at
> >> version 2.0.
> >>
> >> Your consumer bundles D and E would then import the appropriate Model
> API
> >> versions such as [1,2) and [2,3).
> >>
> >> The actual Model class objects are then different for D and E (even
> though
> >> the fully qualified class name is the same). In addition the service
> >> registry makes sure, that D only gets V1 Model service instances and E
> only
> >> gets V2 Model service instances.
> >>
> >> Hope this helps.
> >>
> >> Regards
> >> Felix
> >>
> >> Am 12.06.2013 um 17:56 schrieb Mark Richards:
> >>
> >>> Hi,
> >>>
> >>> I'm new to this list and hopefully this question isn't too long...
> please
> >>> let me know if you'd like further details.
> >>>
> >>> Context: I'd like to create a service architecture that represents
> EIPs,
> >> a
> >>> bit like Camel but more OSGi friendly, however the safe wiring of
> objects
> >>> must ensure the producers are wired to consumers that provide and
> >> consumer
> >>> compatible versions of the objects.
> >>>
> >>> Problem: How do you handle the versions dependencies of objects used a
> >>> layer beneath the services provided?
> >>>
> >>> I believe this issue also affects the listener model, if you wanted to
> >> use
> >>> a generic listener model like so I'm hoping somebody has already solved
> >> it:
> >>>
> >>> interface Listener<T> { //Listener class is handled by bundle
> resolution
> >>>   void Notify(T event); //but what about this T?
> >>> }
> >>>
> >>>
> >>> When you create an implementation you usually know T, so it's quite
> easy
> >> to
> >>> call "bundleContext.register(Listener.class, this, props)" where props
> >>> includes {"listenerOf":"t.class}" and to then filter the class.
> However,
> >>> I'm not sure where to get the version for T from (it may be an imported
> >>> class) and versions are ranges with different rules for import and
> >> export.
> >>>
> >>> Any help advice or also, an idea of whether I'm the only one trying to
> do
> >>> this would be useful.
> >>>
> >>> Thanks,
> >>> Mark
> >>>
> >>>
> >>> Ps: if it helps here is an example of the style of problem in
> semi-pseudo
> >>> code.
> >>> If you cannot filter the version of the Model through the services
> layer
> >>> ModelProvider will provide a Date object and ModelConsumer will try to
> >> read
> >>> a Long. The two shouldn't be allowed to bind to each other.
> >>>
> >>>
> >>> bundle A: wiring-api
> >>>   interface Provider<T> {
> >>>       T giveMeAnObject();
> >>>   }
> >>>   interface Consumer<T> {
> >>>       void hereIsAnObject(T object);
> >>>   }
> >>>
> >>> bundle B: model version 1:
> >>>   class Model {
> >>>       long getDate();{ return (long) 99 }
> >>>   }
> >>>
> >>> bundle C: model version 2:
> >>>   class Model {
> >>>       Date getDate() { return new Date(); }
> >>>   }
> >>>
> >>> bundle D: model-provder version 2: import-packages wiring-api 1 and
> >> model 2
> >>>   class ModelProvider implements Provider <Model>  implements
> >>> BundleActivator { {
> >>>       void start(BundleContext context) {
> >>>           context.register(Provider.class, this, ???? )* // here you'd
> >>> need to specify it is model 2, but how do you get this*
> >>>      }
> >>>       Model giveMeAnObject() {
> >>>           return new Model();
> >>>       }
> >>>   }
> >>> bundle E: consumer imports wiring-api and model 1:
> >>>   class ModelConsumer implements Consumer<Model>, BundleActivator {
> >>>       void start(BundleContext context) {
> >>>           context.register(Consumer.class, this, ???? )* // here you'd
> >>> need to specify it is model 1, but how do you get this**
> >>> *        }*
> >>> *
> >>>
> >>>       void hereIsAnObject(Model object) {
> >>>           System.out.println(Long.valueOf(model.getDate())); // if no
> >>> object version filtering this will fail as bundle D should not be
> >> connected
> >>> to bundle E
> >>>       }
> >>>   }
> >>>
> >>> // here I envisage there should be a Provider Manager perhaps along the
> >>> lines of that could be exposed to have wiring done through a UI,
> >> interface
> >>> or config settings like WireAdmin
> >>> // this isn't too important at this point, except it would need some
> way
> >> to
> >>> manage this *version filtering/matching*!
> >>> bundle F: provider-service imports wiring-api
> >>>   class ProviderManager {
> >>>       Map<ClassVersion, Provider> providers;
> >>>       Map<ClassVersion, Consumer, consumers
> >>>       void registerProvider(ClassVersion<T> provided, Provider<T>
> >>> provider);
> >>>       void registerConsumer(ClassVersion<T> consumed, Consumer<T>
> >>> provider);
> >>>
> >>>      // methods to lookup and match providers with consumers
> >>>   }
> >>
> >>
> >> ---------------------------------------------------------------------
> >> To unsubscribe, e-mail: users-unsubscribe@felix.apache.org
> >> For additional commands, e-mail: users-help@felix.apache.org
> >>
> >>
>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: users-unsubscribe@felix.apache.org
> For additional commands, e-mail: users-help@felix.apache.org
>
>

Re: Object versions in services

Posted by Felix Meschberger <fm...@adobe.com>.
Hi

Am 13.06.2013 um 12:18 schrieb Mark Richards:

> Thanks...
> "In addition the service registry makes sure, that D only gets V1 Model
> service instances and E only gets V2 Model service instances."
> I assumed the registry would only care about the versions of Producer and
> Consumer, as the Models aren't bound directly to the service.

The service registry does not care for versions at all. It cares to make sure a consumer (retrieving the service) can use the service by making sure, the consumer and the service object see the same service object class objects and thus are compatible.

Regards
Felix

> 
> 
> On 13 June 2013 09:56, Felix Meschberger <fm...@adobe.com> wrote:
> 
>> Hi
>> 
>> OSGi wires API by import and export package version.
>> 
>> In you example of two incompatible model classes, you might have bundle B
>> export the Model API at version 1.0 and bundle C export the Model API at
>> version 2.0.
>> 
>> Your consumer bundles D and E would then import the appropriate Model API
>> versions such as [1,2) and [2,3).
>> 
>> The actual Model class objects are then different for D and E (even though
>> the fully qualified class name is the same). In addition the service
>> registry makes sure, that D only gets V1 Model service instances and E only
>> gets V2 Model service instances.
>> 
>> Hope this helps.
>> 
>> Regards
>> Felix
>> 
>> Am 12.06.2013 um 17:56 schrieb Mark Richards:
>> 
>>> Hi,
>>> 
>>> I'm new to this list and hopefully this question isn't too long... please
>>> let me know if you'd like further details.
>>> 
>>> Context: I'd like to create a service architecture that represents EIPs,
>> a
>>> bit like Camel but more OSGi friendly, however the safe wiring of objects
>>> must ensure the producers are wired to consumers that provide and
>> consumer
>>> compatible versions of the objects.
>>> 
>>> Problem: How do you handle the versions dependencies of objects used a
>>> layer beneath the services provided?
>>> 
>>> I believe this issue also affects the listener model, if you wanted to
>> use
>>> a generic listener model like so I'm hoping somebody has already solved
>> it:
>>> 
>>> interface Listener<T> { //Listener class is handled by bundle resolution
>>>   void Notify(T event); //but what about this T?
>>> }
>>> 
>>> 
>>> When you create an implementation you usually know T, so it's quite easy
>> to
>>> call "bundleContext.register(Listener.class, this, props)" where props
>>> includes {"listenerOf":"t.class}" and to then filter the class. However,
>>> I'm not sure where to get the version for T from (it may be an imported
>>> class) and versions are ranges with different rules for import and
>> export.
>>> 
>>> Any help advice or also, an idea of whether I'm the only one trying to do
>>> this would be useful.
>>> 
>>> Thanks,
>>> Mark
>>> 
>>> 
>>> Ps: if it helps here is an example of the style of problem in semi-pseudo
>>> code.
>>> If you cannot filter the version of the Model through the services layer
>>> ModelProvider will provide a Date object and ModelConsumer will try to
>> read
>>> a Long. The two shouldn't be allowed to bind to each other.
>>> 
>>> 
>>> bundle A: wiring-api
>>>   interface Provider<T> {
>>>       T giveMeAnObject();
>>>   }
>>>   interface Consumer<T> {
>>>       void hereIsAnObject(T object);
>>>   }
>>> 
>>> bundle B: model version 1:
>>>   class Model {
>>>       long getDate();{ return (long) 99 }
>>>   }
>>> 
>>> bundle C: model version 2:
>>>   class Model {
>>>       Date getDate() { return new Date(); }
>>>   }
>>> 
>>> bundle D: model-provder version 2: import-packages wiring-api 1 and
>> model 2
>>>   class ModelProvider implements Provider <Model>  implements
>>> BundleActivator { {
>>>       void start(BundleContext context) {
>>>           context.register(Provider.class, this, ???? )* // here you'd
>>> need to specify it is model 2, but how do you get this*
>>>      }
>>>       Model giveMeAnObject() {
>>>           return new Model();
>>>       }
>>>   }
>>> bundle E: consumer imports wiring-api and model 1:
>>>   class ModelConsumer implements Consumer<Model>, BundleActivator {
>>>       void start(BundleContext context) {
>>>           context.register(Consumer.class, this, ???? )* // here you'd
>>> need to specify it is model 1, but how do you get this**
>>> *        }*
>>> *
>>> 
>>>       void hereIsAnObject(Model object) {
>>>           System.out.println(Long.valueOf(model.getDate())); // if no
>>> object version filtering this will fail as bundle D should not be
>> connected
>>> to bundle E
>>>       }
>>>   }
>>> 
>>> // here I envisage there should be a Provider Manager perhaps along the
>>> lines of that could be exposed to have wiring done through a UI,
>> interface
>>> or config settings like WireAdmin
>>> // this isn't too important at this point, except it would need some way
>> to
>>> manage this *version filtering/matching*!
>>> bundle F: provider-service imports wiring-api
>>>   class ProviderManager {
>>>       Map<ClassVersion, Provider> providers;
>>>       Map<ClassVersion, Consumer, consumers
>>>       void registerProvider(ClassVersion<T> provided, Provider<T>
>>> provider);
>>>       void registerConsumer(ClassVersion<T> consumed, Consumer<T>
>>> provider);
>>> 
>>>      // methods to lookup and match providers with consumers
>>>   }
>> 
>> 
>> ---------------------------------------------------------------------
>> To unsubscribe, e-mail: users-unsubscribe@felix.apache.org
>> For additional commands, e-mail: users-help@felix.apache.org
>> 
>> 


---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@felix.apache.org
For additional commands, e-mail: users-help@felix.apache.org


Re: Object versions in services

Posted by Mark Richards <ma...@gmail.com>.
Thanks...
"In addition the service registry makes sure, that D only gets V1 Model
service instances and E only gets V2 Model service instances."
I assumed the registry would only care about the versions of Producer and
Consumer, as the Models aren't bound directly to the service.


On 13 June 2013 09:56, Felix Meschberger <fm...@adobe.com> wrote:

> Hi
>
> OSGi wires API by import and export package version.
>
> In you example of two incompatible model classes, you might have bundle B
> export the Model API at version 1.0 and bundle C export the Model API at
> version 2.0.
>
> Your consumer bundles D and E would then import the appropriate Model API
> versions such as [1,2) and [2,3).
>
> The actual Model class objects are then different for D and E (even though
> the fully qualified class name is the same). In addition the service
> registry makes sure, that D only gets V1 Model service instances and E only
> gets V2 Model service instances.
>
> Hope this helps.
>
> Regards
> Felix
>
> Am 12.06.2013 um 17:56 schrieb Mark Richards:
>
> > Hi,
> >
> > I'm new to this list and hopefully this question isn't too long... please
> > let me know if you'd like further details.
> >
> > Context: I'd like to create a service architecture that represents EIPs,
> a
> > bit like Camel but more OSGi friendly, however the safe wiring of objects
> > must ensure the producers are wired to consumers that provide and
> consumer
> > compatible versions of the objects.
> >
> > Problem: How do you handle the versions dependencies of objects used a
> > layer beneath the services provided?
> >
> > I believe this issue also affects the listener model, if you wanted to
> use
> > a generic listener model like so I'm hoping somebody has already solved
> it:
> >
> > interface Listener<T> { //Listener class is handled by bundle resolution
> >    void Notify(T event); //but what about this T?
> > }
> >
> >
> > When you create an implementation you usually know T, so it's quite easy
> to
> > call "bundleContext.register(Listener.class, this, props)" where props
> > includes {"listenerOf":"t.class}" and to then filter the class. However,
> > I'm not sure where to get the version for T from (it may be an imported
> > class) and versions are ranges with different rules for import and
> export.
> >
> > Any help advice or also, an idea of whether I'm the only one trying to do
> > this would be useful.
> >
> > Thanks,
> > Mark
> >
> >
> > Ps: if it helps here is an example of the style of problem in semi-pseudo
> > code.
> > If you cannot filter the version of the Model through the services layer
> > ModelProvider will provide a Date object and ModelConsumer will try to
> read
> > a Long. The two shouldn't be allowed to bind to each other.
> >
> >
> > bundle A: wiring-api
> >    interface Provider<T> {
> >        T giveMeAnObject();
> >    }
> >    interface Consumer<T> {
> >        void hereIsAnObject(T object);
> >    }
> >
> > bundle B: model version 1:
> >    class Model {
> >        long getDate();{ return (long) 99 }
> >    }
> >
> > bundle C: model version 2:
> >    class Model {
> >        Date getDate() { return new Date(); }
> >    }
> >
> > bundle D: model-provder version 2: import-packages wiring-api 1 and
> model 2
> >    class ModelProvider implements Provider <Model>  implements
> > BundleActivator { {
> >        void start(BundleContext context) {
> >            context.register(Provider.class, this, ???? )* // here you'd
> > need to specify it is model 2, but how do you get this*
> >       }
> >        Model giveMeAnObject() {
> >            return new Model();
> >        }
> >    }
> > bundle E: consumer imports wiring-api and model 1:
> >    class ModelConsumer implements Consumer<Model>, BundleActivator {
> >        void start(BundleContext context) {
> >            context.register(Consumer.class, this, ???? )* // here you'd
> > need to specify it is model 1, but how do you get this**
> > *        }*
> > *
> >
> >        void hereIsAnObject(Model object) {
> >            System.out.println(Long.valueOf(model.getDate())); // if no
> > object version filtering this will fail as bundle D should not be
> connected
> > to bundle E
> >        }
> >    }
> >
> > // here I envisage there should be a Provider Manager perhaps along the
> > lines of that could be exposed to have wiring done through a UI,
> interface
> > or config settings like WireAdmin
> > // this isn't too important at this point, except it would need some way
> to
> > manage this *version filtering/matching*!
> > bundle F: provider-service imports wiring-api
> >    class ProviderManager {
> >        Map<ClassVersion, Provider> providers;
> >        Map<ClassVersion, Consumer, consumers
> >        void registerProvider(ClassVersion<T> provided, Provider<T>
> > provider);
> >        void registerConsumer(ClassVersion<T> consumed, Consumer<T>
> > provider);
> >
> >       // methods to lookup and match providers with consumers
> >    }
>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: users-unsubscribe@felix.apache.org
> For additional commands, e-mail: users-help@felix.apache.org
>
>

Re: Object versions in services

Posted by Felix Meschberger <fm...@adobe.com>.
Hi

OSGi wires API by import and export package version.

In you example of two incompatible model classes, you might have bundle B export the Model API at version 1.0 and bundle C export the Model API at version 2.0.

Your consumer bundles D and E would then import the appropriate Model API versions such as [1,2) and [2,3).

The actual Model class objects are then different for D and E (even though the fully qualified class name is the same). In addition the service registry makes sure, that D only gets V1 Model service instances and E only gets V2 Model service instances.

Hope this helps.

Regards
Felix

Am 12.06.2013 um 17:56 schrieb Mark Richards:

> Hi,
> 
> I'm new to this list and hopefully this question isn't too long... please
> let me know if you'd like further details.
> 
> Context: I'd like to create a service architecture that represents EIPs, a
> bit like Camel but more OSGi friendly, however the safe wiring of objects
> must ensure the producers are wired to consumers that provide and consumer
> compatible versions of the objects.
> 
> Problem: How do you handle the versions dependencies of objects used a
> layer beneath the services provided?
> 
> I believe this issue also affects the listener model, if you wanted to use
> a generic listener model like so I'm hoping somebody has already solved it:
> 
> interface Listener<T> { //Listener class is handled by bundle resolution
>    void Notify(T event); //but what about this T?
> }
> 
> 
> When you create an implementation you usually know T, so it's quite easy to
> call "bundleContext.register(Listener.class, this, props)" where props
> includes {"listenerOf":"t.class}" and to then filter the class. However,
> I'm not sure where to get the version for T from (it may be an imported
> class) and versions are ranges with different rules for import and export.
> 
> Any help advice or also, an idea of whether I'm the only one trying to do
> this would be useful.
> 
> Thanks,
> Mark
> 
> 
> Ps: if it helps here is an example of the style of problem in semi-pseudo
> code.
> If you cannot filter the version of the Model through the services layer
> ModelProvider will provide a Date object and ModelConsumer will try to read
> a Long. The two shouldn't be allowed to bind to each other.
> 
> 
> bundle A: wiring-api
>    interface Provider<T> {
>        T giveMeAnObject();
>    }
>    interface Consumer<T> {
>        void hereIsAnObject(T object);
>    }
> 
> bundle B: model version 1:
>    class Model {
>        long getDate();{ return (long) 99 }
>    }
> 
> bundle C: model version 2:
>    class Model {
>        Date getDate() { return new Date(); }
>    }
> 
> bundle D: model-provder version 2: import-packages wiring-api 1 and model 2
>    class ModelProvider implements Provider <Model>  implements
> BundleActivator { {
>        void start(BundleContext context) {
>            context.register(Provider.class, this, ???? )* // here you'd
> need to specify it is model 2, but how do you get this*
>       }
>        Model giveMeAnObject() {
>            return new Model();
>        }
>    }
> bundle E: consumer imports wiring-api and model 1:
>    class ModelConsumer implements Consumer<Model>, BundleActivator {
>        void start(BundleContext context) {
>            context.register(Consumer.class, this, ???? )* // here you'd
> need to specify it is model 1, but how do you get this**
> *        }*
> *
> 
>        void hereIsAnObject(Model object) {
>            System.out.println(Long.valueOf(model.getDate())); // if no
> object version filtering this will fail as bundle D should not be connected
> to bundle E
>        }
>    }
> 
> // here I envisage there should be a Provider Manager perhaps along the
> lines of that could be exposed to have wiring done through a UI, interface
> or config settings like WireAdmin
> // this isn't too important at this point, except it would need some way to
> manage this *version filtering/matching*!
> bundle F: provider-service imports wiring-api
>    class ProviderManager {
>        Map<ClassVersion, Provider> providers;
>        Map<ClassVersion, Consumer, consumers
>        void registerProvider(ClassVersion<T> provided, Provider<T>
> provider);
>        void registerConsumer(ClassVersion<T> consumed, Consumer<T>
> provider);
> 
>       // methods to lookup and match providers with consumers
>    }


---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@felix.apache.org
For additional commands, e-mail: users-help@felix.apache.org