分享

OpenStack Cinder服务启动过程中的资源加载和扩展源码解析之二

shihailong123 发表于 2014-11-22 15:18:38 [显示全部楼层] 回帖奖励 阅读模式 关闭右栏 0 9294
问题导读

1、self._setup_routes(mapper, ext_mgr)方法的具体实现是怎样的?
2、调用mapper.connect和mapper.resource方法的作用?




(2) self._setup_routes(mapper, ext_mgr)
现在我们回到类/cinder/api/openstack/__init__.py----class APIRouter中的初始化方法:
  1. class APIRouter(base_wsgi.Router):
  2.     def __init__(self, ext_mgr=None):
  3.         if ext_mgr is None:
  4.             if self.ExtensionManager:
  5.                 ext_mgr = self.ExtensionManager() (1)
  6.             else:
  7.                 raise Exception(_("Must specify an ExtensionManager class"))
  8.         
  9.         mapper = ProjectMapper()        
  10.         self.resources = {}
  11.         self._setup_routes(mapper, ext_mgr) (2)
  12.         self._setup_ext_routes(mapper, ext_mgr) (3)
  13.         self._setup_extensions(ext_mgr) (4)
  14.         super(APIRouter, self).__init__(mapper) (5)
复制代码

来看第二条比较重要的语句:self._setup_routes(mapper, ext_mgr),具体来看方法_setup_routes的实现:

  1. def _setup_routes(self, mapper, ext_mgr):
  2.         """
  3.         mapper = Route name Methods Path
  4.         mapper.connect = <b>>
  5.         
  6.         # 示例:
  7.         # map.resource("message", "messages", collection={"rss": "GET"})
  8.         # "GET /message/rss"  =>  ``Messages.rss()``.
  9.         # map.resource('message', 'messages', member={'mark':'POST'})
  10.         # "POST /message/1/mark"  =>  ``Messages.mark(1)``
  11.         """
  12.         self.resources['versions'] = versions.create_resource()
  13.         mapper.connect("versions", "/",
  14.                        controller=self.resources['versions'],
  15.                        action='show')
  16.         """
  17.         mapper =
  18.         Route name         Methods Path
  19.         versions           /
  20.         """
  21.                
  22.         mapper.redirect("", "/")
  23.         self.resources['volumes'] = volumes.create_resource(ext_mgr)
  24.         mapper.resource("volume", "volumes",
  25.                         controller=self.resources['volumes'],
  26.                         collection={'detail': 'GET'},
  27.                         member={'action': 'POST'})
  28.         """
  29.         mapper =
  30.         Route name               Methods Path                                       
  31.         ......                   ......
  32.                                  POST    /{project_id}/volumes.:(format)            
  33.                                  POST    /{project_id}/volumes                       
  34.         formatted_detail_volumes GET     /{project_id}/volumes/detail.:(format)      
  35.         detail_volumes           GET     /{project_id}/volumes/detail               
  36.         formatted_volumes        GET     /{project_id}/volumes.:(format)            
  37.         volumes                  GET     /{project_id}/volumes                       
  38.         formatted_new_volume     GET     /{project_id}/volumes/new.:(format)         
  39.         new_volume               GET     /{project_id}/volumes/new                  
  40.                                  PUT     /{project_id}/volumes/:(id).:(format)      
  41.                                  PUT     /{project_id}/volumes/:(id)                 
  42.         formatted_action_volume  POST    /{project_id}/volumes/:(id)/action.:(format)
  43.         action_volume            POST    /{project_id}/volumes/:(id)/action         
  44.                                  DELETE  /{project_id}/volumes/:(id).:(format)      
  45.                                  DELETE  /{project_id}/volumes/:(id)                 
  46.         formatted_edit_volume    GET     /{project_id}/volumes/:(id)/edit.:(format)  
  47.         edit_volume              GET     /{project_id}/volumes/:(id)/edit            
  48.         formatted_volume         GET     /{project_id}/volumes/:(id).:(format)      
  49.         volume                   GET     /{project_id}/volumes/:(id)                 
  50.         """
  51.                
  52.         self.resources['types'] = types.create_resource()
  53.         mapper.resource("type", "types",
  54.                         controller=self.resources['types'])
  55.         """
  56.         mapper =
  57.         Route name               Methods Path                                       
  58.         ......                   ......
  59.                                  POST    /{project_id}/types.:(format)               
  60.                                  POST    /{project_id}/types                        
  61.         formatted_types          GET     /{project_id}/types.:(format)               
  62.         types                    GET     /{project_id}/types                        
  63.         formatted_new_type       GET     /{project_id}/types/new.:(format)           
  64.         new_type                 GET     /{project_id}/types/new                     
  65.                                  PUT     /{project_id}/types/:(id).:(format)         
  66.                                  PUT     /{project_id}/types/:(id)                  
  67.                                  DELETE  /{project_id}/types/:(id).:(format)         
  68.                                  DELETE  /{project_id}/types/:(id)                  
  69.         formatted_edit_type      GET     /{project_id}/types/:(id)/edit.:(format)   
  70.         edit_type                GET     /{project_id}/types/:(id)/edit              
  71.         formatted_type           GET     /{project_id}/types/:(id).:(format)         
  72.         type                     GET     /{project_id}/types/:(id)                  
  73.         """
  74.               
  75.         self.resources['snapshots'] = snapshots.create_resource(ext_mgr)
  76.         mapper.resource("snapshot", "snapshots",
  77.                         controller=self.resources['snapshots'],
  78.                         collection={'detail': 'GET'},
  79.                         member={'action': 'POST'})
  80.         """
  81.         mapper =
  82.         Route name                 Methods Path                                          
  83.         ......                     ......                 
  84.                                    POST    /{project_id}/snapshots.:(format)            
  85.                                    POST    /{project_id}/snapshots                       
  86.         formatted_detail_snapshots GET     /{project_id}/snapshots/detail.:(format)      
  87.         detail_snapshots           GET     /{project_id}/snapshots/detail               
  88.         formatted_snapshots        GET     /{project_id}/snapshots.:(format)            
  89.         snapshots                  GET     /{project_id}/snapshots                       
  90.         formatted_new_snapshot     GET     /{project_id}/snapshots/new.:(format)         
  91.         new_snapshot               GET     /{project_id}/snapshots/new                  
  92.                                    PUT     /{project_id}/snapshots/:(id).:(format)      
  93.                                    PUT     /{project_id}/snapshots/:(id)                 
  94.         formatted_action_snapshot  POST    /{project_id}/snapshots/:(id)/action.:(format)
  95.         action_snapshot            POST    /{project_id}/snapshots/:(id)/action         
  96.                                    DELETE  /{project_id}/snapshots/:(id).:(format)      
  97.                                    DELETE  /{project_id}/snapshots/:(id)                 
  98.         formatted_edit_snapshot    GET     /{project_id}/snapshots/:(id)/edit.:(format)  
  99.         edit_snapshot              GET     /{project_id}/snapshots/:(id)/edit            
  100.         formatted_snapshot         GET     /{project_id}/snapshots/:(id).:(format)      
  101.         snapshot                   GET     /{project_id}/snapshots/:(id)                 
  102.         """
  103.                
  104.         self.resources['snapshot_metadata'] = snapshot_metadata.create_resource()
  105.         snapshot_metadata_controller = self.resources['snapshot_metadata']
  106.         mapper.resource("snapshot_metadata", "metadata",
  107.                         controller=snapshot_metadata_controller,
  108.                         parent_resource=dict(member_name='snapshot',
  109.                                              collection_name='snapshots'))
  110.         """
  111.         mapper =
  112.         Route name                                Methods Path                                                              
  113.         ......                                    ......                                                
  114.                                                   POST    /{project_id}/snapshots/:snapshot_id/metadata.:(format)           
  115.                                                   POST    /{project_id}/snapshots/:snapshot_id/metadata                     
  116.         formatted_snapshot_metadata               GET     /{project_id}/snapshots/:snapshot_id/metadata.:(format)           
  117.         snapshot_metadata                         GET     /{project_id}/snapshots/:snapshot_id/metadata                     
  118.         formatted_snapshot_new_snapshot_metadata  GET     /{project_id}/snapshots/:snapshot_id/metadata/new.:(format)      
  119.         snapshot_new_snapshot_metadata            GET     /{project_id}/snapshots/:snapshot_id/metadata/new                 
  120.                                                   PUT     /{project_id}/snapshots/:snapshot_id/metadata/:(id).:(format)     
  121.                                                   PUT     /{project_id}/snapshots/:snapshot_id/metadata/:(id)               
  122.                                                   DELETE  /{project_id}/snapshots/:snapshot_id/metadata/:(id).:(format)     
  123.                                                   DELETE  /{project_id}/snapshots/:snapshot_id/metadata/:(id)               
  124.         formatted_snapshot_edit_snapshot_metadata GET     /{project_id}/snapshots/:snapshot_id/metadata/:(id)/edit.:(format)
  125.         snapshot_edit_snapshot_metadata           GET     /{project_id}/snapshots/:snapshot_id/metadata/:(id)/edit         
  126.         formatted_snapshot_snapshot_metadata      GET     /{project_id}/snapshots/:snapshot_id/metadata/:(id).:(format)     
  127.         snapshot_snapshot_metadata                GET     /{project_id}/snapshots/:snapshot_id/metadata/:(id)               
  128.         """
  129.                
  130.         mapper.connect("metadata",
  131.                        "/{project_id}/snapshots/{snapshot_id}/metadata",
  132.                        controller=snapshot_metadata_controller,
  133.                        action='update_all',
  134.                        conditions={"method": ['PUT']})
  135.         """
  136.         mapper =
  137.         Route name                                Methods Path
  138.         ......                                    ......                                                
  139.         metadata                                  PUT     /{project_id}/snapshots/{snapshot_id}/metadata               
  140.         """
  141.                
  142.         self.resources['limits'] = limits.create_resource()
  143.         mapper.resource("limit", "limits",controller=self.resources['limits'])
  144.         """
  145.         mapper =
  146.         Route name                                Methods Path
  147.         ......                                    ......                                                         
  148.                                                   POST    /{project_id}/limits.:(format)                                    
  149.                                                   POST    /{project_id}/limits                                             
  150.         formatted_limits                          GET     /{project_id}/limits.:(format)                                    
  151.         limits                                    GET     /{project_id}/limits                                             
  152.         formatted_new_limit                       GET     /{project_id}/limits/new.:(format)                                
  153.         new_limit                                 GET     /{project_id}/limits/new                                          
  154.                                                   PUT     /{project_id}/limits/:(id).:(format)                              
  155.                                                   PUT     /{project_id}/limits/:(id)                                       
  156.                                                   DELETE  /{project_id}/limits/:(id).:(format)                              
  157.                                                   DELETE  /{project_id}/limits/:(id)                                       
  158.         formatted_edit_limit                      GET     /{project_id}/limits/:(id)/edit.:(format)                        
  159.         edit_limit                                GET     /{project_id}/limits/:(id)/edit                                   
  160.         formatted_limit                           GET     /{project_id}/limits/:(id).:(format)                              
  161.         limit                                     GET     /{project_id}/limits/:(id)               
  162.         """
  163.                
  164.         self.resources['volume_metadata'] = volume_metadata.create_resource()
  165.         volume_metadata_controller = self.resources['volume_metadata']
  166.         mapper.resource("volume_metadata", "metadata",
  167.                         controller=volume_metadata_controller,
  168.                         parent_resource=dict(member_name='volume',
  169.                                              collection_name='volumes'))
  170.         """
  171.         mapper =
  172.         Route name                                Methods Path
  173.         ......                                    ......                                                         
  174.                                                   POST    /{project_id}/volumes/:volume_id/metadata.:(format)               
  175.                                                   POST    /{project_id}/volumes/:volume_id/metadata                        
  176.         formatted_volume_metadata                 GET     /{project_id}/volumes/:volume_id/metadata.:(format)               
  177.         volume_metadata                           GET     /{project_id}/volumes/:volume_id/metadata                        
  178.         formatted_volume_new_volume_metadata      GET     /{project_id}/volumes/:volume_id/metadata/new.:(format)           
  179.         volume_new_volume_metadata                GET     /{project_id}/volumes/:volume_id/metadata/new                     
  180.                                                   PUT     /{project_id}/volumes/:volume_id/metadata/:(id).:(format)         
  181.                                                   PUT     /{project_id}/volumes/:volume_id/metadata/:(id)                  
  182.                                                   DELETE  /{project_id}/volumes/:volume_id/metadata/:(id).:(format)         
  183.                                                   DELETE  /{project_id}/volumes/:volume_id/metadata/:(id)                  
  184.         formatted_volume_edit_volume_metadata     GET     /{project_id}/volumes/:volume_id/metadata/:(id)/edit.:(format)   
  185.         volume_edit_volume_metadata               GET     /{project_id}/volumes/:volume_id/metadata/:(id)/edit              
  186.         formatted_volume_volume_metadata          GET     /{project_id}/volumes/:volume_id/metadata/:(id).:(format)         
  187.         volume_volume_metadata                    GET     /{project_id}/volumes/:volume_id/metadata/:(id)                  
  188.         """
  189.                
  190.         mapper.connect("metadata",
  191.                        "/{project_id}/volumes/{volume_id}/metadata",
  192.                        controller=volume_metadata_controller,
  193.                        action='update_all',
  194.                        conditions={"method": ['PUT']})
  195.         """
  196.         mapper =
  197.         Route name                                Methods Path                                                              
  198.         ......                                    ......                                                         
  199.         metadata                                  PUT     /{project_id}/volumes/{volume_id}/metadata                        
  200.         """</b>
