<commit_before>/**
 * Copyright (C) 2015 The Gravitee team (http://gravitee.io)
 *
 * Licensed 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
 *
 *         http://www.apache.org/licenses/LICENSE-2.0
 *
 * 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 io.gravitee.gateway.core.reactor.handler.impl;

import io.gravitee.common.http.GraviteeHttpHeader;
import io.gravitee.gateway.api.Request;
import io.gravitee.gateway.api.Response;
import io.gravitee.gateway.api.handler.Handler;
import io.gravitee.gateway.core.definition.Api;
import io.gravitee.gateway.core.http.client.HttpClient;
import io.gravitee.gateway.core.policy.Policy;
import io.gravitee.gateway.core.policy.impl.AbstractPolicyChain;
import io.gravitee.gateway.core.reactor.handler.ContextReactorHandler;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;

import java.util.List;

/**
 * @author <NAME> (brasseld at <EMAIL>)
 */
public class ApiReactorHandler extends ContextReactorHandler {

    private final Logger logger = LoggerFactory.getLogger(ApiReactorHandler.class);

    @Autowired
    private Api api;

    @Autowired
    private HttpClient httpClient;

    @Override
    public void handle(Request request, Response response, Handler<Response> handler) {
        request.headers().set(GraviteeHttpHeader.X_GRAVITEE_API_NAME, api.getName());

        // 1_ Calculate policies
        List<Policy> policies = getPolicyResolver().resolve(request);

        // 2_ Apply request policies
        AbstractPolicyChain requestPolicyChain = getRequestPolicyChainBuilder().newPolicyChain(policies);
        requestPolicyChain.setResultHandler(requestPolicyResult -> {
            if (requestPolicyResult.isFailure()) {
                response.status(requestPolicyResult.httpStatusCode());
                handler.handle(response);
            } else {
                // 3_ Call remote service
                httpClient.invoke(request, response, result -> {
                    // 4_ Apply response policies

                    // FIXME: we are never go here because policy does not implement @OnResponse
                    // and so do not apply doNext in policy chain
                    /*
                    AbstractPolicyChain responsePolicyChain = ApiReactorHandler.this.getResponsePolicyChainBuilder().newPolicyChain(policies);
                    responsePolicyChain.setResultHandler(responsePolicyResult -> {
                        if (responsePolicyResult.isFailure()) {
                            ((HttpServerResponse) response).setStatus(requestPolicyResult.httpStatusCode());
                            handler.handle(response);
                            reporterService.report(request, response);
                        } else {

                            // 5_ Transfer the proxy response to the initial consumer
                            handler.handle(response);
                            reporterService.report(request, response);
                        }
                    });

                    responsePolicyChain.doNext(request, response);
                    */

                    // 5_ Transfer the proxy response to the initial consumer
                    handler.handle(response);
                });
            }
        });

        requestPolicyChain.doNext(request, response);
    }

    @Override
    public String getContextPath() {
        return api.getProxy().getContextPath();
    }

    @Override
    public String getVirtualHost() {
        return api.getProxy().getTarget().getAuthority();
    }

    @Override
    protected void doStart() throws Exception {
        super.doStart();
        httpClient.start();
    }

    @Override
    protected void doStop() throws Exception {
        super.doStop();
        httpClient.stop();
    }

    @Override
    public String toString() {
        final StringBuilder sb = new StringBuilder("ApiReactorHandler{");
        sb.append("contextPath=").append(api.getProxy().getContextPath());
        sb.append('}');
        return sb.toString();
    }
}
<commit_msg>fix: When an error occurs in request policy chain, set end flag for response<commit_after>/**
 * Copyright (C) 2015 The Gravitee team (http://gravitee.io)
 *
 * Licensed 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
 *
 *         http://www.apache.org/licenses/LICENSE-2.0
 *
 * 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 io.gravitee.gateway.core.reactor.handler.impl;

import io.gravitee.common.http.GraviteeHttpHeader;
import io.gravitee.common.http.HttpHeaders;
import io.gravitee.common.http.HttpHeadersValues;
import io.gravitee.gateway.api.Request;
import io.gravitee.gateway.api.Response;
import io.gravitee.gateway.api.handler.Handler;
import io.gravitee.gateway.core.definition.Api;
import io.gravitee.gateway.core.http.client.HttpClient;
import io.gravitee.gateway.core.policy.Policy;
import io.gravitee.gateway.core.policy.impl.AbstractPolicyChain;
import io.gravitee.gateway.core.reactor.handler.ContextReactorHandler;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;

import java.util.List;

/**
 * @author <NAME> (brasseld at gmail.com)
 */
public class ApiReactorHandler extends ContextReactorHandler {

    private final Logger logger = LoggerFactory.getLogger(ApiReactorHandler.class);

    @Autowired
    private Api api;

    @Autowired
    private HttpClient httpClient;

    @Override
    public void handle(Request request, Response response, Handler<Response> handler) {
        request.headers().set(GraviteeHttpHeader.X_GRAVITEE_API_NAME, api.getName());

        // 1_ Calculate policies
        List<Policy> policies = getPolicyResolver().resolve(request);

        // 2_ Apply request policies
        AbstractPolicyChain requestPolicyChain = getRequestPolicyChainBuilder().newPolicyChain(policies);
        requestPolicyChain.setResultHandler(requestPolicyResult -> {
            if (requestPolicyResult.isFailure()) {
                response.status(requestPolicyResult.httpStatusCode());
                response.headers().set(HttpHeaders.CONNECTION, HttpHeadersValues.CONNECTION_CLOSE);
                response.end();
                handler.handle(response);
            } else {
                // 3_ Call remote service
                httpClient.invoke(request, response, result -> {
                    // 4_ Apply response policies

                    // FIXME: we are never go here because policy does not implement @OnResponse
                    // and so do not apply doNext in policy chain
                    /*
                    AbstractPolicyChain responsePolicyChain = ApiReactorHandler.this.getResponsePolicyChainBuilder().newPolicyChain(policies);
                    responsePolicyChain.setResultHandler(responsePolicyResult -> {
                        if (responsePolicyResult.isFailure()) {
                            ((HttpServerResponse) response).setStatus(requestPolicyResult.httpStatusCode());
                            handler.handle(response);
                            reporterService.report(request, response);
                        } else {

                            // 5_ Transfer the proxy response to the initial consumer
                            handler.handle(response);
                            reporterService.report(request, response);
                        }
                    });

                    responsePolicyChain.doNext(request, response);
                    */

                    // 5_ Transfer the proxy response to the initial consumer
                    handler.handle(response);
                });
            }
        });

        requestPolicyChain.doNext(request, response);
    }

    @Override
    public String getContextPath() {
        return api.getProxy().getContextPath();
    }

    @Override
    public String getVirtualHost() {
        return api.getProxy().getTarget().getAuthority();
    }

    @Override
    protected void doStart() throws Exception {
        super.doStart();
        httpClient.start();
    }

    @Override
    protected void doStop() throws Exception {
        super.doStop();
        httpClient.stop();
    }

    @Override
    public String toString() {
        final StringBuilder sb = new StringBuilder("ApiReactorHandler{");
        sb.append("contextPath=").append(api.getProxy().getContextPath());
        sb.append('}');
        return sb.toString();
    }
}

{'fraction_non_alphanumeric': 0.09124126813541107, 'fraction_numerical': 0.0034390112842557765, 'mean_word_length': 2.385230993088396, 'pattern_counts': {'":': 0, '<': 10, '<?xml version=': 0, '>': 16, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3756846', 'n_tokens_mistral': 2350, 'n_tokens_neox': 2283, 'n_words': 576}