<commit_before>/*
 * Copyright 2015 SirWellington Tech.
 *
 * 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 tech.sirwellington.alchemy.http;

import com.google.gson.Gson;
import java.util.concurrent.ExecutorService;
import org.apache.http.client.HttpClient;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import tech.sirwellington.alchemy.annotations.access.Internal;
import tech.sirwellington.alchemy.annotations.designs.StepMachineDesign;
import tech.sirwellington.alchemy.http.AlchemyRequest.OnFailure;
import tech.sirwellington.alchemy.http.AlchemyRequest.OnSuccess;
import tech.sirwellington.alchemy.http.exceptions.AlchemyHttpException;

import static java.lang.String.format;
import static tech.sirwellington.alchemy.annotations.designs.StepMachineDesign.Role.MACHINE;
import static tech.sirwellington.alchemy.arguments.Arguments.checkThat;
import static tech.sirwellington.alchemy.arguments.assertions.Assertions.notNull;
import static tech.sirwellington.alchemy.http.HttpAssertions.okResponse;
import static tech.sirwellington.alchemy.http.HttpAssertions.requestReady;
import static tech.sirwellington.alchemy.http.HttpAssertions.validResponseClass;

/**
 *
 * @author SirWellington
 */
@Internal
@StepMachineDesign(role = MACHINE)
final class AlchemyMachineImpl implements AlchemyHttpStateMachine
{

    private final static Logger LOG = LoggerFactory.getLogger(AlchemyMachineImpl.class);

    private final HttpClient apacheHttpClient;
    private final ExecutorService async;
    private final Gson gson;

    AlchemyMachineImpl(HttpClient apacheHttpClient, ExecutorService async, Gson gson)
    {
        checkThat(apacheHttpClient, async, gson)
                .are(notNull());

        this.apacheHttpClient = apacheHttpClient;
        this.async = async;
        this.gson = gson;
    }

    @Override
    public AlchemyRequest.Step1 begin(HttpRequest initialRequest) throws IllegalArgumentException
    {
        checkThat(initialRequest).is(notNull());

        HttpRequest requestCopy = HttpRequest.copyOf(initialRequest);
        LOG.debug("Beginning HTTP request {}", requestCopy);
        return new Step1Impl(this, requestCopy);
    }

    @Override
    public AlchemyRequest.Step2 jumpToStep2(HttpRequest request) throws IllegalArgumentException
    {
        checkThat(request).is(notNull());

        HttpRequest requestCopy = HttpRequest.copyOf(request);
        return new Step2Impl(requestCopy, this, gson);
    }

    @Override
    public AlchemyRequest.Step3 jumpToStep3(HttpRequest request) throws IllegalArgumentException
    {
        checkThat(request).is(notNull());

        HttpRequest requestCopy = HttpRequest.copyOf(request);
        return new Step3Impl(this, requestCopy);
    }

    @Override
    public <ResponseType> AlchemyRequest.Step4<ResponseType> jumpToStep4(HttpRequest request,
                                                                         Class<ResponseType> classOfResponseType) throws IllegalArgumentException
    {
        checkThat(classOfResponseType).is(validResponseClass());

        HttpRequest requestCopy = HttpRequest.copyOf(request);
        return new Step4Impl<>(this, requestCopy, classOfResponseType);
    }

    @Override
    public <ResponseType> AlchemyRequest.Step5<ResponseType> jumpToStep5(HttpRequest request,
                                                                         Class<ResponseType> classOfResponseType,
                                                                         OnSuccess<ResponseType> successCallback) throws IllegalArgumentException
    {
        checkThat(classOfResponseType).is(validResponseClass());

        checkThat(request, successCallback)
                .are(notNull());

        HttpRequest requestCopy = HttpRequest.copyOf(request);
        return new Step5Impl<>(this, requestCopy, classOfResponseType, successCallback);
    }