复制代码

这里调用了方法mapper.connect和mapper.resource,实现进而调用python库routes,来实现从url提取相应的参数,如controller,action或者其它用户自己定义的变量,从而实现URL和相应action的映射。具体实现没有进行解析。也就是可以简单的理解为,通过得到的URL,通过这里实现的映射关系,进行格式匹配,具体定位到所要调用的方法上。具体的输出示例,如上述源码中已经给出,可以作为参考。
需要注意的是,这里实现的是模块中正规的功能的URL和具体方法的映射关系,也就是/cinder/api/v1/或者是/cinder/api/v2/包下的各个py文件中控制类下的功能方法。对于扩展功能方法的URL映射关系,在后面的语句中进行了实现。
(3)self._setup_ext_routes(mapper, ext_mgr)
来看方法/cinder/api/openstack/__init__.py----class APIRouter----def __init__中第三条比较重要的语句:
self._setup_ext_routes(mapper, ext_mgr)
具体来看方法_setup_ext_routes的源码实现:

  1. def _setup_ext_routes(self, mapper, ext_mgr):
  2.         """
  3.         mapper =
  4.         Route name                                Methods Path                                                              
  5.         versions                                          /                                                                 
  6.         ......                                    ......  ......                  
  7.         formatted_volume_edit_volume_metadata     GET     /{project_id}/volumes/:volume_id/metadata/:(id)/edit.:(format)   
  8.         volume_edit_volume_metadata               GET     /{project_id}/volumes/:volume_id/metadata/:(id)/edit              
  9.         formatted_volume_volume_metadata          GET     /{project_id}/volumes/:volume_id/metadata/:(id).:(format)         
  10.         volume_volume_metadata                    GET     /{project_id}/volumes/:volume_id/metadata/:(id)                  
  11.         metadata                                  PUT     /{project_id}/volumes/{volume_id}/metadata  
  12.         """
  13.         # ext_mgr.get_resources():获取ResourceExtension对象列表;
  14.         for resource in ext_mgr.get_resources():
  15.             LOG.debug(_('Extended resource: %s'), resource.collection)
  16.             wsgi_resource = wsgi.Resource(resource.controller)
  17.             self.resources[resource.collection] = wsgi_resource
  18.             kargs = dict(
  19.                 controller=wsgi_resource,
  20.                 collection=resource.collection_actions,
  21.                 member=resource.member_actions)
  22.             
  23.             if resource.parent:
  24.                 kargs['parent_resource'] = resource.parent
  25.             mapper.resource(resource.collection, resource.collection, **kargs)
  26.             if resource.custom_routes_fn:
  27.                 resource.custom_routes_fn(mapper, wsgi_resource)
