diff --git a/modules/integration/tests-common/clients/publisher/api/openapi.yaml b/modules/integration/tests-common/clients/publisher/api/openapi.yaml index b4ce30723f..9ca4fd290c 100644 --- a/modules/integration/tests-common/clients/publisher/api/openapi.yaml +++ b/modules/integration/tests-common/clients/publisher/api/openapi.yaml @@ -10187,7 +10187,10 @@ paths: style: simple responses: "200": - content: {} + content: + application/json: + schema: + type: string description: | OK. Requested swagger document of the API is returned diff --git a/modules/integration/tests-common/clients/publisher/docs/ApiProductsApi.md b/modules/integration/tests-common/clients/publisher/docs/ApiProductsApi.md index 5ad8c3153c..869926f3c5 100644 --- a/modules/integration/tests-common/clients/publisher/docs/ApiProductsApi.md +++ b/modules/integration/tests-common/clients/publisher/docs/ApiProductsApi.md @@ -231,7 +231,7 @@ Name | Type | Description | Notes # **getAPIProductSwagger** -> getAPIProductSwagger(apiProductId, accept, ifNoneMatch) +> String getAPIProductSwagger(apiProductId, accept, ifNoneMatch) Get Swagger Definition @@ -261,7 +261,8 @@ public class Example { String accept = "\"application/json\""; // String | Media types acceptable for the response. Default is application/json. String ifNoneMatch = "ifNoneMatch_example"; // String | Validator for conditional requests; based on the ETag of the formerly retrieved variant of the resource. try { - apiInstance.getAPIProductSwagger(apiProductId, accept, ifNoneMatch); + String result = apiInstance.getAPIProductSwagger(apiProductId, accept, ifNoneMatch); + System.out.println(result); } catch (ApiException e) { System.err.println("Exception when calling ApiProductsApi#getAPIProductSwagger"); System.err.println("Status code: " + e.getCode()); @@ -283,7 +284,7 @@ Name | Type | Description | Notes ### Return type -null (empty response body) +**String** ### Authorization diff --git a/modules/integration/tests-common/clients/publisher/src/gen/java/org/wso2/am/integration/clients/publisher/api/v1/ApiProductsApi.java b/modules/integration/tests-common/clients/publisher/src/gen/java/org/wso2/am/integration/clients/publisher/api/v1/ApiProductsApi.java index 58c6592172..ebf588dbb9 100644 --- a/modules/integration/tests-common/clients/publisher/src/gen/java/org/wso2/am/integration/clients/publisher/api/v1/ApiProductsApi.java +++ b/modules/integration/tests-common/clients/publisher/src/gen/java/org/wso2/am/integration/clients/publisher/api/v1/ApiProductsApi.java @@ -518,6 +518,7 @@ private okhttp3.Call getAPIProductSwaggerValidateBeforeCall(String apiProductId, * @param apiProductId **API Product ID** consisting of the **UUID** of the API Product. Using the **UUID** in the API call is recommended. (required) * @param accept Media types acceptable for the response. Default is application/json. (optional, default to "application/json") * @param ifNoneMatch Validator for conditional requests; based on the ETag of the formerly retrieved variant of the resource. (optional) + * @return String * @throws ApiException If fail to call the API, e.g. server error or cannot deserialize the response body * @http.response.details @@ -528,8 +529,9 @@ private okhttp3.Call getAPIProductSwaggerValidateBeforeCall(String apiProductId,
406 Not Acceptable. The requested media type is not supported. -
*/ - public void getAPIProductSwagger(String apiProductId, String accept, String ifNoneMatch) throws ApiException { - getAPIProductSwaggerWithHttpInfo(apiProductId, accept, ifNoneMatch); + public String getAPIProductSwagger(String apiProductId, String accept, String ifNoneMatch) throws ApiException { + ApiResponse localVarResp = getAPIProductSwaggerWithHttpInfo(apiProductId, accept, ifNoneMatch); + return localVarResp.getData(); } /** @@ -538,7 +540,7 @@ public void getAPIProductSwagger(String apiProductId, String accept, String ifNo * @param apiProductId **API Product ID** consisting of the **UUID** of the API Product. Using the **UUID** in the API call is recommended. (required) * @param accept Media types acceptable for the response. Default is application/json. (optional, default to "application/json") * @param ifNoneMatch Validator for conditional requests; based on the ETag of the formerly retrieved variant of the resource. (optional) - * @return ApiResponse<Void> + * @return ApiResponse<String> * @throws ApiException If fail to call the API, e.g. server error or cannot deserialize the response body * @http.response.details @@ -549,9 +551,10 @@ public void getAPIProductSwagger(String apiProductId, String accept, String ifNo
406 Not Acceptable. The requested media type is not supported. -
*/ - public ApiResponse getAPIProductSwaggerWithHttpInfo(String apiProductId, String accept, String ifNoneMatch) throws ApiException { + public ApiResponse getAPIProductSwaggerWithHttpInfo(String apiProductId, String accept, String ifNoneMatch) throws ApiException { okhttp3.Call localVarCall = getAPIProductSwaggerValidateBeforeCall(apiProductId, accept, ifNoneMatch, null); - return localVarApiClient.execute(localVarCall); + Type localVarReturnType = new TypeToken(){}.getType(); + return localVarApiClient.execute(localVarCall, localVarReturnType); } /** @@ -572,10 +575,11 @@ public ApiResponse getAPIProductSwaggerWithHttpInfo(String apiProductId, S 406 Not Acceptable. The requested media type is not supported. - */ - public okhttp3.Call getAPIProductSwaggerAsync(String apiProductId, String accept, String ifNoneMatch, final ApiCallback _callback) throws ApiException { + public okhttp3.Call getAPIProductSwaggerAsync(String apiProductId, String accept, String ifNoneMatch, final ApiCallback _callback) throws ApiException { okhttp3.Call localVarCall = getAPIProductSwaggerValidateBeforeCall(apiProductId, accept, ifNoneMatch, _callback); - localVarApiClient.executeAsync(localVarCall, _callback); + Type localVarReturnType = new TypeToken(){}.getType(); + localVarApiClient.executeAsync(localVarCall, localVarReturnType, _callback); return localVarCall; } /** diff --git a/modules/integration/tests-common/clients/publisher/src/main/resources/publisher-api.yaml b/modules/integration/tests-common/clients/publisher/src/main/resources/publisher-api.yaml index de67456fcb..4782209fc1 100644 --- a/modules/integration/tests-common/clients/publisher/src/main/resources/publisher-api.yaml +++ b/modules/integration/tests-common/clients/publisher/src/main/resources/publisher-api.yaml @@ -5693,7 +5693,11 @@ paths: The content type of the body. schema: type: string - content: {} + content: + application/json: + schema: + type: string + example: "" 304: description: | Not Modified. diff --git a/modules/integration/tests-common/integration-test-utils/src/main/java/org/wso2/am/integration/test/impl/RestAPIPublisherImpl.java b/modules/integration/tests-common/integration-test-utils/src/main/java/org/wso2/am/integration/test/impl/RestAPIPublisherImpl.java index f1c676f2bc..94a8aaa301 100644 --- a/modules/integration/tests-common/integration-test-utils/src/main/java/org/wso2/am/integration/test/impl/RestAPIPublisherImpl.java +++ b/modules/integration/tests-common/integration-test-utils/src/main/java/org/wso2/am/integration/test/impl/RestAPIPublisherImpl.java @@ -1124,6 +1124,13 @@ public String getSwaggerByID(String apiId) throws ApiException { return response.getData(); } + public String getAPIProductSwaggerByID(String apiProductId) throws ApiException { + + ApiResponse response = apiProductsApi.getAPIProductSwaggerWithHttpInfo(apiProductId, null, null); + Assert.assertEquals(HttpStatus.SC_OK, response.getStatusCode()); + return response.getData(); + } + public String updateSwagger(String apiId, String definition) throws ApiException { ApiResponse apiResponse = apIsApi.updateAPISwaggerWithHttpInfo(apiId, null, definition, null, null); diff --git a/modules/integration/tests-integration/tests-backend/src/test/java/org/wso2/am/integration/tests/apiproduct/APIProductCreationTestCase.java b/modules/integration/tests-integration/tests-backend/src/test/java/org/wso2/am/integration/tests/apiproduct/APIProductCreationTestCase.java index bf294f02b5..7f6cb9e9cb 100644 --- a/modules/integration/tests-integration/tests-backend/src/test/java/org/wso2/am/integration/tests/apiproduct/APIProductCreationTestCase.java +++ b/modules/integration/tests-integration/tests-backend/src/test/java/org/wso2/am/integration/tests/apiproduct/APIProductCreationTestCase.java @@ -35,6 +35,7 @@ import org.wso2.am.integration.clients.publisher.api.v1.dto.APIOperationPoliciesDTO; import org.wso2.am.integration.clients.publisher.api.v1.dto.APIProductDTO; import org.wso2.am.integration.clients.publisher.api.v1.dto.LifecycleStateDTO; +import org.wso2.am.integration.clients.publisher.api.v1.dto.OpenAPIDefinitionValidationResponseDTO; import org.wso2.am.integration.clients.publisher.api.v1.dto.OperationPolicyDTO; import org.wso2.am.integration.clients.publisher.api.v1.dto.WorkflowResponseDTO; import org.wso2.am.integration.clients.publisher.api.v1.dto.APIOperationsDTO; @@ -49,10 +50,13 @@ import org.wso2.am.integration.test.utils.bean.APILifeCycleState; import org.wso2.am.integration.tests.api.lifecycle.APIManagerLifecycleBaseTest; import org.wso2.carbon.automation.engine.context.TestUserMode; +import org.wso2.carbon.automation.test.utils.common.TestConfigurationProvider; import org.wso2.carbon.automation.test.utils.http.client.HttpResponse; import org.wso2.carbon.integration.common.admin.client.UserManagementClient; +import java.io.BufferedWriter; import java.io.File; +import java.io.FileWriter; import java.io.IOException; import java.io.InputStream; import java.util.ArrayList; @@ -65,6 +69,7 @@ import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; public class APIProductCreationTestCase extends APIManagerLifecycleBaseTest { @@ -76,6 +81,7 @@ public class APIProductCreationTestCase extends APIManagerLifecycleBaseTest { private static final String SCOPE = "restricted_scope"; private ApiTestHelper apiTestHelper; private ApiProductTestHelper apiProductTestHelper; + private String resourcePath; @Factory(dataProvider = "userModeDataProvider") public APIProductCreationTestCase(TestUserMode userMode) { @@ -96,6 +102,8 @@ public static Object[][] userModeDataProvider() { public void initialize() throws Exception { super.init(userMode); + resourcePath = TestConfigurationProvider.getResourceLocation() + File.separator + "oas" + File.separator + "v3" + + File.separator + "api-product" + File.separator; userManagementClient = new UserManagementClient(keyManagerContext.getContextUrls().getBackEndUrl(), createSession(keyManagerContext)); apiTestHelper = new ApiTestHelper(restAPIPublisher, restAPIStore, getAMResourceLocation(), @@ -605,6 +613,73 @@ public void testCreateAndDeployApiProductWithMutualSSLEnabled() throws Exception Assert.assertNotNull(revisionUUID); } + @Test(groups = { "wso2.am" }, description = "API product swagger definition reference verification") + public void testAPIProductSwaggerDefinition() throws Exception { + + // Create a REST API using swagger definition + List apisToBeUsed = new ArrayList<>(); + String swaggerPath = resourcePath + "test-api-1-oas.yaml"; + File definition = new File(swaggerPath); + org.json.JSONObject endpoints = new org.json.JSONObject(); + endpoints.put("url", "https://test.com"); + + org.json.JSONObject endpointConfig = new org.json.JSONObject(); + endpointConfig.put("endpoint_type", "http"); + endpointConfig.put("production_endpoints", endpoints); + endpointConfig.put("sandbox_endpoints", endpoints); + + List tierList = new ArrayList<>(); + tierList.add(APIMIntegrationConstants.API_TIER.SILVER); + tierList.add(APIMIntegrationConstants.API_TIER.GOLD); + + org.json.JSONObject apiProperties = new org.json.JSONObject(); + apiProperties.put("name", "testAPI1"); + apiProperties.put("context", "/testapi1"); + apiProperties.put("version", "1.0.0"); + apiProperties.put("provider", user.getUserName()); + apiProperties.put("endpointConfig", endpointConfig); + apiProperties.put("policies", tierList); + + APIDTO apiOne = restAPIPublisher.importOASDefinition(definition, apiProperties.toString()); + APIDTO apiTwo = apiTestHelper.createApiTwo(getBackendEndServiceEndPointHttp("wildcard/resources")); + apisToBeUsed.add(apiOne); + apisToBeUsed.add(apiTwo); + + // Create API Product and verify in publisher + final String provider = user.getUserName(); + final String name = UUID.randomUUID().toString(); + final String context = "/" + UUID.randomUUID().toString(); + + List policies = Arrays.asList(TIER_UNLIMITED, TIER_GOLD); + + APIProductDTO apiProductDTO = apiProductTestHelper.createAPIProductInPublisher( + provider, name, context, apisToBeUsed, policies); + createAPIProductRevisionAndDeployUsingRest(apiProductDTO.getId(), restAPIPublisher); + waitForAPIDeployment(); + apiProductTestHelper.verfiyApiProductInPublisher(apiProductDTO); + apiProductDTO = publishAPIProduct(apiProductDTO.getId()); + String apiProductID = apiProductDTO.getId(); + + // Get api product definition and validate + String apiProductDefinition = restAPIPublisher.getAPIProductSwaggerByID(apiProductID); + validateDefinition(apiProductDefinition); + } + + private void validateDefinition(String oasDefinition) throws Exception { + File file = geTempFileWithContent(oasDefinition); + OpenAPIDefinitionValidationResponseDTO responseDTO = restAPIPublisher.validateOASDefinition(file); + assertTrue(responseDTO.isIsValid()); + } + + private File geTempFileWithContent(String swagger) throws Exception { + File temp = File.createTempFile("swagger", ".json"); + temp.deleteOnExit(); + BufferedWriter out = new BufferedWriter(new FileWriter(temp)); + out.write(swagger); + out.close(); + return temp; + } + @AfterClass(alwaysRun = true) public void cleanUpArtifacts() throws Exception { diff --git a/modules/integration/tests-integration/tests-backend/src/test/resources/oas/v3/api-product/test-api-1-oas.yaml b/modules/integration/tests-integration/tests-backend/src/test/resources/oas/v3/api-product/test-api-1-oas.yaml new file mode 100644 index 0000000000..0ad7037e8e --- /dev/null +++ b/modules/integration/tests-integration/tests-backend/src/test/resources/oas/v3/api-product/test-api-1-oas.yaml @@ -0,0 +1,139 @@ +openapi: 3.0.1 +info: + title: testAPI1 + version: 1.0.0 +servers: + - url: / +security: + - default: [] +paths: + "/users/{userID}/products/": + get: + parameters: + - name: userID + in: path + required: true + style: simple + explode: false + schema: + type: string + format: string + responses: + "200": + description: ok + security: + - default: [] + x-auth-type: Application & Application User + x-throttling-tier: Unlimited + x-wso2-application-security: + security-types: + - oauth2 + optional: false + "/users/{userID}/products/{productID}": + get: + parameters: + - $ref: "#/components/parameters/userIDPathParam" + responses: + "200": + description: ok + security: + - default: [] + x-auth-type: Application & Application User + x-throttling-tier: Unlimited + x-wso2-application-security: + security-types: + - oauth2 + optional: false + post: + parameters: + - $ref: "#/components/parameters/userIDPathParam" + responses: + "200": + description: ok + headers: + location: + $ref: "#/components/headers/Location" + security: + - default: [] + x-auth-type: Application & Application User + x-throttling-tier: Unlimited + x-wso2-application-security: + security-types: + - oauth2 + optional: false + parameters: + - $ref: "#/components/parameters/ProductIDPathParam" +components: + parameters: + ProductIDPathParam: + name: productID + in: path + required: true + style: simple + explode: false + schema: + type: string + format: string + userIDPathParam: + name: userID + in: path + required: true + style: simple + explode: false + schema: + type: string + format: string + headers: + Location: + description: Location of the new created resource + style: simple + explode: false + schema: + type: string + format: uri + securitySchemes: + default: + type: oauth2 + flows: + implicit: + authorizationUrl: "https://test.com" + scopes: {} +x-wso2-auth-header: Authorization +x-wso2-cors: + corsConfigurationEnabled: false + accessControlAllowOrigins: + - "*" + accessControlAllowCredentials: false + accessControlAllowHeaders: + - authorization + - Access-Control-Allow-Origin + - Content-Type + - SOAPAction + - apikey + - Internal-Key + accessControlAllowMethods: + - GET + - PUT + - POST + - DELETE + - PATCH + - OPTIONS +x-wso2-production-endpoints: + urls: + - "http://api.yourdomain.com/" + type: http +x-wso2-sandbox-endpoints: + urls: + - "http://api.yourdomain.com/" + type: http +x-wso2-basePath: /testapi1/1.0.0 +x-wso2-transports: + - http + - https +x-wso2-application-security: + security-types: + - oauth2 + optional: false +x-wso2-response-cache: + enabled: false + cacheTimeoutInSeconds: 300