diff --git a/runtime/config-deployer-service/ballerina/APIClient.bal b/runtime/config-deployer-service/ballerina/APIClient.bal index 7c919c728..be373211d 100644 --- a/runtime/config-deployer-service/ballerina/APIClient.bal +++ b/runtime/config-deployer-service/ballerina/APIClient.bal @@ -860,10 +860,7 @@ public class APIClient { model:HTTPHeader[] setHeaders = []; string[] removeHeaders = []; boolean hasRedirectPolicy = false; - model:HTTPRouteFilter headerModifierFilter = {'type: "RequestHeaderModifier"}; - if !isRequest { - headerModifierFilter.'type = "ResponseHeaderModifier"; - } + foreach APKOperationPolicy policy in operationPolicies { if policy is HeaderModifierPolicy { HeaderModifierPolicyParameters policyParameters = policy.parameters; @@ -871,23 +868,24 @@ public class APIClient { AddHeaders => { ModifierHeader[] headers = policyParameters.headers; foreach ModifierHeader header in headers { - headers.push(header); + addHeaders.push(header); } } SetHeaders => { ModifierHeader[] headers = policyParameters.headers; foreach ModifierHeader header in headers { - headers.push(header); + setHeaders.push(header); } } RemoveHeaders => { string[] headers = policyParameters.headers; foreach string header in headers { - headers.push(header); + removeHeaders.push(header); } } } } else if policy is RequestMirrorPolicy { + log:printInfo("MIRROR POLICY"); RequestMirrorPolicyParameters policyParameters = policy.parameters; string[] urls = policyParameters.urls; foreach string url in urls { @@ -933,41 +931,71 @@ public class APIClient { httpRouteFilters.push(mirrorFilter); } } else if policy is RequestRedirectPolicy { + log:printInfo("REDIRECT POLICY"); hasRedirectPolicy = true; if !isRequest { log:printError("Redirect filter cannot be appended as a response policy."); } RequestRedirectPolicyParameters policyParameters = policy.parameters; string url = policyParameters.url; - int statusCode = policyParameters.statusCode; model:HTTPRouteFilter redirectFilter = {'type: "RequestRedirect"}; int|error port = self.getPort(url); + if port is int { redirectFilter.requestRedirect = { hostname: self.getHost(url), scheme: self.getProtocol(url), - statusCode: statusCode, path: { 'type: "ReplaceFullPath", replaceFullPath: self.getPath(url) } }; + if policyParameters.statusCode is int { + int statusCode = policyParameters.statusCode; + redirectFilter.requestRedirect.statusCode = statusCode; + } } + httpRouteFilters.push(redirectFilter); } } + if isRequest { + model:HTTPHeaderFilter requestHeaderModifier = {}; + if addHeaders != [] { + requestHeaderModifier.add = addHeaders; + } + if setHeaders != [] { + requestHeaderModifier.set = setHeaders; + } + if removeHeaders != [] { + requestHeaderModifier.remove = removeHeaders; + } - if addHeaders != [] { - headerModifierFilter.requestHeaderModifier.add = addHeaders; - } - if setHeaders != [] { - headerModifierFilter.requestHeaderModifier.set = setHeaders; - } - if removeHeaders != [] { - headerModifierFilter.requestHeaderModifier.remove = removeHeaders; - } - if addHeaders.length() > 0 || setHeaders.length() > 0 || removeHeaders.length() > 0 { - httpRouteFilters.push(headerModifierFilter); + if addHeaders.length() > 0 || setHeaders.length() > 0 || removeHeaders.length() > 0 { + model:HTTPRouteFilter headerModifierFilter = { + 'type: "RequestHeaderModifier", + requestHeaderModifier: requestHeaderModifier + }; + httpRouteFilters.push(headerModifierFilter); + } + } else { + model:HTTPHeaderFilter responseHeaderModifier = {}; + if addHeaders != [] { + responseHeaderModifier.add = addHeaders; + } + if setHeaders != [] { + responseHeaderModifier.set = setHeaders; + } + if removeHeaders != [] { + responseHeaderModifier.remove = removeHeaders; + } + if addHeaders.length() > 0 || setHeaders.length() > 0 || removeHeaders.length() > 0 { + model:HTTPRouteFilter headerModifierFilter = { + 'type: "ResponseHeaderModifier", + responseHeaderModifier: responseHeaderModifier + }; + httpRouteFilters.push(headerModifierFilter); + } } return [httpRouteFilters, hasRedirectPolicy]; diff --git a/runtime/config-deployer-service/ballerina/resources/apk-conf-schema.yaml b/runtime/config-deployer-service/ballerina/resources/apk-conf-schema.yaml index 2adc6185e..18688d670 100644 --- a/runtime/config-deployer-service/ballerina/resources/apk-conf-schema.yaml +++ b/runtime/config-deployer-service/ballerina/resources/apk-conf-schema.yaml @@ -268,7 +268,7 @@ components: SetHeaders: "#/components/schemas/HeaderModifierPolicy" RemoveHeaders: "#/components/schemas/HeaderModifierPolicy" RequestMirror: "#/components/schemas/RequestMirrorPolicy" - RequstRedirect: "#/components/schemas/RequestRedirectPolicy" + RequestRedirect: "#/components/schemas/RequestRedirectPolicy" BaseOperationPolicy: title: API Operation Policy required: diff --git a/runtime/config-deployer-service/ballerina/types.bal b/runtime/config-deployer-service/ballerina/types.bal index eecc9c4e9..edd5e4362 100644 --- a/runtime/config-deployer-service/ballerina/types.bal +++ b/runtime/config-deployer-service/ballerina/types.bal @@ -182,7 +182,7 @@ public type RequestRedirectPolicy record { # + statusCode - The status code to be sent as response to the client. public type RequestRedirectPolicyParameters record {| string url; - int statusCode; + int statusCode?; |}; # Configuration for API deployment using the apk-conf file. diff --git a/test/cucumber-tests/src/test/java/org/wso2/apk/integration/utils/clients/SimpleHTTPClient.java b/test/cucumber-tests/src/test/java/org/wso2/apk/integration/utils/clients/SimpleHTTPClient.java index d06cd0705..eb591864b 100644 --- a/test/cucumber-tests/src/test/java/org/wso2/apk/integration/utils/clients/SimpleHTTPClient.java +++ b/test/cucumber-tests/src/test/java/org/wso2/apk/integration/utils/clients/SimpleHTTPClient.java @@ -26,6 +26,7 @@ import javax.net.ssl.TrustManager; import org.apache.http.HttpResponse; import org.apache.http.client.HttpClient; +import org.apache.http.client.config.RequestConfig; import org.apache.http.client.methods.CloseableHttpResponse; import org.apache.http.client.methods.HttpDelete; import org.apache.http.client.methods.HttpGet; @@ -87,7 +88,11 @@ public SimpleHTTPClient() throws NoSuchAlgorithmException, KeyStoreException, Ke .build(); final SSLConnectionSocketFactory csf = new SSLConnectionSocketFactory(sslcontext); + RequestConfig requestConfig = RequestConfig.custom() + .setRedirectsEnabled(false) // Disable redirects + .build(); this.client = HttpClients.custom() + .setDefaultRequestConfig(requestConfig) .setSSLSocketFactory(csf) .evictExpiredConnections() .setMaxConnPerRoute(100) diff --git a/test/cucumber-tests/src/test/resources/artifacts/apk-confs/request_and_response_filters.apk-conf b/test/cucumber-tests/src/test/resources/artifacts/apk-confs/header-modifier-filter.apk-conf similarity index 94% rename from test/cucumber-tests/src/test/resources/artifacts/apk-confs/request_and_response_filters.apk-conf rename to test/cucumber-tests/src/test/resources/artifacts/apk-confs/header-modifier-filter.apk-conf index a41f67efc..a9d08d90f 100644 --- a/test/cucumber-tests/src/test/resources/artifacts/apk-confs/request_and_response_filters.apk-conf +++ b/test/cucumber-tests/src/test/resources/artifacts/apk-confs/header-modifier-filter.apk-conf @@ -1,7 +1,7 @@ --- -id: "api-with-request-and-response-filters" +id: "api-with-header-modifier-filters" name: "EmployeeServiceAPI" -basePath: "/request-and-response-filters" +basePath: "/header-modifier-filters" version: "3.14" type: "REST" defaultVersion: false diff --git a/test/cucumber-tests/src/test/resources/artifacts/apk-confs/request-mirror-filter.apk-conf b/test/cucumber-tests/src/test/resources/artifacts/apk-confs/request-mirror-filter.apk-conf new file mode 100644 index 000000000..46523900a --- /dev/null +++ b/test/cucumber-tests/src/test/resources/artifacts/apk-confs/request-mirror-filter.apk-conf @@ -0,0 +1,35 @@ +--- +id: "api-with-request-mirror-filter" +name: "EmployeeServiceAPI" +basePath: "/request-mirror-filter" +version: "3.14" +type: "REST" +defaultVersion: false +endpointConfigurations: + production: + endpoint: "http://backend:80/anything" +operations: + - target: "/employee" + verb: "GET" + secured: false + scopes: [] + operationPolicies: + request: + - policyName: RequestMirror + policyVersion: v1 + parameters: + urls: + - "http://backend:80/anything" + - "http://backend:80/anything" + - target: "/employee" + verb: "POST" + secured: true + scopes: [] + - target: "/employee/{employeeId}" + verb: "PUT" + secured: true + scopes: [] + - target: "/employee/{employeeId}" + verb: "DELETE" + secured: true + scopes: [] diff --git a/test/cucumber-tests/src/test/resources/artifacts/apk-confs/request-redirect-filter.apk-conf b/test/cucumber-tests/src/test/resources/artifacts/apk-confs/request-redirect-filter.apk-conf new file mode 100644 index 000000000..c972aeea2 --- /dev/null +++ b/test/cucumber-tests/src/test/resources/artifacts/apk-confs/request-redirect-filter.apk-conf @@ -0,0 +1,34 @@ +--- +id: "api-with-request-redirect-filter" +name: "EmployeeServiceAPI" +basePath: "/request-redirect-filter" +version: "3.14" +type: "REST" +defaultVersion: false +endpointConfigurations: + production: + endpoint: "http://backend:80/anything" +operations: + - target: "/employee" + verb: "GET" + secured: false + scopes: [] + operationPolicies: + request: + - policyName: RequestRedirect + policyVersion: v1 + parameters: + url: "http://backend:80/anything" + statusCode: 301 + - target: "/employee" + verb: "POST" + secured: true + scopes: [] + - target: "/employee/{employeeId}" + verb: "PUT" + secured: true + scopes: [] + - target: "/employee/{employeeId}" + verb: "DELETE" + secured: true + scopes: [] diff --git a/test/cucumber-tests/src/test/resources/tests/api/HTTPRouteFilters.feature b/test/cucumber-tests/src/test/resources/tests/api/HeaderModifier.feature similarity index 84% rename from test/cucumber-tests/src/test/resources/tests/api/HTTPRouteFilters.feature rename to test/cucumber-tests/src/test/resources/tests/api/HeaderModifier.feature index e8138c5b5..f6482ceca 100644 --- a/test/cucumber-tests/src/test/resources/tests/api/HTTPRouteFilters.feature +++ b/test/cucumber-tests/src/test/resources/tests/api/HeaderModifier.feature @@ -2,13 +2,13 @@ Feature: Test HTTPRoute Filter Header Modifier functionality Scenario: Test request and response header modification functionality Given The system is ready And I have a valid subscription - When I use the APK Conf file "artifacts/apk-confs/request_and_response_filters.apk-conf" + When I use the APK Conf file "artifacts/apk-confs/header-modifier-filter.apk-conf" And the definition file "artifacts/definitions/employees_api.json" And make the API deployment request Then the response status code should be 200 Then I set headers | Authorization | bearer ${accessToken} | - And I send "GET" request to "https://default.gw.wso2.com:9095/request-and-response-filters/3.14/employee/" with body "" + And I send "GET" request to "https://default.gw.wso2.com:9095/header-modifier-filters/3.14/employee/" with body "" And I eventually receive 200 response code, not accepting | 401 | And the response body should contain "\"Test-Request-Header\": \"Test-Value\"" @@ -22,7 +22,7 @@ Feature: Test HTTPRoute Filter Header Modifier functionality Scenario: Undeploy the API Given The system is ready And I have a valid subscription - When I undeploy the API whose ID is "api-with-request-and-response-filters" + When I undeploy the API whose ID is "api-with-header-modifier-filters" Then the response status code should be 202 \ No newline at end of file diff --git a/test/cucumber-tests/src/test/resources/tests/api/RequestMirror.feature b/test/cucumber-tests/src/test/resources/tests/api/RequestMirror.feature new file mode 100644 index 000000000..0c4ed706f --- /dev/null +++ b/test/cucumber-tests/src/test/resources/tests/api/RequestMirror.feature @@ -0,0 +1,21 @@ +Feature: Test HTTPRoute Filter Request Mirror functionality + Scenario: Test request mirror functionality + Given The system is ready + And I have a valid subscription + When I use the APK Conf file "artifacts/apk-confs/request-mirror-filter.apk-conf" + And the definition file "artifacts/definitions/employees_api.json" + And make the API deployment request + Then the response status code should be 200 + Then I set headers + | Authorization | bearer ${accessToken} | + And I send "GET" request to "https://default.gw.wso2.com:9095/request-mirror-filter/3.14/employee/" with body "" + And I eventually receive 200 response code, not accepting + | 401 | + + Scenario: Undeploy the API + Given The system is ready + And I have a valid subscription + When I undeploy the API whose ID is "api-with-request-mirror-filter" + Then the response status code should be 202 + + \ No newline at end of file diff --git a/test/cucumber-tests/src/test/resources/tests/api/RequestRedirect.feature b/test/cucumber-tests/src/test/resources/tests/api/RequestRedirect.feature new file mode 100644 index 000000000..85b393f90 --- /dev/null +++ b/test/cucumber-tests/src/test/resources/tests/api/RequestRedirect.feature @@ -0,0 +1,21 @@ +Feature: Test HTTPRoute Filter Request Redirect functionality + Scenario: Test request redirect functionality + Given The system is ready + And I have a valid subscription + When I use the APK Conf file "artifacts/apk-confs/request-redirect-filter.apk-conf" + And the definition file "artifacts/definitions/employees_api.json" + And make the API deployment request + Then the response status code should be 200 + Then I set headers + | Authorization | bearer ${accessToken} | + And I send "GET" request to "https://default.gw.wso2.com:9095/request-redirect-filter/3.14/employee/" with body "" + And I eventually receive 301 response code, not accepting + | 401 | + + Scenario: Undeploy the API + Given The system is ready + And I have a valid subscription + When I undeploy the API whose ID is "api-with-request-redirect-filter" + Then the response status code should be 202 + + \ No newline at end of file