Search in sources :

Example 1 with AsyncApiParser

use of org.wso2.carbon.apimgt.impl.definitions.AsyncApiParser in project carbon-apimgt by wso2.

the class AsyncApiParserTest method testGetAsyncAPIDefinitionForStoreFail.

@Test
public void testGetAsyncAPIDefinitionForStoreFail() throws Exception {
    Map<String, String> hostsWithSchemes = new HashMap<>();
    hostsWithSchemes.put("ws", "ws://localhost:9099");
    hostsWithSchemes.put("wss", "wss://localhost:8099");
    APIIdentifier identifier = new APIIdentifier("admin", "HelloServer2", "1.0");
    API api = new API(identifier);
    AsyncApiParser asyncApiParser = new AsyncApiParser();
    String asyncAPIDefinition = IOUtils.toString(getClass().getClassLoader().getResourceAsStream("definitions" + File.separator + "asyncAPI" + File.separator + "incorrectWebSocket.yml"), "UTF-8");
    api.setAsyncApiDefinition(asyncAPIDefinition);
    try {
        asyncApiParser.getAsyncApiDefinitionForStore(api, asyncAPIDefinition, hostsWithSchemes);
    } catch (RuntimeException e) {
        Assert.assertNotNull(e);
    }
}
Also used : HashMap(java.util.HashMap) APIIdentifier(org.wso2.carbon.apimgt.api.model.APIIdentifier) API(org.wso2.carbon.apimgt.api.model.API) Test(org.junit.Test)

Example 2 with AsyncApiParser

use of org.wso2.carbon.apimgt.impl.definitions.AsyncApiParser in project carbon-apimgt by wso2.

the class AsyncApiParserTest method testGenerateAsyncAPIDefinition.

@Test
public void testGenerateAsyncAPIDefinition() throws Exception {
    APIIdentifier identifier = new APIIdentifier("admin", "HelloServer", "1.0");
    API api = new API(identifier);
    api.setType("WS");
    api.setContext("/hello/1.0");
    api.setTransports("ws,wss");
    api.setEndpointConfig("{'endpoint_type':'http','sandbox_endpoints':{'url':'wss://echo.websocket.org:443'}," + "'production_endpoints':{'url':'wss://echo.websocket.org:443'}}");
    AsyncApiParser asyncApiParser = new AsyncApiParser();
    String asyncAPIDefinition = asyncApiParser.generateAsyncAPIDefinition(api);
    Assert.assertNotNull(asyncAPIDefinition);
}
Also used : APIIdentifier(org.wso2.carbon.apimgt.api.model.APIIdentifier) API(org.wso2.carbon.apimgt.api.model.API) Test(org.junit.Test)

Example 3 with AsyncApiParser

use of org.wso2.carbon.apimgt.impl.definitions.AsyncApiParser in project carbon-apimgt by wso2.

the class AsyncApiParserTest method testGenerateAsyncAPIDefinitionFail.

@Test
public void testGenerateAsyncAPIDefinitionFail() throws Exception {
    APIIdentifier identifier = new APIIdentifier("admin", "HelloServer", "1.0");
    API api = new API(identifier);
    AsyncApiParser asyncApiParser = new AsyncApiParser();
    try {
        asyncApiParser.generateAsyncAPIDefinition(api);
    } catch (JSONException e) {
        Assert.assertNotNull(e);
    }
}
Also used : JSONException(org.json.JSONException) APIIdentifier(org.wso2.carbon.apimgt.api.model.APIIdentifier) API(org.wso2.carbon.apimgt.api.model.API) Test(org.junit.Test)

Example 4 with AsyncApiParser

use of org.wso2.carbon.apimgt.impl.definitions.AsyncApiParser in project carbon-apimgt by wso2.

the class PublisherCommonUtils method updateApi.

/**
 * Update an API.
 *
 * @param originalAPI    Existing API
 * @param apiDtoToUpdate New API DTO to update
 * @param apiProvider    API Provider
 * @param tokenScopes    Scopes of the token
 * @throws ParseException         If an error occurs while parsing the endpoint configuration
 * @throws CryptoException        If an error occurs while encrypting the secret key of API
 * @throws APIManagementException If an error occurs while updating the API
 * @throws FaultGatewaysException If an error occurs while updating manage of an existing API
 */
public static API updateApi(API originalAPI, APIDTO apiDtoToUpdate, APIProvider apiProvider, String[] tokenScopes) throws ParseException, CryptoException, APIManagementException, FaultGatewaysException {
    APIIdentifier apiIdentifier = originalAPI.getId();
    // Validate if the USER_REST_API_SCOPES is not set in WebAppAuthenticator when scopes are validated
    if (tokenScopes == null) {
        throw new APIManagementException("Error occurred while updating the  API " + originalAPI.getUUID() + " as the token information hasn't been correctly set internally", ExceptionCodes.TOKEN_SCOPES_NOT_SET);
    }
    boolean isGraphql = originalAPI.getType() != null && APIConstants.APITransportType.GRAPHQL.toString().equals(originalAPI.getType());
    boolean isAsyncAPI = originalAPI.getType() != null && (APIConstants.APITransportType.WS.toString().equals(originalAPI.getType()) || APIConstants.APITransportType.WEBSUB.toString().equals(originalAPI.getType()) || APIConstants.APITransportType.SSE.toString().equals(originalAPI.getType()) || APIConstants.APITransportType.ASYNC.toString().equals(originalAPI.getType()));
    Scope[] apiDtoClassAnnotatedScopes = APIDTO.class.getAnnotationsByType(Scope.class);
    boolean hasClassLevelScope = checkClassScopeAnnotation(apiDtoClassAnnotatedScopes, tokenScopes);
    JSONParser parser = new JSONParser();
    String oldEndpointConfigString = originalAPI.getEndpointConfig();
    JSONObject oldEndpointConfig = null;
    if (StringUtils.isNotBlank(oldEndpointConfigString)) {
        oldEndpointConfig = (JSONObject) parser.parse(oldEndpointConfigString);
    }
    String oldProductionApiSecret = null;
    String oldSandboxApiSecret = null;
    if (oldEndpointConfig != null) {
        if ((oldEndpointConfig.containsKey(APIConstants.ENDPOINT_SECURITY))) {
            JSONObject oldEndpointSecurity = (JSONObject) oldEndpointConfig.get(APIConstants.ENDPOINT_SECURITY);
            if (oldEndpointSecurity.containsKey(APIConstants.OAuthConstants.ENDPOINT_SECURITY_PRODUCTION)) {
                JSONObject oldEndpointSecurityProduction = (JSONObject) oldEndpointSecurity.get(APIConstants.OAuthConstants.ENDPOINT_SECURITY_PRODUCTION);
                if (oldEndpointSecurityProduction.get(APIConstants.OAuthConstants.OAUTH_CLIENT_ID) != null && oldEndpointSecurityProduction.get(APIConstants.OAuthConstants.OAUTH_CLIENT_SECRET) != null) {
                    oldProductionApiSecret = oldEndpointSecurityProduction.get(APIConstants.OAuthConstants.OAUTH_CLIENT_SECRET).toString();
                }
            }
            if (oldEndpointSecurity.containsKey(APIConstants.OAuthConstants.ENDPOINT_SECURITY_SANDBOX)) {
                JSONObject oldEndpointSecuritySandbox = (JSONObject) oldEndpointSecurity.get(APIConstants.OAuthConstants.ENDPOINT_SECURITY_SANDBOX);
                if (oldEndpointSecuritySandbox.get(APIConstants.OAuthConstants.OAUTH_CLIENT_ID) != null && oldEndpointSecuritySandbox.get(APIConstants.OAuthConstants.OAUTH_CLIENT_SECRET) != null) {
                    oldSandboxApiSecret = oldEndpointSecuritySandbox.get(APIConstants.OAuthConstants.OAUTH_CLIENT_SECRET).toString();
                }
            }
        }
    }
    Map endpointConfig = (Map) apiDtoToUpdate.getEndpointConfig();
    CryptoUtil cryptoUtil = CryptoUtil.getDefaultCryptoUtil();
    // OAuth 2.0 backend protection: API Key and API Secret encryption
    encryptEndpointSecurityOAuthCredentials(endpointConfig, cryptoUtil, oldProductionApiSecret, oldSandboxApiSecret, apiDtoToUpdate);
    // AWS Lambda: secret key encryption while updating the API
    if (apiDtoToUpdate.getEndpointConfig() != null) {
        if (endpointConfig.containsKey(APIConstants.AMZN_SECRET_KEY)) {
            String secretKey = (String) endpointConfig.get(APIConstants.AMZN_SECRET_KEY);
            if (!StringUtils.isEmpty(secretKey)) {
                if (!APIConstants.AWS_SECRET_KEY.equals(secretKey)) {
                    String encryptedSecretKey = cryptoUtil.encryptAndBase64Encode(secretKey.getBytes());
                    endpointConfig.put(APIConstants.AMZN_SECRET_KEY, encryptedSecretKey);
                    apiDtoToUpdate.setEndpointConfig(endpointConfig);
                } else {
                    JSONParser jsonParser = new JSONParser();
                    JSONObject originalEndpointConfig = (JSONObject) jsonParser.parse(originalAPI.getEndpointConfig());
                    String encryptedSecretKey = (String) originalEndpointConfig.get(APIConstants.AMZN_SECRET_KEY);
                    endpointConfig.put(APIConstants.AMZN_SECRET_KEY, encryptedSecretKey);
                    apiDtoToUpdate.setEndpointConfig(endpointConfig);
                }
            }
        }
    }
    if (!hasClassLevelScope) {
        // Validate per-field scopes
        apiDtoToUpdate = getFieldOverriddenAPIDTO(apiDtoToUpdate, originalAPI, tokenScopes);
    }
    // API Name change not allowed if OnPrem
    if (APIUtil.isOnPremResolver()) {
        apiDtoToUpdate.setName(apiIdentifier.getApiName());
    }
    apiDtoToUpdate.setVersion(apiIdentifier.getVersion());
    apiDtoToUpdate.setProvider(apiIdentifier.getProviderName());
    apiDtoToUpdate.setContext(originalAPI.getContextTemplate());
    apiDtoToUpdate.setLifeCycleStatus(originalAPI.getStatus());
    apiDtoToUpdate.setType(APIDTO.TypeEnum.fromValue(originalAPI.getType()));
    List<APIResource> removedProductResources = getRemovedProductResources(apiDtoToUpdate, originalAPI);
    if (!removedProductResources.isEmpty()) {
        throw new APIManagementException("Cannot remove following resource paths " + removedProductResources.toString() + " because they are used by one or more API Products", ExceptionCodes.from(ExceptionCodes.API_PRODUCT_USED_RESOURCES, originalAPI.getId().getApiName(), originalAPI.getId().getVersion()));
    }
    // Validate API Security
    List<String> apiSecurity = apiDtoToUpdate.getSecurityScheme();
    // validation for tiers
    List<String> tiersFromDTO = apiDtoToUpdate.getPolicies();
    String originalStatus = originalAPI.getStatus();
    if (apiSecurity.contains(APIConstants.DEFAULT_API_SECURITY_OAUTH2) || apiSecurity.contains(APIConstants.API_SECURITY_API_KEY)) {
        if ((tiersFromDTO == null || tiersFromDTO.isEmpty() && !(APIConstants.CREATED.equals(originalStatus) || APIConstants.PROTOTYPED.equals(originalStatus))) && !apiDtoToUpdate.getAdvertiseInfo().isAdvertised()) {
            throw new APIManagementException("A tier should be defined if the API is not in CREATED or PROTOTYPED state", ExceptionCodes.TIER_CANNOT_BE_NULL);
        }
    }
    if (tiersFromDTO != null && !tiersFromDTO.isEmpty()) {
        // check whether the added API's tiers are all valid
        Set<Tier> definedTiers = apiProvider.getTiers();
        List<String> invalidTiers = getInvalidTierNames(definedTiers, tiersFromDTO);
        if (invalidTiers.size() > 0) {
            throw new APIManagementException("Specified tier(s) " + Arrays.toString(invalidTiers.toArray()) + " are invalid", ExceptionCodes.TIER_NAME_INVALID);
        }
    }
    if (apiDtoToUpdate.getAccessControlRoles() != null) {
        String errorMessage = validateUserRoles(apiDtoToUpdate.getAccessControlRoles());
        if (!errorMessage.isEmpty()) {
            throw new APIManagementException(errorMessage, ExceptionCodes.INVALID_USER_ROLES);
        }
    }
    if (apiDtoToUpdate.getVisibleRoles() != null) {
        String errorMessage = validateRoles(apiDtoToUpdate.getVisibleRoles());
        if (!errorMessage.isEmpty()) {
            throw new APIManagementException(errorMessage, ExceptionCodes.INVALID_USER_ROLES);
        }
    }
    if (apiDtoToUpdate.getAdditionalProperties() != null) {
        String errorMessage = validateAdditionalProperties(apiDtoToUpdate.getAdditionalProperties());
        if (!errorMessage.isEmpty()) {
            throw new APIManagementException(errorMessage, ExceptionCodes.from(ExceptionCodes.INVALID_ADDITIONAL_PROPERTIES, apiDtoToUpdate.getName(), apiDtoToUpdate.getVersion()));
        }
    }
    // Validate if resources are empty
    if (apiDtoToUpdate.getOperations() == null || apiDtoToUpdate.getOperations().isEmpty()) {
        throw new APIManagementException(ExceptionCodes.NO_RESOURCES_FOUND);
    }
    API apiToUpdate = APIMappingUtil.fromDTOtoAPI(apiDtoToUpdate, apiIdentifier.getProviderName());
    if (APIConstants.PUBLIC_STORE_VISIBILITY.equals(apiToUpdate.getVisibility())) {
        apiToUpdate.setVisibleRoles(StringUtils.EMPTY);
    }
    apiToUpdate.setUUID(originalAPI.getUUID());
    apiToUpdate.setOrganization(originalAPI.getOrganization());
    validateScopes(apiToUpdate);
    apiToUpdate.setThumbnailUrl(originalAPI.getThumbnailUrl());
    if (apiDtoToUpdate.getKeyManagers() instanceof List) {
        apiToUpdate.setKeyManagers((List<String>) apiDtoToUpdate.getKeyManagers());
    } else {
        apiToUpdate.setKeyManagers(Collections.singletonList(APIConstants.KeyManager.API_LEVEL_ALL_KEY_MANAGERS));
    }
    if (!isAsyncAPI) {
        String oldDefinition = apiProvider.getOpenAPIDefinition(apiToUpdate.getUuid(), originalAPI.getOrganization());
        APIDefinition apiDefinition = OASParserUtil.getOASParser(oldDefinition);
        SwaggerData swaggerData = new SwaggerData(apiToUpdate);
        String newDefinition = apiDefinition.generateAPIDefinition(swaggerData, oldDefinition);
        apiProvider.saveSwaggerDefinition(apiToUpdate, newDefinition, originalAPI.getOrganization());
        if (!isGraphql) {
            Set<URITemplate> uriTemplates = apiDefinition.getURITemplates(newDefinition);
            // set operation policies from the original API Payload
            Set<URITemplate> uriTemplatesFromPayload = apiToUpdate.getUriTemplates();
            Map<String, List<OperationPolicy>> operationPoliciesPerURITemplate = new HashMap<>();
            for (URITemplate uriTemplate : uriTemplatesFromPayload) {
                if (!uriTemplate.getOperationPolicies().isEmpty()) {
                    String key = uriTemplate.getHTTPVerb() + ":" + uriTemplate.getUriTemplate();
                    operationPoliciesPerURITemplate.put(key, uriTemplate.getOperationPolicies());
                }
            }
            for (URITemplate uriTemplate : uriTemplates) {
                String key = uriTemplate.getHTTPVerb() + ":" + uriTemplate.getUriTemplate();
                if (operationPoliciesPerURITemplate.containsKey(key)) {
                    uriTemplate.setOperationPolicies(operationPoliciesPerURITemplate.get(key));
                }
            }
            apiToUpdate.setUriTemplates(uriTemplates);
        }
    } else {
        String oldDefinition = apiProvider.getAsyncAPIDefinition(apiToUpdate.getUuid(), originalAPI.getOrganization());
        AsyncApiParser asyncApiParser = new AsyncApiParser();
        String updateAsyncAPIDefinition = asyncApiParser.updateAsyncAPIDefinition(oldDefinition, apiToUpdate);
        apiProvider.saveAsyncApiDefinition(originalAPI, updateAsyncAPIDefinition);
    }
    apiToUpdate.setWsdlUrl(apiDtoToUpdate.getWsdlUrl());
    // validate API categories
    List<APICategory> apiCategories = apiToUpdate.getApiCategories();
    List<APICategory> apiCategoriesList = new ArrayList<>();
    for (APICategory category : apiCategories) {
        category.setOrganization(originalAPI.getOrganization());
        apiCategoriesList.add(category);
    }
    apiToUpdate.setApiCategories(apiCategoriesList);
    if (apiCategoriesList.size() > 0) {
        if (!APIUtil.validateAPICategories(apiCategoriesList, originalAPI.getOrganization())) {
            throw new APIManagementException("Invalid API Category name(s) defined", ExceptionCodes.from(ExceptionCodes.API_CATEGORY_INVALID));
        }
    }
    apiToUpdate.setOrganization(originalAPI.getOrganization());
    apiProvider.updateAPI(apiToUpdate, originalAPI);
    return apiProvider.getAPIbyUUID(originalAPI.getUuid(), originalAPI.getOrganization());
// TODO use returend api
}
Also used : HashMap(java.util.HashMap) LinkedHashMap(java.util.LinkedHashMap) SwaggerData(org.wso2.carbon.apimgt.api.model.SwaggerData) ArrayList(java.util.ArrayList) CryptoUtil(org.wso2.carbon.core.util.CryptoUtil) APIManagementException(org.wso2.carbon.apimgt.api.APIManagementException) APIIdentifier(org.wso2.carbon.apimgt.api.model.APIIdentifier) List(java.util.List) ArrayList(java.util.ArrayList) Tier(org.wso2.carbon.apimgt.api.model.Tier) APIResource(org.wso2.carbon.apimgt.api.doc.model.APIResource) URITemplate(org.wso2.carbon.apimgt.api.model.URITemplate) AsyncApiParser(org.wso2.carbon.apimgt.impl.definitions.AsyncApiParser) Scope(org.wso2.carbon.apimgt.rest.api.common.annotations.Scope) JSONObject(org.json.simple.JSONObject) APIDefinition(org.wso2.carbon.apimgt.api.APIDefinition) JSONParser(org.json.simple.parser.JSONParser) API(org.wso2.carbon.apimgt.api.model.API) Map(java.util.Map) HashMap(java.util.HashMap) LinkedHashMap(java.util.LinkedHashMap) APICategory(org.wso2.carbon.apimgt.api.model.APICategory)

Example 5 with AsyncApiParser

use of org.wso2.carbon.apimgt.impl.definitions.AsyncApiParser in project carbon-apimgt by wso2.

the class ApisApiServiceImpl method importAsyncAPISpecification.

private APIDTO importAsyncAPISpecification(InputStream definition, String definitionUrl, APIDTO apiDTOFromProperties, Attachment fileDetail, ServiceEntry service, String organization) {
    // validate and retrieve the AsyncAPI specification
    Map validationResponseMap = null;
    boolean isServiceAPI = false;
    try {
        if (service != null) {
            isServiceAPI = true;
        }
        validationResponseMap = validateAsyncAPISpecification(definitionUrl, definition, fileDetail, true, isServiceAPI);
    } catch (APIManagementException e) {
        RestApiUtil.handleInternalServerError("Error occurred while validating API Definition", e, log);
    }
    AsyncAPISpecificationValidationResponseDTO validationResponseDTO = (AsyncAPISpecificationValidationResponseDTO) validationResponseMap.get(RestApiConstants.RETURN_DTO);
    APIDefinitionValidationResponse validationResponse = (APIDefinitionValidationResponse) validationResponseMap.get(RestApiConstants.RETURN_MODEL);
    if (!validationResponseDTO.isIsValid()) {
        ErrorDTO errorDTO = APIMappingUtil.getErrorDTOFromErrorListItems(validationResponseDTO.getErrors());
        throw RestApiUtil.buildBadRequestException(errorDTO);
    }
    // Import the API and Definition
    try {
        APIProvider apiProvider = RestApiCommonUtil.getLoggedInUserProvider();
        String definitionToAdd = validationResponse.getJsonContent();
        String protocol = validationResponse.getProtocol();
        if (isServiceAPI) {
            apiDTOFromProperties.setType(PublisherCommonUtils.getAPIType(service.getDefinitionType(), protocol));
        }
        if (!APIConstants.WSO2_GATEWAY_ENVIRONMENT.equals(apiDTOFromProperties.getGatewayVendor())) {
            apiDTOFromProperties.getPolicies().add(APIConstants.DEFAULT_SUB_POLICY_ASYNC_UNLIMITED);
            apiDTOFromProperties.setAsyncTransportProtocols(AsyncApiParser.getTransportProtocolsForAsyncAPI(definitionToAdd));
        }
        API apiToAdd = PublisherCommonUtils.prepareToCreateAPIByDTO(apiDTOFromProperties, apiProvider, RestApiCommonUtil.getLoggedInUsername(), organization);
        if (isServiceAPI) {
            apiToAdd.setServiceInfo("key", service.getKey());
            apiToAdd.setServiceInfo("md5", service.getMd5());
            if (!APIConstants.API_TYPE_WEBSUB.equals(protocol.toUpperCase())) {
                apiToAdd.setEndpointConfig(PublisherCommonUtils.constructEndpointConfigForService(service.getServiceUrl(), protocol));
            }
        }
        apiToAdd.setAsyncApiDefinition(definitionToAdd);
        // load topics from AsyncAPI
        apiToAdd.setUriTemplates(new AsyncApiParser().getURITemplates(definitionToAdd, APIConstants.API_TYPE_WS.equals(apiToAdd.getType()) || !APIConstants.WSO2_GATEWAY_ENVIRONMENT.equals(apiToAdd.getGatewayVendor())));
        apiToAdd.setOrganization(organization);
        apiToAdd.setAsyncApiDefinition(definitionToAdd);
        apiProvider.addAPI(apiToAdd);
        return APIMappingUtil.fromAPItoDTO(apiProvider.getAPIbyUUID(apiToAdd.getUuid(), organization));
    } catch (APIManagementException e) {
        String errorMessage = "Error while adding new API : " + apiDTOFromProperties.getProvider() + "-" + apiDTOFromProperties.getName() + "-" + apiDTOFromProperties.getVersion() + " - " + e.getMessage();
        RestApiUtil.handleInternalServerError(errorMessage, e, log);
    }
    return null;
}
Also used : APIManagementException(org.wso2.carbon.apimgt.api.APIManagementException) AsyncAPISpecificationValidationResponseDTO(org.wso2.carbon.apimgt.rest.api.publisher.v1.dto.AsyncAPISpecificationValidationResponseDTO) ErrorDTO(org.wso2.carbon.apimgt.rest.api.common.dto.ErrorDTO) API(org.wso2.carbon.apimgt.api.model.API) ImportExportAPI(org.wso2.carbon.apimgt.impl.importexport.ImportExportAPI) SubscribedAPI(org.wso2.carbon.apimgt.api.model.SubscribedAPI) AsyncApiParser(org.wso2.carbon.apimgt.impl.definitions.AsyncApiParser) Map(java.util.Map) LinkedHashMap(java.util.LinkedHashMap) HashMap(java.util.HashMap) APIProvider(org.wso2.carbon.apimgt.api.APIProvider) APIDefinitionValidationResponse(org.wso2.carbon.apimgt.api.APIDefinitionValidationResponse)

Aggregations

API (org.wso2.carbon.apimgt.api.model.API)8 HashMap (java.util.HashMap)5 APIIdentifier (org.wso2.carbon.apimgt.api.model.APIIdentifier)5 Test (org.junit.Test)4 APIManagementException (org.wso2.carbon.apimgt.api.APIManagementException)4 AsyncApiParser (org.wso2.carbon.apimgt.impl.definitions.AsyncApiParser)4 LinkedHashMap (java.util.LinkedHashMap)3 Map (java.util.Map)3 APIProvider (org.wso2.carbon.apimgt.api.APIProvider)3 ArrayList (java.util.ArrayList)2 APIDefinition (org.wso2.carbon.apimgt.api.APIDefinition)2 APICategory (org.wso2.carbon.apimgt.api.model.APICategory)2 SwaggerData (org.wso2.carbon.apimgt.api.model.SwaggerData)2 URITemplate (org.wso2.carbon.apimgt.api.model.URITemplate)2 CryptoUtil (org.wso2.carbon.core.util.CryptoUtil)2 List (java.util.List)1 JSONException (org.json.JSONException)1 JSONObject (org.json.simple.JSONObject)1 JSONParser (org.json.simple.parser.JSONParser)1 APIDefinitionValidationResponse (org.wso2.carbon.apimgt.api.APIDefinitionValidationResponse)1