Esempio n. 1
0
 def convert_field_info_to_swagger_parameter(self, param_type,
                                             input_parameter_obj, type_dict,
                                             structure_svc, enum_svc,
                                             show_unreleased_apis):
     """
     Converts metamodel fieldinfo to swagger parameter.
     """
     parameter_obj = {}
     ref_path = "#/definitions/"
     tpHandler = ApiTypeHandler(show_unreleased_apis)
     tpHandler.visit_type_category(input_parameter_obj.type, parameter_obj,
                                   type_dict, structure_svc, enum_svc,
                                   ref_path)
     if 'required' not in parameter_obj:
         parameter_obj['required'] = True
     parameter_obj['in'] = param_type
     parameter_obj['name'] = input_parameter_obj.name
     parameter_obj['description'] = input_parameter_obj.documentation
     # $ref should be encapsulated in 'schema' instead of parameter. -> this throws swagger validation error
     # hence another method is to to get data in $ref in parameter_obj
     # itself
     if '$ref' in parameter_obj:
         type_obj = type_dict[parameter_obj['$ref'][len(ref_path):]]
         description = parameter_obj['description']
         if 'description' in type_obj:
             description = ""
             description = "{ 1. " + type_obj['description'] + \
                 " }, { 2. " + parameter_obj['description'] + " }"
         parameter_obj.update(type_obj)
         parameter_obj['description'] = description
         del parameter_obj['$ref']
     return parameter_obj
    def wrap_body_params(
            self,
            service_name,
            operation_name,
            content_type,
            body_param_list,
            type_dict,
            structure_svc,
            enum_svc,
            show_unreleased_apis):
        """
        Creates a  json object wrapper around request body parameters. parameter names are used as keys and the
        parameters as values.
        For instance, datacenter create operation takes CreateSpec whose parameter name is spec.
        This method creates a json wrapper object
        datacenter.create {
        'spec' : {spec obj representation  }
        }
        """
        # todo:
        # form-url-encoded support; not utilized content_type
        # todo:
        # not unique enough. make it unique
        wrapper_name = utils.get_str_camel_case(service_name + '_' + operation_name, *utils.CAMELCASE_SEPARATOR_LIST)
        body_obj = {}
        properties_obj = {}
        required = []
        ref_path = "#/components/schemas/"
        tpHandler = ApiTypeHandler(show_unreleased_apis)
        for param in body_param_list:
            parameter_obj = {}
            tpHandler.visit_type_category(
                param.type,
                parameter_obj,
                type_dict,
                structure_svc,
                enum_svc,
                ref_path)
            parameter_obj['description'] = param.documentation
            body_obj.update(parameter_obj)

        if 'requestBodies' not in type_dict:
            type_dict['requestBodies'] = {}
        type_dict['requestBodies'][wrapper_name] = {
            'content': {
                'application/json': {
                    'schema': {
                        '$ref': ref_path + wrapper_name
                    }
                }
            }
        }
        type_dict[wrapper_name] = body_obj
        parameter_obj = {'$ref': "#/components/requestBodies/" + wrapper_name}

        return parameter_obj
    def wrap_body_params(self, service_name, operation_name, content_type,
                         body_param_list, type_dict, structure_svc, enum_svc,
                         show_unreleased_apis):
        """
        Creates a  json object wrapper around request body parameters. parameter names are used as keys and the
        parameters as values.
        For instance, datacenter create operation takes CreateSpec whose parameter name is spec.
        This method creates a json wrapper object
        datacenter.create {
        'spec' : {spec obj representation  }
        }
        """
        # todo:
        # not unique enough. make it unique
        wrapper_name = utils.get_str_camel_case(
            service_name + '_' + operation_name,
            *utils.CAMELCASE_SEPARATOR_LIST)
        body_obj = {}
        properties_obj = {}
        required = []
        ref_path = "#/definitions/"
        tpHandler = ApiTypeHandler(show_unreleased_apis)
        for param in body_param_list:
            parameter_obj = {}
            tpHandler.visit_type_category(param.type, parameter_obj, type_dict,
                                          structure_svc, enum_svc, ref_path)
            parameter_obj['description'] = param.documentation
            if 'BodyField' in param.metadata:
                body_obj['type'] = 'object'
                body_obj['properties'] = properties_obj
                properties_obj[param.metadata['BodyField'].elements['name'].
                               string_value] = parameter_obj
                if 'required' not in parameter_obj:
                    required.append(param.name)
                elif parameter_obj['required'] == 'true':
                    required.append(param.name)
            else:
                body_obj.update(parameter_obj)

        parameter_obj = {'in': 'body', 'name': 'request_body'}
        if len(required) > 0:
            body_obj['required'] = required
            parameter_obj['required'] = True
        elif 'required' in body_obj:
            del body_obj['required']

        type_dict[wrapper_name] = body_obj

        if content_type == 'FORM_URLENCODED':
            return self.wrap_form_data_params(type_dict, wrapper_name)

        schema_obj = {'$ref': ref_path + wrapper_name}
        parameter_obj['schema'] = schema_obj
        return parameter_obj
