Ejemplo n.º 1
0
 def test_set_info(self):
     service_uuid = str(uuid.uuid4())
     task_id = self.task_manager.create_task(service_uuid,
                                             None,
                                             'test.service',
                                             'op',
                                             False)
     info_val = self.task_manager.get_info(task_id)
     info = TypeConverter.convert_to_python(info_val,
                                            Info.get_binding_type())
     info.description = self.description
     progress = Progress()
     progress.total = 100
     progress.completed = 10
     progress.message = self.progress_msg
     info.progress = progress
     info.start_time = datetime.utcnow()
     info.status = Status.RUNNING
     info.cancelable = True
     self.task_manager.set_info(task_id,
                                TypeConverter.convert_to_vapi(info, Info.get_binding_type()))
     result = self.task_manager.get_info(task_id)
     self.assertEqual(result.get_field('progress'),
                      OptionalValue(TypeConverter.convert_to_vapi(progress,
                         Progress.get_binding_type())))
     self.assertEqual(result.get_field('cancelable'), BooleanValue(info.cancelable))
     self.assertEqual(result.get_field('status'), StringValue('RUNNING'))
Ejemplo n.º 2
0
 def _override_api_info(self, published_info):
     """
     Override service and operation task info fields
     """
     self.info.service = TypeConverter.convert_to_python(
         published_info.get_field('service'), StringType())
     self.info.operation = TypeConverter.convert_to_python(
         published_info.get_field('operation'), StringType())
Ejemplo n.º 3
0
 def _convert(self, dt, dt_str):
     dt_str = StringValue(dt_str)
     self.assertEqual(
         TypeConverter.convert_to_vapi(
             dt, self.typ, rest_converter_mode=RestConverter.SWAGGER_REST),
         dt_str)
     self.assertEqual(
         TypeConverter.convert_to_python(
             dt_str,
             self.typ,
             rest_converter_mode=RestConverter.SWAGGER_REST), dt)
Ejemplo n.º 4
0
 def _initialize_common_info(self):
     """
     Initialize common task info fields
     """
     published_info = self.task_manager.get_info(self.task_id)
     self._override_api_info(published_info)
     self.info.cancelable = TypeConverter.convert_to_python(
         published_info.get_field('cancelable'), BooleanType())
     desc = published_info.get_field('description')
     if desc is not None:
         self.info.description = TypeConverter.convert_to_python(
             desc, LocalizableMessage.get_binding_type())
     self.info.status = TypeConverter.convert_to_python(
         published_info.get_field('status'), StringType())
Ejemplo n.º 5
0
 def test_publish(self):
     info = self.task_handle.get_info()
     progress = Progress()
     progress.total = 100
     progress.completed = 42
     progress.message = self.progress_msg
     desc2 = LocalizableMessage(id='msg2', default_message='task1', args=[])
     info.description = desc2
     info.cancelable = False
     info.status = 'RUNNING'
     info.start_time = datetime.utcnow()
     info.progress = progress
     self.task_handle.publish()
     result = self.task_manager.get_info(self.task_id)
     self.assertEqual(result.get_field('status'), StringValue('RUNNING'))
     progress_val = StructValue('com.vmware.cis.task.progress')
     progress_val.set_field('total', IntegerValue(100))
     progress_val.set_field('completed', IntegerValue(42))
     progress_val.set_field(
         'message',
         TypeConverter.convert_to_vapi(
             self.progress_msg, LocalizableMessage.get_binding_type()))
     self.assertEqual(result.get_field('progress'),
                      OptionalValue(progress_val))
     self.assertEqual(result.get_field('cancelable'), BooleanValue(False))
Ejemplo n.º 6
0
 def get_published_info(self):
     """
     Returns the current published task Info
     """
     info = self.task_manager.get_info(self.task_id)
     converted_info = TypeConverter.convert_to_python(
         info, self.info_type.get_binding_type())
     return converted_info
Ejemplo n.º 7
0
    def test_basic(self):
        dt = datetime.datetime.utcnow()

        string_val = TypeConverter.convert_to_vapi(dt, self.typ)
        self.assertTrue(isinstance(string_val, StringValue))

        dt_new = TypeConverter.convert_to_python(string_val, self.typ)
        self.assertTrue(isinstance(dt_new, datetime.datetime))
        self.assertEqual(dt.year, dt_new.year)
        self.assertEqual(dt.month, dt_new.month)
        self.assertEqual(dt.day, dt_new.day)
        self.assertEqual(dt.hour, dt_new.hour)
        self.assertEqual(dt.minute, dt_new.minute)
        self.assertEqual(dt.second, dt_new.second)

        string_val_new = TypeConverter.convert_to_vapi(dt_new, self.typ)
        self.assertEqual(string_val, string_val_new)
Ejemplo n.º 8
0
    def get_result(self):
        """
        Returns task result

        :rtype: :class:`com.vmware.cis.tasks_client.Info`
        :return: Task Result
        """
        return TypeConverter.convert_to_python(self.get_info().result,
                                               self.result_type)
Ejemplo n.º 9
0
    def create_task(self,
                    description,
                    service_id,
                    operation_id,
                    cancelable,
                    error_types,
                    id_=None):
        """
        Creates a task in task manager.

        :type  description: :class:`com.vmware.vapi.std.LocalizableMessage`
        :param description: Task description.
        :type  service_id: :class:`str`
        :param service_id: Service Id.
        :type  operation_id: :class:`str`
        :param operation_id: Operation Id.
        :type  cancelable: :class:`bool`
        :param cancelable: Is the task cancelable.
        :type  error_types: :class:`list` of
            :class:`vmware.vapi.bindings.type.ReferenceType`
        :param error_types: Error definitions describing the errors this
            operation can report
        :type  id_: :class:`str`
        :param id_: Base task id
        """
        task_info = StructValue()
        if description is not None:
            task_info.set_field(
                'description',
                TypeConverter.convert_to_vapi(
                    description, LocalizableMessage.get_binding_type()))
        else:
            desc_value = StructValue()
            desc_value.set_field('id', StringValue())
            desc_value.set_field('default_message', StringValue())
            desc_value.set_field('args', ListValue())
            task_info.set_field('description', desc_value)

        user = self._get_user_from_sec_ctx()
        if user is not None:
            task_info.set_field('user', StringValue(user))

        task_info.set_field('service', StringValue(service_id))
        task_info.set_field('operation', StringValue(operation_id))
        task_info.set_field('cancelable',
                            BooleanValue(True if cancelable else False))
        task_info.set_field('status', PENDING_STRING_VALUE)
        base_id = id_ if id_ is not None else str(uuid.uuid4())
        task_id = self._create_task_id(base_id, service_id)

        task_summary = TaskSummary(task_info, error_types)
        with self.lock:
            self.task_map.setdefault(task_id, task_summary)

        self._remove_expired_task()
        return task_id
Ejemplo n.º 10
0
    def publish(self, accept=False):
        """
        Publish the temporary task info into task manager

        :type  accept: :class:`bool`
        :param accept: Accept task and return task id to client
        """
        published_info = self.task_manager.get_info(self.task_id)

        # Override the common info fields which can't be modified by providers
        self._override_api_info(published_info)

        if self.info.result is not None:
            # Check if result type is Opaque or actual type
            res_type = self.info_type.get_binding_type().get_field('result')
            if isinstance(res_type.element_type.definition, OpaqueDefinition):
                result = None
                try:
                    result = TypeConverter.convert_to_vapi(
                        self.info.result, self.result_type.get_binding_type())
                except AttributeError:
                    result = TypeConverter.convert_to_vapi(
                        self.info.result, self.result_type)
                self.info.result = result

        info = TypeConverter.convert_to_vapi(self.info,
                                             self.info_type.get_binding_type())
        self.task_manager.set_info(self.task_id, info)

        if accept:
            event = get_event()
            event.set()
            clear_event()
            # Validate that description is set while accepting the task
            if (self.info.description is None
                    or (not self.info.description.id
                        and not self.info.description.default_message)):
                msg = message_factory.get_message(
                    'vapi.data.structure.field.missing', self.info_type,
                    'description')
                logger.debug(msg)
                raise CoreException(msg)
Ejemplo n.º 11
0
    def get_result(self):
        """
        Returns task result

        :rtype: :class:`com.vmware.cis.tasks_client.Info`
        :return: Task Result
        """
        info = self.get_info()
        if hasattr(info, 'result'):
            return TypeConverter.convert_to_python(info.result,
                                                   self.result_type)
        else:
            return None
Ejemplo n.º 12
0
    def _initialize_common_info(self):
        """
        Initialize common task info fields
        """
        summary = self.task_manager.get_summary(self.task_id)
        published_info = summary.info
        self.error_types = summary.errors
        self._override_api_info(published_info)
        self.info.cancelable = TypeConverter.convert_to_python(
            published_info.get_field('cancelable'), BooleanType())
        desc = published_info.get_field('description')
        if desc is not None:
            self.info.description = TypeConverter.convert_to_python(
                desc, LocalizableMessage.get_binding_type())
        self.info.status = TypeConverter.convert_to_python(
            published_info.get_field('status'), StringType())

        try:
            user = published_info.get_field('user')
            self.info.user = TypeConverter.convert_to_python(
                user, StringType())
        except:  # pylint: disable=W0702
            pass
Ejemplo n.º 13
0
    def create_task(self,
                    provider_id,
                    description,
                    service_id,
                    operation_id,
                    cancelable,
                    id_=None):
        """
        Creates a task in task manager.

        :type  provider_id: :class:`str`
        :param provider_id: Service UUID
        :type  description: :class:`com.vmware.vapi.std.LocalizableMessage`
        :param description: Task description.
        :type  service_id: :class:`str`
        :param service_id: Service Id.
        :type  operation_id: :class:`str`
        :param operation_id: Operation Id.
        :type  cancelable: :class:`bool`
        :param cancelable: Is the task cancelable.
        :type  id_: :class:`str`
        :param id_: Base task id
        """
        task_info = StructValue()
        if description is not None:
            task_info.set_field(
                'description',
                TypeConverter.convert_to_vapi(
                    description, LocalizableMessage.get_binding_type()))
        else:
            desc_value = StructValue()
            desc_value.set_field('id', StringValue())
            desc_value.set_field('default_message', StringValue())
            desc_value.set_field('args', ListValue())
            task_info.set_field('description', desc_value)

        task_info.set_field('service', StringValue(service_id))
        task_info.set_field('operation', StringValue(operation_id))
        task_info.set_field('cancelable',
                            BooleanValue(True if cancelable else False))
        task_info.set_field('status', StringValue('PENDING'))
        base_id = id_ if id_ is not None else str(uuid.uuid4())
        task_id = self._create_task_id(base_id, provider_id)

        with self.lock:
            self.task_map.setdefault(task_id, task_info)

        self._remove_expired_task()
        return task_id
Ejemplo n.º 14
0
 def test_create_task(self):
     service_uuid = str(uuid.uuid4())
     task_id = self.task_manager.create_task(service_uuid,
                                             self.description,
                                             'test.service1',
                                             'op',
                                             False)
     info = self.task_manager.get_info(task_id)
     self.assertIn(service_uuid, task_id)
     self.assertEqual(info.get_field('description'),
                      TypeConverter.convert_to_vapi(self.description,
                         LocalizableMessage.get_binding_type()))
     self.assertEqual(info.get_field('service'), StringValue('test.service1'))
     self.assertEqual(info.get_field('operation'), StringValue('op'))
     self.assertEqual(info.get_field('cancelable'), BooleanValue(False))
     self.assertEqual(info.get_field('status'), StringValue('PENDING'))
