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