复制代码

注:需要说明的是在/cinder/api/contrib/目录下的文件都是用来实现功能扩展的,这里主要分为两部分:1.在一个控制器中单纯地实现新的Restful资源功能;2.在一个控制器中即可实现新的Restful资源功能又可对已有的Restful资源功能实现扩展。
方法_setup_ext_routes中针对的是上述第一类,也就是在一个控制器中单纯地实现新的Restful资源功能。这个方法主要实现了两部分的功能,即得到alias和self.extensions[alias]一一对应的关系,以及获取新定义Restful资源功能的URL和具体功能方法的映射关系。
首先来看方法中的语句:
for resource in ext_mgr.get_resources()
    wsgi_resource = wsgi.Resource(resource.controller)
来看输出示例:
  1. resource.controller = <cinder.api.extensions.ExtensionsResource object at 0x3579bd0>
  2. resource.controller = <cinder.api.contrib.hosts.HostController object at 0x3579cd0>
  3. resource.controller = <cinder.api.contrib.quotas.QuotaSetsController object at 0x3579d90>
  4. resource.controller = <cinder.api.contrib.volume_encryption_metadata.VolumeEncryptionMetadataController object at 0x3579e10>
  5. resource.controller = <cinder.api.contrib.backups.BackupsController object at 0x3579ed0>
  6. resource.controller = <cinder.api.contrib.volume_type_encryption.VolumeTypeEncryptionController object at 0x35cf050>
  7. resource.controller = <cinder.api.contrib.availability_zones.Controller object at 0x35cf450>
  8. resource.controller = <cinder.api.contrib.types_extra_specs.VolumeTypeExtraSpecsController object at 0x35cf490>
  9. resource.controller = <cinder.api.contrib.qos_specs_manage.QoSSpecsController object at 0x35cf550>
  10. resource.controller = <cinder.api.contrib.quota_classes.QuotaClassSetsController object at 0x35cf5d0>
  11. resource.controller = <cinder.api.contrib.volume_transfer.VolumeTransferController object at 0x35cf890>
  12. resource.controller = <cinder.api.contrib.services.ServiceController object at 0x35cf710>
复制代码



我们看到这里除了cinder.api.extensions.ExtensionsResource,一共实现了11个扩展类的变量controller的值,应该是在这22个扩展功能的实现类中,其中的11个中实现了方法get_resources。我们继续来看方法get_resources的具体实现:

  1. def get_resources(self):
  2.         """
  3.         Returns a list of ResourceExtension objects.
  4.         获取ResourceExtension对象列表;
  5.         """
  6.         resources = []
  7.         resources.append(ResourceExtension('extensions',ExtensionsResource(self)))
  8.         for ext in self.extensions.values():
  9.             try:
  10.                 resources.extend(ext.get_resources())
  11.                
  12.             except AttributeError:
  13.                 pass
  14.         return resources
复制代码

我们首先来看输出示例:
self.extensions = {
        'OS-SCH-HNT': ,
        'os-hosts': ,
        'os-vol-tenant-attr': ,
        'os-quota-sets': ,
        'os-types-manage': ,
        'os-volume-encryption-metadata': ,
        'os-snapshot-actions': ,
        'backups': ,
        'os-volume-actions': ,
        'os-vol-host-attr': ,
        'encryption': ,
        'os-availability-zone': ,
        'os-types-extra-specs': ,
        'os-vol-mig-status-attr': ,
        'os-image-create': ,
        'os-extended-snapshot-attributes': ,
        'qos-specs': ,
        'os-quota-class-sets': ,
        'os-volume-transfer': ,
        'os-vol-image-meta': ,
        'os-admin-actions': ,
        'os-services': }
