Hi !

I'm trying to expand the scope of the resources hierarchy in Apache™
Bloodhound .

For those not familiar with what's been done in there , in advance
I'll mention that an environment can contain many products (i.e.
projects) and for each one of them there will be a product environment
[1]_ (i.e. component manager , see trasourcec:ticket:11121) containing
everything you might expect to be hosted by a regular Trac environment
e.g. components (enabled / disabled by product) , configuration
(stored in the database rather that in filesystem) , product resources
, permissions , ...

My goal now is to reuse and leverage existing resource APIs to make
them work across product boundaries . You can think of this from a
more abstract perspective . Imagine you have different kinds of
component managers (e.g. environments, product environments, ... CM1,
CM2, ...) and there's a need to refer to resources managed by CM1
while performing some computation (e.g. request handling, trac-admin
command , ...) in CM2 scope .

My initial idea is as follows (notice that so far Resource class are
agnostic to component manager) :

  1. Resources setup as usual will still point to local resources . In the
     sample above Resource('ticket', 1) will be CM2's ticket 1 .
  2. For external resources I've been thinking of 3 approaches (...
after discarding
     quite a few ...)
     a. Add component manager parameters in resource-aware methods
        * e.g. PremissionCache__call__(self, realm_or_resource,
id=False, version=False, compmgr=None)
     b. Keep resource-aware methods signature as-is and incorporate
        «manager resources» in the resource hierarchy
        * e.g.

        Resource('product', 'PREFIX')
        +-- Resource('ticket', 1)

        Resource('product', 'PREFIX')
        +-- Resource('ticket', 1)
          +-- Resource('attachment', 'file.txt')

     c. Keep resource-aware methods signature as-is and add a new
        concept in resources API to switch manager context
        * e.g.

        Manager('product', 'PREFIX')
        +-- Resource('ticket', 1)

        Manager('product', 'PREFIX')
        +-- Resource('ticket', 1)
          +-- Resource('attachment', 'file.txt')

        Manager('CM1', mgrid)
        +-- Resource('ticket', 1)
          +-- Resource('attachment', 'file.txt')

Preliminary observations :

  - I do not quite like (a) , so I won't follow that way ...
  - In order to understand the rationale for using (a) or (b) consider
this example :
    * while handling a request in the scope of component manager CM1 there's
      a need to obtain a link to resource (realm, id) in CM2 , and check whether
      user has permission to see its contents.
      + using (b) (for products) it'd be possible to do something like

      {{{
      #!py

      resource = Resource('product', 'PREFIX').child('ticket',
1).child('attachment', 'f.txt')

      # instantiate product environment and another permission cache
object in that context
      # then invoke has_permission method of the later
      req.perm.has_permission(resource)

      # instantiate product environment and ResourceManager object in
that context
      # then invoke get_resource_url method of the later
      trac.resource.get_resource_url(env, resource, href)
      }}}

      + using (c) (in general) it'd be possible to do something like

      {{{
      #!py

      resource = Manager('cm1', id).child(parent_realm,
parent_id).child(realm, id)

      # instantiate manager and another permission cache object in that context
      # then invoke has_permission method of the later
      req.perm.has_permission(resource)

      # instantiate manager and ResourceManager object in that context
      # then invoke get_resource_url method of the later
      trac.resource.get_resource_url(cm2, resource, href)
      }}}

  - As you might have already noticed the main difference between (b)
    and (c) is that
    in the former case it is a bit hard to identify the exact point
where manager
    instantiation is needed
    * 'product' is a resource realm too .
    * It's difficult to intercept resource management extensions without
      patching Trac core in many locations.
    * The result will be tightly coupled to the implementation details of
      resource managers
    * There is no space for managers that are not resources e.g.
      trac.env.Environment
    * It would be necessary to traverse the resources hierarchy
      and «know-what-to-do» (i.e. what realm has to be used to instantiate a
      given component manager sub-type).
  - OTOH using (c) Manager class makes this boundary explicit,
    and it's possible to do things in such a way that access to resource
    manager will be O(1) .
    * Of course , new interfaces will be needed in order
      to look up and instantiate component managers , among other things ...
  - AFAIK at present the resources API is focused on realms .
    There's no (evident)
    way to implement or hook resource management extensions at such a
    higher level. Hence there are no extension points to make this
    kind of things happen .

So, after all this , my questions are :

  - What option would you prefer (if any) ?
  - If we implement something like this in Apache™ Bloodhound is
    there a chance to propose it as an enhancement to incorporate
    it upstream into Trac trunk ?

I look forward to your replies .

.. [1] BEP 3 # Product environments
       
(https://issues.apache.org/bloodhound/wiki/Proposals/BEP-0003#product-envs)


-- 
Regards,

Olemis.

Apache™ Bloodhound contributor
http://issues.apache.org/bloodhound

Blog ES: http://simelo-es.blogspot.com/
Blog EN: http://simelo-en.blogspot.com/

Featured article:

-- 
You received this message because you are subscribed to the Google Groups "Trac 
Development" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To post to this group, send email to [email protected].
Visit this group at http://groups.google.com/group/trac-dev?hl=en.
For more options, visit https://groups.google.com/groups/opt_out.


Reply via email to