def get_data_values(self): # Data values list_value = ListValue() list_value.add_all([IntegerValue(val) for val in range(1,15)]) data_values = [ VoidValue(), IntegerValue(3), DoubleValue(decimal.Decimal('7.2')), StringValue('blah'), SecretValue(), BooleanValue(True), BlobValue(b"a blob"), BlobValue(b"0\x82\x04\x00"), list_value, OptionalValue(), OptionalValue(IntegerValue(7)), StructValue('name'), self.get_struct_value(), self.get_error_value(), ] struct_value = StructValue('struct') for idx, data_val in enumerate(data_values): struct_value.set_field(str(idx), data_val) data_values.append(struct_value) return data_values
def generate_primitive_value(self, typ): output = StructValue(Introspection.DATA_DEFINITION) output.set_field('type', StringValue(typ)) output.set_field('fields', OptionalValue()) output.set_field('name', OptionalValue()) output.set_field('element_definition', OptionalValue()) return output
def test_query_params_optionals(self): input_val = StructValue(name='operation-input', values={ 'string_val': StringValue('string1'), 'action1_val': OptionalValue(value=StringValue('start')), 'action2_val': OptionalValue() }) rest_metadata = OperationRestMetadata(http_method='POST', url_template='/foo/bar', query_parameters={ 'action1_val': 'action1', 'action2_val': 'action2' }) url_path, actual_headers, actual_body, _ = RestSerializer.serialize_request( input_value=input_val, ctx=None, rest_metadata=rest_metadata, is_vapi_rest=True) expected_url_path = '/foo/bar?action1=start' expected_headers = {} expected_body = '{"string_val":"string1"}' self.assertEqual(expected_url_path, url_path) self.assertEqual(expected_headers, actual_headers) self.assertEqual(expected_body, actual_body)
def test_struct_ref_to_value(self): actual_output = convert_data_def_to_data_value( StructRefDefinition('mock')) expected_output = StructValue(Introspection.DATA_DEFINITION) expected_output.set_field('type', StringValue('STRUCTURE_REF')) expected_output.set_field('fields', OptionalValue()) expected_output.set_field('name', OptionalValue(StringValue('mock'))) expected_output.set_field('element_definition', OptionalValue()) self.assertEqual(actual_output, expected_output)
def test_generic_def_to_value(self): for typ_def, typ in [(OptionalDefinition, 'OPTIONAL'), (ListDefinition, 'LIST')]: typ_def = typ_def(StringDefinition()) actual_output = convert_data_def_to_data_value(typ_def) expected_output = StructValue(Introspection.DATA_DEFINITION) element_value = self.generate_primitive_value('STRING') expected_output.set_field('type', StringValue(typ)) expected_output.set_field('fields', OptionalValue()) expected_output.set_field('name', OptionalValue()) expected_output.set_field('element_definition', OptionalValue(element_value)) self.assertEqual(actual_output, expected_output)
def test_optional_value(self): input_val = OptionalValue(StringValue('val1')) actual_val = DataValueConverter.convert_to_json(input_val) expected_val = '"val1"' self.assertEqual(expected_val, actual_val) # Verify json is valid json.loads(actual_val) input_val = OptionalValue() actual_val = DataValueConverter.convert_to_json(input_val) expected_val = 'null' self.assertEqual(expected_val, actual_val) # Verify json is valid json.loads(actual_val)
def test_error_to_value(self): struct_def = ErrorDefinition('mock', [('field1', StringDefinition())]) actual_output = convert_data_def_to_data_value(struct_def) expected_output = StructValue(Introspection.DATA_DEFINITION) expected_output.set_field('type', StringValue('ERROR')) expected_output.set_field('name', OptionalValue(StringValue('mock'))) expected_output.set_field('element_definition', OptionalValue()) field_value = self.generate_primitive_value('STRING') field_entry = StructValue(MAP_ENTRY) field_entry.set_field('key', StringValue('field1')) field_entry.set_field('value', field_value) field_values = ListValue() field_values.add(field_entry) expected_output.set_field('fields', OptionalValue(field_values)) self.assertEqual(actual_output, expected_output)
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'))
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))
def visit_optional(self, type_info, json_value): """ Deserialize an optional value :type type_info: :class:`com.vmware.vapi.metadata.metamodel_client.Type` :param type_info: Metamodel type information :type json_value: :class:`object` :param json_value: Value to be visited :rtype: :class:`vmware.vapi.data.value.OptionalValue` :return: DataValue created using the input """ if json_value is not None: element_value = self.visit(type_info.element_type, json_value) return OptionalValue(element_value) else: return OptionalValue()
def test_optional_value(self): input_status = 200 input_response = '{"value":null}' expected_result = MethodResult(output=OptionalValue()) actual_result = RestSerializer.deserialize_response( status=input_status, response_str=input_response, is_vapi_rest=True) self.assertEqual(expected_result.output, actual_result.output) self.assertEqual(expected_result.error, actual_result.error)
def _visit_none(self, obj): # pylint: disable=R0201,W0613 """ Visit python None object :type obj: :class:`NoneType` :param obj: Python None object :rtype: :class:`vmware.vapi.data.value.OptionalValue` :return: Optional value """ return OptionalValue()
def test_struct_value_with_optional_unset(self): input_val = StructValue(name='name', values={ 'val1': StringValue('val1'), 'val2': OptionalValue() }) actual_val = DataValueConverter.convert_to_json(input_val) expected_val = '{"val1":"val1"}' self.assertEqual(expected_val, actual_val) # Verify json is valid json.loads(actual_val)
def test_value_to_struct_ref_def(self): struct_value = StructValue(Introspection.DATA_DEFINITION) struct_value.set_field('type', StringValue('STRUCTURE')) struct_value.set_field('name', OptionalValue(StringValue('mock'))) struct_value.set_field('element_definition', OptionalValue()) field_value = self.generate_primitive_value('STRUCTURE_REF') field_value.set_field('name', OptionalValue(StringValue('mock'))) field_entry = StructValue(MAP_ENTRY) field_entry.set_field('key', StringValue('field1')) field_entry.set_field('value', field_value) field_values = ListValue() field_values.add(field_entry) struct_value.set_field('fields', OptionalValue(field_values)) actual_output = convert_data_value_to_data_def(struct_value) expected_output = StructDefinition( 'mock', [('field1', StructRefDefinition('mock'))]) self.assertEqual(actual_output, expected_output) # Check the circular reference as well self.assertEqual( actual_output.get_field('field1').target, expected_output)
def test_struct_value_with_optional_set(self): input_val = StructValue(name='name', values={ 'val1': StringValue('val1'), 'val2': OptionalValue(StringValue('val2')) }) actual_val = DataValueConverter.convert_to_json(input_val) self.assertTrue('"val1":"val1"' in actual_val) self.assertTrue('"val2":"val2"' in actual_val) # Verify json is valid json.loads(actual_val)
def test_introspection_operation_get(self): ctx = ExecutionContext() input_val = StructValue(OPERATION_INPUT) input_val.set_field('service_id', StringValue('mockup_interface')) input_val.set_field('operation_id', StringValue('mock')) actual_output = self.local_provider.invoke( 'com.vmware.vapi.std.introspection.operation', 'get', input_val, ctx) expected_output = StructValue( name='com.vmware.vapi.std.introspection.operation.info') input_def_value = StructValue( 'com.vmware.vapi.std.introspection.operation.data_definition') input_def_value.set_field('fields', OptionalValue(ListValue(values=[]))) input_def_value.set_field('element_definition', OptionalValue()) input_def_value.set_field('type', StringValue('STRUCTURE')) input_def_value.set_field('name', OptionalValue(StringValue(OPERATION_INPUT))) expected_output.set_field('input_definition', input_def_value) output_def_value = StructValue( 'com.vmware.vapi.std.introspection.operation.data_definition') output_def_value.set_field('fields', OptionalValue()) output_def_value.set_field('element_definition', OptionalValue()) output_def_value.set_field('type', StringValue('VOID')) output_def_value.set_field('name', OptionalValue()) expected_output.set_field('output_definition', output_def_value) expected_output.set_field('error_definitions', error_values) self.assertEqual(actual_output.output, expected_output)
def test_check_for_unknown_fields_2(self): optional_struct_type = OptionalType(StructType( 'test', { 'name': StringType() } )) optional_struct_value = OptionalValue(StructValue( name='test', values={ 'name': StringValue('hello') } )) self.assertIsNone( ApiInterfaceSkeleton.check_for_unknown_fields( optional_struct_type, optional_struct_value))
def test_invalid_query_params(self): input_val = StructValue(name='operation-input', values={ 'string_val': StringValue('string1'), 'action1_val': OptionalValue(value=StringValue('start')), 'action2_val': ListValue([]) }) rest_metadata = OperationRestMetadata(http_method='POST', url_template='/foo/bar', query_parameters={ 'action1_val': 'action1', 'action2_val': 'action2' }) self.assertRaises(CoreException, RestSerializer.serialize_request, input_value=input_val, ctx=None, rest_metadata=rest_metadata, is_vapi_rest=True)
def convert_data_def_to_data_value(data_def): """ Convert :class:`vmware.vapi.data.definition.DataDefinition` object to :class:`vmware.vapi.data.value.DataValue` object. The type of the object returned is a struct value that corresponds to DataDefinition VMODL2 type present in introspection service. :type data_def: :class:`vmware.vapi.data.definition.DataDefinition` :param data_def: Data definition :rtype: :class:`vmware.vapi.data.value.DataValue` :return: Data value representing the data definition object """ result = StructValue(Introspection.DATA_DEFINITION) result.set_field('type', StringValue(data_type_map.get(data_def.type))) if (data_def.type == Type.STRUCTURE or data_def.type == Type.STRUCTURE_REF or data_def.type == Type.ERROR): result.set_field('name', OptionalValue(StringValue(data_def.name))) else: result.set_field('name', OptionalValue()) if (data_def.type == Type.OPTIONAL or data_def.type == Type.LIST): element_definition = data_def.element_type element_value = convert_data_def_to_data_value(element_definition) result.set_field('element_definition', OptionalValue(element_value)) else: result.set_field('element_definition', OptionalValue()) if (data_def.type == Type.STRUCTURE or data_def.type == Type.ERROR): fields = ListValue() for field_name in data_def.get_field_names(): element_definition = data_def.get_field(field_name) field_pair = StructValue(MAP_ENTRY) field_pair.set_field('key', StringValue(field_name)) field_pair.set_field( 'value', convert_data_def_to_data_value(element_definition)) fields.add(field_pair) result.set_field('fields', OptionalValue(fields)) else: result.set_field('fields', OptionalValue()) return result
def get_struct_value(self): struct_value = StructValue('struct0') struct_value.set_field('int', IntegerValue(7)) struct_value.set_field('optional', OptionalValue(StringValue("123"))) struct_value.set_field('optional1', OptionalValue()) return struct_value
def get_error_value(self): error_value = ErrorValue('struct0') error_value.set_field('int', IntegerValue(7)) error_value.set_field('optional', OptionalValue(StringValue("123"))) error_value.set_field('optional1', OptionalValue()) return error_value
def test_none(self): input_val = 'null' expected_val = OptionalValue() actual_val = DataValueConverter.convert_to_data_value(input_val) self.assertEqual(expected_val, actual_val)
def build_data_value(py_value, data_def): """ Converts a native python value to data value using the provided data definition :type py_value: :class:`object` :param py_value: Python native value :type data_def: :class:`vmware.vapi.data.definition.DataDefinition` :param data_def: Data definition :rtype: :class:`vmware.vapi.data.value.DataValue` :return: Data value """ output_val = None if data_def.type == Type.OPTIONAL: output_val = data_def.new_value() if py_value is not None: output_val.value = build_data_value(py_value, data_def.element_type) elif data_def.type == Type.LIST: output_val = data_def.new_value() if py_value: for output in py_value: output_val.add(build_data_value(output, data_def.element_type)) elif data_def.type in (Type.STRUCTURE, Type.ERROR): output_val = data_def.new_value() for field in data_def.get_field_names(): field_def = data_def.get_field(field) if py_value is None: if field_def.type == Type.OPTIONAL: output_val.set_field(field, OptionalValue()) else: msg = message_factory.get_message( 'vapi.data.structure.field.missing', data_def.name, field) raise CoreException(msg) else: if isinstance(py_value, dict): value = py_value.get(field) elif isinstance(py_value, VapiStruct): # If Class used in python bindings is the struct value = py_value.get_field(field) else: msg = message_factory.get_message( 'vapi.data.structure.field.invalid', field) raise CoreException(msg) output_val.set_field( field, build_data_value(value, data_def.get_field(field))) elif data_def.type == Type.DYNAMIC_STRUCTURE: output_val = StructValue(DYNAMIC_STRUCTURE) if isinstance(py_value, dict): for key, val in six.iteritems(py_value): if val is None: field_data_def = OptionalDefinition(StringDefinition()) elif isinstance(val, list): if len(val) == 0: # empty list field_data_def = ListDefinition(StringDefinition()) else: # at least one element field_data_def = ListDefinition( _py_to_data_def_map.get(type(val[0]))()) elif isinstance(val, dict): field_data_def = DynamicStructDefinition() else: try: # Field is probably a primitive/atomic type field_data_def_type = _py_to_data_def_map[type(val)] field_data_def = field_data_def_type() except KeyError: msg = message_factory.get_message( 'vapi.data.serializers.python.unsupported.' 'python.type', type(val), key) raise CoreException(msg) output_val.set_field(key, build_data_value(val, field_data_def)) elif data_def.type == Type.VOID: output_val = data_def.new_value() elif data_def.type == Type.OPAQUE: output_val = py_value # Primitive type Integer/Double/String/Boolean/Secret else: output_val = data_def.new_value(py_value) return output_val
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)