text: # All Rights Reserved.
  #
  #    Licensed under the Apache License, Version 2.0 (the "License"); you may
  #    not use this file except in compliance with the License. You may obtain
  #    a copy of the License at
  #
  #         http://www.apache.org/licenses/LICENSE-2.0
  #
  #    Unless required by applicable law or agreed to in writing, software
  #    distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
  #    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
  #    License for the specific language governing permissions and limitations
  #    under the License.
  
  from oslo_log import log as logging
  import pecan
  from pecan import request
  
  from neutron.api import api_common
  from neutron.i18n import _LW
  from neutron import manager
  from neutron.pecan_wsgi.controllers import utils
  
  
  LOG = logging.getLogger(__name__)
  
  
  class ItemController(utils.NeutronPecanController):
  
      def __init__(self, resource, item):
          super(ItemController, self).__init__(None, resource)
          self.item = item
  
      @utils.expose(generic=True)
      def index(self, *args, **kwargs):
          return self.get()
  
      def get(self, *args, **kwargs):
          getter = getattr(self.plugin, 'get_%s' % self.resource)
          neutron_context = request.context['neutron_context']
          return {self.resource: getter(neutron_context, self.item)}
  
      @utils.when(index, method='HEAD')
      @utils.when(index, method='POST')
      @utils.when(index, method='PATCH')
      def not_supported(self):
          pecan.abort(405)
  
      @utils.when(index, method='PUT')
      def put(self, *args, **kwargs):
          neutron_context = request.context['neutron_context']
          resources = request.context['resources']
          # TODO(kevinbenton): bulk?
          updater = getattr(self.plugin, 'update_%s' % self.resource)
          # Bulk update is not supported, 'resources' always contains a single
          # elemenet
          data = {self.resource: resources[0]}
          return {self.resource: updater(neutron_context, self.item, data)}
  
      @utils.when(index, method='DELETE')
      def delete(self):
          # TODO(kevinbenton): setting code could be in a decorator
          pecan.response.status = 204
          neutron_context = request.context['neutron_context']
          deleter = getattr(self.plugin, 'delete_%s' % self.resource)
          return deleter(neutron_context, self.item)
  
      @utils.expose()
      def _lookup(self, collection, *remainder):
          request.context['collection'] = collection
          controller = manager.NeutronManager.get_controller_for_resource(
              collection)
          if not controller:
              LOG.warning(_LW("No controller found for: %s - returning response "
                           "code 404"), collection)
              pecan.abort(404)
          return controller, remainder
  
  
  class CollectionsController(utils.NeutronPecanController):
  
      item_controller_class = ItemController
  
      @utils.expose()
      def _lookup(self, item, *remainder):
          # Store resource identifier in request context
          request.context['resource_id'] = item
          uri_identifier = '%s_id' % self.resource
          request.context['uri_identifiers'][uri_identifier] = item
          return self.item_controller_class(self.resource, item), remainder
  
      @utils.expose(generic=True)
      def index(self, *args, **kwargs):
          return self.get(*args, **kwargs)
  
      def get(self, *args, **kwargs):
          # list request
          # TODO(kevinbenton): use user-provided fields in call to plugin
          # after making sure policy enforced fields remain
          kwargs.pop('fields', None)
          _listify = lambda x: x if isinstance(x, list) else [x]
          filters = api_common.get_filters_from_dict(
              {k: _listify(v) for k, v in kwargs.items()},
              self._resource_info,
              skips=['fields', 'sort_key', 'sort_dir',
                     'limit', 'marker', 'page_reverse'])
          lister = getattr(self.plugin, 'get_%s' % self.collection)
          neutron_context = request.context['neutron_context']
          return {self.collection: lister(neutron_context, filters=filters)}
  
      @utils.when(index, method='HEAD')
      @utils.when(index, method='PATCH')
      @utils.when(index, method='PUT')
      @utils.when(index, method='DELETE')
      def not_supported(self):
          pecan.abort(405)
  
      @utils.when(index, method='POST')
      def post(self, *args, **kwargs):
          # TODO(kevinbenton): emulated bulk!
          resources = request.context['resources']
          pecan.response.status = 201
          return self.create(resources)
  
      def create(self, resources):
          if len(resources) > 1:
              # Bulk!
              method = 'create_%s_bulk' % self.resource
              key = self.collection
              data = {key: [{self.resource: res} for res in resources]}
          else:
              method = 'create_%s' % self.resource
              key = self.resource
              data = {key: resources[0]}
          creator = getattr(self.plugin, method)
          neutron_context = request.context['neutron_context']
          return {key: creator(neutron_context, data)}
  