Sling
  1. Sling
  2. SLING-2396

Make ResourceResolverFactory independent from JCR

    Details

      Description

      As discussed on http://markmail.org/thread/wp6cghi5nqprpusn we would like to create a ResourceResolverFactory implementation that is not dependent on JCR.
      This will make it easier to create custom ResourceResolverFactories, where things like domain mappings, vanity paths and resource provider resolution could will not have to be re-implemented.

      A whiteboard area for this has been created at http://svn.apache.org/repos/asf/sling/whiteboard/resourceresolverfactory

        Activity

        Hide
        Carsten Ziegeler added a comment -

        As the jcr resource bundle has changed since the above whiteboard was created, we started a new whiteboard area based on the latest jcr resource bundle at:
        http://svn.apache.org/repos/asf/sling/whiteboarb/SLING-2396

        It contains three bundles: a copy of the API, the jcr resource bundle and a resourceresolver bundle

        Show
        Carsten Ziegeler added a comment - As the jcr resource bundle has changed since the above whiteboard was created, we started a new whiteboard area based on the latest jcr resource bundle at: http://svn.apache.org/repos/asf/sling/whiteboarb/SLING-2396 It contains three bundles: a copy of the API, the jcr resource bundle and a resourceresolver bundle
        Hide
        Carsten Ziegeler added a comment -

        I've committed all changes to trunk after a vote on the maling list.

        This is the current state; i'll leave this open for further tweaking.

        The current state is a major step as the separation is basically
        working. Most of our integration tests pass as well, so I think we
        have a good ground to discuss these things.
        So nothing is carved in stone yet, but open for discussion

        ResourceProviderFactory
        ----------------------------------
        The main idea behind the change is to introduce a
        ResourceProviderFactory which allows to login a user into a
        ResourceProvider. The current ResourceProvider has no means of
        authentication and therefore we need additional stuff. One goal if
        this change is to not change existing interfaces, therefore I
        introduced a bunch of new interfaces
        If you look at the ResourceProviderFactory interface it looks pretty
        similar to the ResourceResolverFactory except it returns a
        ResourceProvider. Instead of doing the authentication against a JCR
        directly in the ResourceResolverFactory we delegate this to a
        ResourceProviderFactory. In order to make the login as soon as
        possible (= when a resource resolver is requested from a RR factory),
        a RP factory can be marked as required. If a login against one of the
        marked as required RP factories fails, the login to the RR factory
        fails.

        The returned RP (as well as the directly registered RP) can implement
        several "feature interfaces":

        DynamicResourceProvider
        ------------------------------------
        Usually if a RP requires a login (like JCR), it needs a logout/close
        and for some reason the underlying persistence might not be reachable
        anymore. Therefore we have this marker interface which can only be
        implemented by RPs returned from a factory. It has a close() and
        isLive() method.

        Adaptable
        -------------
        A RR might be adaptable to some objects related to a used RP,
        therefore if the RP is Adaptable and the adaptTo method is called on
        the RR, this is delegated to all RPs

        AttributableResourceProvider
        ---------------------------------------
        For the attributes support in the RR, I introduced this interface
        which can be implemented by a RP. If so, attributes querying is
        delegated to such RPs

        QueriableResourceProvider
        -------------------------------------
        Searching through a RR is delegated to all RPs implementing this
        interface and the result is combined (added).

        In the implementation I've introduced a RRContext which keeps tracks
        of used RPs from factories, manages the logout etc. I think so far
        this works quiet well and basically I didn't have to change to much in
        the tree processing of the RR. There are some minor TODOs as well

        Now for the bad news A RR has the method getUserID() which in the
        past has directly returned the user id from the jcr session. I think
        we can completely change this by a) checking the values from the
        provided authentication map and if that does not contain a user
        delegate to all AttributableResourceProviders and search for an
        attribute user name. This is basically already implemented, although
        it still contains a shortcut for the session user.

        Then we have the mangling/unmangling of jcr namespace prefixes in the
        RR which require a session to check whether a prefix exists. I haven't
        changed this yet, although it works without a session now. I think, we
        have talked about making the mapping more dynamic in the future and
        once we do this, this might be somehting which can be moved there as
        well.

        The real bad news is: the whole thing only works with dropping
        workspace support. Currently, it's possible to get resources by a path
        in the form of

        {workspacename}

        :

        {path}

        . As the RR does all the path
        logic, we would have to add workspace support as a first class feature
        into the RR although just JCR supports this. Today, I think adding
        this stuff was a mistake (when we did this I thought differently....)
        and especially with this separation it is possible to mount workspaces
        at paths in the repository. We never used workspace stuff in Sling so
        far, so hopefully there are no users requiring this to be still
        present in future versions Maybe, if really required, this could be
        added through a wrapper RR/RRF, but still it would be really tricky to
        get this running again.

        Show
        Carsten Ziegeler added a comment - I've committed all changes to trunk after a vote on the maling list. This is the current state; i'll leave this open for further tweaking. The current state is a major step as the separation is basically working. Most of our integration tests pass as well, so I think we have a good ground to discuss these things. So nothing is carved in stone yet, but open for discussion ResourceProviderFactory ---------------------------------- The main idea behind the change is to introduce a ResourceProviderFactory which allows to login a user into a ResourceProvider. The current ResourceProvider has no means of authentication and therefore we need additional stuff. One goal if this change is to not change existing interfaces, therefore I introduced a bunch of new interfaces If you look at the ResourceProviderFactory interface it looks pretty similar to the ResourceResolverFactory except it returns a ResourceProvider. Instead of doing the authentication against a JCR directly in the ResourceResolverFactory we delegate this to a ResourceProviderFactory. In order to make the login as soon as possible (= when a resource resolver is requested from a RR factory), a RP factory can be marked as required. If a login against one of the marked as required RP factories fails, the login to the RR factory fails. The returned RP (as well as the directly registered RP) can implement several "feature interfaces": DynamicResourceProvider ------------------------------------ Usually if a RP requires a login (like JCR), it needs a logout/close and for some reason the underlying persistence might not be reachable anymore. Therefore we have this marker interface which can only be implemented by RPs returned from a factory. It has a close() and isLive() method. Adaptable ------------- A RR might be adaptable to some objects related to a used RP, therefore if the RP is Adaptable and the adaptTo method is called on the RR, this is delegated to all RPs AttributableResourceProvider --------------------------------------- For the attributes support in the RR, I introduced this interface which can be implemented by a RP. If so, attributes querying is delegated to such RPs QueriableResourceProvider ------------------------------------- Searching through a RR is delegated to all RPs implementing this interface and the result is combined (added). In the implementation I've introduced a RRContext which keeps tracks of used RPs from factories, manages the logout etc. I think so far this works quiet well and basically I didn't have to change to much in the tree processing of the RR. There are some minor TODOs as well Now for the bad news A RR has the method getUserID() which in the past has directly returned the user id from the jcr session. I think we can completely change this by a) checking the values from the provided authentication map and if that does not contain a user delegate to all AttributableResourceProviders and search for an attribute user name. This is basically already implemented, although it still contains a shortcut for the session user. Then we have the mangling/unmangling of jcr namespace prefixes in the RR which require a session to check whether a prefix exists. I haven't changed this yet, although it works without a session now. I think, we have talked about making the mapping more dynamic in the future and once we do this, this might be somehting which can be moved there as well. The real bad news is: the whole thing only works with dropping workspace support. Currently, it's possible to get resources by a path in the form of {workspacename} : {path} . As the RR does all the path logic, we would have to add workspace support as a first class feature into the RR although just JCR supports this. Today, I think adding this stuff was a mistake (when we did this I thought differently....) and especially with this separation it is possible to mount workspaces at paths in the repository. We never used workspace stuff in Sling so far, so hopefully there are no users requiring this to be still present in future versions Maybe, if really required, this could be added through a wrapper RR/RRF, but still it would be really tricky to get this running again.

          People

          • Assignee:
            Carsten Ziegeler
            Reporter:
            Vidar S. Ramdal
          • Votes:
            0 Vote for this issue
            Watchers:
            1 Start watching this issue

            Dates

            • Created:
              Updated:
              Resolved:

              Development