def remove_com_vmware_from_dict(self, swagger_obj, depth=0, keys_list=[], add_camel_case=False): """ The method 1. removes 'com.vmware.' from model names 2. replaces $ with _ from the model names This is done on both definitions and path 'definitions' : where models are defined and may be referenced. 'path' : where models are referenced. :param swagger_obj: should be path of definitions dictionary :param depth: depth of the dictionary. Defaults to 0 :param keys_list: List of updated model names :return: """ if isinstance(swagger_obj, dict): if '$ref' in swagger_obj and 'required' in swagger_obj: del swagger_obj['required'] for key, item in swagger_obj.items(): if isinstance(item, str): if key in ('$ref', 'summary', 'description'): item = item.replace('com.vmware.', '').replace('ComVmware', '') if key == '$ref': item = item.replace('$', '_') if add_camel_case: item = utils.get_str_camel_case(item, "_") swagger_obj[key] = item elif isinstance(item, list): for itm in item: self.remove_com_vmware_from_dict( itm, depth + 1, keys_list, add_camel_case) elif isinstance(item, dict): if depth == 0 and isinstance(key, str) and ( key.startswith('com.vmware.') or key.startswith('ComVmware') or '$' in key): keys_list.append(key) self.remove_com_vmware_from_dict( item, depth + 1, keys_list, add_camel_case) elif isinstance(swagger_obj, list): for itm in swagger_obj: self.remove_com_vmware_from_dict(itm, depth + 1, add_camel_case) if depth == 0 and len(keys_list) > 0: while keys_list: old_key = keys_list.pop() new_key = old_key.replace('com.vmware.', '').replace('ComVmware', '') new_key = new_key.replace('$', '_') if add_camel_case: new_key = utils.get_str_camel_case(new_key, "_") try: swagger_obj[new_key] = swagger_obj.pop(old_key) except KeyError: print( 'Could not find the Swagger Element : {}'.format(old_key))
def check_type( self, resource_type, type_name, type_dict, structure_svc, enum_svc, ref_path): camel_cased_type_name = utils.get_str_camel_case(type_name, *utils.CAMELCASE_SEPARATOR_LIST) if camel_cased_type_name in type_dict or utils.is_type_builtin(type_name): return if resource_type == 'com.vmware.vapi.structure': structure_info = self.get_structure_info(type_name, structure_svc) if structure_info is not None: # Mark it as visited to handle recursive definitions. (Type A # referring to Type A in one of the fields). type_dict[camel_cased_type_name] = {} self.process_structure_info( camel_cased_type_name, structure_info, type_dict, structure_svc, enum_svc, ref_path) else: enum_info = self.get_enum_info(type_name, enum_svc) if enum_info is not None: # Mark it as visited to handle recursive definitions. (Type A # referring to Type A in one of the fields). type_dict[camel_cased_type_name] = {} self.process_enum_info( camel_cased_type_name, enum_info, type_dict)
def visit_user_defined( self, user_defined_type, newprop, type_dict, structure_svc, enum_svc, ref_path): if user_defined_type.resource_id is None: return camel_cased_ref = utils.get_str_camel_case(user_defined_type.resource_id, *utils.CAMELCASE_SEPARATOR_LIST) if 'type' in newprop and newprop['type'] == 'array': item_obj = {'$ref': ref_path + camel_cased_ref} newprop['items'] = item_obj # if not array, fill in type or ref else: newprop['$ref'] = ref_path + camel_cased_ref self.check_type( user_defined_type.resource_type, user_defined_type.resource_id, type_dict, structure_svc, enum_svc, ref_path)
def visit_generic(self, generic_instantiation, new_prop, type_dict, structure_svc, enum_svc, ref_path): if generic_instantiation.generic_type == 'OPTIONAL': new_prop['required'] = False self.visit_type_category(generic_instantiation.element_type, new_prop, type_dict, structure_svc, enum_svc, ref_path) elif generic_instantiation.generic_type == 'LIST': new_prop['type'] = 'array' self.visit_type_category(generic_instantiation.element_type, new_prop, type_dict, structure_svc, enum_svc, ref_path) elif generic_instantiation.generic_type == 'SET': new_prop['type'] = 'array' new_prop['uniqueItems'] = True self.visit_type_category(generic_instantiation.element_type, new_prop, type_dict, structure_svc, enum_svc, ref_path) elif generic_instantiation.generic_type == 'MAP': # Have static key/value pair object maping for /rest paths # while use additionalProperties for /api paths new_type = {'type': 'object', 'additionalProperties': {}} if generic_instantiation.map_value_type.category == 'USER_DEFINED': new_type['additionalProperties'] = { '$ref': ref_path + utils.get_str_camel_case( generic_instantiation.map_value_type.user_defined_type. resource_id, *utils.CAMELCASE_SEPARATOR_LIST) } res_type = generic_instantiation.map_value_type.user_defined_type.resource_type res_id = generic_instantiation.map_value_type.user_defined_type.resource_id self.check_type(res_type, res_id, type_dict, structure_svc, enum_svc, ref_path) elif generic_instantiation.map_value_type.category == 'BUILTIN': new_type['additionalProperties'] = { 'type': utils.metamodel_to_swagger_type_converter( generic_instantiation.map_value_type.builtin_type)[0] } elif generic_instantiation.map_value_type.category == 'GENERIC': temp_new_type = {} self.visit_generic( generic_instantiation.map_value_type.generic_instantiation, temp_new_type, type_dict, structure_svc, enum_svc, ref_path) new_type['additionalProperties'] = temp_new_type new_prop.update(new_type) if 'additionalProperties' in new_type: if not new_type['additionalProperties'].get('required', True): del new_type['additionalProperties']['required'] if '$ref' in new_prop: del new_prop['$ref']
def test_get_str_camel_case(self): string = "vapi.std_localizable_message" expected = "VapiStdLocalizableMessage" self.assertEqual( expected, utils.get_str_camel_case(string, *utils.CAMELCASE_SEPARATOR_LIST)) string = 'com.vmware.package.mock-1' expected = "ComVmwarePackageMock-1" self.assertEqual( expected, utils.get_str_camel_case(string, *utils.CAMELCASE_SEPARATOR_LIST)) string = "ComVmwarePackageMock1" expected = "ComVmwarePackageMock1" self.assertEqual( expected, utils.get_str_camel_case(string, *utils.CAMELCASE_SEPARATOR_LIST))
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
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