Example #1
0
    def __register_class(self, parsed_config):
        """Register the class implementing this config, so we only add it once.

    Args:
      parsed_config: The JSON object with the API configuration being added.

    Raises:
      ApiConfigurationError: If the class has already been registered.
    """
        methods = parsed_config.get('methods')
        if not methods:
            return

        service_classes = set()
        for method in methods.itervalues():
            rosy_method = method.get('rosyMethod')
            if rosy_method and '.' in rosy_method:
                method_class = rosy_method.split('.', 1)[0]
                service_classes.add(method_class)

        for service_class in service_classes:
            if service_class in self.__registered_classes:
                raise api_config.ApiConfigurationError(
                    'SPI class %s has already been registered.' %
                    service_class)
            self.__registered_classes.add(service_class)
Example #2
0
    def __create_name_version_map(api_services):
        """Create a map from API name/version to Service class/factory.

    This creates a map from an API name and version to a list of remote.Service
    factories that implement that API.

    Args:
      api_services: A list of remote.Service-derived classes or factories
        created with remote.Service.new_factory.

    Returns:
      A mapping from (api name, api version) to a list of service factories,
      for service classes that implement that API.

    Raises:
      ApiConfigurationError: If a Service class appears more than once
        in api_services.
    """
        api_name_version_map = {}
        for service_factory in api_services:
            try:
                service_class = service_factory.service_class
            except AttributeError:
                service_class = service_factory
                service_factory = service_class.new_factory()

            key = service_class.api_info.name, service_class.api_info.version
            service_factories = api_name_version_map.setdefault(key, [])
            if service_factory in service_factories:
                raise api_config.ApiConfigurationError(
                    'Can\'t add the same class to an API twice: %s' %
                    service_factory.service_class.__name__)

            service_factories.append(service_factory)
        return api_name_version_map
Example #3
0
    def __register_services(api_name_version_map, api_config_registry):
        """Register & return a list of each SPI URL and class that handles that URL.

    This finds every service class in api_name_version_map, registers it with
    the given ApiConfigRegistry, builds the SPI url for that class, and adds
    the URL and its factory to a list that's returned.

    Args:
      api_name_version_map: A mapping from (api name, api version) to a list of
        service factories, as returned by __create_name_version_map.
      api_config_registry: The ApiConfigRegistry where service classes will
        be registered.

    Returns:
      A list of (SPI URL, service_factory) for each service class in
      api_name_version_map.

    Raises:
      ApiConfigurationError: If a Service class appears more than once
        in api_name_version_map.  This could happen if one class is used to
        implement multiple APIs.
    """
        generator = api_config.ApiConfigGenerator()
        protorpc_services = []
        for service_factories in api_name_version_map.itervalues():
            service_classes = [
                service_factory.service_class
                for service_factory in service_factories
            ]
            config_file = generator.pretty_print_config_to_json(
                service_classes)
            api_config_registry.register_spi(config_file)

            for service_factory in service_factories:
                protorpc_class_name = service_factory.service_class.__name__
                root = _ApiServer.__SPI_PREFIX + protorpc_class_name
                if any(service_map[0] == root
                       or service_map[1] == service_factory
                       for service_map in protorpc_services):
                    raise api_config.ApiConfigurationError(
                        'Can\'t reuse the same class in multiple APIs: %s' %
                        protorpc_class_name)
                protorpc_services.append((root, service_factory))
        return protorpc_services