You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@felix.apache.org by Martin Nielsen <mn...@gmail.com> on 2016/10/06 09:02:40 UTC

Using service interceptors to inject proxies

Hello everyone

I am looking at the felix servicebinding interceptors with a certain amount
of enthusiasm, but i am having trouble figuring out if they can solve a
specific task.

http://felix.apache.org/documentation/subprojects/apache-felix-ipojo/apache-felix-ipojo-userguide/ipojo-advanced-topics/service-binding-interceptors.html

What i would like to do is the following: Whenever a ServiceReference is
requested for an interface (No matter which one), i want an interceptor to
examine it. If the interface meets some criteria, the an interceptor should
create a proxy for that interface, regardless of a matching implementation
being registered.
So: Even if no object is actually registered as a service to that
interface, i want the interceptor to return a proxy anyway. Is that
possible to do in any way?

Thank you in advance.

-Martin

Re: Using service interceptors to inject proxies

Posted by Pierre De Rop <pi...@gmail.com>.
Martin,

So, I don't know what are mybatis mappers, but IIUC, you need to create an
OSGi service for each interface being annotated with a mybatis annotation
(or any other specific annotation, it does not matter), right ?

Then I think that what Raymond explained is that you can use the OSGi
extender model in order to create those services. Simply put, an extender
provides additional functionalities on behalf of some other bundles (see
[1]). In your context, it seems that you need to have an extender which
will create an osgi service when an interface found from a bundle is
annotated with a specific "@Mybatis" annotation (let's assume that, it's
just an exampe) ? am I correct ?

An extender can be implemented using a bundletracker, or using IPOJO or DM.

So, let's try to make an exemple using DM api:

So, with DM, there are two ways to create an extender: you can first create
a dm component which declares a "bundle dependency" in order to track all
other started bundles. The good practice is to track all started bundles
having a specific manifest header (for sake of performance), then if a
bundle is found, the bundle content can then be inspected and, based on the
mybatis annotated class found,  an osgi service can then be registered
using dm api. (even if I'm wrong about mybatis, let's assume that , it's
just to discuss ...).

Another way is to use a DM bundle adapter: a bundle adapter can register an
osgi service on behalf of a given bundle.

I will give an example based on a bundle adapter.

The bundle adapter example will register a "MybatisService" if a bundle
contains the "My-Batis" header. This header indicates the interface
annotated with the @Mybatis annotation (let's assume that, even if it's not
exactly your usecase). So, for each bundle having the "My-Batis" header, an
adapter service will be registered in the osgi registry. It will scan the
interface annotated with @Mybatis, it will then parse the annotation
attributes and will add some service properties to the registered service
(based on the attributes found from the annotation, again, it's just an
example). the service will also dynamically define a service dependency on
"AnotherService" service (why not ...).

Here is the activator, which defines the bundle adapter. The adapter
registers a MybatisService service in the osgi service registry. It will do
this for each started bundle having a "My-Batis" manifest header.

public class Activator extends DependencyActivatorBase {
    public void init(BundleContext ctx, DependencyManager dm) throws
Exception {

        Component adapter =
                dm.createBundleAdapterService(Bundle.ACTIVE,
"(My-Batis=*)", false);
                     .setImplementation(MybatisServiceImpl.class)
                     .setInterface(MybatisService.class.getName(), null);
        dm.add(adapter);

    }
}

Here is the MybatisServiceImpl component:

public interface MybatisService {
   // the methods for the mybatis service ...
}

public class MybatisServiceImpl implements MybatisService {
   volatile Bundle bundle; // auto injected: it is the bundle having a
"My-Batis" header in its manifest
   volatile AnotherService anotherService; // another service dependency,
dynamically declared from init method.

   // DM lifecycel callback where you can add more dynamic dependencies
before the service is
   // started and registered in the registry.
   void init(Component c) {
      // find the interface annotated with @Mybatis
      Annotation annot = LookForMybatisAnnotation(this.bundle);

      // then create the service properties, based on the attributes found
from the @Mybatis annotation
      Properties props =  calculateProperties(annot);
      c.setServiceProperties(props); // dynamically add some service
dependencies

      // dynamically add a service dependency on another service which has
a property "foo" matching       // the "foo" attribute found from the
annotation (why not ...)
      String filter "(foo=" + props.get("foo") + ")";
      DependencyManager dm = c.getDependencyManager();

c.add(dm.createServiceDependency().setService(AnotherService.class.getName(),
filter).setRequired(true));
     }

     void start() {
          // we have been injected with the "AnotherService" service, our
service is now about to be registered ...
      }

      // implements other methods for our MybatisService interface ...
}

this was just an example ... hope it helps.

cheers;
/pierre

[1] http://stackoverflow.com/questions/20106151/service-mode
l-vs-extender-model





On Thu, Oct 6, 2016 at 10:42 PM, Martin Nielsen <mn...@gmail.com> wrote:

> I was not thinking of making AI proxies:)
>
> I tend to think in how i would like things to work at first. The idea of
> having a single point of entry to deliver proxyable interfaces,  for other
> bundles to catch seems very appealing. Take something like mybatis mappers.
> Those are annotated interfaces.  Being able to simply ask osgi for a
> service implementation of such an interface,  with the mybatis bundle
> recognising and catching the interface and returning the mapper would be
> extremely useful.
>
> But what i am trying to do is using the service registry as a pluggable
> proxy factory i guess. It seems to lack that capability:)
>
> On 6 Oct 2016 9:31 p.m., "Raymond Auge" <ra...@liferay.com> wrote:
>
> I think the point of the service registry is not to fool other code into
> working when it really shouldn't. How would you ensure that the
> implementation of such a proxies would be able to fool the clients?
>
> If you could write a proxy generator that could write any proxy such that
> clients simply work I'd like to invest in your tech because I'll be out of
> a job ;)
>
> In fact, I couldn't see any other way to implement proxies as you suggest
> other than to simply block on any call until a real implementation arrives.
> The closest thing I've seen to what you are describing are the blueprint
> proxies which provide service damping, and let me tell you, you don't want
> to go there. At least I would suggest not going there.
>
> I personally think it's far better to expand your code's awareness of the
> dynamics of OSGi services. And there is no, in my humble opinion, more
> concise and simple way to achieve this than by using Declarative Services.
>
> But implementing such an engine (the one which builds your proxied
> services), if at all, certainly lives in the domain of more powerful
> imperative solutions like Felix DM and/or iPojo.
>
> Sincerely,
> - Ray
>
>
> On Thu, Oct 6, 2016 at 3:02 PM, Martin Nielsen <mn...@gmail.com> wrote:
>
> > Hello Pierre and Reymond
> >
> > First of all, thank you very much for taking the time to provide detailed
> > and patient answers.
> >
> > My usecase was to somehow "Cheat" that service registry, so that a bundle
> > getting a service reference (For example via
> > BundleContext.getServiceReferences) would not actually be supplied by a
> > service from the service registry, but rather a proxy i made, which
> fronts
> > the interface in question.
> > So:
> > Bundle A calls
> > BundleContext.getServiceReference(MyAnnotatedInterface.class) <Note that
> > nothing is registered on this interface at the time of the call>
> > Some interceptor logic (The component i am trying to make) registers that
> > the interface is called and, instead of looking in the serviceregistry,
> > creates a proxy which it returns to BundleA
> > Bundle A happily uses the proxy it got back, completely oblivious to the
> > fact that it never got to the service registry.
> > Bundle A calls
> > BundleContext.ungetService(myAnnotatedInterfaceServiceReference), at
> which
> > point the proxy is told to close and dispose.
> >
> > So the point would be that the client bundle is completely oblivious to
> the
> > "hack", and that the solution works without first having to register any
> > service on the MyAnnotatedInterface interface.
> >
> > From the answers i have seen here, it looks like that usage is not
> > possible, as any calls to getServiceReference requires something already
> be
> > registered on that interface. Correct?
> >
> > In that case, it would seem that i would have to actually register
> > MyAnnotatedInterface as a service, and then hot-swap it from there. DM
> > aspects seems like a good place to start, but i can't quite figure out if
> > you can use it without doing something more in the client than just
> > registering the service?
> >
> > Again, thanks for your help, i you will suffer my ignorance for a wee bit
> > longer :)
> >
> > -Martin
> >
> > On Thu, Oct 6, 2016 at 5:29 PM, Pierre De Rop <pi...@gmail.com>
> > wrote:
> >
> > > Hello Martin,
> > >
> > > If you are interested, I can describe here DM aspects, which is a
> feature
> > > that might be interesting in your case.
> > > DM aspects are kind of (non functional) interceptors at the OSGi
> service
> > > level. DM aspects are real components, they can have a lifecycle,
> > > can be started/stopped at anytime, and they can declare service
> > > dependencies, if they need some.
> > >
> > > Basically, you can programatically (or using annotations) define some
> > > aspect services that will be applied to any relevant original services
> > > matching some given service properties. Multiple aspects can be applied
> > to
> > > the same original service and in such case, the aspects are chained
> using
> > > some ranking order.
> > >
> > > Regarding the start ordering, if a client is already bound to a given
> > > original service, then any post-registered aspects will replace the
> > > original service already bound to the client (either the volatile field
> > in
> > > the client pointing to the original service will be updated or a "swap"
> > > callback will be invoked in order to replace the original service with
> > the
> > > new aspects). If you have a start ordering requirement (that is: you
> need
> > > any client to be injected at the first time with the aspects and not
> with
> > > the original service), then as Raymond said you will have to arrange to
> > > register the aspects before the original services.
> > >
> > > Let's take an example using the dm-lambda library (but the original DM
> > api
> > > or the DM annotations also work):
> > >
> > > Assuming you have an original log service with a property
> > "vendor=apache",
> > > and you want to apply a chain of two aspects on that log service (which
> > has
> > > a vendor service property). Let's assume the first aspect is an
> > > "UpperCaseLogService" which rewrites each log message to uppercase, and
> > the
> > > second one: "ErrorLogEventLogService" is an aspect which triggers an
> OSGi
> > > event (using EventAdmin) in case the log is emitted using an ERROR
> level.
> > >
> > > Then you would declare those two aspects like this:
> > >
> > > public class Activator extends DependencyManagerActivator {
> > >     public void init(BundleContext ctx, DependencyManager dm) throws
> > > Exception {
> > >         // Create the first aspect which is applied to any LogService
> > > having a "service=vendor" service property.
> > >         // Notice the "rank(1)" which means this aspect will be the
> first
> > > in the chain
> > >
> > >         aspect(LogService.class, aspect -> aspect
> > >             .impl(UpperCaseLogService.class)
> > >             .filter("(vendor=apache)")
> > >             .rank(1));
> > >
> > >         // Create the second aspect which is applied to any LogService
> > > having a "service=vendor" service property
> > >         // Notice that this aspect has a dependency required on an
> > > EventAdmin service
> > >         // Also notice the "rank(2)" which means this aspect will be
> the
> > > second one in the chain
> > >
> > >         aspect(LogService.class, aspect -> aspect
> > >             .impl(ErrorLogEventLogService.class)
> > >             .filter("(vendor=apache)")
> > >             .rank(2)
> > >             .withSvc(EventAdmin.class, true));
> > >    }
> > > }
> > >
> > > Now the UpperCaseLogService aspect class, which convert all logs to
> upper
> > > case:
> > >
> > > public class UppercaseLogAspect implements LogService{
> > >     private volatile LogService logService; // injected, possibly the
> > > original LogService, or the next aspect in the chain
> > >
> > >     void start() {
> > >         // optional lifecycle start callback: our aspect is starting
> > >     }
> > >
> > >     void stop() {
> > >         // optional lifecycle stop callback: our aspect is stopping
> > >     }
> > >
> > >     public void log(int level, String message) {
> > >         logService.log(level, message.toUpperCase());
> > >         ...
> > >     }
> > > }
> > >
> > > And the ErrorLogEventLogService aspect, which is injected with the
> > original
> > > LogService , as well as with
> > > the EventAdmin service: it will trigger an event in case the log level
> is
> > > LOG_ERROR:
> > >
> > > public class UppercaseLogAspect implements LogService{
> > >     private volatile LogService logService; // injected, possibly the
> > > original LogService, or the next aspect in the chain
> > >     private volatile EventAdmin eventAdmin; // injected, used to
> trigger
> > an
> > > event when the logged message level is in error
> > >
> > >     void start() {
> > >         // optional lifecycle start callback: our aspect is starting
> > >     }
> > >
> > >     public void log(int level, String message) {
> > >         if (level == LogService.LOG_ERROR) {
> > >             // fire an event using the EventAdmin service injected in
> > this
> > > class
> > >         }
> > >         logService.log(level, message.toUpperCase());
> > >     }
> > > }
> > >
> > > So, now, if a client is already injected with a log service, then it
> will
> > > be swapped at the time the aspect chain is registered.
> > > The aspect chain will be injected automatically in the volatile field
> > which
> > > points to the original service, or you can define a swap callback.
> > >
> > > let's take an example, using a volatile field:
> > >
> > > first the client:
> > >
> > > class Client {
> > >    volatile LogService logService; // the original LogService, or the
> > > aspect chain
> > >
> > >    void doLog() {
> > >          logService.log(...);
> > >    }
> > > }
> > >
> > > and the corresponding client activator:
> > >
> > > public class ClientActivator extends DependencyManagerActivator {
> > >
> > >     public void init(BundleContext ctx, DependencyManager dm) throws
> > > Exception {
> > >         component(Client.class, comp -> comp
> > >             .impl(Client.class.class)
> > >             .withSrv(LogService.class, true));
> > >     }
> > >
> > > }
> > >
> > > And if you want the client to define a swap callback, you can then
> define
> > > some the callback like this:
> > >
> > > class Client implements Runnable {
> > >    volatile LogService logService; // the original LogService, or the
> > > aspect chain
> > >
> > >    // bind the required dependency (possibly the original service, or
> an
> > > aspect)
> > >    void set(LogService logService) {
> > >          this.logService = logService;
> > >    }
> > >
> > >    // called if the original service is swapped with an aspect
> > >    void swap(LogService oldLog, LogService newLog) {
> > >        // handle the swapped service
> > >        this.logService = newLog;
> > >    }
> > >
> > >    public void run() {
> > >          logService.log(...);
> > >    }
> > > }
> > >
> > > then here is the ClientActivor, defining the swap callback like this:
> > >
> > >         component(Client.class, comp -> comp
> > >             .impl(Client.class.class)
> > >             .provides(Runnable.class)
> > >             .withSrv(LogService.class, srv ->
> srv.required().add(Client::
> > > set).swap(Client::swap)));
> > >
> > >
> > > here, the initial LogService is first injected using the "set"
> callback,
> > > and if it's the original service, then the swap callback will be
> invoked
> > > if (ever) an aspect has to replace the original bound service.
> > >
> > > finally, you might also take a look at [1]. I never looked at it, but
> > > aspecio seems to be another solution allowing to manage osgi aspect
> > > services.
> > >
> > > Hope this helps;
> > >
> > > cheers;
> > > /Pierre
> > >
> > > [1] http://www.mail-archive.com/users@felix.apache.org/msg17262.html
> > >
> > >
> > > On Thu, Oct 6, 2016 at 4:04 PM, Raymond Auge <raymond.auge@liferay.com
> >
> > > wrote:
> > >
> > > > The problem with the above solution is that you will end up in a race
> > > where
> > > > a service might already be registered without a proxy, then what? So
> > you
> > > > should try to avoid ordering issues in your design otherwise you will
> > > > regret it later.
> > > >
> > > > What really should happen is that the thing creating the service
> should
> > > add
> > > > the proxy around the service before the service is ever published. An
> > > > extender is an ideal place to do this. Felix DM, and IPojo are ideal
> > for
> > > > this use case since they imperative APIs for managing services and
> can
> > be
> > > > "trained" to add proxies based on arbitrary heuristics.
> > > >
> > > > It's a wish I have also for Felix SCR.
> > > >
> > > > Sincerely,
> > > > - Ray
> > > >
> > > > On Thu, Oct 6, 2016 at 6:45 AM, Martin Nielsen <mn...@gmail.com>
> > wrote:
> > > >
> > > > > I think what i wrote might have made more sense in my own head:) I
> > > > > apologize for the lousy problem description.
> > > > > Maybe an actual use case would help:
> > > > >
> > > > > I would like to use the OSGi serviceregistry to proxy specific
> > > > interfaces.
> > > > > For example:
> > > > > Say that i attempt to get a serviceReference for an interface with
> a
> > > > > mybatis annotation on it. What i would like is that the service
> > > registry
> > > > > returns a proxy that i define (My idea was through something like a
> > > > > ServiceBindingInterceptor). The proxy should then be closed down
> > again
> > > > when
> > > > > get unget method is called on the service.
> > > > >
> > > > > Basically, i would like to supply a proxy implementation of
> > interfaces
> > > in
> > > > > certain situations, but still allow for the serviceregistry
> lifecycle
> > > > > (get/unget) to handle opening and closing the proxies.
> > > > >
> > > > > It doesn't have to use any specific part of the runtime, i just
> > spotted
> > > > the
> > > > > interceptors and mistook their purpose a bit i think.
> > > > >
> > > > > On Thu, Oct 6, 2016 at 12:32 PM, Clement Escoffier <
> > > > > clement.escoffier@gmail.com> wrote:
> > > > >
> > > > > > Hi,
> > > > > >
> > > > > > The service binding interceptor requires to have a “service”
> > > available.
> > > > > > You should be able to do what you want by either:
> > > > > >
> > > > > > - combining a “default-implementation” strategy and a binding
> > > > interceptor
> > > > > > (it would require to have the dependency marked as optional)
> > > > > > - or create your own handler that inject what you want to inject
> (
> > > > > > http://felix.apache.org/documentation/subprojects/
> > > > > > apache-felix-ipojo/apache-felix-ipojo-devguide/how-to-
> > > > > > write-your-own-handler.html <http://felix.apache.org/
> > > > > > documentation/subprojects/apache-felix-ipojo/apache-
> > > > > > felix-ipojo-devguide/how-to-write-your-own-handler.html>)
> > > > > >
> > > > > > Clement
> > > > > >
> > > > > >
> > > > > > > On 6 oct. 2016, at 04:02, Martin Nielsen <mn...@gmail.com>
> > wrote:
> > > > > > >
> > > > > > > Hello everyone
> > > > > > >
> > > > > > > I am looking at the felix servicebinding interceptors with a
> > > certain
> > > > > > amount
> > > > > > > of enthusiasm, but i am having trouble figuring out if they can
> > > > solve a
> > > > > > > specific task.
> > > > > > >
> > > > > > > http://felix.apache.org/documentation/subprojects/
> > > > > > apache-felix-ipojo/apache-felix-ipojo-userguide/ipojo-
> > > > > > advanced-topics/service-binding-interceptors.html
> > > > > > >
> > > > > > > What i would like to do is the following: Whenever a
> > > ServiceReference
> > > > > is
> > > > > > > requested for an interface (No matter which one), i want an
> > > > interceptor
> > > > > > to
> > > > > > > examine it. If the interface meets some criteria, the an
> > > interceptor
> > > > > > should
> > > > > > > create a proxy for that interface, regardless of a matching
> > > > > > implementation
> > > > > > > being registered.
> > > > > > > So: Even if no object is actually registered as a service to
> that
> > > > > > > interface, i want the interceptor to return a proxy anyway. Is
> > that
> > > > > > > possible to do in any way?
> > > > > > >
> > > > > > > Thank you in advance.
> > > > > > >
> > > > > > > -Martin
> > > > > >
> > > > > >
> > > > >
> > > >
> > > >
> > > >
> > > > --
> > > > *Raymond Augé* <http://www.liferay.com/web/raymond.auge/profile>
> > > >  (@rotty3000)
> > > > Senior Software Architect *Liferay, Inc.* <http://www.liferay.com>
> > > >  (@Liferay)
> > > > Board Member & EEG Co-Chair, OSGi Alliance <http://osgi.org>
> > > > (@OSGiAlliance)
> > > >
> > >
> >
>
>
>
> --
> *Raymond Augé* <http://www.liferay.com/web/raymond.auge/profile>
>  (@rotty3000)
> Senior Software Architect *Liferay, Inc.* <http://www.liferay.com>
>  (@Liferay)
> Board Member & EEG Co-Chair, OSGi Alliance <http://osgi.org>
> (@OSGiAlliance)
>

Re: Using service interceptors to inject proxies

Posted by Martin Nielsen <mn...@gmail.com>.
I was not thinking of making AI proxies:)

I tend to think in how i would like things to work at first. The idea of
having a single point of entry to deliver proxyable interfaces,  for other
bundles to catch seems very appealing. Take something like mybatis mappers.
Those are annotated interfaces.  Being able to simply ask osgi for a
service implementation of such an interface,  with the mybatis bundle
recognising and catching the interface and returning the mapper would be
extremely useful.

But what i am trying to do is using the service registry as a pluggable
proxy factory i guess. It seems to lack that capability:)

On 6 Oct 2016 9:31 p.m., "Raymond Auge" <ra...@liferay.com> wrote:

I think the point of the service registry is not to fool other code into
working when it really shouldn't. How would you ensure that the
implementation of such a proxies would be able to fool the clients?

If you could write a proxy generator that could write any proxy such that
clients simply work I'd like to invest in your tech because I'll be out of
a job ;)

In fact, I couldn't see any other way to implement proxies as you suggest
other than to simply block on any call until a real implementation arrives.
The closest thing I've seen to what you are describing are the blueprint
proxies which provide service damping, and let me tell you, you don't want
to go there. At least I would suggest not going there.

I personally think it's far better to expand your code's awareness of the
dynamics of OSGi services. And there is no, in my humble opinion, more
concise and simple way to achieve this than by using Declarative Services.

But implementing such an engine (the one which builds your proxied
services), if at all, certainly lives in the domain of more powerful
imperative solutions like Felix DM and/or iPojo.

Sincerely,
- Ray


On Thu, Oct 6, 2016 at 3:02 PM, Martin Nielsen <mn...@gmail.com> wrote:

> Hello Pierre and Reymond
>
> First of all, thank you very much for taking the time to provide detailed
> and patient answers.
>
> My usecase was to somehow "Cheat" that service registry, so that a bundle
> getting a service reference (For example via
> BundleContext.getServiceReferences) would not actually be supplied by a
> service from the service registry, but rather a proxy i made, which fronts
> the interface in question.
> So:
> Bundle A calls
> BundleContext.getServiceReference(MyAnnotatedInterface.class) <Note that
> nothing is registered on this interface at the time of the call>
> Some interceptor logic (The component i am trying to make) registers that
> the interface is called and, instead of looking in the serviceregistry,
> creates a proxy which it returns to BundleA
> Bundle A happily uses the proxy it got back, completely oblivious to the
> fact that it never got to the service registry.
> Bundle A calls
> BundleContext.ungetService(myAnnotatedInterfaceServiceReference), at which
> point the proxy is told to close and dispose.
>
> So the point would be that the client bundle is completely oblivious to
the
> "hack", and that the solution works without first having to register any
> service on the MyAnnotatedInterface interface.
>
> From the answers i have seen here, it looks like that usage is not
> possible, as any calls to getServiceReference requires something already
be
> registered on that interface. Correct?
>
> In that case, it would seem that i would have to actually register
> MyAnnotatedInterface as a service, and then hot-swap it from there. DM
> aspects seems like a good place to start, but i can't quite figure out if
> you can use it without doing something more in the client than just
> registering the service?
>
> Again, thanks for your help, i you will suffer my ignorance for a wee bit
> longer :)
>
> -Martin
>
> On Thu, Oct 6, 2016 at 5:29 PM, Pierre De Rop <pi...@gmail.com>
> wrote:
>
> > Hello Martin,
> >
> > If you are interested, I can describe here DM aspects, which is a
feature
> > that might be interesting in your case.
> > DM aspects are kind of (non functional) interceptors at the OSGi service
> > level. DM aspects are real components, they can have a lifecycle,
> > can be started/stopped at anytime, and they can declare service
> > dependencies, if they need some.
> >
> > Basically, you can programatically (or using annotations) define some
> > aspect services that will be applied to any relevant original services
> > matching some given service properties. Multiple aspects can be applied
> to
> > the same original service and in such case, the aspects are chained
using
> > some ranking order.
> >
> > Regarding the start ordering, if a client is already bound to a given
> > original service, then any post-registered aspects will replace the
> > original service already bound to the client (either the volatile field
> in
> > the client pointing to the original service will be updated or a "swap"
> > callback will be invoked in order to replace the original service with
> the
> > new aspects). If you have a start ordering requirement (that is: you
need
> > any client to be injected at the first time with the aspects and not
with
> > the original service), then as Raymond said you will have to arrange to
> > register the aspects before the original services.
> >
> > Let's take an example using the dm-lambda library (but the original DM
> api
> > or the DM annotations also work):
> >
> > Assuming you have an original log service with a property
> "vendor=apache",
> > and you want to apply a chain of two aspects on that log service (which
> has
> > a vendor service property). Let's assume the first aspect is an
> > "UpperCaseLogService" which rewrites each log message to uppercase, and
> the
> > second one: "ErrorLogEventLogService" is an aspect which triggers an
OSGi
> > event (using EventAdmin) in case the log is emitted using an ERROR
level.
> >
> > Then you would declare those two aspects like this:
> >
> > public class Activator extends DependencyManagerActivator {
> >     public void init(BundleContext ctx, DependencyManager dm) throws
> > Exception {
> >         // Create the first aspect which is applied to any LogService
> > having a "service=vendor" service property.
> >         // Notice the "rank(1)" which means this aspect will be the
first
> > in the chain
> >
> >         aspect(LogService.class, aspect -> aspect
> >             .impl(UpperCaseLogService.class)
> >             .filter("(vendor=apache)")
> >             .rank(1));
> >
> >         // Create the second aspect which is applied to any LogService
> > having a "service=vendor" service property
> >         // Notice that this aspect has a dependency required on an
> > EventAdmin service
> >         // Also notice the "rank(2)" which means this aspect will be the
> > second one in the chain
> >
> >         aspect(LogService.class, aspect -> aspect
> >             .impl(ErrorLogEventLogService.class)
> >             .filter("(vendor=apache)")
> >             .rank(2)
> >             .withSvc(EventAdmin.class, true));
> >    }
> > }
> >
> > Now the UpperCaseLogService aspect class, which convert all logs to
upper
> > case:
> >
> > public class UppercaseLogAspect implements LogService{
> >     private volatile LogService logService; // injected, possibly the
> > original LogService, or the next aspect in the chain
> >
> >     void start() {
> >         // optional lifecycle start callback: our aspect is starting
> >     }
> >
> >     void stop() {
> >         // optional lifecycle stop callback: our aspect is stopping
> >     }
> >
> >     public void log(int level, String message) {
> >         logService.log(level, message.toUpperCase());
> >         ...
> >     }
> > }
> >
> > And the ErrorLogEventLogService aspect, which is injected with the
> original
> > LogService , as well as with
> > the EventAdmin service: it will trigger an event in case the log level
is
> > LOG_ERROR:
> >
> > public class UppercaseLogAspect implements LogService{
> >     private volatile LogService logService; // injected, possibly the
> > original LogService, or the next aspect in the chain
> >     private volatile EventAdmin eventAdmin; // injected, used to trigger
> an
> > event when the logged message level is in error
> >
> >     void start() {
> >         // optional lifecycle start callback: our aspect is starting
> >     }
> >
> >     public void log(int level, String message) {
> >         if (level == LogService.LOG_ERROR) {
> >             // fire an event using the EventAdmin service injected in
> this
> > class
> >         }
> >         logService.log(level, message.toUpperCase());
> >     }
> > }
> >
> > So, now, if a client is already injected with a log service, then it
will
> > be swapped at the time the aspect chain is registered.
> > The aspect chain will be injected automatically in the volatile field
> which
> > points to the original service, or you can define a swap callback.
> >
> > let's take an example, using a volatile field:
> >
> > first the client:
> >
> > class Client {
> >    volatile LogService logService; // the original LogService, or the
> > aspect chain
> >
> >    void doLog() {
> >          logService.log(...);
> >    }
> > }
> >
> > and the corresponding client activator:
> >
> > public class ClientActivator extends DependencyManagerActivator {
> >
> >     public void init(BundleContext ctx, DependencyManager dm) throws
> > Exception {
> >         component(Client.class, comp -> comp
> >             .impl(Client.class.class)
> >             .withSrv(LogService.class, true));
> >     }
> >
> > }
> >
> > And if you want the client to define a swap callback, you can then
define
> > some the callback like this:
> >
> > class Client implements Runnable {
> >    volatile LogService logService; // the original LogService, or the
> > aspect chain
> >
> >    // bind the required dependency (possibly the original service, or an
> > aspect)
> >    void set(LogService logService) {
> >          this.logService = logService;
> >    }
> >
> >    // called if the original service is swapped with an aspect
> >    void swap(LogService oldLog, LogService newLog) {
> >        // handle the swapped service
> >        this.logService = newLog;
> >    }
> >
> >    public void run() {
> >          logService.log(...);
> >    }
> > }
> >
> > then here is the ClientActivor, defining the swap callback like this:
> >
> >         component(Client.class, comp -> comp
> >             .impl(Client.class.class)
> >             .provides(Runnable.class)
> >             .withSrv(LogService.class, srv ->
srv.required().add(Client::
> > set).swap(Client::swap)));
> >
> >
> > here, the initial LogService is first injected using the "set" callback,
> > and if it's the original service, then the swap callback will be invoked
> > if (ever) an aspect has to replace the original bound service.
> >
> > finally, you might also take a look at [1]. I never looked at it, but
> > aspecio seems to be another solution allowing to manage osgi aspect
> > services.
> >
> > Hope this helps;
> >
> > cheers;
> > /Pierre
> >
> > [1] http://www.mail-archive.com/users@felix.apache.org/msg17262.html
> >
> >
> > On Thu, Oct 6, 2016 at 4:04 PM, Raymond Auge <ra...@liferay.com>
> > wrote:
> >
> > > The problem with the above solution is that you will end up in a race
> > where
> > > a service might already be registered without a proxy, then what? So
> you
> > > should try to avoid ordering issues in your design otherwise you will
> > > regret it later.
> > >
> > > What really should happen is that the thing creating the service
should
> > add
> > > the proxy around the service before the service is ever published. An
> > > extender is an ideal place to do this. Felix DM, and IPojo are ideal
> for
> > > this use case since they imperative APIs for managing services and can
> be
> > > "trained" to add proxies based on arbitrary heuristics.
> > >
> > > It's a wish I have also for Felix SCR.
> > >
> > > Sincerely,
> > > - Ray
> > >
> > > On Thu, Oct 6, 2016 at 6:45 AM, Martin Nielsen <mn...@gmail.com>
> wrote:
> > >
> > > > I think what i wrote might have made more sense in my own head:) I
> > > > apologize for the lousy problem description.
> > > > Maybe an actual use case would help:
> > > >
> > > > I would like to use the OSGi serviceregistry to proxy specific
> > > interfaces.
> > > > For example:
> > > > Say that i attempt to get a serviceReference for an interface with a
> > > > mybatis annotation on it. What i would like is that the service
> > registry
> > > > returns a proxy that i define (My idea was through something like a
> > > > ServiceBindingInterceptor). The proxy should then be closed down
> again
> > > when
> > > > get unget method is called on the service.
> > > >
> > > > Basically, i would like to supply a proxy implementation of
> interfaces
> > in
> > > > certain situations, but still allow for the serviceregistry
lifecycle
> > > > (get/unget) to handle opening and closing the proxies.
> > > >
> > > > It doesn't have to use any specific part of the runtime, i just
> spotted
> > > the
> > > > interceptors and mistook their purpose a bit i think.
> > > >
> > > > On Thu, Oct 6, 2016 at 12:32 PM, Clement Escoffier <
> > > > clement.escoffier@gmail.com> wrote:
> > > >
> > > > > Hi,
> > > > >
> > > > > The service binding interceptor requires to have a “service”
> > available.
> > > > > You should be able to do what you want by either:
> > > > >
> > > > > - combining a “default-implementation” strategy and a binding
> > > interceptor
> > > > > (it would require to have the dependency marked as optional)
> > > > > - or create your own handler that inject what you want to inject (
> > > > > http://felix.apache.org/documentation/subprojects/
> > > > > apache-felix-ipojo/apache-felix-ipojo-devguide/how-to-
> > > > > write-your-own-handler.html <http://felix.apache.org/
> > > > > documentation/subprojects/apache-felix-ipojo/apache-
> > > > > felix-ipojo-devguide/how-to-write-your-own-handler.html>)
> > > > >
> > > > > Clement
> > > > >
> > > > >
> > > > > > On 6 oct. 2016, at 04:02, Martin Nielsen <mn...@gmail.com>
> wrote:
> > > > > >
> > > > > > Hello everyone
> > > > > >
> > > > > > I am looking at the felix servicebinding interceptors with a
> > certain
> > > > > amount
> > > > > > of enthusiasm, but i am having trouble figuring out if they can
> > > solve a
> > > > > > specific task.
> > > > > >
> > > > > > http://felix.apache.org/documentation/subprojects/
> > > > > apache-felix-ipojo/apache-felix-ipojo-userguide/ipojo-
> > > > > advanced-topics/service-binding-interceptors.html
> > > > > >
> > > > > > What i would like to do is the following: Whenever a
> > ServiceReference
> > > > is
> > > > > > requested for an interface (No matter which one), i want an
> > > interceptor
> > > > > to
> > > > > > examine it. If the interface meets some criteria, the an
> > interceptor
> > > > > should
> > > > > > create a proxy for that interface, regardless of a matching
> > > > > implementation
> > > > > > being registered.
> > > > > > So: Even if no object is actually registered as a service to
that
> > > > > > interface, i want the interceptor to return a proxy anyway. Is
> that
> > > > > > possible to do in any way?
> > > > > >
> > > > > > Thank you in advance.
> > > > > >
> > > > > > -Martin
> > > > >
> > > > >
> > > >
> > >
> > >
> > >
> > > --
> > > *Raymond Augé* <http://www.liferay.com/web/raymond.auge/profile>
> > >  (@rotty3000)
> > > Senior Software Architect *Liferay, Inc.* <http://www.liferay.com>
> > >  (@Liferay)
> > > Board Member & EEG Co-Chair, OSGi Alliance <http://osgi.org>
> > > (@OSGiAlliance)
> > >
> >
>



--
*Raymond Augé* <http://www.liferay.com/web/raymond.auge/profile>
 (@rotty3000)
Senior Software Architect *Liferay, Inc.* <http://www.liferay.com>
 (@Liferay)
Board Member & EEG Co-Chair, OSGi Alliance <http://osgi.org> (@OSGiAlliance)

Re: Using service interceptors to inject proxies

Posted by Raymond Auge <ra...@liferay.com>.
I think the point of the service registry is not to fool other code into
working when it really shouldn't. How would you ensure that the
implementation of such a proxies would be able to fool the clients?

If you could write a proxy generator that could write any proxy such that
clients simply work I'd like to invest in your tech because I'll be out of
a job ;)

In fact, I couldn't see any other way to implement proxies as you suggest
other than to simply block on any call until a real implementation arrives.
The closest thing I've seen to what you are describing are the blueprint
proxies which provide service damping, and let me tell you, you don't want
to go there. At least I would suggest not going there.

I personally think it's far better to expand your code's awareness of the
dynamics of OSGi services. And there is no, in my humble opinion, more
concise and simple way to achieve this than by using Declarative Services.

But implementing such an engine (the one which builds your proxied
services), if at all, certainly lives in the domain of more powerful
imperative solutions like Felix DM and/or iPojo.

Sincerely,
- Ray


On Thu, Oct 6, 2016 at 3:02 PM, Martin Nielsen <mn...@gmail.com> wrote:

> Hello Pierre and Reymond
>
> First of all, thank you very much for taking the time to provide detailed
> and patient answers.
>
> My usecase was to somehow "Cheat" that service registry, so that a bundle
> getting a service reference (For example via
> BundleContext.getServiceReferences) would not actually be supplied by a
> service from the service registry, but rather a proxy i made, which fronts
> the interface in question.
> So:
> Bundle A calls
> BundleContext.getServiceReference(MyAnnotatedInterface.class) <Note that
> nothing is registered on this interface at the time of the call>
> Some interceptor logic (The component i am trying to make) registers that
> the interface is called and, instead of looking in the serviceregistry,
> creates a proxy which it returns to BundleA
> Bundle A happily uses the proxy it got back, completely oblivious to the
> fact that it never got to the service registry.
> Bundle A calls
> BundleContext.ungetService(myAnnotatedInterfaceServiceReference), at which
> point the proxy is told to close and dispose.
>
> So the point would be that the client bundle is completely oblivious to the
> "hack", and that the solution works without first having to register any
> service on the MyAnnotatedInterface interface.
>
> From the answers i have seen here, it looks like that usage is not
> possible, as any calls to getServiceReference requires something already be
> registered on that interface. Correct?
>
> In that case, it would seem that i would have to actually register
> MyAnnotatedInterface as a service, and then hot-swap it from there. DM
> aspects seems like a good place to start, but i can't quite figure out if
> you can use it without doing something more in the client than just
> registering the service?
>
> Again, thanks for your help, i you will suffer my ignorance for a wee bit
> longer :)
>
> -Martin
>
> On Thu, Oct 6, 2016 at 5:29 PM, Pierre De Rop <pi...@gmail.com>
> wrote:
>
> > Hello Martin,
> >
> > If you are interested, I can describe here DM aspects, which is a feature
> > that might be interesting in your case.
> > DM aspects are kind of (non functional) interceptors at the OSGi service
> > level. DM aspects are real components, they can have a lifecycle,
> > can be started/stopped at anytime, and they can declare service
> > dependencies, if they need some.
> >
> > Basically, you can programatically (or using annotations) define some
> > aspect services that will be applied to any relevant original services
> > matching some given service properties. Multiple aspects can be applied
> to
> > the same original service and in such case, the aspects are chained using
> > some ranking order.
> >
> > Regarding the start ordering, if a client is already bound to a given
> > original service, then any post-registered aspects will replace the
> > original service already bound to the client (either the volatile field
> in
> > the client pointing to the original service will be updated or a "swap"
> > callback will be invoked in order to replace the original service with
> the
> > new aspects). If you have a start ordering requirement (that is: you need
> > any client to be injected at the first time with the aspects and not with
> > the original service), then as Raymond said you will have to arrange to
> > register the aspects before the original services.
> >
> > Let's take an example using the dm-lambda library (but the original DM
> api
> > or the DM annotations also work):
> >
> > Assuming you have an original log service with a property
> "vendor=apache",
> > and you want to apply a chain of two aspects on that log service (which
> has
> > a vendor service property). Let's assume the first aspect is an
> > "UpperCaseLogService" which rewrites each log message to uppercase, and
> the
> > second one: "ErrorLogEventLogService" is an aspect which triggers an OSGi
> > event (using EventAdmin) in case the log is emitted using an ERROR level.
> >
> > Then you would declare those two aspects like this:
> >
> > public class Activator extends DependencyManagerActivator {
> >     public void init(BundleContext ctx, DependencyManager dm) throws
> > Exception {
> >         // Create the first aspect which is applied to any LogService
> > having a "service=vendor" service property.
> >         // Notice the "rank(1)" which means this aspect will be the first
> > in the chain
> >
> >         aspect(LogService.class, aspect -> aspect
> >             .impl(UpperCaseLogService.class)
> >             .filter("(vendor=apache)")
> >             .rank(1));
> >
> >         // Create the second aspect which is applied to any LogService
> > having a "service=vendor" service property
> >         // Notice that this aspect has a dependency required on an
> > EventAdmin service
> >         // Also notice the "rank(2)" which means this aspect will be the
> > second one in the chain
> >
> >         aspect(LogService.class, aspect -> aspect
> >             .impl(ErrorLogEventLogService.class)
> >             .filter("(vendor=apache)")
> >             .rank(2)
> >             .withSvc(EventAdmin.class, true));
> >    }
> > }
> >
> > Now the UpperCaseLogService aspect class, which convert all logs to upper
> > case:
> >
> > public class UppercaseLogAspect implements LogService{
> >     private volatile LogService logService; // injected, possibly the
> > original LogService, or the next aspect in the chain
> >
> >     void start() {
> >         // optional lifecycle start callback: our aspect is starting
> >     }
> >
> >     void stop() {
> >         // optional lifecycle stop callback: our aspect is stopping
> >     }
> >
> >     public void log(int level, String message) {
> >         logService.log(level, message.toUpperCase());
> >         ...
> >     }
> > }
> >
> > And the ErrorLogEventLogService aspect, which is injected with the
> original
> > LogService , as well as with
> > the EventAdmin service: it will trigger an event in case the log level is
> > LOG_ERROR:
> >
> > public class UppercaseLogAspect implements LogService{
> >     private volatile LogService logService; // injected, possibly the
> > original LogService, or the next aspect in the chain
> >     private volatile EventAdmin eventAdmin; // injected, used to trigger
> an
> > event when the logged message level is in error
> >
> >     void start() {
> >         // optional lifecycle start callback: our aspect is starting
> >     }
> >
> >     public void log(int level, String message) {
> >         if (level == LogService.LOG_ERROR) {
> >             // fire an event using the EventAdmin service injected in
> this
> > class
> >         }
> >         logService.log(level, message.toUpperCase());
> >     }
> > }
> >
> > So, now, if a client is already injected with a log service, then it will
> > be swapped at the time the aspect chain is registered.
> > The aspect chain will be injected automatically in the volatile field
> which
> > points to the original service, or you can define a swap callback.
> >
> > let's take an example, using a volatile field:
> >
> > first the client:
> >
> > class Client {
> >    volatile LogService logService; // the original LogService, or the
> > aspect chain
> >
> >    void doLog() {
> >          logService.log(...);
> >    }
> > }
> >
> > and the corresponding client activator:
> >
> > public class ClientActivator extends DependencyManagerActivator {
> >
> >     public void init(BundleContext ctx, DependencyManager dm) throws
> > Exception {
> >         component(Client.class, comp -> comp
> >             .impl(Client.class.class)
> >             .withSrv(LogService.class, true));
> >     }
> >
> > }
> >
> > And if you want the client to define a swap callback, you can then define
> > some the callback like this:
> >
> > class Client implements Runnable {
> >    volatile LogService logService; // the original LogService, or the
> > aspect chain
> >
> >    // bind the required dependency (possibly the original service, or an
> > aspect)
> >    void set(LogService logService) {
> >          this.logService = logService;
> >    }
> >
> >    // called if the original service is swapped with an aspect
> >    void swap(LogService oldLog, LogService newLog) {
> >        // handle the swapped service
> >        this.logService = newLog;
> >    }
> >
> >    public void run() {
> >          logService.log(...);
> >    }
> > }
> >
> > then here is the ClientActivor, defining the swap callback like this:
> >
> >         component(Client.class, comp -> comp
> >             .impl(Client.class.class)
> >             .provides(Runnable.class)
> >             .withSrv(LogService.class, srv -> srv.required().add(Client::
> > set).swap(Client::swap)));
> >
> >
> > here, the initial LogService is first injected using the "set" callback,
> > and if it's the original service, then the swap callback will be invoked
> > if (ever) an aspect has to replace the original bound service.
> >
> > finally, you might also take a look at [1]. I never looked at it, but
> > aspecio seems to be another solution allowing to manage osgi aspect
> > services.
> >
> > Hope this helps;
> >
> > cheers;
> > /Pierre
> >
> > [1] http://www.mail-archive.com/users@felix.apache.org/msg17262.html
> >
> >
> > On Thu, Oct 6, 2016 at 4:04 PM, Raymond Auge <ra...@liferay.com>
> > wrote:
> >
> > > The problem with the above solution is that you will end up in a race
> > where
> > > a service might already be registered without a proxy, then what? So
> you
> > > should try to avoid ordering issues in your design otherwise you will
> > > regret it later.
> > >
> > > What really should happen is that the thing creating the service should
> > add
> > > the proxy around the service before the service is ever published. An
> > > extender is an ideal place to do this. Felix DM, and IPojo are ideal
> for
> > > this use case since they imperative APIs for managing services and can
> be
> > > "trained" to add proxies based on arbitrary heuristics.
> > >
> > > It's a wish I have also for Felix SCR.
> > >
> > > Sincerely,
> > > - Ray
> > >
> > > On Thu, Oct 6, 2016 at 6:45 AM, Martin Nielsen <mn...@gmail.com>
> wrote:
> > >
> > > > I think what i wrote might have made more sense in my own head:) I
> > > > apologize for the lousy problem description.
> > > > Maybe an actual use case would help:
> > > >
> > > > I would like to use the OSGi serviceregistry to proxy specific
> > > interfaces.
> > > > For example:
> > > > Say that i attempt to get a serviceReference for an interface with a
> > > > mybatis annotation on it. What i would like is that the service
> > registry
> > > > returns a proxy that i define (My idea was through something like a
> > > > ServiceBindingInterceptor). The proxy should then be closed down
> again
> > > when
> > > > get unget method is called on the service.
> > > >
> > > > Basically, i would like to supply a proxy implementation of
> interfaces
> > in
> > > > certain situations, but still allow for the serviceregistry lifecycle
> > > > (get/unget) to handle opening and closing the proxies.
> > > >
> > > > It doesn't have to use any specific part of the runtime, i just
> spotted
> > > the
> > > > interceptors and mistook their purpose a bit i think.
> > > >
> > > > On Thu, Oct 6, 2016 at 12:32 PM, Clement Escoffier <
> > > > clement.escoffier@gmail.com> wrote:
> > > >
> > > > > Hi,
> > > > >
> > > > > The service binding interceptor requires to have a “service”
> > available.
> > > > > You should be able to do what you want by either:
> > > > >
> > > > > - combining a “default-implementation” strategy and a binding
> > > interceptor
> > > > > (it would require to have the dependency marked as optional)
> > > > > - or create your own handler that inject what you want to inject (
> > > > > http://felix.apache.org/documentation/subprojects/
> > > > > apache-felix-ipojo/apache-felix-ipojo-devguide/how-to-
> > > > > write-your-own-handler.html <http://felix.apache.org/
> > > > > documentation/subprojects/apache-felix-ipojo/apache-
> > > > > felix-ipojo-devguide/how-to-write-your-own-handler.html>)
> > > > >
> > > > > Clement
> > > > >
> > > > >
> > > > > > On 6 oct. 2016, at 04:02, Martin Nielsen <mn...@gmail.com>
> wrote:
> > > > > >
> > > > > > Hello everyone
> > > > > >
> > > > > > I am looking at the felix servicebinding interceptors with a
> > certain
> > > > > amount
> > > > > > of enthusiasm, but i am having trouble figuring out if they can
> > > solve a
> > > > > > specific task.
> > > > > >
> > > > > > http://felix.apache.org/documentation/subprojects/
> > > > > apache-felix-ipojo/apache-felix-ipojo-userguide/ipojo-
> > > > > advanced-topics/service-binding-interceptors.html
> > > > > >
> > > > > > What i would like to do is the following: Whenever a
> > ServiceReference
> > > > is
> > > > > > requested for an interface (No matter which one), i want an
> > > interceptor
> > > > > to
> > > > > > examine it. If the interface meets some criteria, the an
> > interceptor
> > > > > should
> > > > > > create a proxy for that interface, regardless of a matching
> > > > > implementation
> > > > > > being registered.
> > > > > > So: Even if no object is actually registered as a service to that
> > > > > > interface, i want the interceptor to return a proxy anyway. Is
> that
> > > > > > possible to do in any way?
> > > > > >
> > > > > > Thank you in advance.
> > > > > >
> > > > > > -Martin
> > > > >
> > > > >
> > > >
> > >
> > >
> > >
> > > --
> > > *Raymond Augé* <http://www.liferay.com/web/raymond.auge/profile>
> > >  (@rotty3000)
> > > Senior Software Architect *Liferay, Inc.* <http://www.liferay.com>
> > >  (@Liferay)
> > > Board Member & EEG Co-Chair, OSGi Alliance <http://osgi.org>
> > > (@OSGiAlliance)
> > >
> >
>



-- 
*Raymond Augé* <http://www.liferay.com/web/raymond.auge/profile>
 (@rotty3000)
Senior Software Architect *Liferay, Inc.* <http://www.liferay.com>
 (@Liferay)
Board Member & EEG Co-Chair, OSGi Alliance <http://osgi.org> (@OSGiAlliance)

Re: Using service interceptors to inject proxies

Posted by Martin Nielsen <mn...@gmail.com>.
Hello Pierre and Reymond

First of all, thank you very much for taking the time to provide detailed
and patient answers.

My usecase was to somehow "Cheat" that service registry, so that a bundle
getting a service reference (For example via
BundleContext.getServiceReferences) would not actually be supplied by a
service from the service registry, but rather a proxy i made, which fronts
the interface in question.
So:
Bundle A calls
BundleContext.getServiceReference(MyAnnotatedInterface.class) <Note that
nothing is registered on this interface at the time of the call>
Some interceptor logic (The component i am trying to make) registers that
the interface is called and, instead of looking in the serviceregistry,
creates a proxy which it returns to BundleA
Bundle A happily uses the proxy it got back, completely oblivious to the
fact that it never got to the service registry.
Bundle A calls
BundleContext.ungetService(myAnnotatedInterfaceServiceReference), at which
point the proxy is told to close and dispose.

So the point would be that the client bundle is completely oblivious to the
"hack", and that the solution works without first having to register any
service on the MyAnnotatedInterface interface.

From the answers i have seen here, it looks like that usage is not
possible, as any calls to getServiceReference requires something already be
registered on that interface. Correct?

In that case, it would seem that i would have to actually register
MyAnnotatedInterface as a service, and then hot-swap it from there. DM
aspects seems like a good place to start, but i can't quite figure out if
you can use it without doing something more in the client than just
registering the service?

Again, thanks for your help, i you will suffer my ignorance for a wee bit
longer :)

-Martin

On Thu, Oct 6, 2016 at 5:29 PM, Pierre De Rop <pi...@gmail.com>
wrote:

> Hello Martin,
>
> If you are interested, I can describe here DM aspects, which is a feature
> that might be interesting in your case.
> DM aspects are kind of (non functional) interceptors at the OSGi service
> level. DM aspects are real components, they can have a lifecycle,
> can be started/stopped at anytime, and they can declare service
> dependencies, if they need some.
>
> Basically, you can programatically (or using annotations) define some
> aspect services that will be applied to any relevant original services
> matching some given service properties. Multiple aspects can be applied to
> the same original service and in such case, the aspects are chained using
> some ranking order.
>
> Regarding the start ordering, if a client is already bound to a given
> original service, then any post-registered aspects will replace the
> original service already bound to the client (either the volatile field in
> the client pointing to the original service will be updated or a "swap"
> callback will be invoked in order to replace the original service with the
> new aspects). If you have a start ordering requirement (that is: you need
> any client to be injected at the first time with the aspects and not with
> the original service), then as Raymond said you will have to arrange to
> register the aspects before the original services.
>
> Let's take an example using the dm-lambda library (but the original DM api
> or the DM annotations also work):
>
> Assuming you have an original log service with a property "vendor=apache",
> and you want to apply a chain of two aspects on that log service (which has
> a vendor service property). Let's assume the first aspect is an
> "UpperCaseLogService" which rewrites each log message to uppercase, and the
> second one: "ErrorLogEventLogService" is an aspect which triggers an OSGi
> event (using EventAdmin) in case the log is emitted using an ERROR level.
>
> Then you would declare those two aspects like this:
>
> public class Activator extends DependencyManagerActivator {
>     public void init(BundleContext ctx, DependencyManager dm) throws
> Exception {
>         // Create the first aspect which is applied to any LogService
> having a "service=vendor" service property.
>         // Notice the "rank(1)" which means this aspect will be the first
> in the chain
>
>         aspect(LogService.class, aspect -> aspect
>             .impl(UpperCaseLogService.class)
>             .filter("(vendor=apache)")
>             .rank(1));
>
>         // Create the second aspect which is applied to any LogService
> having a "service=vendor" service property
>         // Notice that this aspect has a dependency required on an
> EventAdmin service
>         // Also notice the "rank(2)" which means this aspect will be the
> second one in the chain
>
>         aspect(LogService.class, aspect -> aspect
>             .impl(ErrorLogEventLogService.class)
>             .filter("(vendor=apache)")
>             .rank(2)
>             .withSvc(EventAdmin.class, true));
>    }
> }
>
> Now the UpperCaseLogService aspect class, which convert all logs to upper
> case:
>
> public class UppercaseLogAspect implements LogService{
>     private volatile LogService logService; // injected, possibly the
> original LogService, or the next aspect in the chain
>
>     void start() {
>         // optional lifecycle start callback: our aspect is starting
>     }
>
>     void stop() {
>         // optional lifecycle stop callback: our aspect is stopping
>     }
>
>     public void log(int level, String message) {
>         logService.log(level, message.toUpperCase());
>         ...
>     }
> }
>
> And the ErrorLogEventLogService aspect, which is injected with the original
> LogService , as well as with
> the EventAdmin service: it will trigger an event in case the log level is
> LOG_ERROR:
>
> public class UppercaseLogAspect implements LogService{
>     private volatile LogService logService; // injected, possibly the
> original LogService, or the next aspect in the chain
>     private volatile EventAdmin eventAdmin; // injected, used to trigger an
> event when the logged message level is in error
>
>     void start() {
>         // optional lifecycle start callback: our aspect is starting
>     }
>
>     public void log(int level, String message) {
>         if (level == LogService.LOG_ERROR) {
>             // fire an event using the EventAdmin service injected in this
> class
>         }
>         logService.log(level, message.toUpperCase());
>     }
> }
>
> So, now, if a client is already injected with a log service, then it will
> be swapped at the time the aspect chain is registered.
> The aspect chain will be injected automatically in the volatile field which
> points to the original service, or you can define a swap callback.
>
> let's take an example, using a volatile field:
>
> first the client:
>
> class Client {
>    volatile LogService logService; // the original LogService, or the
> aspect chain
>
>    void doLog() {
>          logService.log(...);
>    }
> }
>
> and the corresponding client activator:
>
> public class ClientActivator extends DependencyManagerActivator {
>
>     public void init(BundleContext ctx, DependencyManager dm) throws
> Exception {
>         component(Client.class, comp -> comp
>             .impl(Client.class.class)
>             .withSrv(LogService.class, true));
>     }
>
> }
>
> And if you want the client to define a swap callback, you can then define
> some the callback like this:
>
> class Client implements Runnable {
>    volatile LogService logService; // the original LogService, or the
> aspect chain
>
>    // bind the required dependency (possibly the original service, or an
> aspect)
>    void set(LogService logService) {
>          this.logService = logService;
>    }
>
>    // called if the original service is swapped with an aspect
>    void swap(LogService oldLog, LogService newLog) {
>        // handle the swapped service
>        this.logService = newLog;
>    }
>
>    public void run() {
>          logService.log(...);
>    }
> }
>
> then here is the ClientActivor, defining the swap callback like this:
>
>         component(Client.class, comp -> comp
>             .impl(Client.class.class)
>             .provides(Runnable.class)
>             .withSrv(LogService.class, srv -> srv.required().add(Client::
> set).swap(Client::swap)));
>
>
> here, the initial LogService is first injected using the "set" callback,
> and if it's the original service, then the swap callback will be invoked
> if (ever) an aspect has to replace the original bound service.
>
> finally, you might also take a look at [1]. I never looked at it, but
> aspecio seems to be another solution allowing to manage osgi aspect
> services.
>
> Hope this helps;
>
> cheers;
> /Pierre
>
> [1] http://www.mail-archive.com/users@felix.apache.org/msg17262.html
>
>
> On Thu, Oct 6, 2016 at 4:04 PM, Raymond Auge <ra...@liferay.com>
> wrote:
>
> > The problem with the above solution is that you will end up in a race
> where
> > a service might already be registered without a proxy, then what? So you
> > should try to avoid ordering issues in your design otherwise you will
> > regret it later.
> >
> > What really should happen is that the thing creating the service should
> add
> > the proxy around the service before the service is ever published. An
> > extender is an ideal place to do this. Felix DM, and IPojo are ideal for
> > this use case since they imperative APIs for managing services and can be
> > "trained" to add proxies based on arbitrary heuristics.
> >
> > It's a wish I have also for Felix SCR.
> >
> > Sincerely,
> > - Ray
> >
> > On Thu, Oct 6, 2016 at 6:45 AM, Martin Nielsen <mn...@gmail.com> wrote:
> >
> > > I think what i wrote might have made more sense in my own head:) I
> > > apologize for the lousy problem description.
> > > Maybe an actual use case would help:
> > >
> > > I would like to use the OSGi serviceregistry to proxy specific
> > interfaces.
> > > For example:
> > > Say that i attempt to get a serviceReference for an interface with a
> > > mybatis annotation on it. What i would like is that the service
> registry
> > > returns a proxy that i define (My idea was through something like a
> > > ServiceBindingInterceptor). The proxy should then be closed down again
> > when
> > > get unget method is called on the service.
> > >
> > > Basically, i would like to supply a proxy implementation of interfaces
> in
> > > certain situations, but still allow for the serviceregistry lifecycle
> > > (get/unget) to handle opening and closing the proxies.
> > >
> > > It doesn't have to use any specific part of the runtime, i just spotted
> > the
> > > interceptors and mistook their purpose a bit i think.
> > >
> > > On Thu, Oct 6, 2016 at 12:32 PM, Clement Escoffier <
> > > clement.escoffier@gmail.com> wrote:
> > >
> > > > Hi,
> > > >
> > > > The service binding interceptor requires to have a “service”
> available.
> > > > You should be able to do what you want by either:
> > > >
> > > > - combining a “default-implementation” strategy and a binding
> > interceptor
> > > > (it would require to have the dependency marked as optional)
> > > > - or create your own handler that inject what you want to inject (
> > > > http://felix.apache.org/documentation/subprojects/
> > > > apache-felix-ipojo/apache-felix-ipojo-devguide/how-to-
> > > > write-your-own-handler.html <http://felix.apache.org/
> > > > documentation/subprojects/apache-felix-ipojo/apache-
> > > > felix-ipojo-devguide/how-to-write-your-own-handler.html>)
> > > >
> > > > Clement
> > > >
> > > >
> > > > > On 6 oct. 2016, at 04:02, Martin Nielsen <mn...@gmail.com> wrote:
> > > > >
> > > > > Hello everyone
> > > > >
> > > > > I am looking at the felix servicebinding interceptors with a
> certain
> > > > amount
> > > > > of enthusiasm, but i am having trouble figuring out if they can
> > solve a
> > > > > specific task.
> > > > >
> > > > > http://felix.apache.org/documentation/subprojects/
> > > > apache-felix-ipojo/apache-felix-ipojo-userguide/ipojo-
> > > > advanced-topics/service-binding-interceptors.html
> > > > >
> > > > > What i would like to do is the following: Whenever a
> ServiceReference
> > > is
> > > > > requested for an interface (No matter which one), i want an
> > interceptor
> > > > to
> > > > > examine it. If the interface meets some criteria, the an
> interceptor
> > > > should
> > > > > create a proxy for that interface, regardless of a matching
> > > > implementation
> > > > > being registered.
> > > > > So: Even if no object is actually registered as a service to that
> > > > > interface, i want the interceptor to return a proxy anyway. Is that
> > > > > possible to do in any way?
> > > > >
> > > > > Thank you in advance.
> > > > >
> > > > > -Martin
> > > >
> > > >
> > >
> >
> >
> >
> > --
> > *Raymond Augé* <http://www.liferay.com/web/raymond.auge/profile>
> >  (@rotty3000)
> > Senior Software Architect *Liferay, Inc.* <http://www.liferay.com>
> >  (@Liferay)
> > Board Member & EEG Co-Chair, OSGi Alliance <http://osgi.org>
> > (@OSGiAlliance)
> >
>

Re: Using service interceptors to inject proxies

Posted by Pierre De Rop <pi...@gmail.com>.
Hello Martin,

If you are interested, I can describe here DM aspects, which is a feature
that might be interesting in your case.
DM aspects are kind of (non functional) interceptors at the OSGi service
level. DM aspects are real components, they can have a lifecycle,
can be started/stopped at anytime, and they can declare service
dependencies, if they need some.

Basically, you can programatically (or using annotations) define some
aspect services that will be applied to any relevant original services
matching some given service properties. Multiple aspects can be applied to
the same original service and in such case, the aspects are chained using
some ranking order.

Regarding the start ordering, if a client is already bound to a given
original service, then any post-registered aspects will replace the
original service already bound to the client (either the volatile field in
the client pointing to the original service will be updated or a "swap"
callback will be invoked in order to replace the original service with the
new aspects). If you have a start ordering requirement (that is: you need
any client to be injected at the first time with the aspects and not with
the original service), then as Raymond said you will have to arrange to
register the aspects before the original services.

Let's take an example using the dm-lambda library (but the original DM api
or the DM annotations also work):

Assuming you have an original log service with a property "vendor=apache",
and you want to apply a chain of two aspects on that log service (which has
a vendor service property). Let's assume the first aspect is an
"UpperCaseLogService" which rewrites each log message to uppercase, and the
second one: "ErrorLogEventLogService" is an aspect which triggers an OSGi
event (using EventAdmin) in case the log is emitted using an ERROR level.

Then you would declare those two aspects like this:

public class Activator extends DependencyManagerActivator {
    public void init(BundleContext ctx, DependencyManager dm) throws
Exception {
        // Create the first aspect which is applied to any LogService
having a "service=vendor" service property.
        // Notice the "rank(1)" which means this aspect will be the first
in the chain

        aspect(LogService.class, aspect -> aspect
            .impl(UpperCaseLogService.class)
            .filter("(vendor=apache)")
            .rank(1));

        // Create the second aspect which is applied to any LogService
having a "service=vendor" service property
        // Notice that this aspect has a dependency required on an
EventAdmin service
        // Also notice the "rank(2)" which means this aspect will be the
second one in the chain

        aspect(LogService.class, aspect -> aspect
            .impl(ErrorLogEventLogService.class)
            .filter("(vendor=apache)")
            .rank(2)
            .withSvc(EventAdmin.class, true));
   }
}

Now the UpperCaseLogService aspect class, which convert all logs to upper
case:

public class UppercaseLogAspect implements LogService{
    private volatile LogService logService; // injected, possibly the
original LogService, or the next aspect in the chain

    void start() {
        // optional lifecycle start callback: our aspect is starting
    }

    void stop() {
        // optional lifecycle stop callback: our aspect is stopping
    }

    public void log(int level, String message) {
        logService.log(level, message.toUpperCase());
        ...
    }
}

And the ErrorLogEventLogService aspect, which is injected with the original
LogService , as well as with
the EventAdmin service: it will trigger an event in case the log level is
LOG_ERROR:

public class UppercaseLogAspect implements LogService{
    private volatile LogService logService; // injected, possibly the
original LogService, or the next aspect in the chain
    private volatile EventAdmin eventAdmin; // injected, used to trigger an
event when the logged message level is in error

    void start() {
        // optional lifecycle start callback: our aspect is starting
    }

    public void log(int level, String message) {
        if (level == LogService.LOG_ERROR) {
            // fire an event using the EventAdmin service injected in this
class
        }
        logService.log(level, message.toUpperCase());
    }
}

So, now, if a client is already injected with a log service, then it will
be swapped at the time the aspect chain is registered.
The aspect chain will be injected automatically in the volatile field which
points to the original service, or you can define a swap callback.

let's take an example, using a volatile field:

first the client:

class Client {
   volatile LogService logService; // the original LogService, or the
aspect chain

   void doLog() {
         logService.log(...);
   }
}

and the corresponding client activator:

public class ClientActivator extends DependencyManagerActivator {

    public void init(BundleContext ctx, DependencyManager dm) throws
Exception {
        component(Client.class, comp -> comp
            .impl(Client.class.class)
            .withSrv(LogService.class, true));
    }

}

And if you want the client to define a swap callback, you can then define
some the callback like this:

class Client implements Runnable {
   volatile LogService logService; // the original LogService, or the
aspect chain

   // bind the required dependency (possibly the original service, or an
aspect)
   void set(LogService logService) {
         this.logService = logService;
   }

   // called if the original service is swapped with an aspect
   void swap(LogService oldLog, LogService newLog) {
       // handle the swapped service
       this.logService = newLog;
   }

   public void run() {
         logService.log(...);
   }
}

then here is the ClientActivor, defining the swap callback like this:

        component(Client.class, comp -> comp
            .impl(Client.class.class)
            .provides(Runnable.class)
            .withSrv(LogService.class, srv -> srv.required().add(Client::
set).swap(Client::swap)));


here, the initial LogService is first injected using the "set" callback,
and if it's the original service, then the swap callback will be invoked
if (ever) an aspect has to replace the original bound service.

finally, you might also take a look at [1]. I never looked at it, but
aspecio seems to be another solution allowing to manage osgi aspect
services.

Hope this helps;

cheers;
/Pierre

[1] http://www.mail-archive.com/users@felix.apache.org/msg17262.html


On Thu, Oct 6, 2016 at 4:04 PM, Raymond Auge <ra...@liferay.com>
wrote:

> The problem with the above solution is that you will end up in a race where
> a service might already be registered without a proxy, then what? So you
> should try to avoid ordering issues in your design otherwise you will
> regret it later.
>
> What really should happen is that the thing creating the service should add
> the proxy around the service before the service is ever published. An
> extender is an ideal place to do this. Felix DM, and IPojo are ideal for
> this use case since they imperative APIs for managing services and can be
> "trained" to add proxies based on arbitrary heuristics.
>
> It's a wish I have also for Felix SCR.
>
> Sincerely,
> - Ray
>
> On Thu, Oct 6, 2016 at 6:45 AM, Martin Nielsen <mn...@gmail.com> wrote:
>
> > I think what i wrote might have made more sense in my own head:) I
> > apologize for the lousy problem description.
> > Maybe an actual use case would help:
> >
> > I would like to use the OSGi serviceregistry to proxy specific
> interfaces.
> > For example:
> > Say that i attempt to get a serviceReference for an interface with a
> > mybatis annotation on it. What i would like is that the service registry
> > returns a proxy that i define (My idea was through something like a
> > ServiceBindingInterceptor). The proxy should then be closed down again
> when
> > get unget method is called on the service.
> >
> > Basically, i would like to supply a proxy implementation of interfaces in
> > certain situations, but still allow for the serviceregistry lifecycle
> > (get/unget) to handle opening and closing the proxies.
> >
> > It doesn't have to use any specific part of the runtime, i just spotted
> the
> > interceptors and mistook their purpose a bit i think.
> >
> > On Thu, Oct 6, 2016 at 12:32 PM, Clement Escoffier <
> > clement.escoffier@gmail.com> wrote:
> >
> > > Hi,
> > >
> > > The service binding interceptor requires to have a “service” available.
> > > You should be able to do what you want by either:
> > >
> > > - combining a “default-implementation” strategy and a binding
> interceptor
> > > (it would require to have the dependency marked as optional)
> > > - or create your own handler that inject what you want to inject (
> > > http://felix.apache.org/documentation/subprojects/
> > > apache-felix-ipojo/apache-felix-ipojo-devguide/how-to-
> > > write-your-own-handler.html <http://felix.apache.org/
> > > documentation/subprojects/apache-felix-ipojo/apache-
> > > felix-ipojo-devguide/how-to-write-your-own-handler.html>)
> > >
> > > Clement
> > >
> > >
> > > > On 6 oct. 2016, at 04:02, Martin Nielsen <mn...@gmail.com> wrote:
> > > >
> > > > Hello everyone
> > > >
> > > > I am looking at the felix servicebinding interceptors with a certain
> > > amount
> > > > of enthusiasm, but i am having trouble figuring out if they can
> solve a
> > > > specific task.
> > > >
> > > > http://felix.apache.org/documentation/subprojects/
> > > apache-felix-ipojo/apache-felix-ipojo-userguide/ipojo-
> > > advanced-topics/service-binding-interceptors.html
> > > >
> > > > What i would like to do is the following: Whenever a ServiceReference
> > is
> > > > requested for an interface (No matter which one), i want an
> interceptor
> > > to
> > > > examine it. If the interface meets some criteria, the an interceptor
> > > should
> > > > create a proxy for that interface, regardless of a matching
> > > implementation
> > > > being registered.
> > > > So: Even if no object is actually registered as a service to that
> > > > interface, i want the interceptor to return a proxy anyway. Is that
> > > > possible to do in any way?
> > > >
> > > > Thank you in advance.
> > > >
> > > > -Martin
> > >
> > >
> >
>
>
>
> --
> *Raymond Augé* <http://www.liferay.com/web/raymond.auge/profile>
>  (@rotty3000)
> Senior Software Architect *Liferay, Inc.* <http://www.liferay.com>
>  (@Liferay)
> Board Member & EEG Co-Chair, OSGi Alliance <http://osgi.org>
> (@OSGiAlliance)
>

Re: Using service interceptors to inject proxies

Posted by Raymond Auge <ra...@liferay.com>.
The problem with the above solution is that you will end up in a race where
a service might already be registered without a proxy, then what? So you
should try to avoid ordering issues in your design otherwise you will
regret it later.

What really should happen is that the thing creating the service should add
the proxy around the service before the service is ever published. An
extender is an ideal place to do this. Felix DM, and IPojo are ideal for
this use case since they imperative APIs for managing services and can be
"trained" to add proxies based on arbitrary heuristics.

It's a wish I have also for Felix SCR.

Sincerely,
- Ray

On Thu, Oct 6, 2016 at 6:45 AM, Martin Nielsen <mn...@gmail.com> wrote:

> I think what i wrote might have made more sense in my own head:) I
> apologize for the lousy problem description.
> Maybe an actual use case would help:
>
> I would like to use the OSGi serviceregistry to proxy specific interfaces.
> For example:
> Say that i attempt to get a serviceReference for an interface with a
> mybatis annotation on it. What i would like is that the service registry
> returns a proxy that i define (My idea was through something like a
> ServiceBindingInterceptor). The proxy should then be closed down again when
> get unget method is called on the service.
>
> Basically, i would like to supply a proxy implementation of interfaces in
> certain situations, but still allow for the serviceregistry lifecycle
> (get/unget) to handle opening and closing the proxies.
>
> It doesn't have to use any specific part of the runtime, i just spotted the
> interceptors and mistook their purpose a bit i think.
>
> On Thu, Oct 6, 2016 at 12:32 PM, Clement Escoffier <
> clement.escoffier@gmail.com> wrote:
>
> > Hi,
> >
> > The service binding interceptor requires to have a “service” available.
> > You should be able to do what you want by either:
> >
> > - combining a “default-implementation” strategy and a binding interceptor
> > (it would require to have the dependency marked as optional)
> > - or create your own handler that inject what you want to inject (
> > http://felix.apache.org/documentation/subprojects/
> > apache-felix-ipojo/apache-felix-ipojo-devguide/how-to-
> > write-your-own-handler.html <http://felix.apache.org/
> > documentation/subprojects/apache-felix-ipojo/apache-
> > felix-ipojo-devguide/how-to-write-your-own-handler.html>)
> >
> > Clement
> >
> >
> > > On 6 oct. 2016, at 04:02, Martin Nielsen <mn...@gmail.com> wrote:
> > >
> > > Hello everyone
> > >
> > > I am looking at the felix servicebinding interceptors with a certain
> > amount
> > > of enthusiasm, but i am having trouble figuring out if they can solve a
> > > specific task.
> > >
> > > http://felix.apache.org/documentation/subprojects/
> > apache-felix-ipojo/apache-felix-ipojo-userguide/ipojo-
> > advanced-topics/service-binding-interceptors.html
> > >
> > > What i would like to do is the following: Whenever a ServiceReference
> is
> > > requested for an interface (No matter which one), i want an interceptor
> > to
> > > examine it. If the interface meets some criteria, the an interceptor
> > should
> > > create a proxy for that interface, regardless of a matching
> > implementation
> > > being registered.
> > > So: Even if no object is actually registered as a service to that
> > > interface, i want the interceptor to return a proxy anyway. Is that
> > > possible to do in any way?
> > >
> > > Thank you in advance.
> > >
> > > -Martin
> >
> >
>



-- 
*Raymond Augé* <http://www.liferay.com/web/raymond.auge/profile>
 (@rotty3000)
Senior Software Architect *Liferay, Inc.* <http://www.liferay.com>
 (@Liferay)
Board Member & EEG Co-Chair, OSGi Alliance <http://osgi.org> (@OSGiAlliance)

Re: Using service interceptors to inject proxies

Posted by Martin Nielsen <mn...@gmail.com>.
I think what i wrote might have made more sense in my own head:) I
apologize for the lousy problem description.
Maybe an actual use case would help:

I would like to use the OSGi serviceregistry to proxy specific interfaces.
For example:
Say that i attempt to get a serviceReference for an interface with a
mybatis annotation on it. What i would like is that the service registry
returns a proxy that i define (My idea was through something like a
ServiceBindingInterceptor). The proxy should then be closed down again when
get unget method is called on the service.

Basically, i would like to supply a proxy implementation of interfaces in
certain situations, but still allow for the serviceregistry lifecycle
(get/unget) to handle opening and closing the proxies.

It doesn't have to use any specific part of the runtime, i just spotted the
interceptors and mistook their purpose a bit i think.

On Thu, Oct 6, 2016 at 12:32 PM, Clement Escoffier <
clement.escoffier@gmail.com> wrote:

> Hi,
>
> The service binding interceptor requires to have a “service” available.
> You should be able to do what you want by either:
>
> - combining a “default-implementation” strategy and a binding interceptor
> (it would require to have the dependency marked as optional)
> - or create your own handler that inject what you want to inject (
> http://felix.apache.org/documentation/subprojects/
> apache-felix-ipojo/apache-felix-ipojo-devguide/how-to-
> write-your-own-handler.html <http://felix.apache.org/
> documentation/subprojects/apache-felix-ipojo/apache-
> felix-ipojo-devguide/how-to-write-your-own-handler.html>)
>
> Clement
>
>
> > On 6 oct. 2016, at 04:02, Martin Nielsen <mn...@gmail.com> wrote:
> >
> > Hello everyone
> >
> > I am looking at the felix servicebinding interceptors with a certain
> amount
> > of enthusiasm, but i am having trouble figuring out if they can solve a
> > specific task.
> >
> > http://felix.apache.org/documentation/subprojects/
> apache-felix-ipojo/apache-felix-ipojo-userguide/ipojo-
> advanced-topics/service-binding-interceptors.html
> >
> > What i would like to do is the following: Whenever a ServiceReference is
> > requested for an interface (No matter which one), i want an interceptor
> to
> > examine it. If the interface meets some criteria, the an interceptor
> should
> > create a proxy for that interface, regardless of a matching
> implementation
> > being registered.
> > So: Even if no object is actually registered as a service to that
> > interface, i want the interceptor to return a proxy anyway. Is that
> > possible to do in any way?
> >
> > Thank you in advance.
> >
> > -Martin
>
>

Re: Using service interceptors to inject proxies

Posted by Clement Escoffier <cl...@gmail.com>.
Hi,

The service binding interceptor requires to have a “service” available. You should be able to do what you want by either:

- combining a “default-implementation” strategy and a binding interceptor (it would require to have the dependency marked as optional)
- or create your own handler that inject what you want to inject (http://felix.apache.org/documentation/subprojects/apache-felix-ipojo/apache-felix-ipojo-devguide/how-to-write-your-own-handler.html <http://felix.apache.org/documentation/subprojects/apache-felix-ipojo/apache-felix-ipojo-devguide/how-to-write-your-own-handler.html>)

Clement


> On 6 oct. 2016, at 04:02, Martin Nielsen <mn...@gmail.com> wrote:
> 
> Hello everyone
> 
> I am looking at the felix servicebinding interceptors with a certain amount
> of enthusiasm, but i am having trouble figuring out if they can solve a
> specific task.
> 
> http://felix.apache.org/documentation/subprojects/apache-felix-ipojo/apache-felix-ipojo-userguide/ipojo-advanced-topics/service-binding-interceptors.html
> 
> What i would like to do is the following: Whenever a ServiceReference is
> requested for an interface (No matter which one), i want an interceptor to
> examine it. If the interface meets some criteria, the an interceptor should
> create a proxy for that interface, regardless of a matching implementation
> being registered.
> So: Even if no object is actually registered as a service to that
> interface, i want the interceptor to return a proxy anyway. Is that
> possible to do in any way?
> 
> Thank you in advance.
> 
> -Martin