Esempio n. 4
0
    def wrap_body_params(self, service_name, operation_name, body_param_list,
                         type_dict, structure_svc, enum_svc, enable_filtering):
        """
        Creates a  json object wrapper around request body parameters. parameter names are used as keys and the
        parameters as values.
        For instance, datacenter create operation takes CreateSpec whose parameter name is spec.
        This method creates a json wrapper object
        datacenter.create {
        'spec' : {spec obj representation  }
        }
        """
        # todo:
        # not unique enough. make it unique
        wrapper_name = service_name + '_' + operation_name
        body_obj = {}
        properties_obj = {}
        required = []
        ref_path = "#/components/schemas/"
        tpHandler = ApiTypeHandler()
        for param in body_param_list:
            parameter_obj = {}
            tpHandler.visit_type_category(param.type, parameter_obj, type_dict,
                                          structure_svc, enum_svc, ref_path,
                                          enable_filtering)
            parameter_obj['description'] = param.documentation
            body_obj.update(parameter_obj)

        if 'requestBodies' not in type_dict:
            type_dict['requestBodies'] = {}
        type_dict['requestBodies'][wrapper_name] = {
            'content': {
                'application/json': {
                    'schema': {
                        '$ref': ref_path + wrapper_name
                    }
                }
            }
        }
        type_dict[wrapper_name] = body_obj
        parameter_obj = {'$ref': "#/components/requestBodies/" + wrapper_name}

        return parameter_obj
Esempio n. 5
0
    def wrap_body_params(self, service_name, operation_name, body_param_list,
                         type_dict, structure_svc, enum_svc, enable_filtering):
        """
        Creates a  json object wrapper around request body parameters. parameter names are used as keys and the
        parameters as values.
        For instance, datacenter create operation takes CreateSpec whose parameter name is spec.
        This method creates a json wrapper object
        datacenter.create {
        'spec' : {spec obj representation  }
        }
        """
        # todo:
        # not unique enough. make it unique
        wrapper_name = service_name + '_' + operation_name
        body_obj = {}
        properties_obj = {}
        required = []
        ref_path = "#/definitions/"
        tpHandler = ApiTypeHandler()
        for param in body_param_list:
            parameter_obj = {}
            tpHandler.visit_type_category(param.type, parameter_obj, type_dict,
                                          structure_svc, enum_svc, ref_path,
                                          enable_filtering)
            parameter_obj['description'] = param.documentation
            body_obj.update(parameter_obj)

        parameter_obj = {'in': 'body', 'name': 'request_body'}
        if len(required) > 0:
            body_obj['required'] = required
            parameter_obj['required'] = True
        elif 'required' in body_obj:
            del body_obj['required']

        type_dict[wrapper_name] = body_obj

        schema_obj = {'$ref': ref_path + wrapper_name}
        parameter_obj['schema'] = schema_obj
        return parameter_obj
