All Downloads are FREE. Search and download functionalities are using the official Maven repository.

jp.gopay.sdk.builders.RetrofitRequestCaller Maven / Gradle / Ivy

package jp.gopay.sdk.builders;

import jp.gopay.sdk.models.errors.GoPayErrorBody;
import jp.gopay.sdk.models.errors.GoPayException;
import jp.gopay.sdk.models.errors.TooManyRequestsException;
import jp.gopay.sdk.models.response.GoPayResponse;
import jp.gopay.sdk.types.IdempotencyStatus;
import jp.gopay.sdk.utils.GoPayCallback;
import jp.gopay.sdk.utils.Sleeper;
import okhttp3.MediaType;
import okhttp3.ResponseBody;
import retrofit2.*;

import java.io.IOException;
import java.lang.annotation.Annotation;

import static jp.gopay.sdk.constants.GopayConstants.idempotencyStatusHeaderName;

public class RetrofitRequestCaller implements Request {

    private final Call apiCall;
    private final Converter errorConverter;

    public RetrofitRequestCaller(Retrofit retrofit, Call apiCall) {
        this.errorConverter = retrofit.responseBodyConverter(GoPayErrorBody.class, new Annotation[0]);
        this.apiCall = apiCall;
    }

    public RetrofitRequestCaller(Converter errorConverter, Call apiCall) {
        this.errorConverter = errorConverter;
        this.apiCall = apiCall;
    }

    @Override
    public void dispatch(final GoPayCallback callback) {

        apiCall.enqueue(new Callback() {
            @Override
            public void onResponse(Call call, Response response) {

                E model;
                try {
                    model = extractModel(response);
                } catch (Throwable e) {
                    callback.getFailure(e);
                    return;
                }

                callback.getResponse(model);
            }

            @Override
            public void onFailure(Call call, Throwable t) {
                callback.getFailure(t);
            }
        });
    }

    @Override
    public E dispatch() throws IOException, GoPayException, TooManyRequestsException {
        try {
            return dispatch(1, null);
        } catch (InterruptedException e) {
            throw new AssertionError("Thread never sleep when maxRetry is 1");
        }
    }

    @Override
    public E dispatch(int maxRetry, Sleeper sleeper) throws IOException, GoPayException, TooManyRequestsException, InterruptedException {


        Exception lastException = null;
        Call call = apiCall;

        for (int retry = 0; retry < maxRetry; retry++) {
            try {
                return extractModel(call.execute());
            } catch (IOException | TooManyRequestsException e) {
                lastException = e;
                if (retry + 1 < maxRetry) {
                    sleeper.sleep();
                    call = call.clone();
                }
            }
        }

        assert lastException != null;
        if (lastException instanceof IOException) {
            throw (IOException)lastException;
        } else {
            throw (TooManyRequestsException)lastException;
        }
    }

    private E extractModel(Response response) throws GoPayException, IOException, TooManyRequestsException {
        if (response.isSuccessful()) {
            E model = response.body();
            String unparsedIdempotencyStatus = response.headers().get(idempotencyStatusHeaderName);

            if (model != null) {
                if (unparsedIdempotencyStatus == null) {
                    model.setIdempotencyStatus(IdempotencyStatus.NO_STATUS);
                } else {
                    model.setIdempotencyStatus(IdempotencyStatus.valueOf(unparsedIdempotencyStatus.toUpperCase()));
                }
            }
            return model;
        } else if (response.code() == 429 /* Too Many Requests */) {
            throw new TooManyRequestsException(response.code(), response.message());
        } else {
            GoPayErrorBody body = null;
            ResponseBody errorBody = response.errorBody();
            MediaType contentType = errorBody.contentType();

            if (contentType != null && contentType.subtype().equals("json") && errorBody.contentLength() > 0) {
                body = this.errorConverter.convert(errorBody);
            }
            throw new GoPayException(response.code(), response.message(), body);
        }
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy