Uploaded image for project: '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

      Attachments

        Activity

          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

          cziegeler 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

          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.

          cziegeler 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

            cziegeler Carsten Ziegeler
            vramdal Vidar Skauge Ramdal
            Votes:
            0 Vote for this issue
            Watchers:
            1 Start watching this issue

            Dates

              Created:
              Updated:
              Resolved: