Exemplo n.º 1
0
    def url(self, service_id, operation_id, operation_summary):
        """
        Generate the mapping rule for an operation that has RequestMapping
        in the VMODL2 service definition.
        :type  service_id: :class:`str`
        :param service_id: Service identifier
        :type  operation_id: :class:`str`
        :param operation_id: Operation identifier
        :type  operation_summary:
        :class:`vmware.vapi.server.rest_handler.MetadataStore.OperationSummary`
        :param operation_summary: Details of the operation
        :rtype: :class:`tuple` of :class:`str` and :class:`str`
        :return: Tuple that has URL and the HTTP method for the
            given operation.
        """
        request_mapping = operation_summary.request_mapping_metadata
        http_method = request_mapping.elements[
            RestAnnotations.METHOD_ELEMENT].string_value

        custom_url = request_mapping.elements[
            RestAnnotations.VALUE_ELEMENT].string_value
        custom_url = custom_url.replace('{', '<')
        custom_url = custom_url.replace('}', '>')
        custom_url = '%s%s' % (self._rest_prefix, custom_url[1:])

        # Get value of fixed query parameter 'action' if it exists
        if '?' in custom_url:
            (custom_url, param) = custom_url.split('?')
            (_, action_value) = param.split('=')
            self._validate_action_param(param, http_method)
        else:
            params = request_mapping.elements.get(
                RestAnnotations.PARAMS_ELEMENT)
            if params and params.list_value:
                action_value = None
                for param in params.list_value:
                    param_split = param.split('=')
                    if (len(param_split) == 2
                            and param_split[0] == RestAnnotations.ACTION_PARAM):
                        action_value = param_split[1]
                        self._validate_action_param(param, http_method)
                        break

            else:
                action_value = None

        dispatch_info = DispatchInfo(
            mapping_type=RestAnnotationType.REQUEST,
            operation_id=get_non_task_operation_name(operation_id),
            action_value=action_value)

        return (custom_url, http_method, dispatch_info)
Exemplo n.º 2
0
    def url(self, service_id, operation_id, operation_summary):
        """
        Generate the URL for the given operation

        :type  service_id: :class:`str`
        :param service_id: Service identifier
        :type  operation_id: :class:`str`
        :param operation_id: Operation identifier
        :type  operation_summary:
        :class:`vmware.vapi.server.rest_handler.MetadataStore.OperationSummary`
        :param operation_summary: Details of the operation
        :type  param_info_map: :class:`collections.OrderedDict` of :class:`str`
               and :class:`com.vmware.vapi.metadata.metamodel_client.FieldInfo`
        :return: Tuple that has URL and the HTTP method for the
            given operation.
        """
        http_method, request_metadata = \
            next(iter(operation_summary.verb_metadata.items()))

        custom_url = request_metadata.elements[
            RestAnnotations.PATH_ELEMENT].string_value
        custom_url = custom_url.replace('{', '<')
        custom_url = custom_url.replace('}', '>')
        custom_url = '%s%s' % (self._rest_prefix, custom_url[1:])

        dispatch_params = request_metadata.elements.get(
            RestAnnotations.PARAMS_ELEMENT)
        if dispatch_params is not None:
            dispatch_params = dispatch_params.list_value
        dispatch_headers = request_metadata.elements.get(
            RestAnnotations.HEADERS_ELEMENT)
        if dispatch_headers is not None:
            dispatch_headers = dispatch_headers.list_value

        dispatch_info = DispatchInfo(
            mapping_type=RestAnnotationType.VERB,
            operation_id=get_non_task_operation_name(operation_id),
            params=dispatch_params,
            headers=dispatch_headers
        )

        return (custom_url, http_method, dispatch_info)
Exemplo n.º 3
0
    def url(self, service_id, operation_id, operation_summary):
        """
        Generate the URL for the given operation

        :type  service_id: :class:`str`
        :param service_id: Service identifier
        :type  operation_id: :class:`str`
        :param operation_id: Operation identifier
        :type  operation_summary:
        :class:`vmware.vapi.server.rest_handler.MetadataStore.OperationSummary`
        :param operation_summary: Details of the operation
        :rtype: :class:`tuple` of :class:`str` and :class:`str`
        :return: Tuple that has URL and the HTTP method for the
            given operation.
        """
        service_url = self._generate_service_base_url(service_id)
        dispatch_info = DispatchInfo(
            mapping_type=RestAnnotationType.NONE,
            operation_id=get_non_task_operation_name(operation_id))
        return (service_url, 'POST', dispatch_info)
Exemplo n.º 4
0
    def invoke(self, ctx, method_id, input_value):
        """
        Invokes the specified method using the execution context and
        the input provided

        :type  ctx: :class:`vmware.vapi.core.ExecutionContext`
        :param ctx: Execution context for this method
        :type  input_value: :class:`vmware.vapi.data.value.StructValue`
        :param input_value: Method input parameters

        :rtype: :class:`vmware.vapi.core.MethodResult`
        :return: Result of the method invocation
        """
        op_info = self._operations.get(method_id.get_name())

        # Set execution context
        set_context(ctx)

        try:
            # input validators
            validators = op_info['input_value_validator_list']
            input_type = op_info['input_type']
            for validator in validators:
                msg_list = validator.validate(input_value, input_type)
                if msg_list:
                    error_value = make_error_value_from_msgs(
                        self._invalid_argument_def, *msg_list)
                    return MethodResult(error=error_value)
            error_value = ApiInterfaceSkeleton.check_for_unknown_fields(
                input_type, input_value)
            if error_value:
                return MethodResult(error=error_value)

            try:
                meth_args = TypeConverter.convert_to_python(
                    input_value, binding_type=input_type,
                    resolver=self._resolver)
            except CoreException as e:
                error_value = make_error_value_from_msgs(
                    self._invalid_argument_def, *e.messages)
                return MethodResult(error=error_value)

            method_name = Converter.canonical_to_pep(
                            get_non_task_operation_name(method_id.get_name()))
            method = getattr(self._impl, method_name)

            # If it's a task method then create a new thread to run provider
            # impl and return task id or result depending upon type of
            # invocation.
            if op_info['task_type'] != TaskType.NONE:
                meth_output, task_accepted = self._invoke_task_operation(
                    ctx, method_id, method, meth_args)

                if isinstance(meth_output, VapiError):
                    raise meth_output  # pylint: disable=raising-bad-type

                # In case of provider not accepting task throw an error.
                if task_accepted is False:
                    msg_list = [message_factory.get_message(
                                'vapi.bindings.skeleton.task.invalidstate')]
                    error_value = make_error_value_from_msgs(
                        self._internal_server_error_def,
                        *msg_list)
                    return MethodResult(error=error_value)
            else:
                meth_output = method(**meth_args)

            output_type = op_info['output_type']
            # output validators
            validators = op_info['output_validator_list']

            output = TypeConverter.convert_to_vapi(meth_output,
                                                   output_type)

            for validator in validators:
                msg_list = validator.validate(output, output_type)
                if msg_list:
                    error_value = make_error_value_from_msgs(
                        self._internal_server_error_def, *msg_list)
                    return MethodResult(error=error_value)
            result = MethodResult(output=output)
        except CoreException as e:
            logger.exception("Error in invoking %s - %s",
                             str(method_id), e)
            error_value = make_error_value_from_msgs(
                self._internal_server_error_def,
                *e.messages)
            result = MethodResult(error=error_value)
        except VapiError as e:
            exc_info = sys.exc_info()
            error_type = e.__class__.get_binding_type()
            try:
                error = TypeConverter.convert_to_vapi(e, error_type)
            except CoreException as ce:
                logger.error('Failed to convert %s to error type %s because %s',
                             e, error_type.name,
                             ' because '.join((e.def_msg for e in ce.messages)),
                             exc_info=exc_info)
                raise
            result = MethodResult(error=error)
        finally:
            # Reset the execution context after the operation
            clear_context()

        return result