Hi Ancoron,

You could take a look at the AIOLOS platform I developed (aiolos.intec.ugent.be). There I hide services behind a proxy to be able to transparently dispatch service calls to either a local or a remote instance of the service.

The way I implemented this is by using a combination of both a EventListenerHook and a FindHook. The EventListener hook will make sure that for every service interface that comes online, a proxy will (also) be registered. Using the FindHook, I hide the original implementations from the system and only return the proxy services. (This is basically implemented in https://github.com/aiolos-dev/aiolos/tree/master/be.iminds.aiolos.proxymanager)

Best regards,

Tim



On 01/14/2015 01:26 AM, Ancoron Luciferis wrote:
On 01/12/2015 11:54 AM, Peter Kriens wrote:
So I am a bit confused what you want? The example seems to explain how you 
handle different backends in OSGi from a single REST API. If you want to 
support /rest/backends/:name API’s, then the mechanics in this model should be 
perfectly clear. Obviuosly I did not show how to hide the backend because I’ve 
no idea what kind of policies you want to use, that is right in your domain and 
not depending on OSGi. Therefore, from the given example it should be clear 
where to place that functionality in a proper service oriented way. The purpose 
of the example is to highlight how to architect an OSGi system properly.

So do you still have questions how to do backends with OSGi design or are we 
now discussing communication protocol issues? If the latter is the case I think 
this list is out of scope?

Kind regards,

        Peter Kriens


Hi Peter,

good questions. I totally agree with you that the example application
you made up nicely shows the use of different services being combined
into a single ReST API.

Now, I know how to do the things I want to do programmatically in
application-level code. That's not my issue. My main issue is that I
want to make the presentation layer (the ReST application in your
example) agnostic of the presence of multiple backends. Only the
"routing" should actually know that there are multiple implementations
of the same service.

That's why I was referring to the FindHook earlier in the thread, which
is the only mechanism currently known to me that allows one to hide
services from consumers. However, this has the drawback, that consumers
need to be refreshed once the FindHook gets installed and I didn't find
any place I could "intercept" service registration to not expose the
services to bundles other than the one providing the "routing" proxy
service.

Thinking about it, I probably could make use of a ServiceFactory to
always return the routing DataService proxy. That way, any consumer
would only get the proxy... hm... have to try that...

...thanx for the indirect pointer! :)


Cheers,

        Ancoron





On 8 jan. 2015, at 21:55, Ancoron Luciferis <[email protected]> 
wrote:
Hi Peter,
thanx a lot for this nice example! This is highly appreciated and
enRoute really looks cool, although I want to support more than just
JSON as a content-type.

Anyway, as I see it, the BackendREST service is somewhat comparable to
my planned ReST server implementation in the sense that it actually is a
consumer of the various real backend implementations.

However, what I (ideally) want to achieve is that even the ReST service
does not even know that multiple backends exist.

So, in your example a PUT to create a new BLOB uses the following URI:

/rest/backends/:type/:name

However, what I intend to provide is just this:

/rest/backends/:name

...so that the ReST consumer does not need to care about the different
backends and a "GET /rest/backends" would return all entries, not just
from a single backend. This also allows me then to create a global
caching mechanism for meta-data and also implement more sophisticated
stuff later in the backend routing logic, e.g. moving from File to
InMemory for "hot" data.

As such, also the ReST server-side should not be bothered with the
different backends. In the long-term, I also plan integration for some
kind of process or rules engine which can be used to implement
algorithms for storage tiering, caching policies, geographic or
policy-based data locality, aso.

As those things complicate the actual backend decision logic and/or may
also start executing functionality without any ReST API interaction, I
really would need a unified way of accessing them internally as well.

As OSGi already knows what I would call service instance meta-data (the
service properties usable for filtering), is there any thinking about
call-time meta-data/filtering in a generic fashion?


Thanx a lot,

Ancoron