我们可以看到,这里实现了22个alias和具体实现类的对应字典,即是上篇博客中分析的语句ext_mgr = self.ExtensionManager()所实现的扩展功能目录下所有功能alias和具体实现类的对应。
通过一一到具体类中的验证,我们可以发现其中10个类只实现了方法get_resources,10个类只实现了方法get_controller_extensions,而1个类中即实现了方法get_resources也实现了方法get_controller_extensions。还有一个类中两个方法都没由直接实现;
输出示例(分类):
只实现了方法get_resources:
  1. ext = <cinder.api.contrib.hosts.Hosts object at 0x18b0b50>               
  2. ext = <cinder.api.contrib.quotas.Quotas object at 0x1908250>               
  3. ext = <cinder.api.contrib.volume_encryption_metadata.Volume_encryption_metadata object at 0x18b0750>               
  4. ext = <cinder.api.contrib.backups.Backups object at 0x226f810>              
  5. ext = <cinder.api.contrib.availability_zones.Availability_zones object at 0x226f290>
  6. ext = <cinder.api.contrib.types_extra_specs.Types_extra_specs object at 0x18f91d0>               
  7. ext = <cinder.api.contrib.qos_specs_manage.Qos_specs_manage object at 0x236a490>
  8. ext = <cinder.api.contrib.quota_classes.Quota_classes object at 0x18b0a50>
  9. ext = <cinder.api.contrib.volume_transfer.Volume_transfer object at 0x2282cd0>              
  10. ext = <cinder.api.contrib.services.Services object at 0x18f9c90>
复制代码


只实现了方法get_controller_extensions:
  1. ext = <cinder.api.contrib.volume_image_metadata.Volume_image_metadata object at 0x236ae90>
  2. ext = <cinder.api.contrib.admin_actions.Admin_actions object at 0x2282910>
  3. ext = <cinder.api.contrib.volume_mig_status_attribute.Volume_mig_status_attribute object at 0x18f9710>
  4. ext = <cinder.api.contrib.volume_actions.Volume_actions object at 0x226f910>
  5. ext = <cinder.api.contrib.snapshot_actions.Snapshot_actions object at 0x18b0510>
  6. ext = <cinder.api.contrib.types_manage.Types_manage object at 0x2277c10>
  7. ext = <cinder.api.contrib.volume_tenant_attribute.Volume_tenant_attribute object at 0x236aa90>
  8. ext = <cinder.api.contrib.scheduler_hints.Scheduler_hints object at 0x18f9a10>
  9. ext = <cinder.api.contrib.volume_host_attribute.Volume_host_attribute object at 0x1908050>
  10. ext = <cinder.api.contrib.extended_snapshot_attributes.Extended_snapshot_attributes object at 0x2282090>
复制代码

即实现了方法get_resources也实现了方法get_controller_extensions:
  1. ext = <cinder.api.contrib.volume_type_encryption.Volume_type_encryption object at 0x18b01d0>
复制代码


两个方法都没由直接实现:
  1. ext = <cinder.api.contrib.image_create.Image_create object at 0x18b05d0>
复制代码


经上分析,返回了11个类ResourceExtension的初始化对象;
来看方法get_resources中的语句:resources.extend(ext.get_resources()),这里的方法get_resources()调用了具体类中的get_resources()方法,而类中没有实现get_resources()方法的,在其父类class ExtensionDescriptor(object)中有实现,我们来看具体的类中get_resources的实现,我简单进行了一个归纳:
直接实现了方法get_resources的类(看几个例子,看一下实现过程):

  1. ext = <cinder.api.contrib.backups.Backups object at 0x226f810>:
  2. class Backups(extensions.ExtensionDescriptor):
  3.     """Backups support."""
  4.     name = 'Backups'
  5.     alias = 'backups'
  6.     namespace = 'http://docs.openstack.org/volume/ext/backups/api/v1'
  7.     updated = '2012-12-12T00:00:00+00:00'
  8.     def get_resources(self):
  9.         resources = []
  10.         res = extensions.ResourceExtension(
  11.             Backups.alias,
  12.             BackupsController(),
  13.             collection_actions={'detail': 'GET'},
  14.             member_actions={'restore': 'POST'})
  15.         resources.append(res)
  16.         return resources
  17. class BackupsController(wsgi.Controller):
  18.     """
  19.     The Backups API controller for the OpenStack API.
  20.     OpenStack的备份操作API控制器;
  21.     """
  22.     _view_builder_class = backup_views.ViewBuilder
  23.     def __init__(self):
  24.         self.backup_api = backupAPI.API()
  25.         super(BackupsController, self).__init__()
  26. class Controller(object):
  27.     """Default controller."""
  28.     __metaclass__ = ControllerMetaclass
  29.     _view_builder_class = None
  30.     def __init__(self, view_builder=None):
  31.         """Initialize controller with a view builder instance."""
  32.         if view_builder:
  33.             self._view_builder = view_builder
  34.         elif self._view_builder_class:
  35.             self._view_builder = self._view_builder_class()
  36.         else:
  37.             self._view_builder = None
  38. ==========================================================
  39. ext = <cinder.api.contrib.hosts.Hosts object at 0x18b0b50>:
  40. class Hosts(extensions.ExtensionDescriptor):
  41.     """Admin-only host administration"""
  42.     name = "Hosts"
  43.     alias = "os-hosts"
  44.     namespace = "http://docs.openstack.org/volume/ext/hosts/api/v1.1"
  45.     updated = "2011-06-29T00:00:00+00:00"
  46.     def get_resources(self):
  47.         resources = [extensions.ResourceExtension('os-hosts',
  48.                                                   HostController(),
  49.                                                   collection_actions={'update': 'PUT'},
  50.                                                   member_actions={
  51.                                                       'startup': 'GET',
  52.                                                       'shutdown': 'GET',
  53.                                                       'reboot': 'GET'})]
  54.         return resources
  55. class HostController(object):
  56.     """
  57.     The Hosts API controller for the OpenStack API.
  58.     主机控制API;
  59.     """
  60.     def __init__(self):
  61.         self.api = volume_api.HostAPI()
  62.         super(HostController, self).__init__()
  63. ==========================================================
  64. ext = <cinder.api.contrib.quotas.Quotas object at 0x1908250>:
  65. class Quotas(extensions.ExtensionDescriptor):
  66.     """Quotas management support"""
  67.     name = "Quotas"
  68.     alias = "os-quota-sets"
  69.     namespace = "http://docs.openstack.org/volume/ext/quotas-sets/api/v1.1"
  70.     updated = "2011-08-08T00:00:00+00:00"
  71.     def get_resources(self):
  72.         resources = []
  73.         res = extensions.ResourceExtension('os-quota-sets',
  74.                                            QuotaSetsController(),
  75.                                            member_actions={'defaults': 'GET'})
  76.         resources.append(res)
  77.         return resources
  78. class QuotaSetsController(object)
  79. ==========================================================
  80. ext = <cinder.api.contrib.volume_encryption_metadata.Volume_encryption_metadata object at 0x18b0750>:
  81. class Volume_encryption_metadata(extensions.ExtensionDescriptor):
  82.     """Volume encryption metadata retrieval support."""
  83.     name = "VolumeEncryptionMetadata"
  84.     alias = "os-volume-encryption-metadata"
  85.     namespace = ("http://docs.openstack.org/volume/ext/"
  86.                  "os-volume-encryption-metadata/api/v1")
  87.     updated = "2013-07-10T00:00:00+00:00"
  88.     def get_resources(self):
  89.         resources = []
  90.         res = extensions.ResourceExtension('encryption',
  91.                                            VolumeEncryptionMetadataController(),
  92.                                            parent=dict(member_name='volume', collection_name='volumes'))
  93.         resources.append(res)
  94.         return resources
  95. class VolumeEncryptionMetadataController(wsgi.Controller):
  96.     """
  97.     The volume encryption metadata API extension
  98.     卷加密元数据控制API类;
  99.     """
  100. class Controller(object):
  101.     """Default controller."""
  102.     __metaclass__ = ControllerMetaclass
  103.     _view_builder_class = None
  104.     def __init__(self, view_builder=None):
  105.         """Initialize controller with a view builder instance."""
  106.         if view_builder:
  107.             self._view_builder = view_builder
  108.         elif self._view_builder_class:
  109.             self._view_builder = self._view_builder_class()
  110.         else:
  111.             self._view_builder = None
  112. ==========================================================