Ejemplo n.º 15
0
    def get_struct_value(self):
        """
        Returns the corresponding StructValue for the VapiStruct class

        :rtype: :class:`vmware.vapi.data.value.StructValue`
        :return: StructValue for this VapiStruct
        """
        # For dynamic structures
        if self._struct_value:
            return self._struct_value
        else:
            # For static structures import TypeConverter here since
            # otherwise it causes circular imports
            from vmware.vapi.bindings.converter import TypeConverter
            struct_value = TypeConverter.convert_to_vapi(
                py_val=self, binding_type=self._binding_type)
            return struct_value
Ejemplo n.º 16
0
    def convert_to(self, cls):
        """
        Convert the underlying StructValue to an instance of the provided class
        if possible.  Conversion will be possible if the StructValue contains
        all the fields expected by the provided class and the type of the value
        in each fields matches the type of the field expected by the provided
        class.

        :type  cls: :class:`vmware.vapi.data.value.StructValue`
        :param cls: The type to convert to
        :rtype: :class:'vmware.vapi.bindings.struct.VapiStruct'
        :return: The converted value
        """
        # Import TypeConverter here since otherwise it causes circular imports
        from vmware.vapi.bindings.converter import TypeConverter
        return TypeConverter.convert_to_python(
            vapi_val=self.get_struct_value(),
            binding_type=cls.get_binding_type(),
            rest_converter_mode=self._rest_converter_mode)
Ejemplo n.º 17
0
 def _convert(self, dt, dt_str):
     dt_str = StringValue(dt_str)
     self.assertEqual(TypeConverter.convert_to_vapi(dt, self.typ), dt_str)
     self.assertEqual(TypeConverter.convert_to_python(dt_str, self.typ), dt)
Ejemplo n.º 18
0
 def test_utc_time_conversion(self):
     dt1 = datetime.datetime(2006, 11, 21, 16, 30, tzinfo=GMT1())
     utc_dt = convert_to_utc(dt1)
     self.assertEqual(TypeConverter.convert_to_vapi(utc_dt, self.typ),
                      StringValue('2006-11-21T15:30:00.000Z'))
Ejemplo n.º 19
0
 def _convert(self, uri_string):
     self.assertEqual(TypeConverter.convert_to_vapi(uri_string, self.typ),
                      StringValue(uri_string))
     self.assertEqual(
         TypeConverter.convert_to_python(StringValue(uri_string), self.typ),
         uri_string)
Ejemplo n.º 20
0
    def native_invoke(self, ctx, method_name, kwargs):
        """
        Invokes the method corresponding to the given method name
        with the kwargs.

        In this method, python native values are converted to vAPI
        runtime values, operation is invoked and the result are converted
        back to python native values

        :type  ctx: :class:`vmware.vapi.core.ExecutionContext`
        :param ctx: Execution context for this method
        :type  method_name: :class:`str`
        :param method_name: Method name
        :type  kwargs: :class:`dict`
        :param kwargs: arguments to be passed to the method
        :rtype: :class:`object`
        :return: Method result
        """
        op_info = self._operations.get(method_name)
        if op_info is None:
            raise Exception('Could not find %s method in %s interface' %
                            (method_name, str(self._iface_id)))

        # Convert input
        input_type = op_info['input_type']
        data_val = TypeConverter.convert_to_vapi(kwargs, input_type,
                                                 self._rest_converter_mode)

        # Validate input
        validators = op_info['input_value_validator_list']
        for validator in validators:
            msg_list = validator.validate(data_val, input_type)
            raise_core_exception(msg_list)

        if OPID in ctx.application_context:
            logger.debug(
                'opId: %s invoke: interface_id: %s, operation_name: %s',
                ctx.application_context[OPID], self._iface_id.get_name(),
                method_name)
        else:
            logger.debug('invoke: interface_id: %s, operation_name: %s',
                         self._iface_id, method_name)

        # Invoke
        method_id = MethodIdentifier(self._iface_id, method_name)
        if self._use_rest:
            operation_rest_metadata = None
            if self._rest_metadata:
                operation_rest_metadata = self._rest_metadata.get(method_name)
            if operation_rest_metadata is None:
                msg = message_factory.get_message(
                    'vapi.bindings.stub.rest_metadata.unavailable')
                logger.debug(msg)
                raise CoreException(msg)
        else:
            if self._is_vapi_rest is not None and not self._is_vapi_rest:
                # If the rest format is not vapi, then the server
                # (OpenAPI based) will not be supporting json-rpc.
                msg = message_factory.get_message(
                    'vapi.bindings.stub.jsonrpc.unsupported')
                logger.debug(msg)
                raise CoreException(msg)
        method_result = self.invoke(ctx, method_id, data_val)

        # Validate output
        if method_result.success():
            validators = op_info['output_validator_list']
            output_type = op_info['output_type']

            for validator in validators:
                msg_list = validator.validate(method_result.output, output_type)
                raise_core_exception(msg_list)

            # Convert output
            return TypeConverter.convert_to_python(method_result.output,
                                                   output_type,
                                                   self._config.resolver,
                                                   self._rest_converter_mode)
        else:
            # Convert error
            errors = op_info['errors']
            error_type = errors.get(method_result.error.name)
            if error_type is None:
                error_type = self._config.resolver.resolve(
                    method_result.error.name)
            if error_type is None:
                logger.warning('Unable to convert unexpected vAPI error %s ' +
                               'to native Python exception',
                               method_result.error.name)
                vapi_error = UnresolvedError(method_result.error)
                raise vapi_error
            raise TypeConverter.convert_to_python(method_result.error,  # pylint: disable=E0702
                                                  error_type,
                                                  self._config.resolver,
                                                  self._rest_converter_mode)
Ejemplo n.º 21
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
Ejemplo n.º 22
0
    def publish(self, accept=False):
        """
        Publish the temporary task info into task manager

        :type  accept: :class:`bool`
        :param accept: Accept task and return task id to client
        """
        msg_list = None
        published_info = self.task_manager.get_info(self.task_id)

        # Override the common info fields which can't be modified by providers
        self._override_api_info(published_info)

        if hasattr(self.info, 'error') and self.info.error is not None:
            err_type = self.info.error.get_binding_type()
            # Verify if the error set by provider is amongst the ones
            # defined in VMODL2, if not throw InternalServerError
            if (err_type not in self.error_types):
                msg_list = [
                    message_factory.get_message('vapi.task.invalid.error',
                                                err_type.name,
                                                self.info.operation)
                ]

        if hasattr(self.info, 'result') and self.info.result is not None:
            # Check if result type is Opaque or actual type
            res_type = self.info_type.get_binding_type().get_field('result')
            if isinstance(res_type.element_type.definition, OpaqueDefinition):
                result = None
                try:
                    result = TypeConverter.convert_to_vapi(
                        self.info.result, self.result_type.get_binding_type())
                except AttributeError:
                    try:
                        result = TypeConverter.convert_to_vapi(
                            self.info.result, self.result_type)
                    except CoreException:
                        msg_list = [
                            message_factory.get_message(
                                'vapi.task.invalid.result', self.info.result,
                                self.info.operation)
                        ]
                        self.info.result = None

                if msg_list is None:
                    self.info.result = result

        info = TypeConverter.convert_to_vapi(self.info,
                                             self.info_type.get_binding_type())

        if msg_list is not None:
            info.set_field('status', FAILED_STRING_VALUE)
            logger.error(msg_list[0])
            error = make_error_value_from_msgs(self._internal_server_error_def,
                                               *msg_list)
            info.set_field('error', OptionalValue(error))

        self.task_manager.set_info(self.task_id, info)

        if accept:
            event = get_event()
            event.set()
            clear_event()
            # Validate that description is set while accepting the task
            desc = self.info.description
            if desc is None or (not desc.id and not desc.default_message):
                msg = message_factory.get_message(
                    'vapi.data.structure.field.missing', self.info_type,
                    'description')
                logger.debug(msg)
                raise CoreException(msg)