Page "Proposals/BEP-0003/Routes" was added by olemis
Comment: bep:0003 Product routes specification (rejected)
Content:
-------8<------8<------8<------8<------8<------8<------8<------8<--------
= Routes web bootstrap handlers #routes

This wiki page documents formerly rejected proposal to implement dispatching by 
relying upon [http://routes.groovie.org/ Routes] framework. In first place 
there will be an instance of `routes.mapper.Mapper`. It will contain the 
definitions of the routes used to access product environments and their 
resources. Some variables in routes definitions will have special meaning 
though.

||= Variable =||= Purpose =||= Observations =||
|| `controller` || ''Ignored'' ||  ||
|| `action` || ''Ignored'' ||  ||
|| `envname` || Target environment name || Only used in multiple environment 
mode to determine target environment folder. Ignored otherwise. ||
|| `product` || Target product prefix || Represents  ||
|| `path_info` || Path to product resource or view  || Since paths under 
product base URL will be used to access anything that could be considered as 
belonging to the product, route definitions often will include 
[http://routes.readthedocs.org/en/latest/setting_up.html#magic-path-info 
path_info] to shift `SCRIPT_NAME` and `PATH_INFO` ''WSGI'' variables as 
expected ||

Considering the previous discussion ''Bloodhound'' will provide a modified copy 
of the main entry point for the web interface (i.e. the 
[http://www.python.org/dev/peps/pep-0333/ WSGI] function 
`trac.web.main.dispatch_request`) to make it aware of external routing 
information. It will be wrapped by a `routes.middleware.RoutesMiddleware` 
object responsible for route matching and ''WSGI'' environment updates. This 
fact is important to understand subsequent discussion taking place in this 
section.

Aforementioned data will be considered to dispatch requests in addition to the 
existing ''WSGI'' environment variables (i.e. `trac.env_path`, 
`trac.env_parent_dir`, `trac.env_index_template`, `trac.template_vars`, 
`trac.base_url`, `trac.env_paths`) or the equivalent global variables (i.e. 
`TRAC_ENV`, `TRAC_ENV_PARENT_DIR`, `TRAC_ENV_INDEX_TEMPLATE`, 
`TRAC_TEMPLATE_VARS`, `TRAC_BASE_URL`). The updated copy of 
`trac.web.main.dispatch_request` will read routing information like shown below

{{{
#!py

route = environ.get('routes.route')
match = environ.get('wsgiorg.routing_args', (None, {}) )[1]

}}}

== Environment lookup #env-dispatch

[=#env-dispatch] As a result the following rules will be used to determine the 
environment performing subsequent request dispatching :

  - If `match == {}` (equivalent to `route is None`)
    then no route was matched, hence respond with a 
    404 (''Not Found'') HTTP status code.
  - ... else if `match['envname']` is empty then no 
    specific environment was requested. 
    * For multi-environment deployments 
      (i.e. `TRAC_ENV_PARENT_DIR`) just render an 
      environment index page.
    * For single-environment deployments always 
      instantiate configured environment.
  - ... for multi-environment deployments, if 
    `match['envname']` is not empty then 
    instantiate the environment at the corresponding 
    child folder of the parent directory.
  - ... if `match['product']` is empty then the 
    global environment found up to this point will dispatch the 
    request
  - ... else if `match['product']` is set then 
    [../#product-env-api instantiate the product environment]
    for the corresponding product prefix. There will be
    an instance of `trac.web.main.RequestDispatcher`
    responsible for further request dispatching in that 
    context.

Sub-paths will be handled from there as usual.

== Product sub-domains #routes-domain

Routes for deployments based on [../#deploy-domain product domains] require 
special conditions to match ''HTTP'' `Host` header.

'''TODO'''

== Routes for sibling paths #routes-sibling-paths

[../#deploy-sibling-paths This case] is very similar to the 
[../MultienvParentDir reference multi-environment setup] .

Considering the [#routes enhanced routing mechanism] the following routes 
definition will be suitable for single-environment installations

{{{
#!py

>>> from wsgiref.util import setup_testing_defaults as wsgi_environ
>>> from routes import Mapper
>>> m = Mapper()
>>> m.connect(None, '/path/to/bloodhound/{product}/{path_info:.*}')
>>> m.match('/path/to/bloodhound/product1/ticket/1')
{'action': u'index', 'product': u'product1', 'controller': u'content', 
'path_info': 'ticket/1'}

}}}

If the global environment will be treated as yet another sibling product 
environment

{{{
#!py

>>> from wsgiref.util import setup_testing_defaults as wsgi_environ
>>> from routes import Mapper
>>> m = Mapper()
>>> m.connect(None, '/path/to/bloodhound/global/{path_info:.*}', product='')
>>> m.connect(None, '/path/to/bloodhound/{product}/{path_info:.*}')
>>> m.match('/path/to/bloodhound/global/ticket/1')
{'action': u'index', 'product': u'', 'controller': u'content', 'path_info': 
'ticket/1'}
>>> m.match('/path/to/bloodhound/product1/ticket/1')
{'action': u'index', 'product': u'product1', 'controller': u'content', 
'path_info': 'ticket/1'}

}}}

For multi-environment installations

{{{
#!py

>>> from wsgiref.util import setup_testing_defaults as wsgi_environ
>>> from routes import Mapper
>>> m = Mapper()
>>> m.connect(None, '/path/to/bloodhound/{envname}/{product}/{path_info:.*}')
>>> m.match('/path/to/bloodhound/enterprise/product1/ticket/1')
{'action': u'index', 'product': u'product1', 'envname': u'enterprise', 
'controller': u'content', 'path_info': 'ticket/1'}

}}}

== Embedded product path namespace #routes-global-env-embed

Even if [../#deploy-global-env-embed embedded product path namespace] case is 
very similar to the [../MultienvParentDir reference multi-environment setup] a 
better match will be another setup based on [TracHacks:TracWsgiPlugin]. The 
main difference with respect to [#routes-sibling-paths sibling paths] 
deployment is that the global environment plays an active role dispatching the 
requests addressed to an specific product by forwarding them to the 
corresponding product environment.

This particular case does not even need to make use of the [#routes enhanced 
routing mechanism]. Instead of external routes definitions, a component 
(request handler) will be enabled in the global environment. It will handle 
requests sent to sub-paths of the form `product/<product 
prefix>/path/to/resource` relative to the global environment's base URL. 
Products base URL will be `product/<product prefix>` as a result. In its 
`process_request` method it will forward request dispatching to the instance of 
`trac.web.main.RequestDispatcher` of the corresponding product environment.

== Product sub domain + path namespace #routes-domain-path

[../#deploy-domain-path Product sub domain + path namespace] will be 
implemented as follows.

'''TODO'''

== Complex dispatch scenaries #routes-complex-path

When dealing with [../#deploy-complex-path complex dispatch scenaries] 
considering the [#routes enhanced routing mechanism] the following definitions 
will be suitable for single-environment installations

{{{
#!py

>>> from wsgiref.util import setup_testing_defaults as wsgi_environ
>>> from routes import Mapper
>>> m = Mapper()
>>> m.connect(None, 
>>> '/path/to/bloodhound/{product}/path/to/bloodhound/{path_info:.*}')
>>> m.match('/path/to/bloodhound/product1/path/to/bloodhound/ticket/1')
{'action': u'index', 'product': u'product1', 'controller': u'content', 
'path_info': 'ticket/1'}

}}}

The example mentioned above for ''Allura'' 

{{{
#!py

>>> from wsgiref.util import setup_testing_defaults as wsgi_environ
>>> from routes import Mapper
>>> m = Mapper()
>>> m.connect(None, '/p/{product}/bloodhound/{path_info:.*}')
>>> m.match('/p/product1/bloodhound/ticket/1')
{'action': u'index', 'product': u'product1', 'controller': u'content', 
'path_info': 'ticket/1'}

}}}

For multi-environment installations

{{{
#!py

>>> from wsgiref.util import setup_testing_defaults as wsgi_environ
>>> from routes import Mapper
>>> m = Mapper()
>>> m.connect(None, 
>>> '/{envname}/path/to/bloodhound/{product}/path/to/bloodhound/{path_info:.*}')
>>> m.match('/company/path/to/bloodhound/product1/path/to/bloodhound/ticket/1')
{'action': u'index', 'product': u'product1', 'envname': u'company', 
'controller': u'content', 'path_info': 'ticket/1'}

}}}


-------8<------8<------8<------8<------8<------8<------8<------8<--------

--
Page URL: <https://issues.apache.org/bloodhound/wiki/Proposals/BEP-0003/Routes>
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/Routes' page.
If it was not you, please report to .

Reply via email to