复制代码


没有实现get_resources()方法的类,在其父类class ExtensionDescriptor(object)中有实现:

  1. def get_resources(self):
  2.         """
  3.         List of extensions.ResourceExtension extension objects.
  4.         Resources define new nouns, and are accessible through URLs.
  5.         """
  6.         resources = []
  7.         return resources
复制代码

可见没有做什么具体的工作;
从分析中可以看到,类中直接实现了get_resources()的部分,都进行了类class Resource(wsgi.Application)的初始化工作,简单来看类class Resource(wsgi.Application)的初始化方法:

  1. class Resource(wsgi.Application):
  2.     def __init__(self, controller, action_peek=None, **deserializers):
  3.         """
  4.         :param controller: object that implement methods created by routes lib
  5.         :param action_peek: dictionary of routines for peeking into an action request body to determine the desired action
  6.         """
  7.         self.controller = controller
  8.         # 获取和更新默认的反序列化方法;
  9.         default_deserializers = dict(xml=XMLDeserializer, json=JSONDeserializer)
  10.         default_deserializers.update(deserializers)
  11.         self.default_deserializers = default_deserializers
  12.         # 获取默认的序列化方法;
  13.         self.default_serializers = dict(xml=XMLDictSerializer, json=JSONDictSerializer)
  14.         # 获取和确认所要引用的动作;
  15.         # action_peek_xml:通过解析xml字符串,实现确定所要引用的动作;
  16.         # action_peek_json:通过反序列化操作,实现确定所要引用的动作;
  17.         self.action_peek = dict(xml=action_peek_xml, json=action_peek_json)
  18.         self.action_peek.update(action_peek or {})
  19.         # Copy over the actions dictionary
  20.         self.wsgi_actions = {}
  21.         if controller:
  22.             self.register_actions(controller)
  23.         # Save a mapping of extensions
  24.         self.wsgi_extensions = {}
  25.         self.wsgi_action_extensions = {}
复制代码

其中的语句:self.register_actions(controller)实现的功能就是把self.resources和wsgi_resource一一对应起来。
方法get_resources(self)先分析到这里,我们回到方法_setup_ext_routes:

  1. def _setup_ext_routes(self, mapper, ext_mgr):
  2.         """
  3.         mapper =
  4.         Route name                                Methods Path                                                              
  5.         versions                                          /                                                                 
  6.         ......                                    ......  ......                  
  7.         formatted_volume_edit_volume_metadata     GET     /{project_id}/volumes/:volume_id/metadata/:(id)/edit.:(format)   
  8.         volume_edit_volume_metadata               GET     /{project_id}/volumes/:volume_id/metadata/:(id)/edit              
  9.         formatted_volume_volume_metadata          GET     /{project_id}/volumes/:volume_id/metadata/:(id).:(format)         
  10.         volume_volume_metadata                    GET     /{project_id}/volumes/:volume_id/metadata/:(id)                  
  11.         metadata                                  PUT     /{project_id}/volumes/{volume_id}/metadata  
  12.         """
  13.         # ext_mgr.get_resources():获取ResourceExtension对象列表;
  14.         for resource in ext_mgr.get_resources():
  15.             LOG.debug(_('Extended resource: %s'), resource.collection)
  16.             wsgi_resource = wsgi.Resource(resource.controller)
  17.             self.resources[resource.collection] = wsgi_resource
  18.             kargs = dict(
  19.                 controller=wsgi_resource,
  20.                 collection=resource.collection_actions,
  21.                 member=resource.member_actions)
  22.             
  23.             if resource.parent:
  24.                 kargs['parent_resource'] = resource.parent
  25.             mapper.resource(resource.collection, resource.collection, **kargs)
  26.             if resource.custom_routes_fn:
  27.                 resource.custom_routes_fn(mapper, wsgi_resource)
复制代码

再来看语句:
kargs = dict(controller=wsgi_resource,
        collection=resource.collection_actions,
        member=resource.member_actions)
if resource.parent:
        kargs['parent_resource'] = resource.parent
