Page "Proposals/BEP-0003" was changed by olemis Diff URL: <https://issues.apache.org/bloodhound/wiki/Proposals/BEP-0003?action=diff&version=32> Revision 32 Comment: bep:0003 [RFC] Resource neighborhoods proposal Changes: -------8<------8<------8<------8<------8<------8<------8<------8<-------- Index: Proposals/BEP-0003 ========================================================================= --- Proposals/BEP-0003 (version: 31) +++ Proposals/BEP-0003 (version: 32) @@ -207,6 +207,65 @@ Sub-paths will be handled from there as usual. +=== Resource neighborhoods #resource-neighborhood + +''Apache™ Bloodhound'' will expand resources API by introducing the concept of ''Neighborhoods''. In a few words they are the topmost level of the hierarchy representing resources managed by a component manager, thereby identifying the later. As such ''resource neighborhoods'' serve to the purpose of specifying absolute references to resources hosted beyond the boundaries of a given component manager (e.g. ''Trac'' environments , [#product-envs product environments], ...) . As a side effect they will be used to load manager objects on demand. + +'''Resource neighborhoods''' will always be at the top of the resources hierarchy . Instances will have a ''realm'' identifying the kind of manager (e.g. `tracenv` for ''Trac'' environments, `product` for product environments). For example the following resource identifiers will point to `attachment:file.txt:ticket:1` resource in local scope, product `P1`, product `P2` and global environment, in that order. + +{{{ + ++-- Resource('ticket', 1) + +-- Resource('attachment', 'file.txt') + +Neighborhood('product', 'P1') ++-- Resource('ticket', 1) + +-- Resource('attachment', 'file.txt') + +Neighborhood('product', 'P2') ++-- Resource('ticket', 1) + +-- Resource('attachment', 'file.txt') + +Neighborhood('tracenv', None) ++-- Resource('ticket', 1) + +-- Resource('attachment', 'file.txt') + +}}} + +In the previous examples all resources in `Neighborhood` scope will have a reference to topmost neighborhood instance in its `neighbordhood` attribute. If set to `None` resource resolution will be a responsibility of the local component manager (e.g. environment). + +==== Loading component managers #resource-neighborhood-loader + +At run time neighborhood references must be resolved to obtain the target component manager. Therefore a parallel infrastructure is needed . The new `IExternalResourceManager` interface is introduced for this very same purpose . Its signature is shown below : + +{{{ +#!py + +class IExternalResourceConnector(Interface): + + def get_supported_realms() + """Return supported resource realms. + + :rtype: `basestring` generator + """ + def load_manager(neighborhood): + """Load the component manager identified by a given neighborhood. + + :param neighborhood: manager identifier (i.e. `Neighborhood`) + :rtype: `trac.core.ComponentManager` + """ + def manager_exists(neighborhood): + """Check whether the component manager associated to + the given `neighborhood` exists physically. + + :param neighborhood: manager identifier (i.e. `Neighborhood`) + :rtype: bool + + Attempting to retrieve the manager object for a non-existing + neighborhood should raise a `ResourceNotFound` exception. + """ +}}} + === Database schema changes #database-schema-changes Products shall become a first-class citizen in ''Bloodhound''. To make this possible, some changes will be required at the database schema level, especially as multiple product environments are meant to be hosted in the same database instance. @@ -595,6 +654,25 @@ '''TODO:''' Implementation details TBD +=== Ubiquitous access to resources #resource-refs + +Existing resource APIs have to be extended to work across product boundaries (or component manager, if the feature is analysed from a more abstract perspective) . While performing some computation (e.g. request handling, trac-admin command , ...) it will be possible to refer to resources managed by another product (i.e. in another scope) . Notable use cases are: + + - Rendering context + - Permission checks and related assertions + - Link generation in source code and Genshi templates + - Resource management + +==== Integrating resources managed by other applications #resource-external-apps + +Interoperability with resources managed by [#import-export other applications] has been requested before ^[# citation to brane's comment needed]^ . `IExternalResourceConnector` and `Neighborhood`s will provide the means to make that happen. For instance, the following resource identifier could be used to refer to [https://issues.apache.org/jira/browse/COMDEV-84 this JIRA ticket] + +{{{ +Neighborhood('jira', 'http://issues.apache.org/jira/') + +-- Resource('project', 'COMDEV') + +-- Resource('ticket', 84) +}}} + === Resources moveable between products #migration-resource Tickets should be moveable between products, old ticket product IDs (and URLs) should be remembered, making the same ticket accessible through old products namespaces (URLs). @@ -650,6 +728,84 @@ This is not recommended. Multi-product API components will play an active role in customizations at the product level. That will not be possible if they are disabled. +=== Rejected alternatives to resource neighborhoods #resource-rejected + +Among many solutions considered for resources API it's worth to mention some candidates and the reasons for not adopting them. + +==== Extend the signature of resource-aware methods #resource-rejected-newsig + +As an alternative to resource neighborhoods the signature of resource aware methods could have been extended with a parameter (e.g. `compmgr`) accepting an instance of `trac.core.ComponentManager` . Its default value would be set to `None` for local resources. This approach has the following limitations : + + - It has an impact on code scattered all over Trac core and plugins + - Even if all invocations performed by resource API clients will still work + for local resources , they'll have to be modified to cope with external + references. + * ... which represents a challenge when it comes to providing generic + helpers to render links in ''Genshi'' templates . + +==== Resources hierarchy #resource-rejected-hierarchy + +Another promising approach was to represent absolute references to product resources by inserting a product resource (i.e. `realm = 'product'` as the topmost element in the hierarchy . Sample ticket and attachment references are shown below : + +{{{ +Resource('product', 'PREFIX') ++-- Resource('ticket', 1) + +Resource('product', 'PREFIX') ++-- Resource('ticket', 1) + +-- Resource('attachment', 'file.txt') +}}} + +The drawbacks in this case are : + + - ''Trac'' resources API at present is focused on resource realms and + does not provide extension points to perform this kind of generic + resource management operations. + * It's difficult to intercept resource management extensions without + patching Trac core in many locations. + - There will be collisions with existing resource API classes + * 'product' is a resource realm too . + - Components making use of resource API classes will have to be + updated as well by dealing with product resources in special ways + * The core will be tightly coupled to the product concept. + * The solution does not scale to other kinds of component managers + * It is slightly complicated to implement because, among other + things, it is hard to determine the exact point to instantiate + component managers. + - 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) to determine product context. + * Subtle impact on performance + - There is no space for managers that are not bound to resources e.g. + `trac.env.Environment` + * No support in product environments for links to resources + in global environment ... unless relying upon yet another hack. + - Wrong resource will be referenced by non-product aware components. + In other words, if a plugin makes use of resources and it is not + aware of the new hierarchy hack then the following references will be + both resolved to the local `attachment:file.txt:ticket:1`. + That's wrong. + +{{{ +Resource('product', 'PREFIX') ++-- Resource('ticket', 1) + +-- Resource('attachment', 'file.txt') + +Resource('ticket', 1) ++-- Resource('attachment', 'file.txt') +}}} + +==== Revert req.product_perm #resources-reject-req-product_perm + +Along the way [src:bep_0003_multiproduct/bloodhound_multiproduct/multiproduct/hooks.py] added `product_perm` method in request objects to instantiate permission cache objects in a given product context. This change clashes with ''Trac'' core and leads to [ticket:491 compatibility issues] . This method will not be necessary any more considering the fact that the same result will be achieved by executing the following statement. + +{{{ +#!py + +product_perm = req.perm(Neighborhood('product', 'PREFIX')) + +}}} + == Backwards Compatibility #backwards-compatibility The solution has to be compatible with single product solution whenever possible in order to make possible smooth upgrade paths from previous installations. This is particularly important for plugins to work out-of-the-box under the new circumstances or at least to make easier the upgrade development process for hack authors. @@ -671,6 +827,8 @@ }}} +Instances of `Neighborhood` class will satisfy the contract of `Resource` class. Some parameters (e.g. `version` and `parent`) will be ignored when appropriate. Therefore uniform access to both instances will be offered. That means that existing code will not raise any type error if an instance of `Resource` is substituted by an instance of `Neighborhood` class. + == Reference Implementation #reference-implementation Multi-product plugin is under active development by the ''Bloodhound'' community. It is possible to check out [https://svn.apache.org/repos/asf/incubator/bloodhound/trunk/bloodhound_multiproduct/ the source] using [http://subversion.apache.org/ Apache™ Subversion] by executing the following command -------8<------8<------8<------8<------8<------8<------8<------8<--------
-- Page URL: <https://issues.apache.org/bloodhound/wiki/Proposals/BEP-0003> Apache Bloodhound <https://issues.apache.org/bloodhound/> The Apache Bloodhound issue tracker This is an automated message. Someone added your email address to be notified of changes on 'Proposals/BEP-0003' page. If it was not you, please report to .
