Details

    • Technical task
    • Status: Resolved
    • Major
    • Resolution: Duplicate
    • None
    • None
    • doc
    • None

    Attachments

      Issue Links

        Activity

          Using Mount information to manage storing and reading content in multiplexing setup

          In normal setup all paths are part of "default" mount. In multiplexing setup certain parts of the tree may be part of other mounts.

          • Mount
          • MountInfoProvider - A MountInfoProvider instance would always be present in any setup. By default it would have single mount i.e. default mount.

          Lets taken an example of below setup

          private
          	- /libs
          	- /apps
          default
          	- /
          

          In above setup nodes under /apps and /libs (include apps and libs) are part of "private" mount (mount name is "private"). While all other paths are part of default mount. Now lets see how mount information is used to manage storage in permission store. In a default setup permission store has following structure

          /jcr:system/rep:permissionStore
          	+ default  //workspace name
          	  + editor //principal name
          	    + 1227964008 (rep:PermissionStore) //path hash
          	       - rep:accessControlledPath = /content
          	       + 0
          	         - rep:isAllow = true
          	         - rep:privileges = [1279]
          	    + 1345610890 (rep:PermissionStore) //path hash
          	       - rep:accessControlledPath = /libs
          	       + 0
          	         - rep:isAllow = false
          	         - rep:privileges = [1279]
          

          In above setup permissions for principal 'editor' for various paths are stored as child nodes under '/jcr:system/rep:permissionStore/default/editor'. In a multiplexing setup the structure would get modified for those paths which are not part of default mount

          /jcr:system/rep:permissionStore
          	+ oak:mount-private
          	  + default
          	    + editor
          	       + 1345610890 (rep:PermissionStore) //path hash
          	         - rep:accessControlledPath = /libs
          	         + 0
          	           - rep:isAllow = false
          	           - rep:privileges = [1279]
          
          	+ default  //workspace name
          	  + editor //principal name
          	    + 1227964008 (rep:PermissionStore) //path hash
          	       - rep:accessControlledPath = /content
          	       + 0
          	         - rep:isAllow = true
          	         - rep:privileges = [1279]
          

          In a multiplexing setup we create new buckets under '/jcr:system/rep:permissionStore' based on Mount name and then use that as root for storing permission related data for paths belonging to paths under those mounts.

          Writing side changes

          On commit side when PermissionHook needs to add entries to permission store it would do something like below

          MountInfoProvider mountInfoProvider = ...
          
          String getStoragePath(String path){
          	Mount m = mountInfoProvider.getMountByPath(path);
          	if (m.isDefault()){
          		return defaultPermissionRoot;
          	}
          
          	String mountFragment = m.getPathFragmentName();
          	return '/jcr:system/rep:permissionStore/' + mountFragment + '/default'
          }
          

          Here 'oak:mount-private' is mountFragment as returned by Mount#getPathFragmentName() call

          When such a node structure is saved the NodeStore implementation would look for such path fragment and then would store nodes under such paths to the persistent store meant to store paths belonging to 'private' mount

          Reading Side Changes

          In the reading side where authorization logic needs to look for permissions assigned to principal 'editor' for specific path the code flow would also need to be adapted to account for multiplexing. Currently a PermissionStore loads permission based on single permission root. In multiplexing setup it would be changed to make use of MultiplexingPermissionStore.

          This can be done in 2 ways

          1. Looks for all immediate nodes under '/jcr:system/rep:permissionStore' and see if they confirm to permission root pattern i.e. there name is either 'default' or of form like 'oak:mount-<>-default'. Then construct permission store based on those node as permission root. Then each call to permission store would result in sum of results from permission store created for those permission roots
          2. Look for all Mounts defined in MountInfoProvider and then derive the permission root paths via Mount#getPathFragmentName() and then construct permission store instances with those nodes as permission store root

          See d6a3d262393a98f30 which takes #2 approach mentioned above

          chetanm Chetan Mehrotra added a comment - Using Mount information to manage storing and reading content in multiplexing setup In normal setup all paths are part of "default" mount. In multiplexing setup certain parts of the tree may be part of other mounts. Mount MountInfoProvider - A MountInfoProvider instance would always be present in any setup. By default it would have single mount i.e. default mount. Lets taken an example of below setup private - /libs - /apps default - / In above setup nodes under /apps and /libs (include apps and libs) are part of "private" mount (mount name is "private"). While all other paths are part of default mount. Now lets see how mount information is used to manage storage in permission store. In a default setup permission store has following structure /jcr:system/rep:permissionStore + default //workspace name + editor //principal name + 1227964008 (rep:PermissionStore) //path hash - rep:accessControlledPath = /content + 0 - rep:isAllow = true - rep:privileges = [1279] + 1345610890 (rep:PermissionStore) //path hash - rep:accessControlledPath = /libs + 0 - rep:isAllow = false - rep:privileges = [1279] In above setup permissions for principal 'editor' for various paths are stored as child nodes under '/jcr:system/rep:permissionStore/default/editor'. In a multiplexing setup the structure would get modified for those paths which are not part of default mount /jcr:system/rep:permissionStore + oak:mount-private + default + editor + 1345610890 (rep:PermissionStore) //path hash - rep:accessControlledPath = /libs + 0 - rep:isAllow = false - rep:privileges = [1279] + default //workspace name + editor //principal name + 1227964008 (rep:PermissionStore) //path hash - rep:accessControlledPath = /content + 0 - rep:isAllow = true - rep:privileges = [1279] In a multiplexing setup we create new buckets under '/jcr:system/rep:permissionStore' based on Mount name and then use that as root for storing permission related data for paths belonging to paths under those mounts. Writing side changes On commit side when PermissionHook needs to add entries to permission store it would do something like below MountInfoProvider mountInfoProvider = ... String getStoragePath( String path){ Mount m = mountInfoProvider.getMountByPath(path); if (m.isDefault()){ return defaultPermissionRoot; } String mountFragment = m.getPathFragmentName(); return '/jcr:system/rep:permissionStore/' + mountFragment + '/ default ' } Here 'oak:mount-private' is mountFragment as returned by Mount#getPathFragmentName() call When such a node structure is saved the NodeStore implementation would look for such path fragment and then would store nodes under such paths to the persistent store meant to store paths belonging to 'private' mount Reading Side Changes In the reading side where authorization logic needs to look for permissions assigned to principal 'editor' for specific path the code flow would also need to be adapted to account for multiplexing. Currently a PermissionStore loads permission based on single permission root. In multiplexing setup it would be changed to make use of MultiplexingPermissionStore . This can be done in 2 ways Looks for all immediate nodes under '/jcr:system/rep:permissionStore' and see if they confirm to permission root pattern i.e. there name is either 'default' or of form like 'oak:mount-<>-default'. Then construct permission store based on those node as permission root. Then each call to permission store would result in sum of results from permission store created for those permission roots Look for all Mounts defined in MountInfoProvider and then derive the permission root paths via Mount#getPathFragmentName() and then construct permission store instances with those nodes as permission store root See d6a3d262393a98f30 which takes #2 approach mentioned above

          anchela Can you have a look at above docs and see it explains the required details or not. Would improve it going forward depending on the feedback

          chetanm Chetan Mehrotra added a comment - anchela Can you have a look at above docs and see it explains the required details or not. Would improve it going forward depending on the feedback

          chetanm, I don't think this issue can be fixed before the multiplexing support is implemented
          Also the documentation must go into the oak-doc module and cannot stay in JIRA only.

          Since alex.parvulescu started working on this now, I will reassign the issue to him.

          angela Angela Schreiber added a comment - chetanm , I don't think this issue can be fixed before the multiplexing support is implemented Also the documentation must go into the oak-doc module and cannot stay in JIRA only. Since alex.parvulescu started working on this now, I will reassign the issue to him.
          stillalex Alex Deparvu added a comment -

          Docs added via OAK-3777 so marking as duplicate of that one.

          stillalex Alex Deparvu added a comment - Docs added via OAK-3777 so marking as duplicate of that one.

          People

            stillalex Alex Deparvu
            angela Angela Schreiber
            Votes:
            0 Vote for this issue
            Watchers:
            2 Start watching this issue

            Dates

              Created:
              Updated:
              Resolved: