diff --git a/runtime/config-deployer-service/ballerina/APIClient.bal b/runtime/config-deployer-service/ballerina/APIClient.bal index 237a433b3..60869cc74 100644 --- a/runtime/config-deployer-service/ballerina/APIClient.bal +++ b/runtime/config-deployer-service/ballerina/APIClient.bal @@ -865,23 +865,22 @@ public class APIClient { if policy is HeaderModifierPolicy { HeaderModifierPolicyParameters policyParameters = policy.parameters; match policy.policyName { - AddHeaders => { - ModifierHeader[] headers = policyParameters.headers; - foreach ModifierHeader header in headers { - addHeaders.push(header); - } + AddHeader => { + model:HTTPHeader addHeader = { + name: policyParameters.headerName, + value: policyParameters.headerValue + }; + addHeaders.push(addHeader); } - SetHeaders => { - ModifierHeader[] headers = policyParameters.headers; - foreach ModifierHeader header in headers { - setHeaders.push(header); - } + SetHeader => { + model:HTTPHeader setHeader = { + name: policyParameters.headerName, + value: policyParameters.headerValue + }; + setHeaders.push(setHeader); } - RemoveHeaders => { - string[] headers = policyParameters.headers; - foreach string header in headers { - removeHeaders.push(header); - } + RemoveHeader => { + removeHeaders.push(policyParameters.headerName); } } } else if policy is RequestMirrorPolicy { @@ -1400,7 +1399,7 @@ public class APIClient { model:BackendJWT backendJwt = self.retrieveBackendJWTPolicy(apkConf, apiArtifact, backendJWTPolicy, operations, organization); apiArtifact.backendJwt = backendJwt; policyReferences.push({name: backendJwt.metadata.name}); - } else if policyName != AddHeaders && policyName != SetHeaders && policyName != RemoveHeaders && policyName != RequestMirror && policyName != RequestRedirect { + } else if policyName != AddHeader && policyName != SetHeader && policyName != RemoveHeader && policyName != RequestMirror && policyName != RequestRedirect { return e909052(error("Incorrect API Policy name provided.")); } } 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 6285131a6..07573e27d 100644 --- a/runtime/config-deployer-service/ballerina/resources/apk-conf-schema.yaml +++ b/runtime/config-deployer-service/ballerina/resources/apk-conf-schema.yaml @@ -264,9 +264,9 @@ components: mapping: BackendJwt: "#/components/schemas/BackendJWTPolicy" Interceptor: "#/components/schemas/InterceptorPolicy" - AddHeaders: "#/components/schemas/HeaderModifierPolicy" - SetHeaders: "#/components/schemas/HeaderModifierPolicy" - RemoveHeaders: "#/components/schemas/HeaderModifierPolicy" + AddHeader: "#/components/schemas/HeaderModifierPolicy" + SetHeader: "#/components/schemas/HeaderModifierPolicy" + RemoveHeader: "#/components/schemas/HeaderModifierPolicy" RequestMirror: "#/components/schemas/RequestMirrorPolicy" RequestRedirect: "#/components/schemas/RequestRedirectPolicy" BaseOperationPolicy: @@ -278,9 +278,9 @@ components: policyName: type: string enum: - - AddHeaders - - RemoveHeaders - - SetHeaders + - AddHeader + - RemoveHeader + - SetHeader - Interceptor - BackendJwt policyVersion: @@ -511,20 +511,13 @@ components: title: Header Modifier Parameters type: object properties: - headers: - type: array - items: - oneOf: - - $ref: "#/components/schemas/Header" - - type: string - additionalProperties: false - Header: - type: object - properties: - name: + headerName: type: string - value: + headerValue: type: string + required: + - headerName + additionalProperties: false RequestMirrorPolicy: title: Request Mirror Parameters type: object diff --git a/runtime/config-deployer-service/ballerina/tests/resources/apk-schema.json b/runtime/config-deployer-service/ballerina/tests/resources/apk-schema.json index d7c57998f..5a65a7355 100644 --- a/runtime/config-deployer-service/ballerina/tests/resources/apk-schema.json +++ b/runtime/config-deployer-service/ballerina/tests/resources/apk-schema.json @@ -313,9 +313,9 @@ "type": "string", "description": "The name of the operation policy.", "enum": [ - "AddHeaders", - "RemoveHeaders", - "SetHeaders", + "AddHeader", + "RemoveHeader", + "SetHeader", "Interceptor", "BackendJwt" ] diff --git a/runtime/config-deployer-service/ballerina/types.bal b/runtime/config-deployer-service/ballerina/types.bal index edd5e4362..111624cf5 100644 --- a/runtime/config-deployer-service/ballerina/types.bal +++ b/runtime/config-deployer-service/ballerina/types.bal @@ -139,18 +139,11 @@ public type HeaderModifierPolicy record { # Configuration for header modifiers as received from the apk-conf file. # -# + headers - Headers to be added, set or removed. +# + headerName - Header name to be added, set or removed. +# + headerValue - Header value to be added, set or removed. public type HeaderModifierPolicyParameters record {| - ModifierHeader[]|string[] headers; -|}; - -# Configuration for headers. -# -# + name - The name of the header. -# + value - The value of the header. -public type ModifierHeader record {| - string name; - string value; + string headerName; + string headerValue?; |}; # Request mirror configuration for an operation. @@ -373,9 +366,9 @@ public type BaseOperationPolicy record { public enum PolicyName { BackendJwt, Interceptor, - AddHeaders, - SetHeaders, - RemoveHeaders, + AddHeader, + SetHeader, + RemoveHeader, RequestMirror, RequestRedirect } diff --git a/runtime/config-deployer-service/docker/config-deployer/conf/apk-schema.json b/runtime/config-deployer-service/docker/config-deployer/conf/apk-schema.json index 0ad4df6c2..8178e022f 100644 --- a/runtime/config-deployer-service/docker/config-deployer/conf/apk-schema.json +++ b/runtime/config-deployer-service/docker/config-deployer/conf/apk-schema.json @@ -358,9 +358,9 @@ "type": "string", "description": "The name of the operation policy.", "enum": [ - "AddHeaders", - "RemoveHeaders", - "SetHeaders", + "AddHeader", + "RemoveHeader", + "SetHeader", "Interceptor", "BackendJwt", "RequestMirror", @@ -719,31 +719,20 @@ "title": "Header Modifier Parameters", "type": "object", "properties": { - "headers": { - "type": "array", - "items": { - "oneOf": [ - { - "$ref": "#/schemas/Header" - }, - { - "type": "string" - } - ] - } + "headerName": { + "type": "string", + "description": "The name of the header." + }, + "headerValue": { + "type": "string", + "description": "The value of the header." } }, + "required": [ + "headerName" + ], "additionalProperties": false }, - "Header": { - "type": "object", - "name": { - "type": "string" - }, - "value": { - "type": "string" - } - }, "RequestMirrorProperties": { "title": "Request Mirror Parameters", "type": "object", diff --git a/test/cucumber-tests/src/test/resources/artifacts/apk-confs/httproute-filters/api-level-header.apk-conf b/test/cucumber-tests/src/test/resources/artifacts/apk-confs/httproute-filters/api-level-header.apk-conf new file mode 100644 index 000000000..75067f2f6 --- /dev/null +++ b/test/cucumber-tests/src/test/resources/artifacts/apk-confs/httproute-filters/api-level-header.apk-conf @@ -0,0 +1,58 @@ +--- +id: "api-with-header-modifier-filters" +name: "EmployeeServiceAPI" +basePath: "/header-modifier-filters" +version: "3.14" +type: "REST" +defaultVersion: false +endpointConfigurations: + production: + endpoint: "http://backend:80/anything" +operations: + - target: "/employee" + verb: "GET" + secured: false + scopes: [] + - target: "/employee" + verb: "POST" + secured: true + scopes: [] + - target: "/employee/{employeeId}" + verb: "PUT" + secured: true + scopes: [] + - target: "/employee/{employeeId}" + verb: "DELETE" + secured: true + scopes: [] +apiPolicies: + request: + - policyName: AddHeader + policyVersion: v1 + parameters: + headerName: "Test-Request-Header" + headerValue: "Test-Value" + - policyName: SetHeader + policyVersion: v1 + parameters: + headerName: "Set-Request-Header" + headerValue: "Test-Value" + - policyName: RemoveHeader + policyVersion: v1 + parameters: + headerName: "Authorization" + response: + - policyName: AddHeader + policyVersion: v1 + parameters: + headerName: "Test-Response-Header" + headerValue: "Test-Value" + - policyName: SetHeader + policyVersion: v1 + parameters: + headerName: "Set-Response-Header" + headerValue: "Test-Value" + - policyName: RemoveHeader + policyVersion: v1 + parameters: + headerName: "content-type" diff --git a/test/cucumber-tests/src/test/resources/artifacts/apk-confs/httproute-filters/api-level-mirror.apk-conf b/test/cucumber-tests/src/test/resources/artifacts/apk-confs/httproute-filters/api-level-mirror.apk-conf new file mode 100644 index 000000000..3555f72c8 --- /dev/null +++ b/test/cucumber-tests/src/test/resources/artifacts/apk-confs/httproute-filters/api-level-mirror.apk-conf @@ -0,0 +1,34 @@ +--- +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: [] + - target: "/employee" + verb: "POST" + secured: true + scopes: [] + - target: "/employee/{employeeId}" + verb: "PUT" + secured: true + scopes: [] + - target: "/employee/{employeeId}" + verb: "DELETE" + secured: true + scopes: [] +apiPolicies: + request: + - policyName: RequestMirror + policyVersion: v1 + parameters: + urls: + - "http://backend:80/anything" diff --git a/test/cucumber-tests/src/test/resources/artifacts/apk-confs/httproute-filters/api-level-redirect.apk-conf b/test/cucumber-tests/src/test/resources/artifacts/apk-confs/httproute-filters/api-level-redirect.apk-conf new file mode 100644 index 000000000..2b2c4985f --- /dev/null +++ b/test/cucumber-tests/src/test/resources/artifacts/apk-confs/httproute-filters/api-level-redirect.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: [] + - target: "/employee" + verb: "POST" + secured: true + scopes: [] + - target: "/employee/{employeeId}" + verb: "PUT" + secured: true + scopes: [] + - target: "/employee/{employeeId}" + verb: "DELETE" + secured: true + scopes: [] +apiPolicies: + request: + - policyName: RequestRedirect + policyVersion: v1 + parameters: + url: "http://backend:80/anything" + statusCode: 301 diff --git a/test/cucumber-tests/src/test/resources/artifacts/apk-confs/header-modifier-filter.apk-conf b/test/cucumber-tests/src/test/resources/artifacts/apk-confs/httproute-filters/header-modifier-filter.apk-conf similarity index 56% rename from test/cucumber-tests/src/test/resources/artifacts/apk-confs/header-modifier-filter.apk-conf rename to test/cucumber-tests/src/test/resources/artifacts/apk-confs/httproute-filters/header-modifier-filter.apk-conf index a9d08d90f..e24842b9b 100644 --- a/test/cucumber-tests/src/test/resources/artifacts/apk-confs/header-modifier-filter.apk-conf +++ b/test/cucumber-tests/src/test/resources/artifacts/apk-confs/httproute-filters/header-modifier-filter.apk-conf @@ -15,41 +15,35 @@ operations: scopes: [] operationPolicies: request: - - policyName: AddHeaders + - policyName: AddHeader policyVersion: v1 parameters: - headers: - - name: "Test-Request-Header" - value: "Test-Value" - - policyName: SetHeaders + headerName: "Test-Request-Header" + headerValue: "Test-Value" + - policyName: SetHeader policyVersion: v1 parameters: - headers: - - name: "Set-Request-Header" - value: "Test-Value" - - policyName: RemoveHeaders + headerName: "Set-Request-Header" + headerValue: "Test-Value" + - policyName: RemoveHeader policyVersion: v1 parameters: - headers: - - "Authorization" + headerName: "Authorization" response: - - policyName: AddHeaders + - policyName: AddHeader policyVersion: v1 parameters: - headers: - - name: "Test-Response-Header" - value: "Test-Value" - - policyName: SetHeaders + headerName: "Test-Response-Header" + headerValue: "Test-Value" + - policyName: SetHeader policyVersion: v1 parameters: - headers: - - name: "Set-Response-Header" - value: "Test-Value" - - policyName: RemoveHeaders + headerName: "Set-Response-Header" + headerValue: "Test-Value" + - policyName: RemoveHeader policyVersion: v1 parameters: - headers: - - "content-type" + headerName: "content-type" - target: "/employee" verb: "POST" secured: true 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/httproute-filters/request-mirror-filter.apk-conf similarity index 100% rename from test/cucumber-tests/src/test/resources/artifacts/apk-confs/request-mirror-filter.apk-conf rename to test/cucumber-tests/src/test/resources/artifacts/apk-confs/httproute-filters/request-mirror-filter.apk-conf 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/httproute-filters/request-redirect-filter.apk-conf similarity index 100% rename from test/cucumber-tests/src/test/resources/artifacts/apk-confs/request-redirect-filter.apk-conf rename to test/cucumber-tests/src/test/resources/artifacts/apk-confs/httproute-filters/request-redirect-filter.apk-conf diff --git a/test/cucumber-tests/src/test/resources/tests/api/HeaderModifier.feature b/test/cucumber-tests/src/test/resources/tests/api/HeaderModifier.feature index f6482ceca..75a9ee070 100644 --- a/test/cucumber-tests/src/test/resources/tests/api/HeaderModifier.feature +++ b/test/cucumber-tests/src/test/resources/tests/api/HeaderModifier.feature @@ -2,7 +2,7 @@ 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/header-modifier-filter.apk-conf" + When I use the APK Conf file "artifacts/apk-confs/httproute-filters/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 @@ -24,5 +24,61 @@ Feature: Test HTTPRoute Filter Header Modifier functionality And I have a valid subscription When I undeploy the API whose ID is "api-with-header-modifier-filters" Then the response status code should be 202 + + 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/httproute-filters/api-level-header.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/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\"" + And the response body should contain "\"Set-Request-Header\": \"Test-Value\"" + And the response body should not contain "\"Authorization\"" + Then the response headers contains key "Set-Response-Header" and value "Test-Value" + Then the response headers contains key "Test-Response-Header" and value "Test-Value" + And the response headers should not contain + | content-type | + And I send "POST" 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\"" + And the response body should contain "\"Set-Request-Header\": \"Test-Value\"" + And the response body should not contain "\"Authorization\"" + Then the response headers contains key "Set-Response-Header" and value "Test-Value" + Then the response headers contains key "Test-Response-Header" and value "Test-Value" + And the response headers should not contain + | content-type | + And I send "PUT" request to "https://default.gw.wso2.com:9095/header-modifier-filters/3.14/employee/1" with body "" + And I eventually receive 200 response code, not accepting + | 401 | + And the response body should contain "\"Test-Request-Header\": \"Test-Value\"" + And the response body should contain "\"Set-Request-Header\": \"Test-Value\"" + And the response body should not contain "\"Authorization\"" + Then the response headers contains key "Set-Response-Header" and value "Test-Value" + Then the response headers contains key "Test-Response-Header" and value "Test-Value" + And the response headers should not contain + | content-type | + And I send "DELETE" request to "https://default.gw.wso2.com:9095/header-modifier-filters/3.14/employee/1" with body "" + And I eventually receive 200 response code, not accepting + | 401 | + And the response body should contain "\"Test-Request-Header\": \"Test-Value\"" + And the response body should contain "\"Set-Request-Header\": \"Test-Value\"" + And the response body should not contain "\"Authorization\"" + Then the response headers contains key "Set-Response-Header" and value "Test-Value" + Then the response headers contains key "Test-Response-Header" and value "Test-Value" + And the response headers should not contain + | content-type | + + 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-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 index 0c4ed706f..3dfe4f6af 100644 --- a/test/cucumber-tests/src/test/resources/tests/api/RequestMirror.feature +++ b/test/cucumber-tests/src/test/resources/tests/api/RequestMirror.feature @@ -2,7 +2,7 @@ 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" + When I use the APK Conf file "artifacts/apk-confs/httproute-filters/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 diff --git a/test/cucumber-tests/src/test/resources/tests/api/RequestRedirect.feature b/test/cucumber-tests/src/test/resources/tests/api/RequestRedirect.feature index 85b393f90..28570f428 100644 --- a/test/cucumber-tests/src/test/resources/tests/api/RequestRedirect.feature +++ b/test/cucumber-tests/src/test/resources/tests/api/RequestRedirect.feature @@ -2,7 +2,7 @@ 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" + When I use the APK Conf file "artifacts/apk-confs/httproute-filters/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 @@ -11,6 +11,9 @@ Feature: Test HTTPRoute Filter Request Redirect functionality 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 | + And I send "POST" request to "https://default.gw.wso2.com:9095/request-redirect-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 @@ -18,4 +21,31 @@ Feature: Test HTTPRoute Filter Request Redirect functionality When I undeploy the API whose ID is "api-with-request-redirect-filter" Then the response status code should be 202 + Scenario: Test request redirect functionality with API level redirect + Given The system is ready + And I have a valid subscription + When I use the APK Conf file "artifacts/apk-confs/httproute-filters/api-level-redirect.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 | + And I send "POST" 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 | + And I send "PUT" request to "https://default.gw.wso2.com:9095/request-redirect-filter/3.14/employee/1" with body "" + And I eventually receive 301 response code, not accepting + | 401 | + And I send "DELETE" request to "https://default.gw.wso2.com:9095/request-redirect-filter/3.14/employee/1" 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