Esempio n. 6
0
    def populate_response_map(self, output, errors, http_error_map, type_dict,
                              structure_svc, enum_svc, service_id,
                              operation_id, op_metadata, show_unreleased_apis):

        response_map = {}
        ref_path = "#/components/schemas/"
        success_response = {
            'description': output.documentation,
            'content': {
                'application/json': {}
            }
        }
        schema = {}
        tpHandler = ApiTypeHandler(show_unreleased_apis)
        tpHandler.visit_type_category(output.type, schema, type_dict,
                                      structure_svc, enum_svc, ref_path)
        # if type of schema is void, don't include it.
        # this prevents showing response as void in swagger-ui
        if schema is not None:
            if not ('type' in schema and schema['type'] == 'void'):
                resp = schema
                success_response['content']['application/json'][
                    'schema'] = resp
        # success response is not mapped through metamodel.
        # hardcode it for now.
        success_response_code = requests.codes.ok
        if 'Response' in op_metadata and op_metadata['Response'] is not None:
            success_response_code = int(
                op_metadata['Response'].elements['code'].string_value)
        response_map[success_response_code] = success_response

        for error in errors:
            status_code = http_error_map.error_api_map.get(
                error.structure_id, http_client.INTERNAL_SERVER_ERROR)
            tpHandler.check_type('com.vmware.vapi.structure',
                                 error.structure_id, type_dict, structure_svc,
                                 enum_svc, ref_path)
            response_obj = {
                'description': error.documentation,
                'content': {
                    'application/json': {
                        'schema': {
                            '$ref':
                            ref_path + utils.get_str_camel_case(
                                error.structure_id, *
                                utils.CAMELCASE_SEPARATOR_LIST)
                        }
                    }
                }
            }
            response_map[status_code] = response_obj
        return response_map
class TestApiTypeHandler(unittest.TestCase):

    # Showing unreleased apis (disabled filtering)
    api_tphandler = ApiTypeHandler(True)

    def test_visit_generic(self):
        # case 1: when generic instantiation type is 'SET' and category is 'BUILT-IN'
        generic_instantiation_element_type_mock = mock.Mock()
        generic_instantiation_element_type_mock.category = 'BUILTIN'
        generic_instantiation_element_type_mock.builtin_type = 'date-time'
        generic_instantiation_mock = mock.Mock()
        generic_instantiation_mock.generic_type = 'SET'
        generic_instantiation_mock.element_type = generic_instantiation_element_type_mock

        field_info_mock = mock.Mock()
        field_info_type = mock.Mock()
        field_info_type.category = 'BUILTIN'
        field_info_type.builtin_type = 'date-time'
        field_info_mock.type = field_info_type
        field_info_mock.generic_instantiation = generic_instantiation_mock
        field_info_mock.documentation = 'fieldInfoMockDescription'
        field_info_mock.name = 'fieldInfoMockName'
        field_info_mock.metadata = {}
        structure_info_mock = mock.Mock()
        structure_info_mock.fields = [field_info_mock]
        structure_dict = {'com.vmware.package.mock': structure_info_mock}
        '''
        The structure dict looks like: 
        structure_dict = {
            'com.vmware.package.mock': StructureInfo( fields = [ FieldInfo(
                name = 'fieldInfoMockName', documentation =  'fieldInfoMockDescription',
                generic_instantiation = GenericInstantiation( generic_type = 'SET',
                element_type = Type( category = 'BUILTIN', builtin_type = 'date-time'))
            )])
        }
        '''
        new_prop = {}
        self.api_tphandler.visit_generic(generic_instantiation_mock, new_prop,
                                         {}, structure_dict, {},
                                         '#/definitions/')
        new_prop_expected = {
            'type': 'array',
            'uniqueItems': True,
            'items': {
                'type': 'date-time'
            }
        }
        self.assertEqual(new_prop_expected, new_prop)

        # case 2: when generic instantiation type is 'OPTIONAL' and category is 'BUILT-IN'
        generic_instantiation_mock.generic_type = 'OPTIONAL'
        new_prop = {}
        self.api_tphandler.visit_generic(generic_instantiation_mock, new_prop,
                                         {}, structure_dict, {},
                                         '#/definitions/')
        new_prop_expected = {'required': False, 'type': 'date-time'}
        self.assertEqual(new_prop_expected, new_prop)

        # case 3: when generic instantiation type is 'LIST' and category is 'USER-DEFINED'
        generic_instantiation_mock.generic_type = 'LIST'
        user_defined_type_mock = mock.Mock()
        user_defined_type_mock.resource_type = 'com.vmware.vapi.structure'
        user_defined_type_mock.resource_id = 'com.vmware.package.mock'
        generic_instantiation_element_type_mock.category = 'USER_DEFINED'
        generic_instantiation_element_type_mock.user_defined_type = user_defined_type_mock
        '''
        The structure dict looks like: 
        structure_dict = {
            'com.vmware.package.mock': StructureInfo( fields = [ FieldInfo(
                name = 'fieldInfoMockName', documentation =  'fieldInfoMockDescription',
                generic_instantiation = GenericInstantiation( generic_type = 'LIST',
                element_type = Type( category = 'USER_DEFINED', user_defined_type = UserDefinedType(
                    resource_type = 'com.vmware.vapi.structure', resource_id = 'ComVmwarePackageMock'
                )))
            )])
        }
        '''
        new_prop = {}
        self.api_tphandler.visit_generic(generic_instantiation_mock, new_prop,
                                         {}, structure_dict, {},
                                         '#/definitions/')
        new_prop_expected = {
            'type': 'array',
            'items': {
                '$ref': '#/definitions/ComVmwarePackageMock'
            }
        }
        self.assertEqual(new_prop_expected, new_prop)

        # case 4: when generic instantiation type is 'MAP'
        # case 4.1 : map key and value type is 'BUILTIN'
        map_key_type_mock = mock.Mock()
        map_key_type_mock.category = 'BUILTIN'
        map_key_type_mock.builtin_type = 'long'
        map_value_type_mock = mock.Mock()
        map_value_type_mock.category = 'BUILTIN'
        map_value_type_mock.builtin_type = 'long'
        generic_instantiation_mock = mock.Mock()
        generic_instantiation_mock.generic_type = 'MAP'
        generic_instantiation_mock.map_key_type = map_key_type_mock
        generic_instantiation_mock.map_value_type = map_value_type_mock
        '''
        The structure dict looks like: 
        structure_dict = {
            'com.vmware.package.mock': StructureInfo( fields = [ FieldInfo(
                name = 'fieldInfoMockName', documentation =  'fieldInfoMockDescription',
                generic_instantiation = GenericInstantiation( generic_type = 'MAP',
                map_key_type = MapKeyType( category = 'BUILTIN', builtin_type = 'long'),
                map_value_type = MapValueType( category = 'BUILTIN', builtin_type = 'long')
                )
            )])
        }
        '''
        new_prop = {}
        self.api_tphandler.visit_generic(generic_instantiation_mock, new_prop,
                                         {}, structure_dict, {},
                                         '#/definitions/')
        new_prop_expected = {
            'type': 'object',
            'additionalProperties': {
                'type': 'integer'
            }
        }
        self.assertEqual(new_prop_expected, new_prop)

        # case 4.2: map key and value type is 'USER_DEFINED'
        map_value_type_mock.category = 'USER_DEFINED'
        map_value_type_mock.user_defined_type = user_defined_type_mock
        type_dict = {'com.vmware.package.mock': {}}
        new_prop = {}
        self.api_tphandler.visit_generic(generic_instantiation_mock, new_prop,
                                         type_dict, structure_dict, {},
                                         '#/definitions/')
        new_prop_expected = {
            'type': 'object',
            'additionalProperties': {
                '$ref': '#/definitions/ComVmwarePackageMock'
            }
        }
        self.assertEqual(new_prop_expected, new_prop)

        # case 4.3: map key and value type is 'GENERIC'
        generic_instantiation_map_value_type_mock = mock.Mock()
        generic_instantiation_map_value_type_mock.generic_type = 'OPTIONAL'
        generic_instantiation_map_value_type_mock.element_type = generic_instantiation_element_type_mock
        map_value_type_mock.category = 'GENERIC'
        map_value_type_mock.generic_instantiation = generic_instantiation_map_value_type_mock
        new_prop = {}
        self.api_tphandler.visit_generic(generic_instantiation_mock, new_prop,
                                         type_dict, structure_dict, {},
                                         '#/definitions/')
        new_prop_expected = {
            'type': 'object',
            'additionalProperties': {
                '$ref': '#/definitions/ComVmwarePackageMock'
            }
        }
        self.assertEqual(new_prop_expected, new_prop)
