Skip to content

Commit

Permalink
Adding Gateway implementation
Browse files Browse the repository at this point in the history
  • Loading branch information
Ashi1993 committed Oct 24, 2024
1 parent efa77d1 commit 8edaedf
Show file tree
Hide file tree
Showing 11 changed files with 322 additions and 57 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -1424,71 +1424,50 @@ definitions:
description: Meta Data relevant to the payload
additionalProperties: { }
ISODateTime:
type: string
format: date-time
description: >-
All dates in the JSON payloads are represented in ISO 8601 date-time
format.
All date-time fields in responses must include the timezone. An example is
below:
2017-04-05T10:43:07+00:00
type: string
format: date-time
description: >-
All dates in the JSON payloads are represented in ISO 8601 date-time
format.
All date-time fields in responses must include the timezone. An example is
below:
2017-04-05T10:43:07+00:00
OBError1:
type: object
properties:
ErrorCode:
description: 'Low level textual error code, e.g., UK.OBIE.Field.Missing'
code:
description: 'error code'
type: string
Message:
message:
description: >-
A description of the error that occurred. e.g., 'A mandatory field
isn't supplied' or 'RequestedExecutionDateTime must be in future'
OBIE doesn't standardise this field
type: string
minLength: 1
maxLength: 500
description:
description: >-
A description of the error that occurred. e.g., 'A mandatory field
isn't supplied' or 'RequestedExecutionDateTime must be in future'
type: string
minLength: 1
maxLength: 1000
required:
- ErrorCode
- Message
- code
- message
- description
additionalProperties: false
minProperties: 1
OBErrorResponse1:
description: >-
An array of detail error codes, and messages, and URLs to documentation to
help remediation.
type: object
properties:
Code:
description: 'High level textual error code, to help categorize the errors.'
type: string
minLength: 1
maxLength: 40
Id:
description: >-
A unique reference for the error instance, for audit purposes, in case
of unknown/unclassified errors.
type: string
minLength: 1
maxLength: 40
Message:
description: >-
Brief Error message, e.g., 'There is something wrong with the request
parameters provided'
type: string
minLength: 1
maxLength: 500
Errors:
errors:
type: array
items:
$ref: '#/definitions/OBError1'
type: array
minItems: 1
required:
- Code
- Message
- Errors
additionalProperties: false
x-wso2-security:
apim:
x-wso2-scopes:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -422,6 +422,9 @@ name = "Default"
[[financial_services.gateway.gateway_executors.type.executors]]
name = "org.wso2.financial.services.accelerator.gateway.executor.impl.consent.ConsentEnforcementExecutor"
priority = 1
[[financial_services.gateway.gateway_executors.type.executors]]
name = "org.wso2.financial.services.accelerator.gateway.executor.impl.error.handling.DefaultErrorHandlingExecutor"
priority = 1000

[financial_services.gateway.consent.validation]
endpoint="https://IS_HOSTNAME:9446/api/fs/consent/validate"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -166,7 +166,7 @@ private void validateAccountSubmission(ConsentValidateData consentValidateData,
consentValidationResult.setValid(false);
consentValidationResult.setErrorMessage(PERMISSION_MISMATCH_ERROR);
consentValidationResult.setErrorCode(ResponseStatus.FORBIDDEN.getReasonPhrase());
consentValidationResult.setHttpCode(403);
consentValidationResult.setHttpCode(HttpStatus.SC_FORBIDDEN);
return;
}

Expand All @@ -185,8 +185,8 @@ private void validateAccountSubmission(ConsentValidateData consentValidateData,
log.error(CONSENT_EXPIRED_ERROR);
consentValidationResult.setValid(false);
consentValidationResult.setErrorMessage(CONSENT_EXPIRED_ERROR);
consentValidationResult.setErrorCode(ResponseStatus.UNAUTHORIZED.getReasonPhrase());
consentValidationResult.setHttpCode(HttpStatus.SC_UNAUTHORIZED);
consentValidationResult.setErrorCode(ResponseStatus.BAD_REQUEST.getReasonPhrase());
consentValidationResult.setHttpCode(HttpStatus.SC_BAD_REQUEST);
return;
}
consentValidationResult.setValid(true);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -312,9 +312,9 @@ public void testValidateWithExpiredInitiationForAccounts() {
validator.validate(consentValidateDataMock, consentValidationResultMock);

Assert.assertFalse(consentValidationResultMock.isValid());
Assert.assertEquals(consentValidationResultMock.getErrorCode(), ResponseStatus.UNAUTHORIZED.getReasonPhrase());
Assert.assertEquals(consentValidationResultMock.getErrorCode(), ResponseStatus.BAD_REQUEST.getReasonPhrase());
Assert.assertEquals(consentValidationResultMock.getErrorMessage(), "Provided consent is expired");
Assert.assertEquals(consentValidationResultMock.getHttpCode(), HttpStatus.SC_UNAUTHORIZED);
Assert.assertEquals(consentValidationResultMock.getHttpCode(), HttpStatus.SC_BAD_REQUEST);
}

@Test
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -140,7 +140,6 @@ public void postProcessRequest(FSAPIRequestContext fsapiRequestContext) {
String errorCode = jsonResponse.get(ERROR_CODE).toString();
String errorMessage = jsonResponse.get(ERROR_MESSAGE).toString();
String httpCode = jsonResponse.get(HTTP_CODE).toString();
fsapiRequestContext.setError(true);
handleError(fsapiRequestContext, errorCode, errorMessage, httpCode);
return;
} else if (!jsonResponse.isNull(MODIFIED_PAYLOAD)) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,181 @@
/**
* Copyright (c) 2024, WSO2 LLC. (https://www.wso2.com).
* <p>
* WSO2 LLC. licenses this file to you under the Apache License,
* Version 2.0 (the "License"); you may not use this file except
* in compliance with the License.
* You may obtain a copy of the License at
* <p>
* http://www.apache.org/licenses/LICENSE-2.0
* <p>
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/

package org.wso2.financial.services.accelerator.gateway.executor.impl.error.handling;

import org.apache.http.HttpStatus;
import org.json.JSONArray;
import org.json.JSONObject;
import org.wso2.financial.services.accelerator.gateway.executor.core.FinancialServicesGatewayExecutor;
import org.wso2.financial.services.accelerator.gateway.executor.model.FSAPIRequestContext;
import org.wso2.financial.services.accelerator.gateway.executor.model.FSAPIResponseContext;
import org.wso2.financial.services.accelerator.gateway.executor.model.FSExecutorError;
import org.wso2.financial.services.accelerator.gateway.util.GatewayConstants;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Map;

/**
* Default Executor to handle gateway errors.
*/
public class DefaultErrorHandlingExecutor implements FinancialServicesGatewayExecutor {

private static final String ERRORS_TAG = "errors";

/**
* Method to handle pre request.
*
* @param fsapiRequestContext FS request context object
*/
@Override
public void preProcessRequest(FSAPIRequestContext fsapiRequestContext) {

handleRequestError(fsapiRequestContext);

}

/**
* Method to handle post request.
*
* @param fsapiRequestContext FS request context object
*/
@Override
public void postProcessRequest(FSAPIRequestContext fsapiRequestContext) {

handleRequestError(fsapiRequestContext);
}

/**
* Method to handle pre response.
*
* @param fsapiResponseContext FS response context object
*/
@Override
public void preProcessResponse(FSAPIResponseContext fsapiResponseContext) {

handleResponseError(fsapiResponseContext);
}

/**
* Method to handle post response.
*
* @param fsapiResponseContext FS response context object
*/
@Override
public void postProcessResponse(FSAPIResponseContext fsapiResponseContext) {

handleResponseError(fsapiResponseContext);
}

private void handleRequestError(FSAPIRequestContext fsapiRequestContext) {

if (!fsapiRequestContext.isError()) {
return;
}
JSONObject payload = new JSONObject();
ArrayList<FSExecutorError> errors = fsapiRequestContext.getErrors();
JSONArray errorList = getErrorJSON(errors);
HashSet<String> statusCodes = new HashSet<>();

for (FSExecutorError error : errors) {
statusCodes.add(error.getHttpStatusCode());
}

payload.put(ERRORS_TAG, errorList);
if (errorList.length() != 0) {
fsapiRequestContext.setModifiedPayload(payload.toString());
Map<String, String> addedHeaders = fsapiRequestContext.getAddedHeaders();
addedHeaders.put(GatewayConstants.CONTENT_TYPE_TAG, GatewayConstants.JSON_CONTENT_TYPE);
fsapiRequestContext.setAddedHeaders(addedHeaders);
}
int statusCode;
if (fsapiRequestContext.getContextProps().containsKey(GatewayConstants.ERROR_STATUS_PROP)) {
statusCode = Integer.parseInt(fsapiRequestContext
.getContextProperty(GatewayConstants.ERROR_STATUS_PROP).toString());
} else if (isAnyClientErrors(statusCodes)) {
statusCode = HttpStatus.SC_BAD_REQUEST;
} else {
statusCode = HttpStatus.SC_INTERNAL_SERVER_ERROR;
}
fsapiRequestContext.addContextProperty(GatewayConstants.ERROR_STATUS_PROP,
String.valueOf(statusCode));
}

private void handleResponseError(FSAPIResponseContext fsapiResponseContext) {

if (!fsapiResponseContext.isError()) {
return;
}
JSONObject payload = new JSONObject();
ArrayList<FSExecutorError> errors = fsapiResponseContext.getErrors();
JSONArray errorList = getErrorJSON(errors);
HashSet<String> statusCodes = new HashSet<>();

for (FSExecutorError error : errors) {
statusCodes.add(error.getHttpStatusCode());
}

payload.put(ERRORS_TAG, errorList);
fsapiResponseContext.setModifiedPayload(payload.toString());
Map<String, String> addedHeaders = fsapiResponseContext.getAddedHeaders();
addedHeaders.put(GatewayConstants.CONTENT_TYPE_TAG, GatewayConstants.JSON_CONTENT_TYPE);
fsapiResponseContext.setAddedHeaders(addedHeaders);
int statusCode;
if (fsapiResponseContext.getContextProps().containsKey(GatewayConstants.ERROR_STATUS_PROP)) {
statusCode = Integer.parseInt(fsapiResponseContext
.getContextProperty(GatewayConstants.ERROR_STATUS_PROP).toString());
} else if (isAnyClientErrors(statusCodes)) {
statusCode = HttpStatus.SC_BAD_REQUEST;
} else {
statusCode = HttpStatus.SC_INTERNAL_SERVER_ERROR;
}
fsapiResponseContext.addContextProperty(GatewayConstants.ERROR_STATUS_PROP,
String.valueOf(statusCode));
}

private JSONArray getErrorJSON(List<FSExecutorError> errors) {

JSONArray errorList = new JSONArray();
for (FSExecutorError error : errors) {
JSONObject errorObj = new JSONObject();
errorObj.put("code", error.getCode());
errorObj.put("message", error.getTitle());
errorObj.put("description", error.getMessage());
Map<String, String> links = error.getLinks();
if (links != null && links.size() > 0) {
JSONObject linksObj = new JSONObject();
links.forEach(linksObj::put);
errorObj.put("Links", linksObj);
}
errorList.put(errorObj);
}
return errorList;
}

private boolean isAnyClientErrors(HashSet<String> statusCodes) {

for (String statusCode : statusCodes) {
if (statusCode.startsWith("4")) {
return true;
}
}
return false;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@
import java.util.Map;

/**
* Test for open Banking extension implementation.
* Test for FS extension implementation.
*/
public class FSExtensionImplTest {

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,9 @@
import org.wso2.financial.services.accelerator.gateway.executor.model.FSAPIResponseContext;

/**
* Mock Open banking executor for testing.
* Mock FS executor for testing.
*/
public class MockOBExecutor implements FinancialServicesGatewayExecutor {
public class MockFSExecutor implements FinancialServicesGatewayExecutor {

@Override
public void preProcessRequest(FSAPIRequestContext fsapiRequestContext) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@
/**
* Test for enforcement executor.
*/
public class TestEnforcementExecutor {
public class ConsentEnforcementExecutorTest {

private static ConsentEnforcementExecutor consentEnforcementExecutor;
private static MockedStatic<HTTPClientUtils> httpClientUtilsMockedStatic;
Expand Down
Loading

0 comments on commit 8edaedf

Please sign in to comment.