Page "Proposals/BEP-0003" was changed by olemis Diff URL: <https://issues.apache.org/bloodhound/wiki/Proposals/BEP-0003?action=diff&version=7> Revision 7 Comment: [BEP-0003] Towards an introduction to product environments (not finished) Changes: -------8<------8<------8<------8<------8<------8<------8<------8<-------- Index: Proposals/BEP-0003 ========================================================================= --- Proposals/BEP-0003 (version: 6) +++ Proposals/BEP-0003 (version: 7) @@ -24,27 +24,127 @@ == Motivation == -Nowadays it is possible to manage multiple projects by creating multiple environments. As a consequence data is scattered across multiple databases and maintenance tasks turn out to be more difficult. Since a long time users have expressed the need for managing multiple ''projects'' in an easy way . In the case of a family of related products it is usually important to have a unified view on the development activity as well as the ability to share common resources among them. Under those circumstances it is convenient to manage multiple products within a single ''Trac'' environment. +Nowadays it is possible to manage multiple projects by creating multiple environments. One notable example is [./MultienvParentDir the multi-environment setup] considered as a reference for this specification. As a consequence data is scattered across multiple databases and maintenance tasks turn out to be more difficult. Since a long time users have expressed the need for managing multiple ''projects'' in an easy way . In the case of a family of related products it is usually important to have a unified view on the development activity as well as the ability to share common resources among them. Under those circumstances it is convenient to manage multiple products within a single ''Trac'' environment. The term ''project'' is very generic and may be confusing considering the context. Therefore in this specification the word ''product'' is used instead . == Proposal #proposal -'''TODO''' +In a few words the current proposal tries to reproduce a well-known [./MultienvParentDir multi-environment setup] inside a single enviroment. In this section you'll find the most important details necessary to implement multi-product support. In order to understand the reasons that make this is a valid and reliable specification, please see [#rationale Rationale] below. In order and know more about similar alternatives rejected along the way, please consult [#rejected Rejected ideas] below. + +=== Product environments #product-envs + +The key design mechanism is known as ''product environments'' . Their main goal is to provide components (both in core and those defined by plugins) with a lightweight virtual representation of an isolated environment inside the ''global'' environment when dealing with requests addressed to a resource owned by a product. The following figure illustrates how they work. + +[[Image(Product_environments.png)]] + +If you notice similarities with the [attachment:wiki:Proposals/BEP-0003/MultienvParentDir:Multienv_small.png reference multi-environment setup] it is an intentional design decision. + +=== Product extensions to the trac.env.Environment API #product-env-api + +There is no need to create ''product environments'' explicitly via [TracAdmin trac-admin] commands. Provided that the target product exists in the database, they will be instantiated like shown in the following code snippet. The instance of `trac.env.Environment` representing the global environment will be accessed via `parent_env` attribute. The target product will be available in `product` attribute. + +{{{ +#!py + +>>> env +<trac.env.Environment object at 0x7faacb1e9490> +>>> from multiproduct.env import ProductEnvironment +>>> product_env = ProductEnvironment(env, product_prefix) +>>> product_env.parent_env +<trac.env.Environment object at 0x7faacb1e9490> +>>> product_env.product +<multiproduct.model.Product object at 0x35566d0> + +}}} + +Product environments will not be recursive , which means that the following statement will fail + +{{{ +#!py + +>>> new_product_env = ProductEnvironment(product_env, product_prefix) +Traceback (most recent call last): + File "<stdin>", line 1, in <module> +TypeError: Initializer must be called with + trac.env.Environment instance as first argument + (got multiproduct.env.ProductEnvironment instance instead) + +}}} + +Instantiating a component involved in multi-product architecture will always return `None`, just like if it was disabled e.g. + +{{{ +#!py + +>>> ps = product.api.MultiProductSystem(product_env) +>>> repr(ps) +None +}}} + +''Product environments'' will implement both `trac.core.ComponentManager` and `trac.core.Component` APIs by inheriting most of the properties of the global `trac.env.Environment`, so they will act as wrappers. As a consequence instances will have its own components cache, which means that every active component class will only have a single instance for every product environment. + +The following list explains how product environments will adapt existing environment API while still being compatible with it. + + - '''[=#product-env-conf] conf''' will contain an + instance of `trac.conf.Configuration` (or equivalent) setup in + such a way that it reads product-specific + settings from a file located at path + `./conf/product_<product prefix>.ini` relative + to the global environment's directory and + inherits globals settings stored in + `./conf/trac.ini` file. Some exceptions needs to + be installed in place. + * '''TODO''' + - '''[=#product-env-shared_plugins_dir] shared_plugins_dir''' will always be empty . There + will be no way to deploy plugins for a particular + product, just enable/disable those installed in + the global environment. + - '''TODO''' + +[=#product-env-idem] The following methods and options will behave exactly the same as the corresponding `parent_env`'s methods: ''get_system_info'' , ''components_section'' , '''TODO''' . == Rationale #rationale The following is a list of proposed features for multi product support in ''Bloodhound''. Goals related to compatibility are considered in [#backwards-compatibility Backwards compatibility] below. In each case you'll find notes explaining how candidate implementation will solve related issues. +=== Per product ticket workflow #workflow + +Depending on the product, different ticket workflows should be supported. + +=== Per product notifications + +Notifications should be configurable per product. + +=== Per product ticket field configuration + +Components, milestone, version, priority, defaults, custom fields should be configurable per product. + +=== Per product permission scheme #permissions + +Permission scheme is defined by assigning permissions (from a predefined permission list) to specific users or groups. Permission scheme is assigned to a product. + +==== Product roles #roles + +Support for per product user groups. Roles can be used to configure notifications and permissions per product. + === Product resources namespaces #url-mapping -Product and resource ID should form a two dimensional namespace. The mapping - -Each resource would in addition to current URL scheme also be addressable through the product URL namespace, namely /ticket/<product prefix>/<local ticket id>. +Product and resource ID should form a two dimensional namespace. The mapping should be flexible enough to support the following scenarios . + + - '''Product path namespace''' : '''TODO''' + - '''Product sub domain''' : '''TODO''' + - '''Product sub domain + path namespace''' : '''TODO''' + +'''FIXME''' also be addressable through the product URL namespace, namely /ticket/<product prefix>/<local ticket id>. + +In a multi-product configuration product resources should not be accessed using current global URL scheme (i.e. /path/to/bloodhound/<environment>/<realm>/<id>). '''TODO''' why ? ==== Tickets #tickets-namespace -Each product would have a separate number sequence for product ticket IDs. +Tickets will keep their absolute ID and will be unique in the context of the global environment. Besides each product would have a separate number sequence for product ticket IDs. + + '''TODO:''' Implementation details TBD === Resources moveable between products #migration-resource @@ -54,30 +154,10 @@ By default, search is global. Search and queries should allow search queries to be limited to specific product. -=== Per product ticket workflow #workflow - -Depending on the product, different ticket workflows should be supported. - === Inter product ticket relations It should be possible to link tickets from different products. -=== Per product notifications - -Notifications should be configurable per product. - -=== Per product ticket field configuration - -Components, milestone, version, priority, defaults, custom fields should be configurable per product. - -=== Per product permission scheme #permissions - -Permission scheme is defined by assigning permissions (from a predefined permission list) to specific users or groups. Permission scheme is assigned to a product. - -==== Product roles #roles - -Support for per product user groups. Roles can be used to configure notifications and permissions per product. - === Per product repository #vcs Each product can have different repository (and type) assigned. @@ -89,6 +169,23 @@ == 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. + +''Product environments'' in proposed multi-product configuration will act as the replacement for sibling environments under common parent directory in [./MultienvParentDir reference multi-environments setup]. They will ensure that the correct translations will be performed for requests addressed to resources owned by a product using the `trac.env.Environment` API as usual. Components will have access to it by reading `self.env` attribute (as usual !!!). All this means that from a component perspective the very same operations will be invoked , thus plugins adaptation to the new conditions will be rather smooth. If plugins do want to know whether they are acting on behalf of a product environment or the global environment then the following conditional statement would be enough + +{{{ +#!py + +from trac.env import Environment +from multiproduct.env import ProductEnvironment + +if isinstance(self.env, Environment): + # Trac environment +elif isinstance(self.env, ProductEnvironment): + # Product environment ... activate super-powers ! +else: + # Unidentified environment object ... aliens & zombies ! + +}}} == Reference Implementation #reference-implementation -------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 (incubating) 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 .