Esempio n. 8
0
 def flatten_query_param_spec(self, query_param_info, type_dict,
                              structure_svc, enum_svc,
                              show_unreleased_apis):
     """
     Flattens query parameters specs.
     1. Create a query parameter for every field in spec.
         Example 1:
             consider datacenter get which accepts optional filterspec.
             Optional<Datacenter.FilterSpec> filter)
             The method would convert the filterspec to 3 separate query parameters
             filter.datacenters, filter.names and filter.folders.
         Example 2:
             consider /vcenter/deployment/install/initial-config/remote-psc/thumbprint get
             which accepts parameter
             vcenter.deployment.install.initial_config.remote_psc.thumbprint.remote_spec.
             The two members defined under remote_spec
             address and https_port are converted to two separate query parameters
             address(required) and https_port(optional).
     2. The field info is simple type. i.e the type is string, integer
         then it is converted it to swagger parameter.
         Example:
             consider /com/vmware/content/library/item get
             which accepts parameter 'library_id'. The field is converted
             to library_id query parameter.
     3. This field has references to a spec but the spec is not
         a complex type and does not have property 'properties'.
         i.e the type is string, integer. The members defined under the spec are
         converted to query parameter.
         Example:
             consider /appliance/update/pending get which accepts two parameter
             'source_type' and url. Where source_type is defined in the spec
             'appliance.update.pending.source_type' and field url
             is of type string.
             The fields 'source_type' and 'url' are converted to query parameter
             of type string.
     """
     prop_array = []
     parameter_obj = {}
     ref_path = "#/definitions/"
     tpHandler = ApiTypeHandler(show_unreleased_apis)
     tpHandler.visit_type_category(query_param_info.type, parameter_obj,
                                   type_dict, structure_svc, enum_svc,
                                   ref_path)
     if '$ref' in parameter_obj:
         reference = parameter_obj['$ref'].replace(ref_path, '')
         type_ref = type_dict.get(reference, None)
         if type_ref is None:
             return None
         if 'properties' in type_ref:
             for property_name, property_value in six.iteritems(
                     type_ref['properties']):
                 prop = {'in': 'query', 'name': property_name}
                 if 'type' in property_value:
                     prop['type'] = property_value['type']
                     if prop['type'] == 'array':
                         prop['collectionFormat'] = 'multi'
                         prop['items'] = property_value['items']
                         if '$ref' in property_value['items']:
                             ref = property_value['items']['$ref'].replace(
                                 ref_path, '')
                             type_ref = type_dict[ref]
                             prop['items'] = type_ref
                             if 'description' in prop['items']:
                                 del prop['items']['description']
                     if 'description' in property_value:
                         prop['description'] = property_value['description']
                 elif '$ref' in property_value:
                     reference = property_value['$ref'].replace(
                         ref_path, '')
                     prop_obj = type_dict[reference]
                     if 'type' in prop_obj:
                         prop['type'] = prop_obj['type']
                         # Query parameter's type is object, Coverting it to
                         # string given type object for query is not
                         # supported by swagger 2.0.
                         if prop['type'] == "object":
                             prop['type'] = "string"
                     if 'enum' in prop_obj:
                         prop['enum'] = prop_obj['enum']
                     if 'description' in prop_obj:
                         prop['description'] = prop_obj['description']
                 if 'required' in type_ref:
                     if property_name in type_ref['required']:
                         prop['required'] = True
                     else:
                         prop['required'] = False
                 prop_array.append(prop)
         else:
             prop = {
                 'in': 'query',
                 'name': query_param_info.name,
                 'description': type_ref['description'],
                 'type': type_ref['type']
             }
             if 'enum' in type_ref:
                 prop['enum'] = type_ref['enum']
             if 'required' not in parameter_obj:
                 prop['required'] = True
             else:
                 prop['required'] = parameter_obj['required']
             prop_array.append(prop)
     else:
         parameter_obj['in'] = 'query'
         parameter_obj['name'] = query_param_info.name
         parameter_obj['description'] = query_param_info.documentation
         if 'required' not in parameter_obj:
             parameter_obj['required'] = True
         prop_array.append(parameter_obj)
     return prop_array