    @Override
    public <ResponseType> AlchemyRequest.Step6<ResponseType> jumpToStep6(HttpRequest request,
                                                                         Class<ResponseType> classOfResponseType,
                                                                         OnSuccess<ResponseType> successCallback,
                                                                         OnFailure failureCallback)
    {
        checkThat(classOfResponseType).is(validResponseClass());

        checkThat(request, successCallback, failureCallback)
                .are(notNull());

        HttpRequest requestCopy = HttpRequest.copyOf(request);
        return new Step6Impl<>(this, requestCopy, classOfResponseType, successCallback, failureCallback);
    }

    @Override
    public <ResponseType> ResponseType executeSync(HttpRequest request, Class<ResponseType> classOfResponseType)
    {
        LOG.debug("Executing synchronous HTTP Request {}", request);

        checkThat(classOfResponseType).is(validResponseClass());

        checkThat(request)
                .is(notNull())
                .is(requestReady());

        HttpVerb verb = request.getVerb();

        HttpResponse response;
        try
        {
            response = verb.execute(apacheHttpClient, request);
        }
        catch (AlchemyHttpException ex)
        {
            LOG.info("Encountered AlchemyHttpException when running verb {} on request {}", verb, request, ex);
            throw ex;
        }
        catch (Exception ex)
        {
            LOG.error("Failed to execute verb {} on request {}", verb, request, ex);
            throw new AlchemyHttpException(request, ex);
        }

        checkThat(response)
                .throwing(ex -> new AlchemyHttpException(request, "HTTP Verb returned null response"))
                .is(notNull());

        checkThat(response)
                .throwing(ex -> new AlchemyHttpException(request,
                                                        response,
                                                        format("Http Response not OK. Status Code: %s Body: %s", 
                                                               response.statusCode(),
                                                               response.bodyAsString())))
                .is(okResponse());<commit_msg>Updates error message<commit_after>/*
 * Copyright 2015 SirWellington Tech.
 *
 * 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 tech.sirwellington.alchemy.http;

import com.google.gson.Gson;
import java.util.concurrent.ExecutorService;
import org.apache.http.client.HttpClient;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import tech.sirwellington.alchemy.annotations.access.Internal;
import tech.sirwellington.alchemy.annotations.designs.StepMachineDesign;
import tech.sirwellington.alchemy.http.AlchemyRequest.OnFailure;
import tech.sirwellington.alchemy.http.AlchemyRequest.OnSuccess;
import tech.sirwellington.alchemy.http.exceptions.AlchemyHttpException;

import static java.lang.String.format;
import static tech.sirwellington.alchemy.annotations.designs.StepMachineDesign.Role.MACHINE;
import static tech.sirwellington.alchemy.arguments.Arguments.checkThat;
import static tech.sirwellington.alchemy.arguments.assertions.Assertions.notNull;
import static tech.sirwellington.alchemy.http.HttpAssertions.okResponse;
import static tech.sirwellington.alchemy.http.HttpAssertions.requestReady;
import static tech.sirwellington.alchemy.http.HttpAssertions.validResponseClass;

/**
 *
 * @author SirWellington
 */
@Internal
@StepMachineDesign(role = MACHINE)
final class AlchemyMachineImpl implements AlchemyHttpStateMachine
{

    private final static Logger LOG = LoggerFactory.getLogger(AlchemyMachineImpl.class);

    private final HttpClient apacheHttpClient;
    private final ExecutorService async;
    private final Gson gson;

    AlchemyMachineImpl(HttpClient apacheHttpClient, ExecutorService async, Gson gson)
    {
        checkThat(apacheHttpClient, async, gson)
                .are(notNull());

        this.apacheHttpClient = apacheHttpClient;
        this.async = async;
        this.gson = gson;
    }

    @Override
    public AlchemyRequest.Step1 begin(HttpRequest initialRequest) throws IllegalArgumentException
    {
        checkThat(initialRequest).is(notNull());

        HttpRequest requestCopy = HttpRequest.copyOf(initialRequest);
        LOG.debug("Beginning HTTP request {}", requestCopy);
        return new Step1Impl(this, requestCopy);
    }

    @Override
    public AlchemyRequest.Step2 jumpToStep2(HttpRequest request) throws IllegalArgumentException
    {
        checkThat(request).is(notNull());

        HttpRequest requestCopy = HttpRequest.copyOf(request);
        return new Step2Impl(requestCopy, this, gson);
    }

    @Override
    public AlchemyRequest.Step3 jumpToStep3(HttpRequest request) throws IllegalArgumentException
    {
        checkThat(request).is(notNull());

        HttpRequest requestCopy = HttpRequest.copyOf(request);
        return new Step3Impl(this, requestCopy);
    }

    @Override
    public <ResponseType> AlchemyRequest.Step4<ResponseType> jumpToStep4(HttpRequest request,
                                                                         Class<ResponseType> classOfResponseType) throws IllegalArgumentException
    {
        checkThat(classOfResponseType).is(validResponseClass());

        HttpRequest requestCopy = HttpRequest.copyOf(request);
        return new Step4Impl<>(this, requestCopy, classOfResponseType);
    }

    @Override
    public <ResponseType> AlchemyRequest.Step5<ResponseType> jumpToStep5(HttpRequest request,
                                                                         Class<ResponseType> classOfResponseType,
                                                                         OnSuccess<ResponseType> successCallback) throws IllegalArgumentException
    {
        checkThat(classOfResponseType).is(validResponseClass());

        checkThat(request, successCallback)
                .are(notNull());

        HttpRequest requestCopy = HttpRequest.copyOf(request);
        return new Step5Impl<>(this, requestCopy, classOfResponseType, successCallback);
    }

    @Override
    public <ResponseType> AlchemyRequest.Step6<ResponseType> jumpToStep6(HttpRequest request,
                                                                         Class<ResponseType> classOfResponseType,
                                                                         OnSuccess<ResponseType> successCallback,
                                                                         OnFailure failureCallback)
    {
        checkThat(classOfResponseType).is(validResponseClass());

        checkThat(request, successCallback, failureCallback)
                .are(notNull());

        HttpRequest requestCopy = HttpRequest.copyOf(request);
        return new Step6Impl<>(this, requestCopy, classOfResponseType, successCallback, failureCallback);
    }

    @Override
    public <ResponseType> ResponseType executeSync(HttpRequest request, Class<ResponseType> classOfResponseType)
    {
        LOG.debug("Executing synchronous HTTP Request {}", request);

        checkThat(classOfResponseType).is(validResponseClass());

        checkThat(request)
                .is(notNull())
                .is(requestReady());

        HttpVerb verb = request.getVerb();

        HttpResponse response;
        try
        {
            response = verb.execute(apacheHttpClient, request);
        }
        catch (AlchemyHttpException ex)
        {
            LOG.info("Encountered AlchemyHttpException when running verb {} on request {}", verb, request, ex);
            throw ex;
        }
        catch (Exception ex)
        {
            LOG.error("Failed to execute verb {} on request {}", verb, request, ex);
            throw new AlchemyHttpException(request, ex);
        }

        checkThat(response)
                .throwing(ex -> new AlchemyHttpException(request, "HTTP Verb returned null response"))
                .is(notNull());

        checkThat(response)
                .throwing(ex -> new AlchemyHttpException(request,
                                                        response,
                                                        format("Http Response not OK. Status Code: %d Body: %s", 
                                                               response.statusCode(),
                                                               response.bodyAsString())))
                .is(okResponse());
{'fraction_non_alphanumeric': 0.07985803016858918, 'fraction_numerical': 0.003992901508429458, 'mean_word_length': 2.4318700837350926, 'pattern_counts': {'":': 0, '<': 35, '<?xml version=': 0, '>': 39, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 52, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2893675', 'n_tokens_mistral': 3334, 'n_tokens_neox': 3171, 'n_words': 751}