You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@sling.apache.org by Andreas Kollegger <an...@kollegger.name> on 2009/06/03 19:37:19 UTC
Exposing DB Data
Hi,
I'd like to expose data stored in an external database as resource
nodes in Sling. Access to the database is already wrapped in an OSGi
service (MyService.java), and there is a Java model for the data
(MyModel.java). From what I can understand from reading the examples,
searching the mailing list and looking at documentation, the steps to
integrate with Sling could be:
1. MyResourceProvider implements ResourceProvider
- bridge to MyService for getting data rows
- provider.roots = /my/resources/
- sub-path of root used to select row in table (/my/resources/
3245.html retrieves row index 3245 as Resource)
- listChildren() of root would list all database rows (probably add
query params to limit number of rows returned)
- getResource() returns a MyResourceWrapper
2. MyResourceWrapper implements Resource
- wraps MyModel
- resourceType = my/Model
- adaptable to javax.jcr.Node (exposing columns as node properties)
That would take care of read access to the data. I can then easily add
scripts to render the data as appropriate.
Write access is a little less clear to me. I'd like to have a servlet
which handles json, xml or form POSTs for anything submitted to the
path of my ResourceProvider. I think I need to do this:
1. MyResourceTypeProvider implements JcrResourceTypeProvider
- provider.roots = /my/resources
- any node below the root is returned as resourceType my/Model,
otherwise return null
2. MyPostServlet extends SlingAllMethodsServlet
- registered to handle nodes of type my/Model
- override doPost() to handle data based on content-type
- creates new database entries using MyService
That would allow the creation of a new database row by posting an
appropriate json or xml file to /my/resource/*.html . For the form
data, I'd conform to the SlingPostServlet interface to remain
compatible with generic node editing.
Am I thinking about this correctly, or is their a more appropriate
Sling-Way?
Thanks for your thoughts,
Andreas
Re: Exposing DB Data
Posted by Andreas Kollegger <ak...@tembopublic.org>.
>> Write access is a little less clear to me. I'd like to have a servlet
>> which handles json, xml or form POSTs for anything submitted to the
>> path
>> of my ResourceProvider. I think I need to do this:
>>
>> 1. MyResourceTypeProvider implements JcrResourceTypeProvider
>> - provider.roots = /my/resources
>> - any node below the root is returned as resourceType my/Model,
>> otherwise return null
>>
>> 2. MyPostServlet extends SlingAllMethodsServlet
>> - registered to handle nodes of type my/Model
>> - override doPost() to handle data based on content-type
>> - creates new database entries using MyService
>>
>> That would allow the creation of a new database row by posting an
>> appropriate json or xml file to /my/resource/*.html . For the form
>> data,
>> I'd conform to the SlingPostServlet interface to remain compatible
>> with
>> generic node editing.
>>
>> Am I thinking about this correctly, or is their a more appropriate
>> Sling-Way?
> Hmm not sure :) I guess your idea should work. Now, for updating db
> data
> it should already work if your resource is adaptable to
> PersistableValueMap.
>
> For adding/deleting resources something like the above might work. We
> are thinking of extending the resource provider interface to get
> better support for these use cases. This is one of the topics for the
> near future, so maybe we should start thinking about this (again)
> now :)
The PersistableValueMap seems like a good way to go. If I extend
MyResourceProvider to allow creation of MyResources from a node, I
should then consider adding a SlingPostProcessor instead, which would
use MyResourceProvider.createResourceForNode(n) for any nodes created
under /my/resource. I guess I'd have to undo any nodes actually
created in the jcr since they'd be masked by MyResourceProvider. But,
that would then get me round-trip node semantics.
For xml or json posts, I've noticed the OptingServlet interface, which
is probably a better approach than trying to use the
JcrResourceTypeProvider to assert a default resource type in an
attempt to resolve the request to a POST servlet mapped to that type.
I could then register my POST servlets as default resource type
handlers, which only opt-in for post requests to the appropriate path
and http content-type. Better, right?
Thanks for your advice,
Andreas
Re: Exposing DB Data
Posted by Carsten Ziegeler <cz...@apache.org>.
Hi Andreas,
Andreas Kollegger wrote:
> Hi,
>
> I'd like to expose data stored in an external database as resource nodes
> in Sling. Access to the database is already wrapped in an OSGi service
> (MyService.java), and there is a Java model for the data (MyModel.java).
> From what I can understand from reading the examples, searching the
> mailing list and looking at documentation, the steps to integrate with
> Sling could be:
>
> 1. MyResourceProvider implements ResourceProvider
> - bridge to MyService for getting data rows
> - provider.roots = /my/resources/
> - sub-path of root used to select row in table
> (/my/resources/3245.html retrieves row index 3245 as Resource)
> - listChildren() of root would list all database rows (probably add
> query params to limit number of rows returned)
> - getResource() returns a MyResourceWrapper
>
> 2. MyResourceWrapper implements Resource
> - wraps MyModel
> - resourceType = my/Model
> - adaptable to javax.jcr.Node (exposing columns as node properties)
it depends on your application (code) but I think making your resource
adaptable to ValueMap (jcr resources are adaptable to value map as well)
is more generic. It allows you to access different kind of resources
(backed by jcr, backed by your db provider) in a unique way. And the
ValueMap interface is easier to use than jcr Node :)
> That would take care of read access to the data. I can then easily add
> scripts to render the data as appropriate.
Sounds good to me :)
>
> Write access is a little less clear to me. I'd like to have a servlet
> which handles json, xml or form POSTs for anything submitted to the path
> of my ResourceProvider. I think I need to do this:
>
> 1. MyResourceTypeProvider implements JcrResourceTypeProvider
> - provider.roots = /my/resources
> - any node below the root is returned as resourceType my/Model,
> otherwise return null
>
> 2. MyPostServlet extends SlingAllMethodsServlet
> - registered to handle nodes of type my/Model
> - override doPost() to handle data based on content-type
> - creates new database entries using MyService
>
> That would allow the creation of a new database row by posting an
> appropriate json or xml file to /my/resource/*.html . For the form data,
> I'd conform to the SlingPostServlet interface to remain compatible with
> generic node editing.
>
> Am I thinking about this correctly, or is their a more appropriate
> Sling-Way?
Hmm not sure :) I guess your idea should work. Now, for updating db data
it should already work if your resource is adaptable to PersistableValueMap.
For adding/deleting resources something like the above might work. We
are thinking of extending the resource provider interface to get
better support for these use cases. This is one of the topics for the
near future, so maybe we should start thinking about this (again) now :)
Regards
Carsten
--
Carsten Ziegeler
cziegeler@apache.org
Re: Exposing DB Data
Posted by Felix Meschberger <fm...@gmail.com>.
Hi Andreas,
Andreas Kollegger schrieb:
> Hi,
>
> I'd like to expose data stored in an external database as resource nodes
> in Sling. Access to the database is already wrapped in an OSGi service
> (MyService.java), and there is a Java model for the data (MyModel.java).
> From what I can understand from reading the examples, searching the
> mailing list and looking at documentation, the steps to integrate with
> Sling could be:
>
> 1. MyResourceProvider implements ResourceProvider
> - bridge to MyService for getting data rows
> - provider.roots = /my/resources/
> - sub-path of root used to select row in table
> (/my/resources/3245.html retrieves row index 3245 as Resource)
> - listChildren() of root would list all database rows (probably add
> query params to limit number of rows returned)
> - getResource() returns a MyResourceWrapper
Makes perfect sense.
> 2. MyResourceWrapper implements Resource
> - wraps MyModel
> - resourceType = my/Model
> - adaptable to javax.jcr.Node (exposing columns as node properties)
I would not adapt it to a Node. Rather I would adapt it to the MyModel
class and propbably to ValueMap (or even PersistableValueMap) to get at
the properties.
>
> That would take care of read access to the data. I can then easily add
> scripts to render the data as appropriate.
>
> Write access is a little less clear to me. I'd like to have a servlet
> which handles json, xml or form POSTs for anything submitted to the path
> of my ResourceProvider. I think I need to do this:
>
> 1. MyResourceTypeProvider implements JcrResourceTypeProvider
> - provider.roots = /my/resources
> - any node below the root is returned as resourceType my/Model,
> otherwise return null
The problem exists mainly for non-existing resources (rows). Existing
rows already map to the correct implementation (see above) and thus have
the correct resource type.
For non-existing resources, Ian Boston is preparing a patch providing a
PathResourceTypeProvider which may be used to assign a special resource
type to non-existing nodes much like the JcrResourceTypeProvider does
for plain JCR Item based resources.
So in your use case Ian's PathResourceTypeProvider would probably be
appropriate.
>
> 2. MyPostServlet extends SlingAllMethodsServlet
> - registered to handle nodes of type my/Model
> - override doPost() to handle data based on content-type
> - creates new database entries using MyService
Makes perfect sense to me. We might want to inspect how much of the
existing SlingPostServlet could be abstracted to support general
resource creation, modification, removal, not just JCR Item based ones.
>
> That would allow the creation of a new database row by posting an
> appropriate json or xml file to /my/resource/*.html . For the form data,
> I'd conform to the SlingPostServlet interface to remain compatible with
> generic node editing.
>
> Am I thinking about this correctly, or is their a more appropriate
> Sling-Way?
I think you are approach looks perfectly like the Sling way.
Another approach could of course be to create a Jackrabbit
PersistenceManager for your database and access your database through
Jackrabbit. But I suspect that this would be more complicated.
Regards
Felix