Diff URL: <
https://issues.apache.org/**bloodhound/wiki/Proposals/BEP-**
0003?action=diff&version=7<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 <https://issues.apache.org/bloodhound/wiki/Proposals/BEP-0003>>
Apache Bloodhound
<https://issues.apache.org/**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 .