@Override
    protected Optional<ErrorResponse> filter(DiscFilterRequest request) {
        String method = request.getMethod();
        URI uri = request.getUri();
        for (Rule rule : rules) {
            if (rule.matches(method, uri)) {
                log.log(Level.FINE, () ->
                        String.format("Request '%h' with method '%s' and uri '%s' matched rule '%s'", request, method, uri, rule.name));
                return responseFor(request, rule.name, rule.response);
            }
        }
        return responseFor(request, "default", defaultResponse);
    }
@Test
    void performs_action_on_first_matching_rule() throws IOException {
        RuleBasedFilterConfig config = new RuleBasedFilterConfig.Builder()
                .dryrun(false)
                .defaultRule(new DefaultRule.Builder()
                        .action(DefaultRule.Action.Enum.ALLOW))
                .rule(new Rule.Builder()
                        .name("first")
                        .pathExpressions("/path-to-resource")
                        .methods(Rule.Methods.Enum.DELETE)
                        .action(Rule.Action.Enum.BLOCK)
                        .blockResponseCode(403))
                .rule(new Rule.Builder()
                        .name("second")
                        .pathExpressions("/path-to-resource")
                        .methods(Rule.Methods.Enum.GET)
                        .action(Rule.Action.Enum.BLOCK)
                        .blockResponseCode(404))
                .build();

        Metric metric = mock(Metric.class);
        RuleBasedRequestFilter filter = new RuleBasedRequestFilter(metric, config);
        MockResponseHandler responseHandler = new MockResponseHandler();
        filter.filter(request("GET", "http://myserver:80/path-to-resource"), responseHandler);

        assertBlocked(responseHandler, metric, 404, "");
    }