Viewing File: /usr/local/cpanel/whostmgr/docroot/cgi/ncssl/source/src/Service/NcGatewayApi/Caller.php

<?php

namespace App\Service\NcGatewayApi;

use App\Service\NcGatewayApi\Exceptions\NcGatewayApiException;
use App\Traits\RequestBodyCreatorTrait;
use GuzzleHttp\Client;
use GuzzleHttp\Exception\GuzzleException;
use GuzzleHttp\Psr7\Request;
use GuzzleHttp\Psr7\Response;
use Psr\Http\Message\ResponseInterface;

abstract class Caller
{
    use RequestBodyCreatorTrait;
    public const PROTOCOL_VERSION = '1.0.0';
    public const GATEWAY_DELAY = 3;
    public const GATEWAY_RETRY_LIMIT = 3;
    public const ERR_MSG_RETRY_LIMIT = 'Gateway API error: retry limit (%s) reached';

    public function __construct(
        private readonly string $apiUrl,
        private readonly string $gatewayAccessToken,
        private readonly  Client $client
    ) {
    }

    /**
     * Call Gateway API and return parsed response
     *
     * @param string $method API method
     * @param array $parameters API parameters
     *
     * @return array
     *
     * @throws NcGatewayApiException
     * @throws \JsonException
     */
    protected function call(string $method, array $parameters = []): array
    {
        $body = json_encode($this->createRequest($method, $parameters), JSON_THROW_ON_ERROR);

        $headers = ['Content-Type' => 'application/json'];

        $request = new Request('POST', $this->apiUrl, $headers, $body);

        $response = $this->callWithRetry($request);

        $data = $this->parseResponse($response);

        $this->checkApiError($data);

        return $data['result'];
    }

    /**
     * @param $request
     * @return mixed|ResponseInterface
     * @throws NcGatewayApiException
     */
    protected function callWithRetry($request): mixed
    {
        $retryCounter = 0;
        do {
            try {
                return $this->client->send($request);
            } catch (GuzzleException $e) {
                if ($retryCounter++ === self::GATEWAY_RETRY_LIMIT) {
                    $message = sprintf(self::ERR_MSG_RETRY_LIMIT, self::GATEWAY_RETRY_LIMIT);
                    throw new NcGatewayApiException($message);
                }

                sleep(self::GATEWAY_DELAY);
            }

        } while (true);
    }

    /**
     * Parse API response
     *
     * @param Response $response
     *
     * @return array API result
     *
     * @throws NcGatewayApiException|\JsonException
     */
    private function parseResponse(Response $response): array
    {
        if ($response->getStatusCode() !== 200) {
            throw new NcGatewayApiException('Wrong response status code');
        }

        $content = $response->getBody()->getContents();
        $data = json_decode($content, true, 512, JSON_THROW_ON_ERROR);

        if (!is_array($data)) {
            throw new NcGatewayApiException('Wrong response format');
        }

        if (empty($data['version'])) {
            throw new NcGatewayApiException('Protocol version missing');
        }

        if (empty($data['meta']['timestamp'])) {
            throw new NcGatewayApiException('Protocol timestamp missing');
        }

        if (empty($data['meta']['server'])) {
            throw new NcGatewayApiException('Protocol server missing');
        }

        if (!array_key_exists('result', $data)
            && !array_key_exists('error', $data)
        ) {
            throw new NcGatewayApiException('Response without any result or error');
        }

        if (array_key_exists('error', $data)) {
            if (!isset($data['error']['code'])) {
                throw new NcGatewayApiException('Error code missing');
            }

            if (!isset($data['error']['message'])) {
                throw new NcGatewayApiException('Error message missing');
            }
        }

        return $data;
    }

    /**
     * @return string[]
     */
    private function getRequestAuthParameter(): array
    {
        return ['accessToken' => $this->gatewayAccessToken];
    }

    /**
     * @param array $data
     * @return void
     * @throws NcGatewayApiException
     */
    private function checkApiError(array $data): void
    {
        if (!isset($data['error'])) {
            return;
        }

        $error = $data['error'];
        throw new NcGatewayApiException($error['message'], $error['code']);
    }
}

Back to Directory File Manager