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
 
<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]> 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]
> https://mail.osgi.org/mailman/listinfo/osgi-dev

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

Reply via email to