这里实现的功能就是获取各个类中的collection_actions和member_actions,分别赋值给collection和member,实现格式的统一,为后续的调用做准备;
再来看语句:
mapper.resource(resource.collection, resource.collection, **kargs)
实现的功能就是获取新定义Restful资源功能的URL和具体功能方法的映射关系。
输出示例:
      
  1.       ==================================================================================
  2.             mapper =
  3.             Route name                                Methods Path
  4.             ......                                                  ......     ......
  5.                                                       POST    /{project_id}/extensions.:(format)                                
  6.                                                       POST    /{project_id}/extensions                                          
  7.             formatted_extensions                      GET     /{project_id}/extensions.:(format)                                
  8.             extensions                                GET     /{project_id}/extensions                                          
  9.             formatted_new_extensions                  GET     /{project_id}/extensions/new.:(format)                           
  10.             new_extensions                            GET     /{project_id}/extensions/new                                      
  11.                                                       PUT     /{project_id}/extensions/:(id).:(format)                          
  12.                                                       PUT     /{project_id}/extensions/:(id)                                    
  13.                                                       DELETE  /{project_id}/extensions/:(id).:(format)                          
  14.                                                       DELETE  /{project_id}/extensions/:(id)                                    
  15.             formatted_edit_extensions                 GET     /{project_id}/extensions/:(id)/edit.:(format)                     
  16.             edit_extensions                           GET     /{project_id}/extensions/:(id)/edit                              
  17.             formatted_extensions                      GET     /{project_id}/extensions/:(id).:(format)                          
  18.             extensions                                GET     /{project_id}/extensions/:(id)                                    
  19.             ==================================================================================
  20.             mapper =
  21.             Route name                                Methods Path
  22.             ......                                                  ......     ......
  23.                                                       PUT     /{project_id}/os-hosts.:(format)                                 
  24.                                                       PUT     /{project_id}/os-hosts                                            
  25.                                                       POST    /{project_id}/os-hosts.:(format)                                 
  26.                                                       POST    /{project_id}/os-hosts                                            
  27.             formatted_os-hosts                        GET     /{project_id}/os-hosts.:(format)                                 
  28.             os-hosts                                  GET     /{project_id}/os-hosts                                            
  29.             formatted_new_os-hosts                    GET     /{project_id}/os-hosts/new.:(format)                              
  30.             new_os-hosts                              GET     /{project_id}/os-hosts/new                                       
  31.                                                       PUT     /{project_id}/os-hosts/:(id).:(format)                           
  32.                                                       PUT     /{project_id}/os-hosts/:(id)                                      
  33.                                                       DELETE  /{project_id}/os-hosts/:(id).:(format)                           
  34.                                                       DELETE  /{project_id}/os-hosts/:(id)                                      
  35.             formatted_edit_os-hosts                   GET     /{project_id}/os-hosts/:(id)/edit.:(format)                       
  36.             edit_os-hosts                             GET     /{project_id}/os-hosts/:(id)/edit                                 
  37.             formatted_startup_os-hosts                GET     /{project_id}/os-hosts/:(id)/startup.:(format)                    
  38.             startup_os-hosts                          GET     /{project_id}/os-hosts/:(id)/startup                              
  39.             formatted_reboot_os-hosts                 GET     /{project_id}/os-hosts/:(id)/reboot.:(format)                     
  40.             reboot_os-hosts                           GET     /{project_id}/os-hosts/:(id)/reboot                              
  41.             formatted_shutdown_os-hosts               GET     /{project_id}/os-hosts/:(id)/shutdown.:(format)                  
  42.             shutdown_os-hosts                         GET     /{project_id}/os-hosts/:(id)/shutdown                             
  43.             formatted_os-hosts                        GET     /{project_id}/os-hosts/:(id).:(format)                           
  44.             os-hosts                                  GET     /{project_id}/os-hosts/:(id)                                      
  45.             ==================================================================================
  46.             mapper =
  47.             Route name                                Methods Path
  48.             ......                                                  ......     ......
  49.                                                       POST    /{project_id}/os-quota-sets.:(format)                             
  50.                                                       POST    /{project_id}/os-quota-sets                                       
  51.             formatted_os-quota-sets                   GET     /{project_id}/os-quota-sets.:(format)                             
  52.             os-quota-sets                             GET     /{project_id}/os-quota-sets                                       
  53.             formatted_new_os-quota-sets               GET     /{project_id}/os-quota-sets/new.:(format)                        
  54.             new_os-quota-sets                         GET     /{project_id}/os-quota-sets/new                                   
  55.                                                       PUT     /{project_id}/os-quota-sets/:(id).:(format)                       
  56.                                                       PUT     /{project_id}/os-quota-sets/:(id)                                 
  57.                                                       DELETE  /{project_id}/os-quota-sets/:(id).:(format)                       
  58.                                                       DELETE  /{project_id}/os-quota-sets/:(id)                                 
  59.             formatted_edit_os-quota-sets              GET     /{project_id}/os-quota-sets/:(id)/edit.:(format)                  
  60.             edit_os-quota-sets                        GET     /{project_id}/os-quota-sets/:(id)/edit                           
  61.             formatted_defaults_os-quota-sets          GET     /{project_id}/os-quota-sets/:(id)/defaults.:(format)              
  62.             defaults_os-quota-sets                    GET     /{project_id}/os-quota-sets/:(id)/defaults                        
  63.             formatted_os-quota-sets                   GET     /{project_id}/os-quota-sets/:(id).:(format)                       
  64.             os-quota-sets                             GET     /{project_id}/os-quota-sets/:(id)                                 
  65.             ==================================================================================
  66.             mapper =
  67.             Route name                                Methods Path
  68.             ......                                                  ......     ......
  69.                                                       POST    /{project_id}/volumes/:volume_id/encryption.:(format)            
  70.                                                       POST    /{project_id}/volumes/:volume_id/encryption                       
  71.             formatted_volume_encryption               GET     /{project_id}/volumes/:volume_id/encryption.:(format)            
  72.             volume_encryption                         GET     /{project_id}/volumes/:volume_id/encryption                       
  73.             formatted_volume_new_encryption           GET     /{project_id}/volumes/:volume_id/encryption/new.:(format)         
  74.             volume_new_encryption                     GET     /{project_id}/volumes/:volume_id/encryption/new                  
  75.                                                       PUT     /{project_id}/volumes/:volume_id/encryption/:(id).:(format)      
  76.                                                       PUT     /{project_id}/volumes/:volume_id/encryption/:(id)                 
  77.                                                       DELETE  /{project_id}/volumes/:volume_id/encryption/:(id).:(format)      
  78.                                                       DELETE  /{project_id}/volumes/:volume_id/encryption/:(id)                 
  79.             formatted_volume_edit_encryption          GET     /{project_id}/volumes/:volume_id/encryption/:(id)/edit.:(format)  
  80.             volume_edit_encryption                    GET     /{project_id}/volumes/:volume_id/encryption/:(id)/edit            
  81.             formatted_volume_encryption               GET     /{project_id}/volumes/:volume_id/encryption/:(id).:(format)      
  82.             volume_encryption                         GET     /{project_id}/volumes/:volume_id/encryption/:(id)                 
  83.             ==================================================================================
  84.             mapper =
  85.             Route name                                Methods Path
  86.             ......                                                  ......     ......
  87.                                                       POST    /{project_id}/backups.:(format)                                   
  88.                                                       POST    /{project_id}/backups                                             
  89.             formatted_detail_backups                  GET     /{project_id}/backups/detail.:(format)                           
  90.             detail_backups                            GET     /{project_id}/backups/detail                                      
  91.             formatted_backups                         GET     /{project_id}/backups.:(format)                                   
  92.             backups                                   GET     /{project_id}/backups                                             
  93.             formatted_new_backups                     GET     /{project_id}/backups/new.:(format)                              
  94.             new_backups                               GET     /{project_id}/backups/new                                         
  95.                                                       PUT     /{project_id}/backups/:(id).:(format)                             
  96.                                                       PUT     /{project_id}/backups/:(id)                                       
  97.             formatted_restore_backups                 POST    /{project_id}/backups/:(id)/restore.:(format)                     
  98.             restore_backups                           POST    /{project_id}/backups/:(id)/restore                              
  99.                                                       DELETE  /{project_id}/backups/:(id).:(format)                             
  100.                                                       DELETE  /{project_id}/backups/:(id)                                       
  101.             formatted_edit_backups                    GET     /{project_id}/backups/:(id)/edit.:(format)                        
  102.             edit_backups                              GET     /{project_id}/backups/:(id)/edit                                 
  103.             formatted_backups                         GET     /{project_id}/backups/:(id).:(format)                             
  104.             backups                                   GET     /{project_id}/backups/:(id)                                       
  105.             ==================================================================================
  106.             mapper =
  107.             Route name                                Methods Path
  108.             ......                                                  ......     ......
  109.                                                       POST    /{project_id}/types/:type_id/encryption.:(format)                 
  110.                                                       POST    /{project_id}/types/:type_id/encryption                           
  111.             formatted_type_encryption                 GET     /{project_id}/types/:type_id/encryption.:(format)                 
  112.             type_encryption                           GET     /{project_id}/types/:type_id/encryption                           
  113.             formatted_type_new_encryption             GET     /{project_id}/types/:type_id/encryption/new.:(format)            
  114.             type_new_encryption                       GET     /{project_id}/types/:type_id/encryption/new                       
  115.                                                       PUT     /{project_id}/types/:type_id/encryption/:(id).:(format)           
  116.                                                       PUT     /{project_id}/types/:type_id/encryption/:(id)                     
  117.                                                       DELETE  /{project_id}/types/:type_id/encryption/:(id).:(format)           
  118.                                                       DELETE  /{project_id}/types/:type_id/encryption/:(id)                     
  119.             formatted_type_edit_encryption            GET     /{project_id}/types/:type_id/encryption/:(id)/edit.:(format)      
  120.             type_edit_encryption                      GET     /{project_id}/types/:type_id/encryption/:(id)/edit               
  121.             formatted_type_encryption                 GET     /{project_id}/types/:type_id/encryption/:(id).:(format)           
  122.             type_encryption                           GET     /{project_id}/types/:type_id/encryption/:(id)                     
  123.             ==================================================================================
  124.             mapper =
  125.             Route name                                Methods Path
  126.             ......                                                  ......     ......
  127.                                                       POST    /{project_id}/os-availability-zone.:(format)                     
  128.                                                       POST    /{project_id}/os-availability-zone                                
  129.             formatted_os-availability-zone            GET     /{project_id}/os-availability-zone.:(format)                     
  130.             os-availability-zone                      GET     /{project_id}/os-availability-zone                                
  131.             formatted_new_os-availability-zone        GET     /{project_id}/os-availability-zone/new.:(format)                  
  132.             new_os-availability-zone                  GET     /{project_id}/os-availability-zone/new                           
  133.                                                       PUT     /{project_id}/os-availability-zone/:(id).:(format)               
  134.                                                       PUT     /{project_id}/os-availability-zone/:(id)                          
  135.                                                       DELETE  /{project_id}/os-availability-zone/:(id).:(format)               
  136.                                                       DELETE  /{project_id}/os-availability-zone/:(id)                          
  137.             formatted_edit_os-availability-zone       GET     /{project_id}/os-availability-zone/:(id)/edit.:(format)           
  138.             edit_os-availability-zone                 GET     /{project_id}/os-availability-zone/:(id)/edit                     
  139.             formatted_os-availability-zone            GET     /{project_id}/os-availability-zone/:(id).:(format)               
  140.             os-availability-zone                      GET     /{project_id}/os-availability-zone/:(id)                          
  141.             ==================================================================================
  142.             mapper =
  143.             Route name                                Methods Path
  144.             ......                                                  ......     ......
  145.                                                       POST    /{project_id}/types/:type_id/extra_specs.:(format)               
  146.                                                       POST    /{project_id}/types/:type_id/extra_specs                          
  147.             formatted_type_extra_specs                GET     /{project_id}/types/:type_id/extra_specs.:(format)               
  148.             type_extra_specs                          GET     /{project_id}/types/:type_id/extra_specs                          
  149.             formatted_type_new_extra_specs            GET     /{project_id}/types/:type_id/extra_specs/new.:(format)            
  150.             type_new_extra_specs                      GET     /{project_id}/types/:type_id/extra_specs/new                     
  151.                                                       PUT     /{project_id}/types/:type_id/extra_specs/:(id).:(format)         
  152.                                                       PUT     /{project_id}/types/:type_id/extra_specs/:(id)                    
  153.                                                       DELETE  /{project_id}/types/:type_id/extra_specs/:(id).:(format)         
  154.                                                       DELETE  /{project_id}/types/:type_id/extra_specs/:(id)                    
  155.             formatted_type_edit_extra_specs           GET     /{project_id}/types/:type_id/extra_specs/:(id)/edit.:(format)     
  156.             type_edit_extra_specs                     GET     /{project_id}/types/:type_id/extra_specs/:(id)/edit               
  157.             formatted_type_extra_specs                GET     /{project_id}/types/:type_id/extra_specs/:(id).:(format)         
  158.             type_extra_specs                          GET     /{project_id}/types/:type_id/extra_specs/:(id)                    
  159.             ==================================================================================
  160.             mapper =
  161.             Route name                                Methods Path
  162.             ......                                                  ......     ......
  163.                                                       POST    /{project_id}/qos-specs.:(format)                                 
  164.                                                       POST    /{project_id}/qos-specs                                          
  165.             formatted_qos-specs                       GET     /{project_id}/qos-specs.:(format)                                 
  166.             qos-specs                                 GET     /{project_id}/qos-specs                                          
  167.             formatted_new_qos-specs                   GET     /{project_id}/qos-specs/new.:(format)                             
  168.             new_qos-specs                             GET     /{project_id}/qos-specs/new                                       
  169.             formatted_delete_keys_qos-specs           PUT     /{project_id}/qos-specs/:(id)/delete_keys.:(format)               
  170.             delete_keys_qos-specs                     PUT     /{project_id}/qos-specs/:(id)/delete_keys                        
  171.                                                       PUT     /{project_id}/qos-specs/:(id).:(format)                           
  172.                                                       PUT     /{project_id}/qos-specs/:(id)                                    
  173.                                                       DELETE  /{project_id}/qos-specs/:(id).:(format)                           
  174.                                                       DELETE  /{project_id}/qos-specs/:(id)                                    
  175.             formatted_associations_qos-specs          GET     /{project_id}/qos-specs/:(id)/associations.:(format)              
  176.             associations_qos-specs                    GET     /{project_id}/qos-specs/:(id)/associations                        
  177.             formatted_disassociate_all_qos-specs      GET     /{project_id}/qos-specs/:(id)/disassociate_all.:(format)         
  178.             disassociate_all_qos-specs                GET     /{project_id}/qos-specs/:(id)/disassociate_all                    
  179.             formatted_disassociate_qos-specs          GET     /{project_id}/qos-specs/:(id)/disassociate.:(format)              
  180.             disassociate_qos-specs                    GET     /{project_id}/qos-specs/:(id)/disassociate                        
  181.             formatted_associate_qos-specs             GET     /{project_id}/qos-specs/:(id)/associate.:(format)                 
  182.             associate_qos-specs                       GET     /{project_id}/qos-specs/:(id)/associate                           
  183.             formatted_edit_qos-specs                  GET     /{project_id}/qos-specs/:(id)/edit.:(format)                     
  184.             edit_qos-specs                            GET     /{project_id}/qos-specs/:(id)/edit                                
  185.             formatted_qos-specs                       GET     /{project_id}/qos-specs/:(id).:(format)                           
  186.             qos-specs                                 GET     /{project_id}/qos-specs/:(id)                                    
  187.             ==================================================================================
  188.             mapper =
  189.             Route name                                Methods Path
  190.             ......                                                  ......     ......
  191.                                                       POST    /{project_id}/os-quota-class-sets.:(format)                       
  192.                                                       POST    /{project_id}/os-quota-class-sets                                 
  193.             formatted_os-quota-class-sets             GET     /{project_id}/os-quota-class-sets.:(format)                       
  194.             os-quota-class-sets                       GET     /{project_id}/os-quota-class-sets                                 
  195.             formatted_new_os-quota-class-sets         GET     /{project_id}/os-quota-class-sets/new.:(format)                  
  196.             new_os-quota-class-sets                   GET     /{project_id}/os-quota-class-sets/new                             
  197.                                                       PUT     /{project_id}/os-quota-class-sets/:(id).:(format)                 
  198.                                                       PUT     /{project_id}/os-quota-class-sets/:(id)                           
  199.                                                       DELETE  /{project_id}/os-quota-class-sets/:(id).:(format)                 
  200.                                                       DELETE  /{project_id}/os-quota-class-sets/:(id)                           
  201.             formatted_edit_os-quota-class-sets        GET     /{project_id}/os-quota-class-sets/:(id)/edit.:(format)            
  202.             edit_os-quota-class-sets                  GET     /{project_id}/os-quota-class-sets/:(id)/edit                     
  203.             formatted_os-quota-class-sets             GET     /{project_id}/os-quota-class-sets/:(id).:(format)                 
  204.             os-quota-class-sets                       GET     /{project_id}/os-quota-class-sets/:(id)
  205.             ==================================================================================
  206.             mapper =
  207.             Route name                                Methods Path
  208.             ......                                                  ......     ......
  209.                                                       POST    /{project_id}/os-volume-transfer.:(format)                        
  210.                                                       POST    /{project_id}/os-volume-transfer                                 
  211.             formatted_detail_os-volume-transfer       GET     /{project_id}/os-volume-transfer/detail.:(format)                 
  212.             detail_os-volume-transfer                 GET     /{project_id}/os-volume-transfer/detail                           
  213.             formatted_os-volume-transfer              GET     /{project_id}/os-volume-transfer.:(format)                        
  214.             os-volume-transfer                        GET     /{project_id}/os-volume-transfer                                 
  215.             formatted_new_os-volume-transfer          GET     /{project_id}/os-volume-transfer/new.:(format)                    
  216.             new_os-volume-transfer                    GET     /{project_id}/os-volume-transfer/new                              
  217.                                                       PUT     /{project_id}/os-volume-transfer/:(id).:(format)                  
  218.                                                       PUT     /{project_id}/os-volume-transfer/:(id)                           
  219.             formatted_accept_os-volume-transfer       POST    /{project_id}/os-volume-transfer/:(id)/accept.:(format)           
  220.             accept_os-volume-transfer                 POST    /{project_id}/os-volume-transfer/:(id)/accept                     
  221.                                                       DELETE  /{project_id}/os-volume-transfer/:(id).:(format)                  
  222.                                                       DELETE  /{project_id}/os-volume-transfer/:(id)                           
  223.             formatted_edit_os-volume-transfer         GET     /{project_id}/os-volume-transfer/:(id)/edit.:(format)            
  224.             edit_os-volume-transfer                   GET     /{project_id}/os-volume-transfer/:(id)/edit                       
  225.             formatted_os-volume-transfer              GET     /{project_id}/os-volume-transfer/:(id).:(format)                  
  226.             os-volume-transfer                        GET     /{project_id}/os-volume-transfer/:(id)                           
  227.             =================================================================================         
  228.             mapper =
  229.             Route name                                Methods Path
  230.             ......                                                  ......     ......
  231.                                                       POST    /{project_id}/os-services.:(format)                              
  232.                                                       POST    /{project_id}/os-services                                         
  233.             formatted_os-services                     GET     /{project_id}/os-services.:(format)                              
  234.             os-services                               GET     /{project_id}/os-services                                         
  235.             formatted_new_os-services                 GET     /{project_id}/os-services/new.:(format)                           
  236.             new_os-services                           GET     /{project_id}/os-services/new                                    
  237.                                                       PUT     /{project_id}/os-services/:(id).:(format)                        
  238.                                                       PUT     /{project_id}/os-services/:(id)                                   
  239.                                                       DELETE  /{project_id}/os-services/:(id).:(format)                        
  240.                                                       DELETE  /{project_id}/os-services/:(id)                                   
  241.             formatted_edit_os-services                GET     /{project_id}/os-services/:(id)/edit.:(format)                    
  242.             edit_os-services                          GET     /{project_id}/os-services/:(id)/edit                              
  243.             formatted_os-services                     GET     /{project_id}/os-services/:(id).:(format)                        
  244.             os-services                               GET     /{project_id}/os-services/:(id)                                   
  245.             =================================================================================
复制代码


至此方法def _setup_ext_routes(self, mapper, ext_mgr)的实现分析完成。



相关文章
OpenStack Cinder服务启动过程中的资源加载和扩展源码解析之一
http://www.aboutyun.com/thread-10222-1-1.html


OpenStack Cinder服务启动过程中的资源加载和扩展源码解析之三
http://www.aboutyun.com/thread-10224-1-1.html




原文链接:http://blog.csdn.net/gaoxingnengjisuan/article/details/21752277




没找到任何评论,期待你打破沉寂

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

关闭

推荐上一条 /2 下一条