Как имитировать конечную точку, замаскировавшую номер карты в Wiremock?

У нас есть конечная точка, которая маскирует номера карт. Я хочу поиздеваться над этой конечной точкой с помощью Wiremock. Так как это будет работать для более чем одного номера карты, я не могу подготовить отдельный файл макета для каждой карты. Как я могу имитировать эту конечную точку, используя один файл? Отправленный запрос и ответ на этот запрос выглядят следующим образом:

Request:
{
    "cardNumber": "1234561234561234"
}
Response:
{
    "maskedCard": "123456******1234"
}

Я подготовил файл Wiremock, который работает только для 1 номера карты:

{
    "request": {
        "method": "POST",
        "url": "/maskedCard",
        "bodyPatterns": [
            {
                "matchesJsonPath": "[?(@.cardNumber == '1234561234561234')]"
            }
        ]
    },
    "response": {
        "status": 200,
        "headers": {
            "Content-Type": "application/json"
        },
        "jsonBody": {
            "maskedCard": "123456******1234"
        }
    }
}

Как сделать так, чтобы это работало для всех номеров входящих карт?


person Ahmet Rufai Babur    schedule 18.10.2020    source источник


Ответы (1)


Если cardNumber, прикрепленный к запросу, не имеет значения, я бы просто исключил bodyPatterns для сопоставления.

{
    "request": {
        "method": "POST",
        "url": "/maskedCard"
    }

Если затем вам нужно взять то, что есть cardNumber в теле запроса, и замаскировать его, я не знаю ни одного нестандартного решения, которое могло бы сделать это за вас. Вместо этого вам придется написать Response Transformer, чтобы изменить немаскированный cardNumber на замаскированный CardNumber. Что-то вроде...

public class MaskCardNumbers extends ResponseTransformer {

    public String getName() {
        return "MaskCardNumbers";
    }

    @Override
    public Response transform(Request request, Response response, FileSource files, Parameters parameters) {
        Pattern pattern = Pattern.compile("/maskedCard");
        Matcher matcher = pattern.matcher(request.getUrl());
        if(matcher.matches()) { 
            // Logic to extract cardNumber - my library of choice is JsonSimple
            JSONObject responseBody = (JSONObject) parser.parse(response.getBodyAsString());
            String cardNumber = responseBody.get("cardNumber").toString();
            
            // Logic to replace cardNumber
            String maskedCard = "";
            for (int i = 0; i < cardNumber.length(); i++) {
                if (i < 6 || i > 11) {
                    maskedCard += cardNumber.charAt(i);
                } else {
                    maskedCard += "*";
                }
            }

            // Create response JSON Object
            JSONObject responseObject = new JSONObject();
            responseObject.put("cardNumber", maskedCard)

            // Return responseObject
                            return Response.Builder.like(response).but().body(responseBody.toJSONString()).build();
        }
    }
}       

Затем вам нужно будет убедиться, что WireMock запускается с подключенным трансформатором. Наконец, ваше отображение будет выглядеть так:

{
    "request": {
        "method": "POST",
        "url": "/maskedCard"
    },
    "response": {
        "status": 200,
        "headers": {
            "Content-Type": "application/json"
        },
        "jsonBody": {
            "maskedCard": "123456******1234"
        }
    }
}

Возможно, вам придется поэкспериментировать с некоторыми особенностями, но я думаю, что это должно сделать вашу работу или, по крайней мере, помочь вам в этом.

person agoff    schedule 19.10.2020
comment
Правильно ли я понял, что предлагаемое решение - написать код Java, скомпилировать его, собрать, упаковать, развернуть с помощью WireMock, поддерживать его в долгосрочной перспективе (например, обновления версии)? При этом убедитесь, что любые используемые им зависимости, такие как библиотека JSON, не противоречат тому, что использует WireMock (я не знаю, предотвращается ли это каким-то специальным подходом к загрузке классов)? Есть способ попроще? - person apisim; 20.10.2020
comment
Да, поскольку похоже, что вам требуется какой-то специальный код для выполнения этой маскировки. WireMock не может предвидеть все варианты использования для преобразования ответов. Доступно большое количество готовых трансформаторов, но, к сожалению, ваш вариант использования достаточно специфичен, и для него требуется полностью настраиваемый трансформатор. Описанный мною процесс является стандартным для написания, подключения и обслуживания заказных трансформаторов. Если вы считаете, что ваш вариант использования достаточно общий, чтобы быть стандартным, я бы написал о проблеме в репозитории WireMock на github. - person agoff; 20.10.2020