On 01/08/2015 04:33 PM, Peter Kriens wrote:
Hmm, all the text ahead what is before ‘Anacron’ should have been
removed :-( The actual code is on the link.

I started a few days ago but noticed it was getting too long. This
morning I just made an enRoute project out of it.

So please discard any code in my mail and look
at 
https://github.com/osgi/osgi.enroute.examples/tree/master/osgi.enroute.examples.backend.application

Sorry, kind regards,

Peter Kriens


On 8 jan. 2015, at 15:48, Raymond Auge <[email protected]
<mailto:[email protected]>> wrote:

Peter is there a typo in the addBackend method on the put operation?

On Thu, Jan 8, 2015 at 9:45 AM, Peter Kriens <[email protected]
<mailto:[email protected]>> wrote:

    This is the archetypical use case for OSGi:

    interface Backend {
       void store( String name, byte[] data ) throws Exception;
    }

    @Component
    public class FrontEnd implements REST {
      final Map<String,Backend>  backends = new ConcurrentHashMap<>();

      @Reference(multiple=true,dynamic=true)
      void addBackend(Backend backend, Map<String,Object> props) {
        backends.put(backend, props.get(“type”));
      }
      void removeBackend(Map<String,Object> props) {
        backends.remove(props.get(“type”));
      }

      interface PUTRequest extends RESTRequest {
        byte[] _body();
        String type();
      }

      public void putData( PUTRequest req, String [] path ) {
        Backend b = backends.get(req.type());
        if ( b == null)
    throw new FileNotFoundException(“No such type “ + req.type());

        String p = Strings.join(path, “/“);
        b.store(p, req._body() );
      }
    }

    @Component
    public class FileSystemBackend implements Backend {

    Ancoron,
    I though the problem was kind of nice for an example so in the
    light of the OSgi enRoute work I turned it into a little enRoute
    application. I added all the documentation in the readme file. You
    can find the app here:

    
https://github.com/osgi/osgi.enroute.examples/tree/master/osgi.enroute.examples.backend.application

    Let me know if this works for you.

    Kind regards,

    Peter Kriens


    On 30 dec. 2014, at 23:49, Ancoron Luciferis
    <[email protected]
    <mailto:[email protected]>> wrote:

    Hi OSGi devs and experts,

    I've got a problem which I really want to solve in an elegant way
    but I
    think I haven't found the appropriate pieces yet.

    The problem is the following:

    I want to create some abstraction for a little data management system
    which should be connected to different data backends at the same time
    (e.g. S3, Dropbox, local/network filesystem, ...).

    Now let's consider a simple example of the logic involving the
    following
    standard CRUD operations (because I want to publish that in a single
    ReST endpoint):

    * create (e.g. upload)
    * read (get metadata or list objects/files/buckets/... or just
    download)
    * update (e.g. re-upload or change metadata)
    * delete

    So, what I actually want is the following:

    1.) For creating/uploading a new object, a specific data backend
    may be
    specified via HTTP header or determined automatically (e.g. based on
    expected size or some other metadata).

    2.) For listing existing objects all service instances/data backends
    shall be queried at the same time (in parallel) and results combined
    into a single list.

    3.) For retrieving object metadata, downloading a specific object,
    modifying, deleting it or executing some other operation with a
    specific
    object, the correct service instance/data backend is called.


    So, for case 1 I would need some way to evaluate the contextual
    information of the upcoming service call (in this case the HTTP
    header).
    If that is not available, I'll have to look at some service instance
    information that helps me figuring out where to put some object
    (DNS-SD
    or ZeroConf keep popping up conceptually here in my head).

    For case 2 I just need to actually execute the same call for each
    available service instance (like a network broadcast).

    For case 3 I need to know somehow (this could be done by a local
    object
    identity/location mapping) which service instance is responsible (or
    allowed to) manage a specific object.


    Now, I could code all this inside the ReST layer. However, what I
    really
    want is to make it abstract in a way that I can hook it into other
    places as well.

    So, the initial caller 'A' should just have code like this:

    private B b;
    //...

    myObjectId = b.create(newObject);
    //...

    List objects = b.list(filter, sort, paging);
    //...

    myObject = b.get(myObjectId);
    //...

    b.updateMetadata(myObjectMetadata);
    //...

    b.delete(myObjectId);


    So that the ReST layer does not even have to know that there is more
    than just one backend.

    The magic should be done outside in a generic way if possible, so
    that I
    could re-use it as it is for other types of services.


    Does that idea sound familiar to someone? Has that been solved
    already
    and I just missed something?

    I first started with the idea of using an aggregating proxy plus a
    FindHook and stuff, but this imposes the runtime issue that consumers
    need to be refreshed which I want to avoid if possible.

    The main problem I think here is to present a single service
    instance to
    the consumer for which there actually exists no real service
    registration as it is just some kind of invocation handler with a
    specialized purpose (routing/broadcasting service requests).

    I would be thankful for any ideas!


    Thanx,

    Ancoron
    _______________________________________________
    OSGi Developer Mail List
    [email protected] <mailto:[email protected]>
    https://mail.osgi.org/mailman/listinfo/osgi-dev

    _______________________________________________
    OSGi Developer Mail List
    [email protected] <mailto:[email protected]>
    https://mail.osgi.org/mailman/listinfo/osgi-dev




--
*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)
_______________________________________________
OSGi Developer Mail List
[email protected] <mailto:[email protected]>
https://mail.osgi.org/mailman/listinfo/osgi-dev


_______________________________________________
OSGi Developer Mail List
[email protected]
https://mail.osgi.org/mailman/listinfo/osgi-dev

_______________________________________________
OSGi Developer Mail List
[email protected]
https://mail.osgi.org/mailman/listinfo/osgi-dev
_______________________________________________
OSGi Developer Mail List
[email protected]
https://mail.osgi.org/mailman/listinfo/osgi-dev

_______________________________________________
OSGi Developer Mail List
[email protected]
https://mail.osgi.org/mailman/listinfo/osgi-dev


--
Tim Verbelen
Department of Information Technology
Broadband Communication Networks (IBCN)
Ghent University - iMinds
Gaston Crommenlaan 8 (Bus 201), B-9050 Gent, Belgium
T: +32 9 33 14940 ; T Secr: +32 9 33 14900
F: +32 9 33 14899
E: [email protected]
W : www.ibcn.intec.UGent.be

_______________________________________________
OSGi Developer Mail List
[email protected]
https://mail.osgi.org/mailman/listinfo/osgi-dev

Reply via email to