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.