Skip to content

Commit

Permalink
Add support for HeaderModifier filter in config deployer
Browse files Browse the repository at this point in the history
  • Loading branch information
sgayangi committed May 29, 2024
1 parent 62c8df7 commit a498253
Show file tree
Hide file tree
Showing 5 changed files with 179 additions and 20 deletions.
67 changes: 50 additions & 17 deletions runtime/config-deployer-service/ballerina/APIClient.bal
Original file line number Diff line number Diff line change
Expand Up @@ -785,7 +785,11 @@ public class APIClient {
return e909022("Provided Type currently not supported for GraphQL APIs.", error("Provided Type currently not supported for GraphQL APIs."));
}
} else {
model:HTTPRouteRule httpRouteRule = {matches: self.retrieveHTTPMatches(apkConf, operation, organization), backendRefs: self.retrieveGeneratedBackend(apkConf, endpointToUse, endpointType), filters: self.generateFilters(apiArtifact, apkConf, endpointToUse, operation, endpointType, organization)};
model:HTTPRouteRule httpRouteRule = {
matches: self.retrieveHTTPMatches(apkConf, operation, organization),
backendRefs: self.retrieveGeneratedBackend(apkConf, endpointToUse, endpointType),
filters: self.generateFilters(apiArtifact, apkConf, endpointToUse, operation, endpointType, organization)
};
return httpRouteRule;
}
} else {
Expand All @@ -800,7 +804,15 @@ public class APIClient {
private isolated function generateFilters(model:APIArtifact apiArtifact, APKConf apkConf, model:Endpoint endpoint, APKOperations operation, string endpointType, commons:Organization organization) returns model:HTTPRouteFilter[] {
model:HTTPRouteFilter[] routeFilters = [];
string generatedPath = self.generatePrefixMatch(endpoint, operation);
model:HTTPRouteFilter replacePathFilter = {'type: "URLRewrite", urlRewrite: {path: {'type: "ReplaceFullPath", replaceFullPath: generatedPath}}};
model:HTTPRouteFilter replacePathFilter = {
'type: "URLRewrite",
urlRewrite: {
path: {
'type: "ReplaceFullPath",
replaceFullPath: generatedPath
}
}
};
routeFilters.push(replacePathFilter);
APIOperationPolicies? operationPoliciesToUse = ();
if (apkConf.apiPolicies is APIOperationPolicies) {
Expand All @@ -809,33 +821,53 @@ public class APIClient {
operationPoliciesToUse = operation.operationPolicies;
}
if operationPoliciesToUse is APIOperationPolicies {
APKOperationPolicy[]? request = operationPoliciesToUse.request;
APKOperationPolicy[]? requestPolicies = operationPoliciesToUse.request;
APKOperationPolicy[]? responsePolicies = operationPoliciesToUse.response;
if requestPolicies is APKOperationPolicy[] && requestPolicies.length() > 0 {
model:HTTPRouteFilter headerModifierFilter = {'type: "RequestHeaderModifier"};
headerModifierFilter.requestHeaderModifier = self.extractHttpHeaderFilterData(requestPolicies, organization);
routeFilters.push(headerModifierFilter);
}
if responsePolicies is APKOperationPolicy[] && responsePolicies.length() > 0 {
model:HTTPRouteFilter headerModifierFilter = {'type: "ResponseHeaderModifier"};
headerModifierFilter.responseHeaderModifier = self.extractHttpHeaderFilterData(responsePolicies, organization);
routeFilters.push(headerModifierFilter);
}
}
return routeFilters;
}

isolated function extractHttpHeaderFilterData(APKOperationPolicy[] operationPolicy, commons:Organization organization) returns model:HTTPHeaderFilter {
model:HTTPHeader[] addPolicies = [];
model:HTTPHeader[] setPolicies = [];
string[] removePolicies = [];
foreach APKOperationPolicy policy in operationPolicy {
string policyName = policy.policyName;

record {}? policyParameters = policy.parameters;
if (policyParameters is record {}) {
if (policyName == "addHeader") {
model:HTTPHeader httpHeader = {
name: <string>policyParameters.get("headerName"),
value: <string>policyParameters.get("headerValue")
};
setPolicies.push(httpHeader);
if policy is HeaderModifierPolicy {
HeaderModifierPolicyParameters policyParameters = policy.parameters;
if policy.policyName == "AddHeaders" {
ModifierHeader[] addHeaders = <ModifierHeader[]>policyParameters.headers;
foreach ModifierHeader header in addHeaders {
addPolicies.push(header);
}
}
if policy.policyName == "SetHeaders" {
ModifierHeader[] setHeaders = <ModifierHeader[]>policyParameters.headers;
foreach ModifierHeader header in setHeaders {
setPolicies.push(header);
}
}
if (policyName == "removeHeader") {
string httpHeader = <string>policyParameters.get("headerName");
removePolicies.push(httpHeader);
if policy.policyName == "RemoveHeaders" {
string[] removeHeaders = <string[]>policyParameters.headers;
foreach string header in removeHeaders {
removePolicies.push(header);
}
}
}
}
model:HTTPHeaderFilter headerModifier = {};
if (addPolicies != []) {
headerModifier.add = addPolicies;
}
if (setPolicies != []) {
headerModifier.set = setPolicies;
}
Expand Down Expand Up @@ -1228,6 +1260,8 @@ public class APIClient {
model:BackendJWT backendJwt = self.retrieveBackendJWTPolicy(apkConf, apiArtifact, backendJWTPolicy, operations, organization);
apiArtifact.backendJwt = backendJwt;
policyReferences.push(<model:BackendJwtReference>{name: backendJwt.metadata.name});
} else if (policyName == "AddHeaders" || policyName == "SetHeaders" || policyName == "RemoveHeaders") {

} else {
return e909052(error("Incorrect API Policy name provided."));
}
Expand Down Expand Up @@ -1593,7 +1627,6 @@ public class APIClient {
private isolated function validateAndRetrieveAPKConfiguration(json apkconfJson) returns APKConf|commons:APKError? {
do {
runtimeapi:APKConfValidationResponse validationResponse = check apkConfValidator.validate(apkconfJson.toJsonString());

if validationResponse.isValidated() {
APKConf apkConf = check apkconfJson.cloneWithType(APKConf);
map<string> errors = {};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -256,11 +256,15 @@ components:
oneOf:
- $ref: "#/components/schemas/InterceptorPolicy"
- $ref: "#/components/schemas/BackendJWTPolicy"
- $ref: "#/components/schemas/HeaderModifierPolicy"
discriminator:
propertyName: "policyName"
mapping:
BackendJwt: "#/components/schemas/BackendJWTPolicy"
Interceptor: "#/components/schemas/InterceptorPolicy"
AddHeaders: "#/components/schemas/HeaderModifierPolicy"
SetHeaders: "#/components/schemas/HeaderModifierPolicy"
RemoveHeadersHeaders: "#/components/schemas/HeaderModifierPolicy"
BaseOperationPolicy:
title: API Operation Policy
required:
Expand All @@ -269,6 +273,12 @@ components:
properties:
policyName:
type: string
enum:
- AddHeaders
- RemoveHeaders
- SetHeaders
- Interceptor
- BackendJwt
policyVersion:
type: string
default: "v1"
Expand Down Expand Up @@ -493,6 +503,24 @@ components:
required:
- enabled
additionalProperties: false
HeaderModifierPolicy:
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:
type: string
value:
type: string
CustomClaims:
type: object
required:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -311,7 +311,14 @@
"properties": {
"policyName": {
"type": "string",
"description": "The name of the operation policy."
"description": "The name of the operation policy.",
"enum": [
"AddHeaders",
"RemoveHeaders",
"SetHeaders",
"Interceptor",
"BackendJwt"
]
},
"policyVersion": {
"type": "string",
Expand All @@ -330,6 +337,9 @@
},
{
"$ref": "#/schemas/BackendJWTProperties"
},
{
"$ref": "#/schemas/HeaderModifierProperties"
}
]
}
Expand Down Expand Up @@ -652,6 +662,35 @@
},
"additionalProperties": false
},
"HeaderModifierProperties": {
"title": "Header Modifier Parameters",
"type": "object",
"properties": {
"headers": {
"type": "array",
"items": {
"oneOf": [
{
"$ref": "#/schemas/Header"
},
{
"type": "string"
}
]
}
}
},
"additionalProperties": false
},
"Header": {
"type": "object",
"name": {
"type": "string"
},
"value": {
"type": "string"
}
},
"CustomClaims": {
"type": "object",
"required": [
Expand Down
22 changes: 21 additions & 1 deletion runtime/config-deployer-service/ballerina/types.bal
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ public type APKOperations record {
string[] scopes?;
};

public type APKOperationPolicy InterceptorPolicy|BackendJWTPolicy;
public type APKOperationPolicy InterceptorPolicy|BackendJWTPolicy|HeaderModifierPolicy;

public type DeployApiBody record {
# apk-configuration file
Expand Down Expand Up @@ -202,6 +202,11 @@ public type Authentication record {|
boolean enabled = true;
|};

public type HeaderModifierPolicy record {
*BaseOperationPolicy;
HeaderModifierPolicyParameters parameters;
};

public type InterceptorPolicy record {
*BaseOperationPolicy;
InterceptorPolicy_parameters parameters?;
Expand Down Expand Up @@ -236,6 +241,21 @@ public type APKConf record {
CORSConfiguration corsConfiguration?;
};

public type HeaderModifierPolicyParameters record {|
ModifierHeader[]|string[] headers;
|};

public type HeaderModifierFilterParameters record {|
ModifierHeader[] addHeaders;
ModifierHeader[] setHeaders;
string[] removeHeaders;
|};

public type ModifierHeader record {|
string name;
string value;
|};

public type InterceptorPolicy_parameters record {|
string backendUrl?;
boolean headersEnabled?;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -356,7 +356,14 @@
"properties": {
"policyName": {
"type": "string",
"description": "The name of the operation policy."
"description": "The name of the operation policy.",
"enum": [
"AddHeaders",
"RemoveHeaders",
"SetHeaders",
"Interceptor",
"BackendJwt"
]
},
"policyVersion": {
"type": "string",
Expand All @@ -375,6 +382,9 @@
},
{
"$ref": "#/schemas/BackendJWTProperties"
},
{
"$ref": "#/schemas/HeaderModifierProperties"
}
]
}
Expand Down Expand Up @@ -697,6 +707,35 @@
},
"additionalProperties": false
},
"HeaderModifierProperties": {
"title": "Header Modifier Parameters",
"type": "object",
"properties": {
"headers": {
"type": "array",
"items": {
"oneOf": [
{
"$ref": "#/schemas/Header"
},
{
"type": "string"
}
]
}
}
},
"additionalProperties": false
},
"Header": {
"type": "object",
"name": {
"type": "string"
},
"value": {
"type": "string"
}
},
"CustomClaims": {
"type": "object",
"required": [
Expand Down

0 comments on commit a498253

Please sign in to comment.