First commit

This commit is contained in:
2025-10-02 10:33:06 +08:00
parent 198b8bf2a6
commit c38eed4a22
5512 changed files with 958855 additions and 0 deletions

View File

@@ -0,0 +1,53 @@
<?php
namespace AlibabaCloud\Client;
/**
* Class Accept
*
* @package AlibabaCloud\Client
*/
class Accept
{
/**
* @var string
*/
private $format;
/**
* Accept constructor.
*
* @param string $format
*/
private function __construct($format)
{
$this->format = $format;
}
/**
* @param $format
*
* @return Accept
*/
public static function create($format)
{
return new static($format);
}
/**
* @return mixed|string
*/
public function toString()
{
$key = \strtoupper($this->format);
$list = [
'JSON' => 'application/json',
'XML' => 'application/xml',
'RAW' => 'application/octet-stream',
'FORM' => 'application/x-www-form-urlencoded'
];
return isset($list[$key]) ? $list[$key] : $list['RAW'];
}
}

View File

@@ -0,0 +1,63 @@
<?php
namespace AlibabaCloud\Client;
use AlibabaCloud\Client\Traits\LogTrait;
use AlibabaCloud\Client\Traits\MockTrait;
use AlibabaCloud\Client\Traits\ClientTrait;
use AlibabaCloud\Client\Traits\HistoryTrait;
use AlibabaCloud\Client\Traits\RequestTrait;
use AlibabaCloud\Client\Traits\EndpointTrait;
use AlibabaCloud\Client\Traits\DefaultRegionTrait;
use AlibabaCloud\Client\Exception\ClientException;
/**
* Class AlibabaCloud
*
* @package AlibabaCloud\Client
* @mixin \AlibabaCloud\IdeHelper
*/
class AlibabaCloud
{
use ClientTrait;
use DefaultRegionTrait;
use EndpointTrait;
use RequestTrait;
use MockTrait;
use HistoryTrait;
use LogTrait;
/**
* Version of the Client
*/
const VERSION = '1.5.16';
/**
* This static method can directly call the specific service.
*
* @param string $product
* @param array $arguments
*
* @codeCoverageIgnore
* @return object
* @throws ClientException
*/
public static function __callStatic($product, $arguments)
{
$product = \ucfirst($product);
$product_class = 'AlibabaCloud' . '\\' . $product . '\\' . $product;
if (\class_exists($product_class)) {
return new $product_class;
}
throw new ClientException(
"May not yet support product $product quick access, "
. 'you can use [Alibaba Cloud Client for PHP] to send any custom '
. 'requests: https://github.com/aliyun/openapi-sdk-php-client/blob/master/docs/en/3-Request.md',
SDK::SERVICE_NOT_FOUND
);
}
}

View File

@@ -0,0 +1,30 @@
<?php
namespace AlibabaCloud\Client\Clients;
use AlibabaCloud\Client\Exception\ClientException;
use AlibabaCloud\Client\Signature\ShaHmac1Signature;
use AlibabaCloud\Client\Credentials\AccessKeyCredential;
/**
* Use the AccessKey to complete the authentication.
*
* @package AlibabaCloud\Client\Clients
*/
class AccessKeyClient extends Client
{
/**
* @param string $accessKeyId
* @param string $accessKeySecret
*
* @throws ClientException
*/
public function __construct($accessKeyId, $accessKeySecret)
{
parent::__construct(
new AccessKeyCredential($accessKeyId, $accessKeySecret),
new ShaHmac1Signature()
);
}
}

View File

@@ -0,0 +1,29 @@
<?php
namespace AlibabaCloud\Client\Clients;
use AlibabaCloud\Client\Exception\ClientException;
use AlibabaCloud\Client\Signature\BearerTokenSignature;
use AlibabaCloud\Client\Credentials\BearerTokenCredential;
/**
* Use the Bearer Token to complete the authentication.
*
* @package AlibabaCloud\Client\Clients
*/
class BearerTokenClient extends Client
{
/**
* @param string $bearerToken
*
* @throws ClientException
*/
public function __construct($bearerToken)
{
parent::__construct(
new BearerTokenCredential($bearerToken),
new BearerTokenSignature()
);
}
}

View File

@@ -0,0 +1,72 @@
<?php
namespace AlibabaCloud\Client\Clients;
use AlibabaCloud\Client\Request\Request;
use AlibabaCloud\Client\Traits\HttpTrait;
use AlibabaCloud\Client\Traits\RegionTrait;
use AlibabaCloud\Client\Credentials\StsCredential;
use AlibabaCloud\Client\Signature\ShaHmac1Signature;
use AlibabaCloud\Client\Signature\SignatureInterface;
use AlibabaCloud\Client\Signature\ShaHmac256Signature;
use AlibabaCloud\Client\Signature\BearerTokenSignature;
use AlibabaCloud\Client\Credentials\AccessKeyCredential;
use AlibabaCloud\Client\Credentials\CredentialsInterface;
use AlibabaCloud\Client\Credentials\EcsRamRoleCredential;
use AlibabaCloud\Client\Credentials\RamRoleArnCredential;
use AlibabaCloud\Client\Credentials\RsaKeyPairCredential;
use AlibabaCloud\Client\Credentials\BearerTokenCredential;
use AlibabaCloud\Client\Signature\ShaHmac256WithRsaSignature;
/**
* Custom Client.
*
* @package AlibabaCloud\Client\Clients
*/
class Client
{
use HttpTrait;
use RegionTrait;
use ManageTrait;
/**
* @var CredentialsInterface|AccessKeyCredential|BearerTokenCredential|StsCredential|EcsRamRoleCredential|RamRoleArnCredential|RsaKeyPairCredential
*/
private $credential;
/**
* @var SignatureInterface
*/
private $signature;
/**
* Self constructor.
*
* @param CredentialsInterface $credential
* @param SignatureInterface $signature
*/
public function __construct(CredentialsInterface $credential, SignatureInterface $signature)
{
$this->credential = $credential;
$this->signature = $signature;
$this->options['connect_timeout'] = Request::CONNECT_TIMEOUT;
$this->options['timeout'] = Request::TIMEOUT;
$this->options['verify'] = false;
}
/**
* @return AccessKeyCredential|BearerTokenCredential|CredentialsInterface|EcsRamRoleCredential|RamRoleArnCredential|RsaKeyPairCredential|StsCredential
*/
public function getCredential()
{
return $this->credential;
}
/**
* @return SignatureInterface|BearerTokenSignature|ShaHmac1Signature|ShaHmac256Signature|ShaHmac256WithRsaSignature
*/
public function getSignature()
{
return $this->signature;
}
}

View File

@@ -0,0 +1,26 @@
<?php
namespace AlibabaCloud\Client\Clients;
use AlibabaCloud\Client\Exception\ClientException;
use AlibabaCloud\Client\Signature\ShaHmac1Signature;
use AlibabaCloud\Client\Credentials\EcsRamRoleCredential;
/**
* Use the RAM role of an ECS instance to complete the authentication.
*/
class EcsRamRoleClient extends Client
{
/**
* @param string $roleName
*
* @throws ClientException
*/
public function __construct($roleName)
{
parent::__construct(
new EcsRamRoleCredential($roleName),
new ShaHmac1Signature()
);
}
}

View File

@@ -0,0 +1,98 @@
<?php
namespace AlibabaCloud\Client\Clients;
use AlibabaCloud\Client\AlibabaCloud;
use AlibabaCloud\Client\Filter\Filter;
use AlibabaCloud\Client\Request\Request;
use AlibabaCloud\Client\Credentials\StsCredential;
use AlibabaCloud\Client\Exception\ClientException;
use AlibabaCloud\Client\Exception\ServerException;
use AlibabaCloud\Client\Credentials\CredentialsInterface;
use AlibabaCloud\Client\Credentials\EcsRamRoleCredential;
use AlibabaCloud\Client\Credentials\RamRoleArnCredential;
use AlibabaCloud\Client\Credentials\RsaKeyPairCredential;
use AlibabaCloud\Client\Credentials\Providers\EcsRamRoleProvider;
use AlibabaCloud\Client\Credentials\Providers\RamRoleArnProvider;
use AlibabaCloud\Client\Credentials\Providers\RsaKeyPairProvider;
use AlibabaCloud\Client\Credentials\Providers\CredentialsProvider;
/**
* Trait ManageTrait.
*
* @mixin Client
*/
trait ManageTrait
{
/**
* @param int $timeout
* @param int $connectTimeout
*
* @return CredentialsInterface|StsCredential
*
* @throws ClientException
* @throws ServerException
*/
public function getSessionCredential($timeout = Request::TIMEOUT, $connectTimeout = Request::CONNECT_TIMEOUT)
{
switch (\get_class($this->credential)) {
case EcsRamRoleCredential::class:
return (new EcsRamRoleProvider($this))->get();
case RamRoleArnCredential::class:
return (new RamRoleArnProvider($this))->get($timeout, $connectTimeout);
case RsaKeyPairCredential::class:
return (new RsaKeyPairProvider($this))->get($timeout, $connectTimeout);
default:
return $this->credential;
}
}
/**
* @return static
* @throws ClientException
* @deprecated
* @codeCoverageIgnore
*/
public function asGlobalClient()
{
return $this->asDefaultClient();
}
/**
* Set the current client as the default client.
*
* @return static
* @throws ClientException
*/
public function asDefaultClient()
{
return $this->name(CredentialsProvider::getDefaultName());
}
/**
* Naming clients.
*
* @param string $name
*
* @return static
* @throws ClientException
*/
public function name($name)
{
Filter::name($name);
return AlibabaCloud::set($name, $this);
}
/**
* @return bool
*/
public function isDebug()
{
if (isset($this->options['debug'])) {
return $this->options['debug'] === true && PHP_SAPI === 'cli';
}
return false;
}
}

View File

@@ -0,0 +1,33 @@
<?php
namespace AlibabaCloud\Client\Clients;
use AlibabaCloud\Client\Exception\ClientException;
use AlibabaCloud\Client\Signature\ShaHmac1Signature;
use AlibabaCloud\Client\Credentials\RamRoleArnCredential;
/**
* Use the AssumeRole of the RAM account to complete the authentication.
*
* @package AlibabaCloud\Client\Clients
*/
class RamRoleArnClient extends Client
{
/**
* @param string $accessKeyId
* @param string $accessKeySecret
* @param string $roleArn
* @param string $roleSessionName
* @param string|array $policy
*
* @throws ClientException
*/
public function __construct($accessKeyId, $accessKeySecret, $roleArn, $roleSessionName, $policy = '')
{
parent::__construct(
new RamRoleArnCredential($accessKeyId, $accessKeySecret, $roleArn, $roleSessionName, $policy),
new ShaHmac1Signature()
);
}
}

View File

@@ -0,0 +1,30 @@
<?php
namespace AlibabaCloud\Client\Clients;
use AlibabaCloud\Client\Exception\ClientException;
use AlibabaCloud\Client\Signature\ShaHmac1Signature;
use AlibabaCloud\Client\Credentials\RsaKeyPairCredential;
/**
* Use the RSA key pair to complete the authentication (supported only on Japanese site)
*
* @package AlibabaCloud\Client\Clients
*/
class RsaKeyPairClient extends Client
{
/**
* @param string $publicKeyId
* @param string $privateKeyFile
*
* @throws ClientException
*/
public function __construct($publicKeyId, $privateKeyFile)
{
parent::__construct(
new RsaKeyPairCredential($publicKeyId, $privateKeyFile),
new ShaHmac1Signature()
);
}
}

View File

@@ -0,0 +1,28 @@
<?php
namespace AlibabaCloud\Client\Clients;
use AlibabaCloud\Client\Credentials\StsCredential;
use AlibabaCloud\Client\Exception\ClientException;
use AlibabaCloud\Client\Signature\ShaHmac1Signature;
/**
* Use the STS Token to complete the authentication.
*/
class StsClient extends Client
{
/**
* @param string $accessKeyId Access key ID
* @param string $accessKeySecret Access Key Secret
* @param string $securityToken Security Token
*
* @throws ClientException
*/
public function __construct($accessKeyId, $accessKeySecret, $securityToken = '')
{
parent::__construct(
new StsCredential($accessKeyId, $accessKeySecret, $securityToken),
new ShaHmac1Signature()
);
}
}

View File

@@ -0,0 +1,62 @@
<?php
namespace AlibabaCloud\Client\Config;
use Exception;
use clagiordano\weblibs\configmanager\ConfigManager;
/**
* Class Config
*
* @package AlibabaCloud\Client\Config
*/
class Config
{
/**
* @var ConfigManager|null
*/
private static $configManager;
/**
* @param string $configPath
*
* @param string|null $defaultValue
*
* @return mixed
*/
public static function get($configPath, $defaultValue = null)
{
return self::getConfigManager()
->getValue(
\strtolower($configPath),
$defaultValue
);
}
/**
* @return ConfigManager
*/
private static function getConfigManager()
{
if (!self::$configManager instanceof ConfigManager) {
self::$configManager = new ConfigManager(__DIR__ . DIRECTORY_SEPARATOR . 'Data.php');
}
return self::$configManager;
}
/**
* @param string $configPath
* @param mixed $newValue
*
* @return ConfigManager
* @throws Exception
*/
public static function set($configPath, $newValue)
{
self::getConfigManager()->setValue(\strtolower($configPath), $newValue);
return self::getConfigManager()->saveConfigFile();
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,65 @@
<?php
namespace AlibabaCloud\Client\Credentials;
use AlibabaCloud\Client\Filter\CredentialFilter;
use AlibabaCloud\Client\Exception\ClientException;
/**
* Use the AccessKey to complete the authentication.
*
* @package AlibabaCloud\Client\Credentials
*/
class AccessKeyCredential implements CredentialsInterface
{
/**
* @var string
*/
private $accessKeyId;
/**
* @var string
*/
private $accessKeySecret;
/**
* AccessKeyCredential constructor.
*
* @param string $accessKeyId Access key ID
* @param string $accessKeySecret Access Key Secret
*
* @throws ClientException
*/
public function __construct($accessKeyId, $accessKeySecret)
{
CredentialFilter::AccessKey($accessKeyId, $accessKeySecret);
$this->accessKeyId = $accessKeyId;
$this->accessKeySecret = $accessKeySecret;
}
/**
* @return string
*/
public function getAccessKeyId()
{
return $this->accessKeyId;
}
/**
* @return string
*/
public function getAccessKeySecret()
{
return $this->accessKeySecret;
}
/**
* @return string
*/
public function __toString()
{
return "$this->accessKeyId#$this->accessKeySecret";
}
}

View File

@@ -0,0 +1,66 @@
<?php
namespace AlibabaCloud\Client\Credentials;
use AlibabaCloud\Client\Filter\CredentialFilter;
use AlibabaCloud\Client\Exception\ClientException;
/**
* Class BearerTokenCredential
*
* @package AlibabaCloud\Client\Credentials
*/
class BearerTokenCredential implements CredentialsInterface
{
/**
* @var string
*/
private $bearerToken;
/**
* Class constructor.
*
* @param string $bearerToken
*
* @throws ClientException
*/
public function __construct($bearerToken)
{
CredentialFilter::bearerToken($bearerToken);
$this->bearerToken = $bearerToken;
}
/**
* @return string
*/
public function getBearerToken()
{
return $this->bearerToken;
}
/**
* @return string
*/
public function getAccessKeyId()
{
return '';
}
/**
* @return string
*/
public function getAccessKeySecret()
{
return '';
}
/**
* @return string
*/
public function __toString()
{
return "bearerToken#$this->bearerToken";
}
}

View File

@@ -0,0 +1,18 @@
<?php
namespace AlibabaCloud\Client\Credentials;
/**
* interface CredentialsInterface
*
* @package AlibabaCloud\Client\Credentials
*
* @codeCoverageIgnore
*/
interface CredentialsInterface
{
/**
* @return string
*/
public function __toString();
}

View File

@@ -0,0 +1,50 @@
<?php
namespace AlibabaCloud\Client\Credentials;
use AlibabaCloud\Client\Filter\CredentialFilter;
use AlibabaCloud\Client\Exception\ClientException;
/**
* Use the RAM role of an ECS instance to complete the authentication.
*
* @package AlibabaCloud\Client\Credentials
*/
class EcsRamRoleCredential implements CredentialsInterface
{
/**
* @var string
*/
private $roleName;
/**
* Class constructor.
*
* @param string $roleName
*
* @throws ClientException
*/
public function __construct($roleName)
{
CredentialFilter::roleName($roleName);
$this->roleName = $roleName;
}
/**
* @return string
*/
public function getRoleName()
{
return $this->roleName;
}
/**
* @return string
*/
public function __toString()
{
return "roleName#$this->roleName";
}
}

View File

@@ -0,0 +1,181 @@
<?php
namespace AlibabaCloud\Client\Credentials\Ini;
use AlibabaCloud\Client\SDK;
use AlibabaCloud\Client\Clients\Client;
use AlibabaCloud\Client\Clients\AccessKeyClient;
use AlibabaCloud\Client\Clients\RamRoleArnClient;
use AlibabaCloud\Client\Clients\RsaKeyPairClient;
use AlibabaCloud\Client\Clients\EcsRamRoleClient;
use AlibabaCloud\Client\Exception\ClientException;
use AlibabaCloud\Client\Clients\BearerTokenClient;
/**
* Trait CreateTrait
*
* @package AlibabaCloud\Client\Credentials\Ini
*
* @mixin IniCredential
*/
trait CreateTrait
{
/**
* @param string $clientName
* @param array $credential
*
* @return Client|bool
* @throws ClientException
*/
protected function createClient($clientName, array $credential)
{
if (!isset($credential['enable']) || !$credential['enable']) {
return false;
}
if (!isset($credential['type'])) {
$this->missingRequired('type', $clientName);
}
return $this->createClientByType($clientName, $credential)->name($clientName);
}
/**
* @param string $clientName
* @param array $credential
*
* @return AccessKeyClient|BearerTokenClient|EcsRamRoleClient|RamRoleArnClient|RsaKeyPairClient
* @throws ClientException
*/
private function createClientByType($clientName, array $credential)
{
switch (\strtolower($credential['type'])) {
case 'access_key':
return $this->accessKeyClient($clientName, $credential);
case 'ecs_ram_role':
return $this->ecsRamRoleClient($clientName, $credential);
case 'ram_role_arn':
return $this->ramRoleArnClient($clientName, $credential);
case 'bearer_token':
return $this->bearerTokenClient($clientName, $credential);
case 'rsa_key_pair':
return $this->rsaKeyPairClient($clientName, $credential);
default:
throw new ClientException(
"Invalid type '{$credential['type']}' for '$clientName' in {$this->filename}",
SDK::INVALID_CREDENTIAL
);
}
}
/**
* @param array $credential
* @param string $clientName
*
* @return AccessKeyClient
* @throws ClientException
*/
private function accessKeyClient($clientName, array $credential)
{
if (!isset($credential['access_key_id'])) {
$this->missingRequired('access_key_id', $clientName);
}
if (!isset($credential['access_key_secret'])) {
$this->missingRequired('access_key_secret', $clientName);
}
return new AccessKeyClient(
$credential['access_key_id'],
$credential['access_key_secret']
);
}
/**
* @param string $clientName
* @param array $credential
*
* @return EcsRamRoleClient
* @throws ClientException
*/
private function ecsRamRoleClient($clientName, array $credential)
{
if (!isset($credential['role_name'])) {
$this->missingRequired('role_name', $clientName);
}
return new EcsRamRoleClient($credential['role_name']);
}
/**
* @param string $clientName
* @param array $credential
*
* @return RamRoleArnClient
* @throws ClientException
*/
private function ramRoleArnClient($clientName, array $credential)
{
if (!isset($credential['access_key_id'])) {
$this->missingRequired('access_key_id', $clientName);
}
if (!isset($credential['access_key_secret'])) {
$this->missingRequired('access_key_secret', $clientName);
}
if (!isset($credential['role_arn'])) {
$this->missingRequired('role_arn', $clientName);
}
if (!isset($credential['role_session_name'])) {
$this->missingRequired('role_session_name', $clientName);
}
return new RamRoleArnClient(
$credential['access_key_id'],
$credential['access_key_secret'],
$credential['role_arn'],
$credential['role_session_name']
);
}
/**
* @param string $clientName
* @param array $credential
*
* @return BearerTokenClient
* @throws ClientException
*/
private function bearerTokenClient($clientName, array $credential)
{
if (!isset($credential['bearer_token'])) {
$this->missingRequired('bearer_token', $clientName);
}
return new BearerTokenClient($credential['bearer_token']);
}
/**
* @param array $credential
* @param string $clientName
*
* @return RsaKeyPairClient
* @throws ClientException
*/
private function rsaKeyPairClient($clientName, array $credential)
{
if (!isset($credential['public_key_id'])) {
$this->missingRequired('public_key_id', $clientName);
}
if (!isset($credential['private_key_file'])) {
$this->missingRequired('private_key_file', $clientName);
}
return new RsaKeyPairClient(
$credential['public_key_id'],
$credential['private_key_file']
);
}
}

View File

@@ -0,0 +1,209 @@
<?php
namespace AlibabaCloud\Client\Credentials\Ini;
use AlibabaCloud\Client\SDK;
use AlibabaCloud\Client\Clients\Client;
use AlibabaCloud\Client\Exception\ClientException;
/**
* Class IniCredential
*
* @package AlibabaCloud\Client\Credentials\Ini
*/
class IniCredential
{
use CreateTrait;
use OptionsTrait;
/**
* @var array
*/
private static $hasLoaded;
/**
* @var string
*/
protected $filename;
/**
* IniCredential constructor.
*
* @param string $filename
*/
public function __construct($filename = '')
{
$this->filename = $filename ?: $this->getDefaultFile();
}
/**
* Get the default credential file.
*
* @return string
*/
public function getDefaultFile()
{
return self::getHomeDirectory() . DIRECTORY_SEPARATOR . '.alibabacloud' . DIRECTORY_SEPARATOR . 'credentials';
}
/**
* Gets the environment's HOME directory.
*
* @return null|string
*/
private static function getHomeDirectory()
{
if (getenv('HOME')) {
return getenv('HOME');
}
return (getenv('HOMEDRIVE') && getenv('HOMEPATH'))
? getenv('HOMEDRIVE') . getenv('HOMEPATH')
: null;
}
/**
* Clear credential cache.
*
* @return void
*/
public static function forgetLoadedCredentialsFile()
{
self::$hasLoaded = [];
}
/**
* Get the credential file.
*
* @return string
*/
public function getFilename()
{
return $this->filename;
}
/**
* @param array $array
* @param string $key
*
* @return bool
*/
protected static function isNotEmpty(array $array, $key)
{
return isset($array[$key]) && !empty($array[$key]);
}
/**
* @param string $key
* @param string $clientName
*
* @throws ClientException
*/
public function missingRequired($key, $clientName)
{
throw new ClientException(
"Missing required '$key' option for '$clientName' in " . $this->getFilename(),
SDK::INVALID_CREDENTIAL
);
}
/**
* @return array|mixed
* @throws ClientException
*/
public function load()
{
// If it has been loaded, assign the client directly.
if (isset(self::$hasLoaded[$this->filename])) {
/**
* @var $client Client
*/
foreach (self::$hasLoaded[$this->filename] as $projectName => $client) {
$client->name($projectName);
}
return self::$hasLoaded[$this->filename];
}
return $this->loadFile();
}
/**
* Exceptions will be thrown if the file is unreadable and not the default file.
*
* @return array|mixed
* @throws ClientException
*/
private function loadFile()
{
if (!\AlibabaCloud\Client\inOpenBasedir($this->filename)) {
return [];
}
if (!\is_readable($this->filename) || !\is_file($this->filename)) {
if ($this->filename === $this->getDefaultFile()) {
// @codeCoverageIgnoreStart
return [];
// @codeCoverageIgnoreEnd
}
throw new ClientException(
'Credential file is not readable: ' . $this->getFilename(),
SDK::INVALID_CREDENTIAL
);
}
return $this->parseFile();
}
/**
* Decode the ini file into an array.
*
* @return array|mixed
* @throws ClientException
*/
private function parseFile()
{
try {
$file = \parse_ini_file($this->filename, true);
if (\is_array($file) && $file !== []) {
return $this->initClients($file);
}
throw new ClientException(
'Format error: ' . $this->getFilename(),
SDK::INVALID_CREDENTIAL
);
} catch (\Exception $e) {
throw new ClientException(
$e->getMessage(),
SDK::INVALID_CREDENTIAL,
$e
);
}
}
/**
* Initialize clients.
*
* @param array $array
*
* @return array|mixed
* @throws ClientException
*/
private function initClients($array)
{
foreach (\array_change_key_case($array) as $clientName => $configures) {
$configures = \array_change_key_case($configures);
$clientInstance = $this->createClient($clientName, $configures);
if ($clientInstance instanceof Client) {
self::$hasLoaded[$this->filename][$clientName] = $clientInstance;
self::setClientAttributes($configures, $clientInstance);
self::setCert($configures, $clientInstance);
self::setProxy($configures, $clientInstance);
}
}
return isset(self::$hasLoaded[$this->filename])
? self::$hasLoaded[$this->filename]
: [];
}
}

View File

@@ -0,0 +1,111 @@
<?php
namespace AlibabaCloud\Client\Credentials\Ini;
use AlibabaCloud\Client\Clients\Client;
use AlibabaCloud\Client\Exception\ClientException;
/**
* Trait OptionsTrait
*
* @package AlibabaCloud\Client\Credentials\Ini
*
* @mixin IniCredential
*/
trait OptionsTrait
{
/**
* @param array $configures
* @param Client $client
*
* @throws ClientException
*/
private static function setClientAttributes($configures, Client $client)
{
if (self::isNotEmpty($configures, 'region_id')) {
$client->regionId($configures['region_id']);
}
if (isset($configures['debug'])) {
$client->options(
[
'debug' => (bool)$configures['debug'],
]
);
}
if (self::isNotEmpty($configures, 'timeout')) {
$client->options(
[
'timeout' => $configures['timeout'],
]
);
}
if (self::isNotEmpty($configures, 'connect_timeout')) {
$client->options(
[
'connect_timeout' => $configures['connect_timeout'],
]
);
}
}
/**
* @param array $configures
* @param Client $client
*/
private static function setProxy($configures, Client $client)
{
if (self::isNotEmpty($configures, 'proxy')) {
$client->options(
[
'proxy' => $configures['proxy'],
]
);
}
$proxy = [];
if (self::isNotEmpty($configures, 'proxy_http')) {
$proxy['http'] = $configures['proxy_http'];
}
if (self::isNotEmpty($configures, 'proxy_https')) {
$proxy['https'] = $configures['proxy_https'];
}
if (self::isNotEmpty($configures, 'proxy_no')) {
$proxy['no'] = \explode(',', $configures['proxy_no']);
}
if ($proxy !== []) {
$client->options(
[
'proxy' => $proxy,
]
);
}
}
/**
* @param array $configures
* @param Client $client
*/
private static function setCert($configures, Client $client)
{
if (self::isNotEmpty($configures, 'cert_file') && !self::isNotEmpty($configures, 'cert_password')) {
$client->options(
[
'cert' => $configures['cert_file'],
]
);
}
if (self::isNotEmpty($configures, 'cert_file') && self::isNotEmpty($configures, 'cert_password')) {
$client->options(
[
'cert' => [
$configures['cert_file'],
$configures['cert_password'],
],
]
);
}
}
}

View File

@@ -0,0 +1,170 @@
<?php
namespace AlibabaCloud\Client\Credentials\Providers;
use Closure;
use AlibabaCloud\Client\SDK;
use AlibabaCloud\Client\AlibabaCloud;
use AlibabaCloud\Client\Exception\ClientException;
/**
* Class CredentialsProvider
*
* @package AlibabaCloud\Client\Credentials\Providers
*/
class CredentialsProvider
{
/**
* @var array
*/
private static $customChains;
/**
* @throws ClientException
*/
public static function chain()
{
$providers = func_get_args();
if (empty($providers)) {
throw new ClientException('No providers in chain', SDK::INVALID_ARGUMENT);
}
foreach ($providers as $provider) {
if (!$provider instanceof Closure) {
throw new ClientException('Providers must all be Closures', SDK::INVALID_ARGUMENT);
}
}
self::$customChains = $providers;
}
/**
* Forget the custom providers chain.
*/
public static function flush()
{
self::$customChains = [];
}
/**
* @return bool
*/
public static function hasCustomChain()
{
return (bool)self::$customChains;
}
/**
* @param string $clientName
*
* @throws ClientException
*/
public static function customProvider($clientName)
{
foreach (self::$customChains as $provider) {
$provider();
if (AlibabaCloud::has($clientName)) {
break;
}
}
}
/**
* @param string $clientName
*
* @throws ClientException
*/
public static function defaultProvider($clientName)
{
$providers = [
self::env(),
self::ini(),
self::instance(),
];
foreach ($providers as $provider) {
$provider();
if (AlibabaCloud::has($clientName)) {
break;
}
}
}
/**
* @return Closure
*/
public static function env()
{
return static function () {
$accessKeyId = \AlibabaCloud\Client\envNotEmpty('ALIBABA_CLOUD_ACCESS_KEY_ID');
$accessKeySecret = \AlibabaCloud\Client\envNotEmpty('ALIBABA_CLOUD_ACCESS_KEY_SECRET');
if ($accessKeyId && $accessKeySecret) {
AlibabaCloud::accessKeyClient($accessKeyId, $accessKeySecret)->asDefaultClient();
}
};
}
/**
* @return Closure
*/
public static function ini()
{
return static function () {
$ini = \AlibabaCloud\Client\envNotEmpty('ALIBABA_CLOUD_CREDENTIALS_FILE');
if ($ini) {
AlibabaCloud::load($ini);
} else {
// @codeCoverageIgnoreStart
AlibabaCloud::load();
// @codeCoverageIgnoreEnd
}
self::compatibleWithGlobal();
};
}
/**
* @codeCoverageIgnore
*
* Compatible with global
*
* @throws ClientException
*/
private static function compatibleWithGlobal()
{
if (AlibabaCloud::has('global') && !AlibabaCloud::has(self::getDefaultName())) {
AlibabaCloud::get('global')->name(self::getDefaultName());
}
}
/**
* @return array|false|string
* @throws ClientException
*/
public static function getDefaultName()
{
$name = \AlibabaCloud\Client\envNotEmpty('ALIBABA_CLOUD_PROFILE');
if ($name) {
return $name;
}
return 'default';
}
/**
* @return Closure
*/
public static function instance()
{
return static function () {
$instance = \AlibabaCloud\Client\envNotEmpty('ALIBABA_CLOUD_ECS_METADATA');
if ($instance) {
AlibabaCloud::ecsRamRoleClient($instance)->asDefaultClient();
}
};
}
}

View File

@@ -0,0 +1,128 @@
<?php
namespace AlibabaCloud\Client\Credentials\Providers;
use Exception;
use Stringy\Stringy;
use AlibabaCloud\Client\SDK;
use AlibabaCloud\Client\Result\Result;
use Psr\Http\Message\ResponseInterface;
use GuzzleHttp\Exception\GuzzleException;
use AlibabaCloud\Client\Request\RpcRequest;
use AlibabaCloud\Client\Credentials\StsCredential;
use AlibabaCloud\Client\Exception\ClientException;
use AlibabaCloud\Client\Exception\ServerException;
use AlibabaCloud\Client\Credentials\EcsRamRoleCredential;
/**
* Class EcsRamRoleProvider
*
* @package AlibabaCloud\Client\Credentials\Providers
*/
class EcsRamRoleProvider extends Provider
{
/**
* Expiration time slot for temporary security credentials.
*
* @var int
*/
protected $expirationSlot = 10;
/**
* @var string
*/
private $uri = 'http://100.100.100.200/latest/meta-data/ram/security-credentials/';
/**
* Get credential.
*
* @return StsCredential
* @throws ClientException
* @throws ServerException
*/
public function get()
{
$result = $this->getCredentialsInCache();
if ($result === null) {
$result = $this->request();
if (!isset($result['AccessKeyId'], $result['AccessKeySecret'], $result['SecurityToken'])) {
throw new ServerException($result, $this->error, SDK::INVALID_CREDENTIAL);
}
$this->cache($result->toArray());
}
return new StsCredential(
$result['AccessKeyId'],
$result['AccessKeySecret'],
$result['SecurityToken']
);
}
/**
* Get credentials by request.
*
* @return Result
* @throws ClientException
* @throws ServerException
*/
public function request()
{
$result = $this->getResponse();
if ($result->getStatusCode() === 404) {
$message = 'The role was not found in the instance';
throw new ClientException($message, SDK::INVALID_CREDENTIAL);
}
if (!$result->isSuccess()) {
$message = 'Error retrieving credentials from result';
throw new ServerException($result, $message, SDK::INVALID_CREDENTIAL);
}
return $result;
}
/**
* Get data from meta.
*
* @return mixed|ResponseInterface
* @throws ClientException
* @throws Exception
*/
public function getResponse()
{
/**
* @var EcsRamRoleCredential $credential
*/
$credential = $this->client->getCredential();
$url = $this->uri . $credential->getRoleName();
$options = [
'http_errors' => false,
'timeout' => 1,
'connect_timeout' => 1,
'debug' => $this->client->isDebug(),
];
try {
return RpcRequest::createClient()->request('GET', $url, $options);
} catch (GuzzleException $exception) {
if (Stringy::create($exception->getMessage())->contains('timed')) {
$message = 'Timeout or instance does not belong to Alibaba Cloud';
} else {
$message = $exception->getMessage();
}
throw new ClientException(
$message,
SDK::SERVER_UNREACHABLE,
$exception
);
}
}
}

View File

@@ -0,0 +1,88 @@
<?php
namespace AlibabaCloud\Client\Credentials\Providers;
use AlibabaCloud\Client\Clients\Client;
/**
* Class Provider
*
* @package AlibabaCloud\Client\Credentials\Providers
*/
class Provider
{
/**
* For TSC Duration Seconds
*/
const DURATION_SECONDS = 3600;
/**
* @var array
*/
protected static $credentialsCache = [];
/**
* Expiration time slot for temporary security credentials.
*
* @var int
*/
protected $expirationSlot = 180;
/**
* @var Client
*/
protected $client;
/**
* @var string
*/
protected $error = 'Result contains no credentials';
/**
* CredentialTrait constructor.
*
* @param Client $client
*/
public function __construct(Client $client)
{
$this->client = $client;
}
/**
* Get the credentials from the cache in the validity period.
*
* @return array|null
*/
public function getCredentialsInCache()
{
if (isset(self::$credentialsCache[$this->key()])) {
$result = self::$credentialsCache[$this->key()];
if (\strtotime($result['Expiration']) - \time() >= $this->expirationSlot) {
return $result;
}
unset(self::$credentialsCache[$this->key()]);
}
return null;
}
/**
* Get the toString of the credentials as the key.
*
* @return string
*/
protected function key()
{
return (string)$this->client->getCredential();
}
/**
* Cache credentials.
*
* @param array $credential
*/
protected function cache(array $credential)
{
self::$credentialsCache[$this->key()] = $credential;
}
}

View File

@@ -0,0 +1,84 @@
<?php
namespace AlibabaCloud\Client\Credentials\Providers;
use AlibabaCloud\Client\SDK;
use AlibabaCloud\Client\AlibabaCloud;
use AlibabaCloud\Client\Result\Result;
use AlibabaCloud\Client\Request\Request;
use AlibabaCloud\Client\Credentials\StsCredential;
use AlibabaCloud\Client\Exception\ClientException;
use AlibabaCloud\Client\Exception\ServerException;
use AlibabaCloud\Client\Credentials\Requests\AssumeRole;
/**
* Class RamRoleArnProvider
*
* @package AlibabaCloud\Client\Credentials\Providers
*/
class RamRoleArnProvider extends Provider
{
/**
* Get credential.
*
*
* @param int $timeout
* @param int $connectTimeout
*
* @return StsCredential
* @throws ClientException
* @throws ServerException
*/
public function get($timeout = Request::TIMEOUT, $connectTimeout = Request::CONNECT_TIMEOUT)
{
$credential = $this->getCredentialsInCache();
if (null === $credential) {
$result = $this->request($timeout, $connectTimeout);
if (!isset($result['Credentials']['AccessKeyId'],
$result['Credentials']['AccessKeySecret'],
$result['Credentials']['SecurityToken'])) {
throw new ServerException($result, $this->error, SDK::INVALID_CREDENTIAL);
}
$credential = $result['Credentials'];
$this->cache($credential);
}
return new StsCredential(
$credential['AccessKeyId'],
$credential['AccessKeySecret'],
$credential['SecurityToken']
);
}
/**
* Get credentials by request.
*
* @param $timeout
* @param $connectTimeout
*
* @return Result
* @throws ClientException
* @throws ServerException
*/
private function request($timeout, $connectTimeout)
{
$clientName = __CLASS__ . \uniqid('ak', true);
$credential = $this->client->getCredential();
AlibabaCloud::accessKeyClient(
$credential->getAccessKeyId(),
$credential->getAccessKeySecret()
)->name($clientName);
return (new AssumeRole($credential))
->client($clientName)
->timeout($timeout)
->connectTimeout($connectTimeout)
->debug($this->client->isDebug())
->request();
}
}

View File

@@ -0,0 +1,86 @@
<?php
namespace AlibabaCloud\Client\Credentials\Providers;
use AlibabaCloud\Client\SDK;
use AlibabaCloud\Client\AlibabaCloud;
use AlibabaCloud\Client\Result\Result;
use AlibabaCloud\Client\Request\Request;
use AlibabaCloud\Client\Credentials\StsCredential;
use AlibabaCloud\Client\Exception\ClientException;
use AlibabaCloud\Client\Exception\ServerException;
use AlibabaCloud\Client\Credentials\AccessKeyCredential;
use AlibabaCloud\Client\Signature\ShaHmac256WithRsaSignature;
use AlibabaCloud\Client\Credentials\Requests\GenerateSessionAccessKey;
/**
* Class RsaKeyPairProvider
*
* @package AlibabaCloud\Client\Credentials\Providers
*/
class RsaKeyPairProvider extends Provider
{
/**
* Get credential.
*
* @param int $timeout
* @param int $connectTimeout
*
* @return StsCredential
* @throws ClientException
* @throws ServerException
*/
public function get($timeout = Request::TIMEOUT, $connectTimeout = Request::CONNECT_TIMEOUT)
{
$credential = $this->getCredentialsInCache();
if ($credential === null) {
$result = $this->request($timeout, $connectTimeout);
if (!isset($result['SessionAccessKey']['SessionAccessKeyId'],
$result['SessionAccessKey']['SessionAccessKeySecret'])) {
throw new ServerException($result, $this->error, SDK::INVALID_CREDENTIAL);
}
$credential = $result['SessionAccessKey'];
$this->cache($credential);
}
return new StsCredential(
$credential['SessionAccessKeyId'],
$credential['SessionAccessKeySecret']
);
}
/**
* Get credentials by request.
*
* @param $timeout
* @param $connectTimeout
*
* @return Result
* @throws ClientException
* @throws ServerException
*/
private function request($timeout, $connectTimeout)
{
$clientName = __CLASS__ . \uniqid('rsa', true);
$credential = $this->client->getCredential();
AlibabaCloud::client(
new AccessKeyCredential(
$credential->getPublicKeyId(),
$credential->getPrivateKey()
),
new ShaHmac256WithRsaSignature()
)->name($clientName);
return (new GenerateSessionAccessKey($credential->getPublicKeyId()))
->client($clientName)
->timeout($timeout)
->connectTimeout($connectTimeout)
->debug($this->client->isDebug())
->request();
}
}

View File

@@ -0,0 +1,110 @@
<?php
namespace AlibabaCloud\Client\Credentials;
use AlibabaCloud\Client\Filter\CredentialFilter;
use AlibabaCloud\Client\Exception\ClientException;
/**
* Use the AssumeRole of the RAM account to complete the authentication.
*
* @package AlibabaCloud\Client\Credentials
*/
class RamRoleArnCredential implements CredentialsInterface
{
/**
* @var string
*/
private $accessKeyId;
/**
* @var string
*/
private $accessKeySecret;
/**
* @var string
*/
private $roleArn;
/**
* @var string
*/
private $roleSessionName;
/**
* @var string
*/
private $policy;
/**
* Class constructor.
*
* @param string $accessKeyId
* @param string $accessKeySecret
* @param string $roleArn
* @param string $roleSessionName
* @param string|array $policy
*
* @throws ClientException
*/
public function __construct($accessKeyId, $accessKeySecret, $roleArn, $roleSessionName, $policy = '')
{
CredentialFilter::AccessKey($accessKeyId, $accessKeySecret);
$this->accessKeyId = $accessKeyId;
$this->accessKeySecret = $accessKeySecret;
$this->roleArn = $roleArn;
$this->roleSessionName = $roleSessionName;
$this->policy = $policy;
}
/**
* @return string
*/
public function getAccessKeyId()
{
return $this->accessKeyId;
}
/**
* @return string
*/
public function getAccessKeySecret()
{
return $this->accessKeySecret;
}
/**
* @return string
*/
public function getRoleArn()
{
return $this->roleArn;
}
/**
* @return string
*/
public function getRoleSessionName()
{
return $this->roleSessionName;
}
/**
* @return string
*/
public function getPolicy()
{
return $this->policy;
}
/**
* @return string
*/
public function __toString()
{
return "$this->accessKeyId#$this->accessKeySecret#$this->roleArn#$this->roleSessionName";
}
}

View File

@@ -0,0 +1,47 @@
<?php
namespace AlibabaCloud\Client\Credentials\Requests;
use AlibabaCloud\Client\Request\RpcRequest;
use AlibabaCloud\Client\Exception\ClientException;
use AlibabaCloud\Client\Credentials\Providers\Provider;
use AlibabaCloud\Client\Credentials\RamRoleArnCredential;
/**
* Retrieving assume role credentials.
*
* @package AlibabaCloud\Client\Credentials\Requests
*/
class AssumeRole extends RpcRequest
{
/**
* AssumeRole constructor.
*
* @param RamRoleArnCredential $arnCredential
*
* @throws ClientException
*/
public function __construct(RamRoleArnCredential $arnCredential)
{
parent::__construct();
$this->product('Sts');
$this->version('2015-04-01');
$this->action('AssumeRole');
$this->host('sts.aliyuncs.com');
$this->scheme('https');
$this->regionId('cn-hangzhou');
$this->options['verify'] = false;
$this->options['query']['RoleArn'] = $arnCredential->getRoleArn();
$this->options['query']['RoleSessionName'] = $arnCredential->getRoleSessionName();
$this->options['query']['DurationSeconds'] = Provider::DURATION_SECONDS;
if ($arnCredential->getPolicy()) {
if (is_array($arnCredential->getPolicy())) {
$this->options['query']['Policy'] = json_encode($arnCredential->getPolicy());
}
if (is_string($arnCredential->getPolicy())) {
$this->options['query']['Policy'] = $arnCredential->getPolicy();
}
}
}
}

View File

@@ -0,0 +1,37 @@
<?php
namespace AlibabaCloud\Client\Credentials\Requests;
use AlibabaCloud\Client\Request\RpcRequest;
use AlibabaCloud\Client\Exception\ClientException;
use AlibabaCloud\Client\Credentials\Providers\Provider;
/**
* Use the RSA key pair to complete the authentication (supported only on Japanese site)
*
* @package AlibabaCloud\Client\Credentials\Requests
*/
class GenerateSessionAccessKey extends RpcRequest
{
/**
* GenerateSessionAccessKey constructor.
*
* @param string $publicKeyId
*
* @throws ClientException
*/
public function __construct($publicKeyId)
{
parent::__construct();
$this->product('Sts');
$this->version('2015-04-01');
$this->action('GenerateSessionAccessKey');
$this->host('sts.ap-northeast-1.aliyuncs.com');
$this->scheme('https');
$this->regionId('cn-hangzhou');
$this->options['verify'] = false;
$this->options['query']['PublicKeyId'] = $publicKeyId;
$this->options['query']['DurationSeconds'] = Provider::DURATION_SECONDS;
}
}

View File

@@ -0,0 +1,75 @@
<?php
namespace AlibabaCloud\Client\Credentials;
use Exception;
use AlibabaCloud\Client\SDK;
use AlibabaCloud\Client\Filter\CredentialFilter;
use AlibabaCloud\Client\Exception\ClientException;
/**
* Use the RSA key pair to complete the authentication (supported only on Japanese site)
*
* @package AlibabaCloud\Client\Credentials
*/
class RsaKeyPairCredential implements CredentialsInterface
{
/**
* @var string
*/
private $publicKeyId;
/**
* @var string
*/
private $privateKey;
/**
* RsaKeyPairCredential constructor.
*
* @param string $publicKeyId
* @param string $privateKeyFile
*
* @throws ClientException
*/
public function __construct($publicKeyId, $privateKeyFile)
{
CredentialFilter::publicKeyId($publicKeyId);
CredentialFilter::privateKeyFile($privateKeyFile);
$this->publicKeyId = $publicKeyId;
try {
$this->privateKey = file_get_contents($privateKeyFile);
} catch (Exception $exception) {
throw new ClientException(
$exception->getMessage(),
SDK::INVALID_CREDENTIAL
);
}
}
/**
* @return mixed
*/
public function getPrivateKey()
{
return $this->privateKey;
}
/**
* @return string
*/
public function getPublicKeyId()
{
return $this->publicKeyId;
}
/**
* @return string
*/
public function __toString()
{
return "publicKeyId#$this->publicKeyId";
}
}

View File

@@ -0,0 +1,80 @@
<?php
namespace AlibabaCloud\Client\Credentials;
use AlibabaCloud\Client\Filter\CredentialFilter;
use AlibabaCloud\Client\Exception\ClientException;
/**
* Use the STS Token to complete the authentication.
*
* @package AlibabaCloud\Client\Credentials
*/
class StsCredential implements CredentialsInterface
{
/**
* @var string
*/
private $accessKeyId;
/**
* @var string
*/
private $accessKeySecret;
/**
* @var string
*/
private $securityToken;
/**
* StsCredential constructor.
*
* @param string $accessKeyId Access key ID
* @param string $accessKeySecret Access Key Secret
* @param string $securityToken Security Token
*
* @throws ClientException
*/
public function __construct($accessKeyId, $accessKeySecret, $securityToken = '')
{
CredentialFilter::AccessKey($accessKeyId, $accessKeySecret);
$this->accessKeyId = $accessKeyId;
$this->accessKeySecret = $accessKeySecret;
$this->securityToken = $securityToken;
}
/**
* @return string
*/
public function getAccessKeyId()
{
return $this->accessKeyId;
}
/**
* @return string
*/
public function getAccessKeySecret()
{
return $this->accessKeySecret;
}
/**
* @return string
*/
public function getSecurityToken()
{
return $this->securityToken;
}
/**
* @return string
*/
public function __toString()
{
return "$this->accessKeyId#$this->accessKeySecret#$this->securityToken";
}
}

View File

@@ -0,0 +1,55 @@
<?php
namespace AlibabaCloud\Client;
use AlibabaCloud\Client\Result\Result;
use AlibabaCloud\Client\Clients\Client;
use AlibabaCloud\Client\Request\Request;
use AlibabaCloud\Client\Exception\ClientException;
use AlibabaCloud\Client\Exception\ServerException;
/**
* Class DefaultAcsClient
*
* @package AlibabaCloud
*
* @deprecated deprecated since version 2.0, Use AlibabaCloud instead.
* @codeCoverageIgnore
*/
class DefaultAcsClient
{
/**
* @var string
*/
public $randClientName;
/**
* DefaultAcsClient constructor.
*
* @param Client $client
*
* @throws ClientException
*/
public function __construct(Client $client)
{
$this->randClientName = \uniqid('', true);
$client->name($this->randClientName);
}
/**
* @param Request|Result $request
*
* @return Result|string
* @throws ClientException
* @throws ServerException
*/
public function getAcsResponse($request)
{
if ($request instanceof Result) {
return $request;
}
return $request->client($this->randClientName)->request();
}
}

View File

@@ -0,0 +1,64 @@
<?php
namespace AlibabaCloud\Client;
/**
* Class Encode
*
* @package AlibabaCloud\Client
*/
class Encode
{
/**
* @var array
*/
private $data;
/**
* @param array $data
*
* @return static
*/
public static function create(array $data)
{
return new static($data);
}
/**
* Encode constructor.
*
* @param array $data
*/
private function __construct(array $data)
{
$this->data = $data;
}
/**
* @return bool|string
*/
public function toString()
{
$string = '';
foreach ($this->data as $key => $value) {
$encode = rawurlencode($value);
$string .= "$key=$encode&";
}
if (0 < count($this->data)) {
$string = substr($string, 0, -1);
}
return $string;
}
/**
* @return $this
*/
public function ksort()
{
ksort($this->data);
return $this;
}
}

View File

@@ -0,0 +1,70 @@
<?php
namespace AlibabaCloud\Client\Exception;
use Exception;
use RuntimeException;
/**
* Class AlibabaCloudException
*
* @package AlibabaCloud\Client\Exception
*/
abstract class AlibabaCloudException extends Exception
{
/**
* @var string
*/
protected $errorCode;
/**
* @var string
*/
protected $errorMessage;
/**
* @return string
*/
public function getErrorCode()
{
return $this->errorCode;
}
/**
* @codeCoverageIgnore
* @deprecated
*/
public function setErrorCode()
{
throw new RuntimeException('deprecated since 2.0.');
}
/**
* @return string
*/
public function getErrorMessage()
{
return $this->errorMessage;
}
/**
* @codeCoverageIgnore
*
* @param $errorMessage
*
* @deprecated
*/
public function setErrorMessage($errorMessage)
{
$this->errorMessage = $errorMessage;
}
/**
* @codeCoverageIgnore
* @deprecated
*/
public function setErrorType()
{
}
}

View File

@@ -0,0 +1,38 @@
<?php
namespace AlibabaCloud\Client\Exception;
use Exception;
use RuntimeException;
/**
* Class ClientException
*
* @package AlibabaCloud\Client\Exception
*/
class ClientException extends AlibabaCloudException
{
/**
* ClientException constructor.
*
* @param string $errorMessage
* @param string $errorCode
* @param Exception|null $previous
*/
public function __construct($errorMessage, $errorCode, $previous = null)
{
parent::__construct($errorMessage, 0, $previous);
$this->errorMessage = $errorMessage;
$this->errorCode = $errorCode;
}
/**
* @codeCoverageIgnore
* @deprecated
*/
public function getErrorType()
{
return 'Client';
}
}

View File

@@ -0,0 +1,158 @@
<?php
namespace AlibabaCloud\Client\Exception;
use Stringy\Stringy;
use RuntimeException;
use AlibabaCloud\Client\SDK;
use AlibabaCloud\Client\Result\Result;
/**
* Class ServerException
*
* @package AlibabaCloud\Client\Exception
*/
class ServerException extends AlibabaCloudException
{
/**
* @var string
*/
protected $requestId;
/**
* @var Result
*/
protected $result;
/**
* ServerException constructor.
*
* @param Result|null $result
* @param string $errorMessage
* @param string $errorCode
*/
public function __construct(
Result $result,
$errorMessage = SDK::RESPONSE_EMPTY,
$errorCode = SDK::SERVICE_UNKNOWN_ERROR
) {
$this->result = $result;
$this->errorMessage = $errorMessage;
$this->errorCode = $errorCode;
$this->resolvePropertiesByReturn();
$this->distinguishSignatureErrors();
$this->bodyAsErrorMessage();
parent::__construct(
$this->getMessageString(),
$this->result->getStatusCode()
);
}
/**
* Resolve the error message based on the return of the server.
*
* @return void
*/
private function resolvePropertiesByReturn()
{
if (isset($this->result['message'])) {
$this->errorMessage = $this->result['message'];
$this->errorCode = $this->result['code'];
}
if (isset($this->result['Message'])) {
$this->errorMessage = $this->result['Message'];
$this->errorCode = $this->result['Code'];
}
if (isset($this->result['errorMsg'])) {
$this->errorMessage = $this->result['errorMsg'];
$this->errorCode = $this->result['errorCode'];
}
if (isset($this->result['requestId'])) {
$this->requestId = $this->result['requestId'];
}
if (isset($this->result['RequestId'])) {
$this->requestId = $this->result['RequestId'];
}
}
/**
* If the string to be signed are the same with server's, it is considered a credential error.
*/
private function distinguishSignatureErrors()
{
if ($this->result->getRequest()
&& Stringy::create($this->errorMessage)->contains($this->result->getRequest()->stringToSign())) {
$this->errorCode = 'InvalidAccessKeySecret';
$this->errorMessage = 'Specified Access Key Secret is not valid.';
}
}
/**
* If the error message matches the default message and
* the server has returned content, use the return content
*/
private function bodyAsErrorMessage()
{
$body = (string)$this->result->getBody();
if ($this->errorMessage === SDK::RESPONSE_EMPTY && $body) {
$this->errorMessage = $body;
}
}
/**
* Get standard exception message.
*
* @return string
*/
private function getMessageString()
{
$message = "$this->errorCode: $this->errorMessage RequestId: $this->requestId";
if ($this->getResult()->getRequest()) {
$method = $this->getResult()->getRequest()->method;
$uri = (string)$this->getResult()->getRequest()->uri;
$message .= " $method \"$uri\"";
if ($this->result) {
$message .= ' ' . $this->result->getStatusCode();
}
}
return $message;
}
/**
* @return Result
*/
public function getResult()
{
return $this->result;
}
/**
* @return string
*/
public function getRequestId()
{
return $this->requestId;
}
/**
* @codeCoverageIgnore
* @deprecated
*/
public function getErrorType()
{
return 'Server';
}
/**
* @codeCoverageIgnore
* @deprecated
*/
public function getHttpStatus()
{
return $this->getResult()->getStatusCode();
}
}

View File

@@ -0,0 +1,245 @@
<?php
namespace AlibabaCloud\Client\Filter;
use AlibabaCloud\Client\SDK;
use AlibabaCloud\Client\Exception\ClientException;
/**
* Class ApiFilter
*
* @package AlibabaCloud\Client\Filter
*/
class ApiFilter
{
/**
* @param $serviceCode
*
* @return mixed
* @throws ClientException
*/
public static function serviceCode($serviceCode)
{
if (!is_string($serviceCode)) {
throw new ClientException(
'Service Code must be a string',
SDK::INVALID_ARGUMENT
);
}
if ($serviceCode === '') {
throw new ClientException(
'Service Code cannot be empty',
SDK::INVALID_ARGUMENT
);
}
return $serviceCode;
}
/**
* @param $endpointType
*
* @return mixed
* @throws ClientException
*/
public static function endpointType($endpointType)
{
if (!is_string($endpointType)) {
throw new ClientException(
'Endpoint Type must be a string',
SDK::INVALID_ARGUMENT
);
}
if ($endpointType === '') {
throw new ClientException(
'Endpoint Type cannot be empty',
SDK::INVALID_ARGUMENT
);
}
return $endpointType;
}
/**
* @param $action
*
* @return mixed
* @throws ClientException
*/
public static function action($action)
{
if (!is_string($action)) {
throw new ClientException(
'Action must be a string',
SDK::INVALID_ARGUMENT
);
}
if ($action === '') {
throw new ClientException(
'Action cannot be empty',
SDK::INVALID_ARGUMENT
);
}
return $action;
}
/**
* @codeCoverageIgnore
*
* @param string $endpointSuffix
*
* @return mixed
* @throws ClientException
*/
public static function endpointSuffix($endpointSuffix)
{
if (!is_string($endpointSuffix)) {
throw new ClientException(
'Endpoint Suffix must be a string',
SDK::INVALID_ARGUMENT
);
}
if ($endpointSuffix === '') {
throw new ClientException(
'Endpoint Suffix cannot be empty',
SDK::INVALID_ARGUMENT
);
}
return $endpointSuffix;
}
/**
* @codeCoverageIgnore
*
* @param string $network
*
* @return mixed
* @throws ClientException
*/
public static function network($network)
{
if (!is_string($network)) {
throw new ClientException(
'Network Suffix must be a string',
SDK::INVALID_ARGUMENT
);
}
if ($network === '') {
throw new ClientException(
'Network Suffix cannot be empty',
SDK::INVALID_ARGUMENT
);
}
return $network;
}
/**
* @param string $version
*
* @return mixed
* @throws ClientException
*/
public static function version($version)
{
if (!is_string($version)) {
throw new ClientException(
'Version must be a string',
SDK::INVALID_ARGUMENT
);
}
if ($version === '') {
throw new ClientException(
'Version cannot be empty',
SDK::INVALID_ARGUMENT
);
}
return $version;
}
/**
* @param $format
*
* @return mixed
* @throws ClientException
*/
public static function format($format)
{
if (!is_string($format)) {
throw new ClientException(
'Format must be a string',
SDK::INVALID_ARGUMENT
);
}
if ($format === '') {
throw new ClientException(
'Format cannot be empty',
SDK::INVALID_ARGUMENT
);
}
return \strtoupper($format);
}
/**
* @param $product
*
* @return string
*
* @throws ClientException
*/
public static function product($product)
{
if (!is_string($product)) {
throw new ClientException(
'Product must be a string',
SDK::INVALID_ARGUMENT
);
}
if ($product === '') {
throw new ClientException(
'Product cannot be empty',
SDK::INVALID_ARGUMENT
);
}
return $product;
}
/**
* @param $pattern
*
* @return string
*
* @throws ClientException
*/
public static function pattern($pattern)
{
if (!is_string($pattern)) {
throw new ClientException(
'Pattern must be a string',
SDK::INVALID_ARGUMENT
);
}
if ($pattern === '') {
throw new ClientException(
'Pattern cannot be empty',
SDK::INVALID_ARGUMENT
);
}
return $pattern;
}
}

View File

@@ -0,0 +1,139 @@
<?php
namespace AlibabaCloud\Client\Filter;
use AlibabaCloud\Client\SDK;
use AlibabaCloud\Client\Exception\ClientException;
/**
* Class ClientFilter
*
* @package AlibabaCloud\Client\Filter
*/
class ClientFilter
{
/**
* @param $regionId
*
* @return string
*
* @throws ClientException
*/
public static function regionId($regionId)
{
if (!is_string($regionId)) {
throw new ClientException(
'Region ID must be a string',
SDK::INVALID_ARGUMENT
);
}
if ($regionId === '') {
throw new ClientException(
'Region ID cannot be empty',
SDK::INVALID_ARGUMENT
);
}
return strtolower($regionId);
}
/**
* @param $clientName
*
* @return string
*
* @throws ClientException
*/
public static function clientName($clientName)
{
if (!is_string($clientName)) {
throw new ClientException(
'Client Name must be a string',
SDK::INVALID_ARGUMENT
);
}
if ($clientName === '') {
throw new ClientException(
'Client Name cannot be empty',
SDK::INVALID_ARGUMENT
);
}
return strtolower($clientName);
}
/**
* @param $times
*
* @return string
*
* @throws ClientException
*/
public static function retry($times)
{
if (!is_int($times)) {
throw new ClientException(
'Retry must be a int',
SDK::INVALID_ARGUMENT
);
}
return $times;
}
/**
* @param $connectTimeout
*
* @return mixed
* @throws ClientException
*/
public static function connectTimeout($connectTimeout)
{
if ($connectTimeout === '') {
throw new ClientException(
'Connect Timeout cannot be empty',
SDK::INVALID_ARGUMENT
);
}
return $connectTimeout;
}
/**
* @param $timeout
*
* @return mixed
* @throws ClientException
*/
public static function timeout($timeout)
{
if ($timeout === '') {
throw new ClientException(
'Timeout cannot be empty',
SDK::INVALID_ARGUMENT
);
}
return $timeout;
}
/**
* @param int $Milliseconds
*
* @return mixed
* @throws ClientException
*/
public static function milliseconds($Milliseconds)
{
if (!is_int($Milliseconds)) {
throw new ClientException(
'Milliseconds must be int',
SDK::INVALID_ARGUMENT
);
}
return $Milliseconds;
}
}

View File

@@ -0,0 +1,152 @@
<?php
namespace AlibabaCloud\Client\Filter;
use AlibabaCloud\Client\SDK;
use AlibabaCloud\Client\Exception\ClientException;
/**
* Class CredentialFilter
*
* @package AlibabaCloud\Client\Filter
*/
class CredentialFilter
{
/**
* @param $bearerToken
*
* @return mixed
* @throws ClientException
*/
public static function bearerToken($bearerToken)
{
if (!is_string($bearerToken)) {
throw new ClientException(
'Bearer Token must be a string',
SDK::INVALID_ARGUMENT
);
}
if ($bearerToken === '') {
throw new ClientException(
'Bearer Token cannot be empty',
SDK::INVALID_ARGUMENT
);
}
return $bearerToken;
}
/**
* @param $publicKeyId
*
* @return mixed
* @throws ClientException
*/
public static function publicKeyId($publicKeyId)
{
if (!is_string($publicKeyId)) {
throw new ClientException(
'Public Key ID must be a string',
SDK::INVALID_ARGUMENT
);
}
if ($publicKeyId === '') {
throw new ClientException(
'Public Key ID cannot be empty',
SDK::INVALID_ARGUMENT
);
}
return $publicKeyId;
}
/**
* @param $privateKeyFile
*
* @return mixed
* @throws ClientException
*/
public static function privateKeyFile($privateKeyFile)
{
if (!is_string($privateKeyFile)) {
throw new ClientException(
'Private Key File must be a string',
SDK::INVALID_ARGUMENT
);
}
if ($privateKeyFile === '') {
throw new ClientException(
'Private Key File cannot be empty',
SDK::INVALID_ARGUMENT
);
}
return $privateKeyFile;
}
/**
* @param $roleName
*
* @return string
*
* @throws ClientException
*/
public static function roleName($roleName)
{
if (!is_string($roleName)) {
throw new ClientException(
'Role Name must be a string',
SDK::INVALID_ARGUMENT
);
}
if ($roleName === '') {
throw new ClientException(
'Role Name cannot be empty',
SDK::INVALID_ARGUMENT
);
}
return $roleName;
}
/**
* @param string $accessKeyId
* @param string $accessKeySecret
*
* @throws ClientException
*/
public static function AccessKey($accessKeyId, $accessKeySecret)
{
if (!is_string($accessKeyId)) {
throw new ClientException(
'AccessKey ID must be a string',
SDK::INVALID_ARGUMENT
);
}
if ($accessKeyId === '') {
throw new ClientException(
'AccessKey ID cannot be empty',
SDK::INVALID_ARGUMENT
);
}
if (!is_string($accessKeySecret)) {
throw new ClientException(
'AccessKey Secret must be a string',
SDK::INVALID_ARGUMENT
);
}
if ($accessKeySecret === '') {
throw new ClientException(
'AccessKey Secret cannot be empty',
SDK::INVALID_ARGUMENT
);
}
}
}

View File

@@ -0,0 +1,67 @@
<?php
namespace AlibabaCloud\Client\Filter;
use AlibabaCloud\Client\SDK;
use AlibabaCloud\Client\Exception\ClientException;
/**
* Class Filter
*
* @package AlibabaCloud\Client\Filter
*/
class Filter
{
/**
* @param $name
*
* @return string
*
* @throws ClientException
*/
public static function name($name)
{
if (!is_string($name)) {
throw new ClientException(
'Name must be a string',
SDK::INVALID_ARGUMENT
);
}
if ($name === '') {
throw new ClientException(
'Name cannot be empty',
SDK::INVALID_ARGUMENT
);
}
return $name;
}
/**
* @param $value
*
* @return string
*
* @throws ClientException
*/
public static function value($value)
{
if (!is_numeric($value) && !is_string($value)) {
throw new ClientException(
'Value must be a string or int',
SDK::INVALID_ARGUMENT
);
}
if ($value === '') {
throw new ClientException(
'Value cannot be empty',
SDK::INVALID_ARGUMENT
);
}
return $value;
}
}

View File

@@ -0,0 +1,166 @@
<?php
namespace AlibabaCloud\Client\Filter;
use AlibabaCloud\Client\SDK;
use AlibabaCloud\Client\Exception\ClientException;
/**
* Class HttpFilter
*
* @package AlibabaCloud\Client\Filter
*/
class HttpFilter
{
/**
* @param $host
*
* @return string
*
* @throws ClientException
*/
public static function host($host)
{
if (!is_string($host)) {
throw new ClientException(
'Host must be a string',
SDK::INVALID_ARGUMENT
);
}
if ($host === '') {
throw new ClientException(
'Host cannot be empty',
SDK::INVALID_ARGUMENT
);
}
return $host;
}
/**
* @param $scheme
*
* @return string
*
* @throws ClientException
*/
public static function scheme($scheme)
{
if (!is_string($scheme)) {
throw new ClientException(
'Scheme must be a string',
SDK::INVALID_ARGUMENT
);
}
if ($scheme === '') {
throw new ClientException(
'Scheme cannot be empty',
SDK::INVALID_ARGUMENT
);
}
return $scheme;
}
/**
* @param $body
*
* @return mixed
* @throws ClientException
*/
public static function body($body)
{
if (!is_string($body) && !is_numeric($body)) {
throw new ClientException(
'Body must be a string or int',
SDK::INVALID_ARGUMENT
);
}
if ($body === '') {
throw new ClientException(
'Body cannot be empty',
SDK::INVALID_ARGUMENT
);
}
return $body;
}
/**
* @param $method
*
* @return mixed
* @throws ClientException
*/
public static function method($method)
{
if (!is_string($method)) {
throw new ClientException(
'Method must be a string',
SDK::INVALID_ARGUMENT
);
}
if ($method === '') {
throw new ClientException(
'Method cannot be empty',
SDK::INVALID_ARGUMENT
);
}
return \strtoupper($method);
}
/**
* @param $contentType
*
* @return mixed
* @throws ClientException
*/
public static function contentType($contentType)
{
if (!is_string($contentType)) {
throw new ClientException(
'Content-Type must be a string',
SDK::INVALID_ARGUMENT
);
}
if ($contentType === '') {
throw new ClientException(
'Content-Type cannot be empty',
SDK::INVALID_ARGUMENT
);
}
return $contentType;
}
/**
* @param $accept
*
* @return mixed
* @throws ClientException
*/
public static function accept($accept)
{
if (!is_string($accept)) {
throw new ClientException(
'Accept must be a string',
SDK::INVALID_ARGUMENT
);
}
if ($accept === '') {
throw new ClientException(
'Accept cannot be empty',
SDK::INVALID_ARGUMENT
);
}
return $accept;
}
}

View File

@@ -0,0 +1,289 @@
<?php
namespace AlibabaCloud\Client;
use Closure;
use Stringy\Stringy;
use League\CLImate\CLImate;
use AlibabaCloud\Client\Exception\ClientException;
/*
|--------------------------------------------------------------------------
| Global Functions for Alibaba Cloud
|--------------------------------------------------------------------------
|
| Some common global functions are defined here.
| This file will be automatically loaded.
|
*/
/**
* @param $filename
* @param bool $throwException
*
* @return bool
* @throws ClientException
*/
function inOpenBasedir($filename, $throwException = false)
{
$open_basedir = ini_get('open_basedir');
if (!$open_basedir) {
return true;
}
$dirs = explode(PATH_SEPARATOR, $open_basedir);
if (empty($dirs)) {
return true;
}
if (inDir($filename, $dirs)) {
return true;
}
if ($throwException === false) {
return false;
}
throw new ClientException(
'open_basedir restriction in effect. '
. "File($filename) is not within the allowed path(s): ($open_basedir)",
'SDK.InvalidPath'
);
}
/**
* @param string $filename
* @param array $dirs
*
* @return bool
*/
function inDir($filename, array $dirs)
{
foreach ($dirs as $dir) {
if (!Stringy::create($dir)->endsWith(DIRECTORY_SEPARATOR)) {
$dir .= DIRECTORY_SEPARATOR;
}
if (0 === strpos($filename, $dir)) {
return true;
}
}
return false;
}
/**
* @return bool
*/
function isWindows()
{
return PATH_SEPARATOR === ';';
}
/**
* @return CLImate
*/
function cliMate()
{
return new CLImate();
}
/**
* @param string $string
* @param string|null $flank
* @param string|null $char
* @param int|null $length
*
* @return void
*/
function backgroundRed($string, $flank = null, $char = null, $length = null)
{
cliMate()->br();
if ($flank !== null) {
cliMate()->backgroundRed()->flank($flank, $char, $length);
cliMate()->br();
}
cliMate()->backgroundRed($string);
cliMate()->br();
}
/**
* @param string $string
* @param string|null $flank
* @param string|null $char
* @param int|null $length
*
* @return void
*/
function backgroundGreen($string, $flank = null, $char = null, $length = null)
{
cliMate()->br();
if ($flank !== null) {
cliMate()->backgroundGreen()->flank($flank, $char, $length);
}
cliMate()->backgroundGreen($string);
cliMate()->br();
}
/**
* @param string $string
* @param string|null $flank
* @param string|null $char
* @param int|null $length
*
* @return void
*/
function backgroundBlue($string, $flank = null, $char = null, $length = null)
{
cliMate()->br();
if ($flank !== null) {
cliMate()->backgroundBlue()->flank($flank, $char, $length);
}
cliMate()->backgroundBlue($string);
cliMate()->br();
}
/**
* @param string $string
* @param string|null $flank
* @param string|null $char
* @param int|null $length
*
* @return void
*/
function backgroundMagenta($string, $flank = null, $char = null, $length = null)
{
cliMate()->br();
if ($flank !== null) {
cliMate()->backgroundMagenta()->flank($flank, $char, $length);
}
cliMate()->backgroundMagenta($string);
cliMate()->br();
}
/**
* @param array $array
*/
function json(array $array)
{
cliMate()->br();
cliMate()->backgroundGreen()->json($array);
cliMate()->br();
}
/**
* @param array $array
*
* @return void
*/
function redTable($array)
{
/**
* @noinspection PhpUndefinedMethodInspection
*/
cliMate()->redTable($array);
}
/**
* @param mixed $result
* @param string $title
*
* @return void
*/
function block($result, $title)
{
cliMate()->backgroundGreen()->flank($title, '--', 20);
dump($result);
}
/**
* Gets the value of an environment variable.
*
* @param string $key
* @param mixed $default
*
* @return mixed
*/
function env($key, $default = null)
{
$value = getenv($key);
if ($value === false) {
return value($default);
}
if (envSubstr($value)) {
return substr($value, 1, -1);
}
return envConversion($value);
}
/**
* @param $value
*
* @return bool|string|null
*/
function envConversion($value)
{
$key = strtolower($value);
if ($key === 'null' || $key === '(null)') {
return null;
}
$list = [
'true' => true,
'(true)' => true,
'false' => false,
'(false)' => false,
'empty' => '',
'(empty)' => '',
];
return isset($list[$key]) ? $list[$key] : $value;
}
/**
* @param $key
*
* @return bool|mixed
* @throws ClientException
*/
function envNotEmpty($key)
{
$value = env($key, false);
if ($value !== false && !$value) {
throw new ClientException(
"Environment variable '$key' cannot be empty",
SDK::INVALID_ARGUMENT
);
}
if ($value) {
return $value;
}
return false;
}
/**
* @param $value
*
* @return bool
*/
function envSubstr($value)
{
return ($valueLength = strlen($value)) > 1 && strpos($value, '"') === 0 && $value[$valueLength - 1] === '"';
}
/**
* Return the default value of the given value.
*
* @param mixed $value
*
* @return mixed
*/
function value($value)
{
return $value instanceof Closure ? $value() : $value;
}

View File

@@ -0,0 +1,78 @@
<?php
namespace AlibabaCloud\Client\Log;
use DateTime;
use Exception;
use DateTimeZone;
use GuzzleHttp\MessageFormatter;
use Psr\Http\Message\RequestInterface;
use Psr\Http\Message\ResponseInterface;
/**
* Class LogFormatter
*
* @package AlibabaCloud\Client\Log
*/
class LogFormatter extends MessageFormatter
{
/**
* @var float
*/
private static $logStartTime = 0;
/**
* @var DateTime
*/
private static $ts;
/** @var string Template used to format log messages */
public $template;
/**
* @param string $template Log message template
*
* @throws Exception
*/
public function __construct($template)
{
parent::__construct($template);
self::$logStartTime = microtime(true);
$this->template = $template;
$timezone = new DateTimeZone(date_default_timezone_get() ?: 'UTC');
if (PHP_VERSION_ID < 70100) {
self::$ts = DateTime::createFromFormat('U.u', sprintf('%.6F', microtime(true)), $timezone);
} else {
self::$ts = new DateTime(null, $timezone);
}
}
/**
* Returns a formatted message string.
*
* @param RequestInterface $request Request that was sent
* @param ResponseInterface $response Response that was received
* @param Exception $error Exception that was received
*
* @return string
*/
public function format(
RequestInterface $request,
ResponseInterface $response = null,
Exception $error = null
) {
$this->template = str_replace('{pid}', getmypid(), $this->template);
$this->template = str_replace('{cost}', self::getCost(), $this->template);
$this->template = str_replace('{start_time}', self::$ts->format('Y-m-d H:i:s.u'), $this->template);
return (new MessageFormatter($this->template))->format($request, $response, $error);
}
/**
* @return float|mixed
*/
private static function getCost()
{
return microtime(true) - self::$logStartTime;
}
}

View File

@@ -0,0 +1,74 @@
<?php
namespace AlibabaCloud\Client\Profile;
use AlibabaCloud\Client\AlibabaCloud;
use AlibabaCloud\Client\Clients\Client;
use AlibabaCloud\Client\Exception\ClientException;
/**
* Class DefaultProfile
*
* @package AlibabaCloud\Client\Profile
* @codeCoverageIgnore
* @deprecated deprecated since version 2.0, Use AlibabaCloud instead.
*/
class DefaultProfile
{
/**
* @param string $regionId
* @param string $accessKeyId
* @param string $accessKeySecret
*
* @return Client
* @throws ClientException
*/
public static function getProfile($regionId, $accessKeyId, $accessKeySecret)
{
return AlibabaCloud::accessKeyClient($accessKeyId, $accessKeySecret)
->regionId($regionId);
}
/**
* @param string $regionId
* @param string $accessKeyId
* @param string $accessKeySecret
* @param string $roleArn
* @param string $roleSessionName
*
* @return Client
* @throws ClientException
*/
public static function getRamRoleArnProfile($regionId, $accessKeyId, $accessKeySecret, $roleArn, $roleSessionName)
{
return AlibabaCloud::ramRoleArnClient($accessKeyId, $accessKeySecret, $roleArn, $roleSessionName)
->regionId($regionId);
}
/**
* @param string $regionId
* @param string $roleName
*
* @return Client
* @throws ClientException
*/
public static function getEcsRamRoleProfile($regionId, $roleName)
{
return AlibabaCloud::ecsRamRoleClient($roleName)
->regionId($regionId);
}
/**
* @param string $regionId
* @param string $bearerToken
*
* @return Client
* @throws ClientException
*/
public static function getBearerTokenProfile($regionId, $bearerToken)
{
return AlibabaCloud::bearerTokenClient($bearerToken)
->regionId($regionId);
}
}

View File

@@ -0,0 +1,18 @@
<?php
namespace AlibabaCloud\Client\Regions;
use AlibabaCloud\Client\Traits\EndpointTrait;
/**
* Class EndpointProvider
*
* @package AlibabaCloud\Client\Regions
*
* @deprecated deprecated since version 2.0, Use AlibabaCloud instead.
* @codeCoverageIgnore
*/
class EndpointProvider
{
use EndpointTrait;
}

View File

@@ -0,0 +1,160 @@
<?php
namespace AlibabaCloud\Client\Regions;
use Exception;
use RuntimeException;
use AlibabaCloud\Client\SDK;
use AlibabaCloud\Client\Config\Config;
use AlibabaCloud\Client\Request\Request;
use AlibabaCloud\Client\Filter\ApiFilter;
use AlibabaCloud\Client\Filter\HttpFilter;
use AlibabaCloud\Client\Filter\ClientFilter;
use AlibabaCloud\Client\Exception\ClientException;
use AlibabaCloud\Client\Exception\ServerException;
/**
* Class LocationService
*
* @package AlibabaCloud\Client\Regions
*/
class LocationService
{
/**
* Global Region Name
*/
const GLOBAL_REGION = 'global';
/**
* @var array
*/
protected static $hosts = [];
/**
* @var Request
*/
protected $request;
/**
* LocationService constructor.
*
* @param Request $request
*/
private function __construct(Request $request)
{
$this->request = $request;
}
/**
* @param Request $request
* @param string $domain
*
* @return string
* @throws ClientException
* @throws ServerException
* @deprecated
* @codeCoverageIgnore
*/
public static function findProductDomain(Request $request, $domain = 'location.aliyuncs.com')
{
return self::resolveHost($request, $domain);
}
/**
* @param $regionId
* @param $product
* @param $domain
*
* @throws ClientException
* @deprecated
* @codeCoverageIgnore
*/
public static function addEndPoint($regionId, $product, $domain)
{
self::addHost($product, $domain, $regionId);
}
/**
* @param Request $request
* @param string $domain
*
* @return string
* @throws ClientException
* @throws ServerException
*/
public static function resolveHost(Request $request, $domain = 'location.aliyuncs.com')
{
$locationService = new static($request);
$product = $locationService->request->product;
$regionId = $locationService->request->realRegionId();
if (!isset(self::$hosts[$product][$regionId])) {
self::$hosts[$product][$regionId] = self::getResult($locationService, $domain);
}
return self::$hosts[$product][$regionId];
}
/**
* @param static $locationService
* @param string $domain
*
* @return string
* @throws ClientException
* @throws ServerException
*/
private static function getResult($locationService, $domain)
{
$locationRequest = new LocationServiceRequest($locationService->request, $domain);
$result = $locationRequest->request();
if (!isset($result['Endpoints']['Endpoint'][0]['Endpoint'])) {
throw new ClientException(
'Not found Region ID in ' . $domain,
SDK::INVALID_REGION_ID
);
}
return $result['Endpoints']['Endpoint'][0]['Endpoint'];
}
/**
* @param string $product
* @param string $host
* @param string $regionId
*
* @throws ClientException
*/
public static function addHost($product, $host, $regionId = self::GLOBAL_REGION)
{
ApiFilter::product($product);
HttpFilter::host($host);
ClientFilter::regionId($regionId);
self::$hosts[$product][$regionId] = $host;
}
/**
* Update endpoints from OSS.
*
* @codeCoverageIgnore
* @throws Exception
*/
public static function updateEndpoints()
{
$ossUrl = 'https://openapi-endpoints.oss-cn-hangzhou.aliyuncs.com/endpoints.json';
$json = \file_get_contents($ossUrl);
$list = \json_decode($json, true);
foreach ($list['endpoints'] as $endpoint) {
Config::set(
"endpoints.{$endpoint['service']}.{$endpoint['regionid']}",
\strtolower($endpoint['endpoint'])
);
}
}
}

View File

@@ -0,0 +1,46 @@
<?php
namespace AlibabaCloud\Client\Regions;
use AlibabaCloud\Client\Request\Request;
use AlibabaCloud\Client\Request\RpcRequest;
use AlibabaCloud\Client\Exception\ClientException;
/**
* Class LocationServiceRequest
*
* @package AlibabaCloud\Client\Regions
*/
class LocationServiceRequest extends RpcRequest
{
/**
* LocationServiceRequest constructor.
*
* @param Request $request
* @param string $domain
*
* @throws ClientException
*/
public function __construct(Request $request, $domain)
{
parent::__construct();
$this->product('Location');
$this->version('2015-06-12');
$this->action('DescribeEndpoints');
$this->regionId('cn-hangzhou');
$this->format('JSON');
$this->options['query']['Id'] = $request->realRegionId();
$this->options['query']['ServiceCode'] = $request->serviceCode;
$this->options['query']['Type'] = $request->endpointType;
$this->client($request->client);
$this->host($domain);
if (isset($request->options['timeout'])) {
$this->timeout($request->options['timeout']);
}
if (isset($request->options['connect_timeout'])) {
$this->connectTimeout($request->options['connect_timeout']);
}
}
}

View File

@@ -0,0 +1,112 @@
<?php
namespace AlibabaCloud\Client;
use Composer\Script\Event;
/**
* Class Release
*
* @codeCoverageIgnore
* @package AlibabaCloud\Client
*/
class Release
{
/**
* @param Event $event
*/
public static function release(Event $event)
{
$arguments = $event->getArguments();
if (count($arguments) <= 1) {
echo 'Missing ChangeLog';
return;
}
self::updateChangelogFile($arguments[0], $arguments[1]);
self::changeVersionInCode($arguments[0]);
}
/**
* @param $version
* @param $changeLog
*/
private static function updateChangelogFile($version, $changeLog)
{
$content = preg_replace(
'/# CHANGELOG/',
'# CHANGELOG'
. "\n"
. "\n"
. "## $version - " . date('Y-m-d')
. self::log($changeLog),
self::getChangeLogContent()
);
file_put_contents(self::getChangeLogFile(), $content);
}
/**
* @param $changeLog
*
* @return string
*/
private static function log($changeLog)
{
$logs = explode('|', $changeLog);
$string = "\n";
foreach ($logs as $log) {
if ($log) {
$string .= "- $log." . "\n";
}
}
return $string;
}
/**
* @return string
*/
private static function getChangeLogContent()
{
return file_get_contents(self::getChangeLogFile());
}
/**
* @return string
*/
private static function getChangeLogFile()
{
return __DIR__ . '/../CHANGELOG.md';
}
/**
* @param $version
*/
private static function changeVersionInCode($version)
{
$content = preg_replace(
"/const VERSION = \'(.*)\';/",
"const VERSION = '" . $version . "';",
self::getCodeContent()
);
file_put_contents(self::getCodeFile(), $content);
}
/**
* @return string
*/
private static function getCodeContent()
{
return file_get_contents(self::getCodeFile());
}
/**
* @return string
*/
private static function getCodeFile()
{
return __DIR__ . '/AlibabaCloud.php';
}
}

View File

@@ -0,0 +1,445 @@
<?php
namespace AlibabaCloud\Client\Request;
use Exception;
use ArrayAccess;
use GuzzleHttp\Client;
use GuzzleHttp\Psr7\Uri;
use GuzzleHttp\Middleware;
use AlibabaCloud\Client\SDK;
use GuzzleHttp\HandlerStack;
use AlibabaCloud\Client\Encode;
use AlibabaCloud\Client\AlibabaCloud;
use AlibabaCloud\Client\Filter\Filter;
use AlibabaCloud\Client\Result\Result;
use Psr\Http\Message\ResponseInterface;
use GuzzleHttp\Promise\PromiseInterface;
use AlibabaCloud\Client\Filter\ApiFilter;
use AlibabaCloud\Client\Log\LogFormatter;
use AlibabaCloud\Client\Traits\HttpTrait;
use GuzzleHttp\Exception\GuzzleException;
use AlibabaCloud\Client\Filter\HttpFilter;
use AlibabaCloud\Client\Traits\RegionTrait;
use AlibabaCloud\Client\Filter\ClientFilter;
use AlibabaCloud\Client\Request\Traits\AcsTrait;
use AlibabaCloud\Client\Traits\ArrayAccessTrait;
use AlibabaCloud\Client\Traits\ObjectAccessTrait;
use AlibabaCloud\Client\Request\Traits\RetryTrait;
use AlibabaCloud\Client\Exception\ClientException;
use AlibabaCloud\Client\Exception\ServerException;
use AlibabaCloud\Client\Request\Traits\ClientTrait;
use AlibabaCloud\Client\Request\Traits\DeprecatedTrait;
use AlibabaCloud\Client\Credentials\Providers\CredentialsProvider;
/**
* Class Request
*
* @package AlibabaCloud\Client\Request
*
* @method string stringToSign()
* @method string resolveParameter()
*/
abstract class Request implements ArrayAccess
{
use DeprecatedTrait;
use HttpTrait;
use RegionTrait;
use ClientTrait;
use AcsTrait;
use ArrayAccessTrait;
use ObjectAccessTrait;
use RetryTrait;
/**
* Request Connect Timeout
*/
const CONNECT_TIMEOUT = 5;
/**
* Request Timeout
*/
const TIMEOUT = 10;
/**
* @var string HTTP Method
*/
public $method = 'GET';
/**
* @var string
*/
public $format = 'JSON';
/**
* @var string HTTP Scheme
*/
protected $scheme = 'http';
/**
* @var string
*/
public $client;
/**
* @var Uri
*/
public $uri;
/**
* @var array The original parameters of the request.
*/
public $data = [];
/**
* @var array
*/
private $userAgent = [];
/**
* Request constructor.
*
* @param array $options
*
* @throws ClientException
*/
public function __construct(array $options = [])
{
$this->client = CredentialsProvider::getDefaultName();
$this->uri = new Uri();
$this->uri = $this->uri->withScheme($this->scheme);
$this->options['http_errors'] = false;
$this->options['connect_timeout'] = self::CONNECT_TIMEOUT;
$this->options['timeout'] = self::TIMEOUT;
// Turn on debug mode based on environment variable.
if (strtolower(\AlibabaCloud\Client\env('DEBUG')) === 'sdk') {
$this->options['debug'] = true;
}
// Rewrite configuration if the user has a configuration.
if ($options !== []) {
$this->options($options);
}
}
/**
* @param string $name
* @param string $value
*
* @return $this
* @throws ClientException
*/
public function appendUserAgent($name, $value)
{
$filter_name = Filter::name($name);
if (!UserAgent::isGuarded($filter_name)) {
$this->userAgent[$filter_name] = Filter::value($value);
}
return $this;
}
/**
* @param array $userAgent
*
* @return $this
*/
public function withUserAgent(array $userAgent)
{
$this->userAgent = UserAgent::clean($userAgent);
return $this;
}
/**
* Set Accept format.
*
* @param string $format
*
* @return $this
* @throws ClientException
*/
public function format($format)
{
$this->format = ApiFilter::format($format);
return $this;
}
/**
* @param $contentType
*
* @return $this
* @throws ClientException
*/
public function contentType($contentType)
{
$this->options['headers']['Content-Type'] = HttpFilter::contentType($contentType);
return $this;
}
/**
* @param string $accept
*
* @return $this
* @throws ClientException
*/
public function accept($accept)
{
$this->options['headers']['Accept'] = HttpFilter::accept($accept);
return $this;
}
/**
* Set the request body.
*
* @param string $body
*
* @return $this
* @throws ClientException
*/
public function body($body)
{
$this->options['body'] = HttpFilter::body($body);
return $this;
}
/**
* Set the json as body.
*
* @param array|object $content
*
* @return $this
* @throws ClientException
*/
public function jsonBody($content)
{
if (!\is_array($content) && !\is_object($content)) {
throw new ClientException(
'jsonBody only accepts an array or object',
SDK::INVALID_ARGUMENT
);
}
return $this->body(\json_encode($content));
}
/**
* Set the request scheme.
*
* @param string $scheme
*
* @return $this
* @throws ClientException
*/
public function scheme($scheme)
{
$this->scheme = HttpFilter::scheme($scheme);
$this->uri = $this->uri->withScheme($scheme);
return $this;
}
/**
* Set the request host.
*
* @param string $host
*
* @return $this
* @throws ClientException
*/
public function host($host)
{
$this->uri = $this->uri->withHost(HttpFilter::host($host));
return $this;
}
/**
* @param string $method
*
* @return $this
* @throws ClientException
*/
public function method($method)
{
$this->method = HttpFilter::method($method);
return $this;
}
/**
* @param string $clientName
*
* @return $this
* @throws ClientException
*/
public function client($clientName)
{
$this->client = ClientFilter::clientName($clientName);
return $this;
}
/**
* @return bool
* @throws ClientException
*/
public function isDebug()
{
if (isset($this->options['debug'])) {
return $this->options['debug'] === true;
}
if (isset($this->httpClient()->options['debug'])) {
return $this->httpClient()->options['debug'] === true;
}
return false;
}
/**
* @throws ClientException
* @throws ServerException
*/
public function resolveOption()
{
$this->options['headers']['User-Agent'] = UserAgent::toString($this->userAgent);
$this->cleanQuery();
$this->cleanFormParams();
$this->resolveHost();
$this->resolveParameter();
if (isset($this->options['form_params'])) {
$this->options['form_params'] = \GuzzleHttp\Psr7\parse_query(
Encode::create($this->options['form_params'])->toString()
);
}
$this->mergeOptionsIntoClient();
}
/**
* @return Result
* @throws ClientException
* @throws ServerException
*/
public function request()
{
$this->resolveOption();
$result = $this->response();
if ($this->shouldServerRetry($result)) {
return $this->request();
}
if (!$result->isSuccess()) {
throw new ServerException($result);
}
return $result;
}
/***
* @return PromiseInterface
* @throws Exception
*/
public function requestAsync()
{
$this->resolveOption();
return self::createClient($this)->requestAsync(
$this->method,
(string)$this->uri,
$this->options
);
}
/**
* @param Request $request
*
* @return Client
* @throws Exception
*/
public static function createClient(Request $request = null)
{
if (AlibabaCloud::hasMock()) {
$stack = HandlerStack::create(AlibabaCloud::getMock());
} else {
$stack = HandlerStack::create();
}
if (AlibabaCloud::isRememberHistory()) {
$stack->push(Middleware::history(AlibabaCloud::referenceHistory()));
}
if (AlibabaCloud::getLogger()) {
$stack->push(Middleware::log(
AlibabaCloud::getLogger(),
new LogFormatter(AlibabaCloud::getLogFormat())
));
}
$stack->push(Middleware::mapResponse(static function (ResponseInterface $response) use ($request) {
return new Result($response, $request);
}));
self::$config['handler'] = $stack;
return new Client(self::$config);
}
/**
* @throws ClientException
* @throws Exception
*/
private function response()
{
try {
return self::createClient($this)->request(
$this->method,
(string)$this->uri,
$this->options
);
} catch (GuzzleException $exception) {
if ($this->shouldClientRetry($exception)) {
return $this->response();
}
throw new ClientException(
$exception->getMessage(),
SDK::SERVER_UNREACHABLE,
$exception
);
}
}
/**
* Remove redundant Query
*
* @codeCoverageIgnore
*/
private function cleanQuery()
{
if (isset($this->options['query']) && $this->options['query'] === []) {
unset($this->options['query']);
}
}
/**
* Remove redundant Headers
*
* @codeCoverageIgnore
*/
private function cleanFormParams()
{
if (isset($this->options['form_params']) && $this->options['form_params'] === []) {
unset($this->options['form_params']);
}
}
}

View File

@@ -0,0 +1,335 @@
<?php
namespace AlibabaCloud\Client\Request;
use Exception;
use Stringy\Stringy;
use RuntimeException;
use AlibabaCloud\Client\SDK;
use AlibabaCloud\Client\Encode;
use AlibabaCloud\Client\Accept;
use AlibabaCloud\Client\Support\Path;
use AlibabaCloud\Client\Support\Sign;
use AlibabaCloud\Client\Filter\Filter;
use AlibabaCloud\Client\Support\Arrays;
use AlibabaCloud\Client\Filter\ApiFilter;
use AlibabaCloud\Client\Credentials\StsCredential;
use AlibabaCloud\Client\Exception\ClientException;
use AlibabaCloud\Client\Exception\ServerException;
use AlibabaCloud\Client\Credentials\AccessKeyCredential;
use AlibabaCloud\Client\Credentials\BearerTokenCredential;
use AlibabaCloud\Client\Request\Traits\DeprecatedRoaTrait;
/**
* RESTful ROA Request.
*
* @package AlibabaCloud\Client\Request
* @method setParameter()
*/
class RoaRequest extends Request
{
use DeprecatedRoaTrait;
/**
* @var string
*/
public $pathPattern = '/';
/**
* @var array
*/
public $pathParameters = [];
/**
* @var string
*/
private $dateTimeFormat = "D, d M Y H:i:s \G\M\T";
/**
* Resolve request parameter.
*
* @throws ClientException
* @throws Exception
*/
public function resolveParameter()
{
$this->resolveQuery();
$this->resolveHeaders();
$this->resolveBody();
$this->resolveUri();
$this->resolveSignature();
}
private function resolveQuery()
{
if (!isset($this->options['query']['Version'])) {
$this->options['query']['Version'] = $this->version;
}
}
private function resolveBody()
{
// If the body has already been specified, it will not be resolved.
if (isset($this->options['body'])) {
return;
}
if (!isset($this->options['form_params'])) {
return;
}
// Merge data, compatible with parameters set from constructor.
$params = Arrays::merge(
[
$this->data,
$this->options['form_params']
]
);
$this->encodeBody($params);
unset($this->options['form_params']);
}
/**
* Determine the body format based on the Content-Type and calculate the MD5 value.
*
* @param array $params
*/
private function encodeBody(array $params)
{
$stringy = Stringy::create($this->options['headers']['Content-Type']);
if ($stringy->contains('application/json', false)) {
$this->options['body'] = json_encode($params);
$this->options['headers']['Content-MD5'] = base64_encode(md5($this->options['body'], true));
return;
}
$this->options['body'] = Encode::create($params)->ksort()->toString();
$this->options['headers']['Content-MD5'] = base64_encode(md5($this->options['body'], true));
$this->options['headers']['Content-Type'] = 'application/x-www-form-urlencoded; charset=UTF-8';
}
/**
* @throws ClientException
* @throws ServerException
* @throws Exception
*/
private function resolveHeaders()
{
$this->options['headers']['x-acs-version'] = $this->version;
$this->options['headers']['x-acs-region-id'] = $this->realRegionId();
$this->options['headers']['Date'] = gmdate($this->dateTimeFormat);
$signature = $this->httpClient()->getSignature();
$this->options['headers']['x-acs-signature-method'] = $signature->getMethod();
$this->options['headers']['x-acs-signature-nonce'] = Sign::uuid($this->product . $this->realRegionId());
$this->options['headers']['x-acs-signature-version'] = $signature->getVersion();
if ($signature->getType()) {
$this->options['headers']['x-acs-signature-type'] = $signature->getType();
}
$this->resolveAccept();
$this->resolveContentType();
$this->resolveSecurityToken();
$this->resolveBearerToken();
}
/**
* @throws ClientException
* @throws Exception
*/
private function resolveSignature()
{
$this->options['headers']['Authorization'] = $this->signature();
}
/**
* If accept is not specified, it is determined by format.
*/
private function resolveAccept()
{
if (!isset($this->options['headers']['Accept'])) {
$this->options['headers']['Accept'] = Accept::create($this->format)->toString();
}
}
/**
* If the Content-Type is not specified, it is determined according to accept.
*/
private function resolveContentType()
{
if (!isset($this->options['headers']['Content-Type'])) {
$this->options['headers']['Content-Type'] = "{$this->options['headers']['Accept']}; charset=utf-8";
}
}
/**
* @throws ClientException
* @throws ServerException
*/
private function resolveSecurityToken()
{
if (!$this->credential() instanceof StsCredential) {
return;
}
if (!$this->credential()->getSecurityToken()) {
return;
}
$this->options['headers']['x-acs-security-token'] = $this->credential()->getSecurityToken();
}
/**
* @throws ClientException
* @throws ServerException
*/
private function resolveBearerToken()
{
if ($this->credential() instanceof BearerTokenCredential) {
$this->options['headers']['x-acs-bearer-token'] = $this->credential()->getBearerToken();
}
}
/**
* Sign the request message.
*
* @return string
* @throws ClientException
* @throws ServerException
*/
private function signature()
{
/**
* @var AccessKeyCredential $credential
*/
$credential = $this->credential();
$access_key_id = $credential->getAccessKeyId();
$signature = $this->httpClient()
->getSignature()
->sign(
$this->stringToSign(),
$credential->getAccessKeySecret()
);
return "acs $access_key_id:$signature";
}
/**
* @return void
*/
private function resolveUri()
{
$path = Path::assign($this->pathPattern, $this->pathParameters);
$this->uri = $this->uri->withPath($path)
->withQuery(
$this->queryString()
);
}
/**
* @return string
*/
public function stringToSign()
{
$request = new \GuzzleHttp\Psr7\Request(
$this->method,
$this->uri,
$this->options['headers']
);
return Sign::roaString($request);
}
/**
* @return bool|string
*/
private function queryString()
{
$query = isset($this->options['query'])
? $this->options['query']
: [];
return Encode::create($query)->ksort()->toString();
}
/**
* Set path parameter by name.
*
* @param string $name
* @param string $value
*
* @return RoaRequest
* @throws ClientException
*/
public function pathParameter($name, $value)
{
Filter::name($name);
if ($value === '') {
throw new ClientException(
'Value cannot be empty',
SDK::INVALID_ARGUMENT
);
}
$this->pathParameters[$name] = $value;
return $this;
}
/**
* Set path pattern.
*
* @param string $pattern
*
* @return self
* @throws ClientException
*/
public function pathPattern($pattern)
{
ApiFilter::pattern($pattern);
$this->pathPattern = $pattern;
return $this;
}
/**
* Magic method for set or get request parameters.
*
* @param string $name
* @param mixed $arguments
*
* @return $this
*/
public function __call($name, $arguments)
{
if (strncmp($name, 'get', 3) === 0) {
$parameter_name = \mb_strcut($name, 3);
return $this->__get($parameter_name);
}
if (strncmp($name, 'with', 4) === 0) {
$parameter_name = \mb_strcut($name, 4);
$this->__set($parameter_name, $arguments[0]);
$this->pathParameters[$parameter_name] = $arguments[0];
return $this;
}
if (strncmp($name, 'set', 3) === 0) {
$parameter_name = \mb_strcut($name, 3);
$with_method = "with$parameter_name";
throw new RuntimeException("Please use $with_method instead of $name");
}
throw new RuntimeException('Call to undefined method ' . __CLASS__ . '::' . $name . '()');
}
}

View File

@@ -0,0 +1,203 @@
<?php
namespace AlibabaCloud\Client\Request;
use Exception;
use RuntimeException;
use AlibabaCloud\Client\Support\Sign;
use AlibabaCloud\Client\Support\Arrays;
use AlibabaCloud\Client\Credentials\StsCredential;
use AlibabaCloud\Client\Exception\ClientException;
use AlibabaCloud\Client\Exception\ServerException;
use AlibabaCloud\Client\Credentials\BearerTokenCredential;
/**
* RESTful RPC Request.
*
* @package AlibabaCloud\Client\Request
*/
class RpcRequest extends Request
{
/**
* @var string
*/
private $dateTimeFormat = 'Y-m-d\TH:i:s\Z';
/**
* Resolve request parameter.
*
* @throws ClientException
*/
public function resolveParameter()
{
$this->resolveBoolInParameters();
$this->resolveCommonParameters();
$this->repositionParameters();
}
/**
* Convert a Boolean value to a string
*/
private function resolveBoolInParameters()
{
if (isset($this->options['query'])) {
$this->options['query'] = array_map(
static function ($value) {
return self::boolToString($value);
},
$this->options['query']
);
}
}
/**
* Convert a Boolean value to a string.
*
* @param bool|string $value
*
* @return string
*/
public static function boolToString($value)
{
if (is_bool($value)) {
return $value ? 'true' : 'false';
}
return $value;
}
/**
* Resolve Common Parameters.
*
* @throws ClientException
* @throws Exception
*/
private function resolveCommonParameters()
{
$signature = $this->httpClient()->getSignature();
$this->options['query']['RegionId'] = $this->realRegionId();
$this->options['query']['Format'] = $this->format;
$this->options['query']['SignatureMethod'] = $signature->getMethod();
$this->options['query']['SignatureVersion'] = $signature->getVersion();
$this->options['query']['SignatureNonce'] = Sign::uuid($this->product . $this->realRegionId());
$this->options['query']['Timestamp'] = gmdate($this->dateTimeFormat);
$this->options['query']['Action'] = $this->action;
if ($this->credential()->getAccessKeyId()) {
$this->options['query']['AccessKeyId'] = $this->credential()->getAccessKeyId();
}
if ($signature->getType()) {
$this->options['query']['SignatureType'] = $signature->getType();
}
if (!isset($this->options['query']['Version'])) {
$this->options['query']['Version'] = $this->version;
}
$this->resolveSecurityToken();
$this->resolveBearerToken();
$this->options['query']['Signature'] = $this->signature();
}
/**
* @throws ClientException
* @throws ServerException
*/
private function resolveSecurityToken()
{
if (!$this->credential() instanceof StsCredential) {
return;
}
if (!$this->credential()->getSecurityToken()) {
return;
}
$this->options['query']['SecurityToken'] = $this->credential()->getSecurityToken();
}
/**
* @throws ClientException
* @throws ServerException
*/
private function resolveBearerToken()
{
if ($this->credential() instanceof BearerTokenCredential) {
$this->options['query']['BearerToken'] = $this->credential()->getBearerToken();
}
}
/**
* Sign the parameters.
*
* @return mixed
* @throws ClientException
* @throws ServerException
*/
private function signature()
{
return $this->httpClient()
->getSignature()
->sign(
$this->stringToSign(),
$this->credential()->getAccessKeySecret() . '&'
);
}
/**
* @return string
*/
public function stringToSign()
{
$query = isset($this->options['query']) ? $this->options['query'] : [];
$form_params = isset($this->options['form_params']) ? $this->options['form_params'] : [];
$parameters = Arrays::merge([$query, $form_params]);
return Sign::rpcString($this->method, $parameters);
}
/**
* Adjust parameter position
*/
private function repositionParameters()
{
if ($this->method === 'POST' || $this->method === 'PUT') {
foreach ($this->options['query'] as $api_key => $api_value) {
$this->options['form_params'][$api_key] = $api_value;
}
unset($this->options['query']);
}
}
/**
* Magic method for set or get request parameters.
*
* @param string $name
* @param mixed $arguments
*
* @return $this
*/
public function __call($name, $arguments)
{
if (strncmp($name, 'get', 3) === 0) {
$parameter_name = \mb_strcut($name, 3);
return $this->__get($parameter_name);
}
if (strncmp($name, 'with', 4) === 0) {
$parameter_name = \mb_strcut($name, 4);
$this->__set($parameter_name, $arguments[0]);
$this->options['query'][$parameter_name] = $arguments[0];
return $this;
}
if (strncmp($name, 'set', 3) === 0) {
$parameter_name = \mb_strcut($name, 3);
$with_method = "with$parameter_name";
throw new RuntimeException("Please use $with_method instead of $name");
}
throw new RuntimeException('Call to undefined method ' . __CLASS__ . '::' . $name . '()');
}
}

View File

@@ -0,0 +1,237 @@
<?php
namespace AlibabaCloud\Client\Request\Traits;
use GuzzleHttp\Psr7\Uri;
use AlibabaCloud\Client\SDK;
use AlibabaCloud\Client\AlibabaCloud;
use AlibabaCloud\Client\Request\Request;
use AlibabaCloud\Client\Filter\ApiFilter;
use AlibabaCloud\Client\Regions\LocationService;
use AlibabaCloud\Client\Exception\ClientException;
use AlibabaCloud\Client\Exception\ServerException;
/**
* Trait AcsTrait
*
* @package AlibabaCloud\Client\Request\Traits
* @property Uri $uri
* @mixin Request
*/
trait AcsTrait
{
/**
* @var string
*/
public $version;
/**
* @var string
*/
public $product;
/**
* @var string
*/
public $action;
/**
* @var string
*/
public $serviceCode = '';
/**
* @var string
*/
public $endpointType = 'openAPI';
/**
* @var string|null
*/
public $network = 'public';
/**
* @var array|null
*/
public $endpointMap;
/**
* @var string|null
*/
public $endpointRegional;
/**
* @var string
*/
public $endpointSuffix = '';
/**
* @param string $action
*
* @return $this
* @throws ClientException
*/
public function action($action)
{
$this->action = ApiFilter::action($action);
return $this;
}
/**
* @codeCoverageIgnore
*
* @param string $endpointSuffix
*
* @return AcsTrait
* @throws ClientException
*/
public function endpointSuffix($endpointSuffix)
{
$this->endpointSuffix = ApiFilter::endpointSuffix($endpointSuffix);
return $this;
}
/**
* @param string $network
*/
public function network($network)
{
$this->network = ApiFilter::network($network);
return $this;
}
/**
* @param string $version
*
* @return $this
* @throws ClientException
*/
public function version($version)
{
$this->version = ApiFilter::version($version);
return $this;
}
/**
* @param string $product
*
* @return $this
* @throws ClientException
*/
public function product($product)
{
$this->product = ApiFilter::product($product);
return $this;
}
/**
* @param string $endpointType
*
* @return $this
* @throws ClientException
*/
public function endpointType($endpointType)
{
$this->endpointType = ApiFilter::endpointType($endpointType);
return $this;
}
/**
* @param string $serviceCode
*
* @return $this
* @throws ClientException
*/
public function serviceCode($serviceCode)
{
$this->serviceCode = ApiFilter::serviceCode($serviceCode);
return $this;
}
/**
* Resolve Host.
*
* @throws ClientException
* @throws ServerException
*/
public function resolveHost()
{
// Return if specified
if ($this->uri->getHost() !== 'localhost') {
return;
}
$region_id = $this->realRegionId();
$host = '';
$this->resolveHostWays($host, $region_id);
if (!$host) {
throw new ClientException(
"No host found for {$this->product} in the {$region_id}, you can specify host by host() method. " .
'Like $request->host(\'xxx.xxx.aliyuncs.com\')',
SDK::HOST_NOT_FOUND
);
}
$this->uri = $this->uri->withHost($host);
}
/**
* @param string $host
* @param string $region_id
*
* @throws ClientException
* @throws ServerException
*/
private function resolveHostWays(&$host, $region_id)
{
// 1. Find host by map.
if ($this->network === 'public' && isset($this->endpointMap[$region_id])) {
$host = $this->endpointMap[$region_id];
}
// 2. Find host by rules.
if (!$host && $this->endpointRegional !== null) {
$host = AlibabaCloud::resolveHostByRule($this);
}
// 3. Find in the local array file.
if (!$host) {
$host = AlibabaCloud::resolveHost($this->product, $region_id);
}
// 4. Find in the Location service.
if (!$host && $this->serviceCode) {
$host = LocationService::resolveHost($this);
}
}
/**
* @return string
* @throws ClientException
*/
public function realRegionId()
{
if ($this->regionId !== null) {
return $this->regionId;
}
if ($this->httpClient()->regionId !== null) {
return $this->httpClient()->regionId;
}
if (AlibabaCloud::getDefaultRegionId() !== null) {
return AlibabaCloud::getDefaultRegionId();
}
throw new ClientException("Missing required 'RegionId' for Request", SDK::INVALID_REGION_ID);
}
}

View File

@@ -0,0 +1,98 @@
<?php
namespace AlibabaCloud\Client\Request\Traits;
use AlibabaCloud\Client\AlibabaCloud;
use AlibabaCloud\Client\Clients\Client;
use AlibabaCloud\Client\Support\Arrays;
use AlibabaCloud\Client\Request\Request;
use AlibabaCloud\Client\Credentials\StsCredential;
use AlibabaCloud\Client\Exception\ClientException;
use AlibabaCloud\Client\Exception\ServerException;
use AlibabaCloud\Client\Credentials\AccessKeyCredential;
use AlibabaCloud\Client\Credentials\Requests\AssumeRole;
use AlibabaCloud\Client\Credentials\CredentialsInterface;
use AlibabaCloud\Client\Credentials\BearerTokenCredential;
use AlibabaCloud\Client\Credentials\Providers\CredentialsProvider;
use AlibabaCloud\Client\Credentials\Requests\GenerateSessionAccessKey;
/**
* Trait ClientTrait
*
* @package AlibabaCloud\Client\Request\Traits
*
* @mixin Request
*/
trait ClientTrait
{
/**
* @var array
*/
private static $config = [];
/**
* @param array $config
*/
public static function config(array $config)
{
self::$config = $config;
}
/**
* Return credentials directly if it is an AssumeRole or GenerateSessionAccessKey.
*
* @return AccessKeyCredential|BearerTokenCredential|CredentialsInterface|StsCredential
* @throws ClientException
* @throws ServerException
*/
public function credential()
{
if ($this instanceof AssumeRole || $this instanceof GenerateSessionAccessKey) {
return $this->httpClient()->getCredential();
}
$timeout = isset($this->options['timeout'])
? $this->options['timeout']
: Request::TIMEOUT;
$connectTimeout = isset($this->options['connect_timeout'])
? $this->options['connect_timeout']
: Request::CONNECT_TIMEOUT;
return $this->httpClient()->getSessionCredential($timeout, $connectTimeout);
}
/**
* Get the client based on the request's settings.
*
* @return Client
* @throws ClientException
*/
public function httpClient()
{
if (!AlibabaCloud::all()) {
if (CredentialsProvider::hasCustomChain()) {
CredentialsProvider::customProvider($this->client);
} else {
CredentialsProvider::defaultProvider($this->client);
}
}
return AlibabaCloud::get($this->client);
}
/**
* Merged with the client's options, the same name will be overwritten.
*
* @throws ClientException
*/
public function mergeOptionsIntoClient()
{
$this->options = Arrays::merge(
[
$this->httpClient()->options,
$this->options
]
);
}
}

View File

@@ -0,0 +1,55 @@
<?php
namespace AlibabaCloud\Client\Request\Traits;
/**
* @package AlibabaCloud\Client\Request\Traits
* @codeCoverageIgnore
*/
trait DeprecatedRoaTrait
{
/**
* @param $name
* @param $value
*
* @return $this
* @deprecated
* @codeCoverageIgnore
*/
public function putPathParameter($name, $value)
{
return $this->pathParameter($name, $value);
}
/**
* @param $pathPattern
*
* @return $this
* @deprecated
* @codeCoverageIgnore
*/
public function setUriPattern($pathPattern)
{
return $this->pathPattern($pathPattern);
}
/**
* @return string
* @deprecated
* @codeCoverageIgnore
*/
public function getUriPattern()
{
return $this->pathPattern;
}
/**
* @return array
* @deprecated
* @codeCoverageIgnore
*/
public function getPathParameters()
{
return $this->pathParameters;
}
}

View File

@@ -0,0 +1,246 @@
<?php
namespace AlibabaCloud\Client\Request\Traits;
use AlibabaCloud\Client\Exception\ClientException;
use RuntimeException;
use AlibabaCloud\Client\Request\Request;
/**
* @package AlibabaCloud\Client\Request\Traits
*
* @mixin Request
*/
trait DeprecatedTrait
{
/**
* @param $content
*
* @return $this
* @throws ClientException
* @deprecated
* @codeCoverageIgnore
*/
public function setContent($content)
{
return $this->body($content);
}
/**
* @param $method
*
* @return $this
* @throws ClientException
* @deprecated
* @codeCoverageIgnore
*/
public function setMethod($method)
{
return $this->method($method);
}
/**
* @param $scheme
*
* @return $this
* @throws ClientException
* @deprecated
* @codeCoverageIgnore
*/
public function setProtocol($scheme)
{
return $this->scheme($scheme);
}
/**
* @deprecated
* @codeCoverageIgnore
*/
public function getProtocolType()
{
return $this->uri->getScheme();
}
/**
* @param $scheme
*
* @return $this
* @throws ClientException
* @deprecated
* @codeCoverageIgnore
*/
public function setProtocolType($scheme)
{
return $this->scheme($scheme);
}
/**
* @param $actionName
*
* @return $this
* @throws ClientException
* @deprecated
* @codeCoverageIgnore
*/
public function setActionName($actionName)
{
return $this->action($actionName);
}
/**
* @param $format
*
* @return $this
* @throws ClientException
* @deprecated
* @codeCoverageIgnore
*/
public function setAcceptFormat($format)
{
return $this->format($format);
}
/**
* @deprecated
* @codeCoverageIgnore
*/
public function getProtocol()
{
return $this->uri->getScheme();
}
/**
* @deprecated
* @codeCoverageIgnore
*/
public function getContent()
{
return isset($this->options['body'])
? $this->options['body']
: null;
}
/**
* @deprecated
* @codeCoverageIgnore
*/
public function getMethod()
{
return $this->method;
}
/**
* @deprecated
* @codeCoverageIgnore
*/
public function getHeaders()
{
return isset($this->options['headers'])
? $this->options['headers']
: [];
}
/**
* @param $headerKey
* @param $headerValue
*
* @return $this
* @deprecated
* @codeCoverageIgnore
*/
public function addHeader($headerKey, $headerValue)
{
$this->options['headers'][$headerKey] = $headerValue;
return $this;
}
/**
* @deprecated
* @codeCoverageIgnore
*/
public function getQueryParameters()
{
return isset($this->options['query'])
? $this->options['query']
: [];
}
/**
* @param $name
* @param $value
*
* @return $this
* @deprecated
* @codeCoverageIgnore
*/
public function setQueryParameters($name, $value)
{
$this->options['query'][$name] = $value;
return $this;
}
/**
* @deprecated
* @codeCoverageIgnore
*/
public function getDomainParameter()
{
return isset($this->options['form_params'])
? $this->options['form_params']
: [];
}
/**
* @param $name
* @param $value
*
* @return $this
* @deprecated
* @codeCoverageIgnore
*/
public function putDomainParameters($name, $value)
{
$this->options['form_params'][$name] = $value;
return $this;
}
/**
* @deprecated
* @codeCoverageIgnore
*/
public function getActionName()
{
return $this->action;
}
/**
* @deprecated
* @codeCoverageIgnore
*/
public function getAcceptFormat()
{
return $this->format;
}
/**
* @deprecated
* @codeCoverageIgnore
*/
public function getLocationEndpointType()
{
return $this->endpointType;
}
/**
* @deprecated
* @codeCoverageIgnore
*/
public function getLocationServiceCode()
{
return $this->serviceCode;
}
}

View File

@@ -0,0 +1,149 @@
<?php
namespace AlibabaCloud\Client\Request\Traits;
use Exception;
use Stringy\Stringy;
use AlibabaCloud\Client\Result\Result;
use AlibabaCloud\Client\Filter\ClientFilter;
use AlibabaCloud\Client\Exception\ClientException;
/**
* Trait RetryTrait
*
* @package AlibabaCloud\Client\Request\Traits
*/
trait RetryTrait
{
/**
* Server Retry Times
*
* @var int
*/
private $serverRetry = 0;
/**
* Server Retry Strings
*
* @var string[]
*/
private $serverRetryStrings = [];
/**
* Server Retry Codes
*
* @var int[]
*/
private $serverRetryStatusCodes = [];
/**
* Client Retry Times
*
* @var int
*/
private $clientRetry = 0;
/**
* Client Retry Strings
*
* @var string[]
*/
private $clientRetryStrings = [];
/**
* Client Retry Codes
*
* @var int[]
*/
private $clientRetryStatusCodes = [];
/**
* @param int $times
* @param array $strings
* @param array $statusCodes
*
* @return $this
* @throws ClientException
*/
public function retryByServer($times, array $strings, array $statusCodes = [])
{
$this->serverRetry = ClientFilter::retry($times);
$this->serverRetryStrings = $strings;
$this->serverRetryStatusCodes = $statusCodes;
return $this;
}
/**
* @param int $times
* @param array $strings
* @param array $codes
*
* @return $this
* @throws ClientException
*/
public function retryByClient($times, array $strings, array $codes = [])
{
$this->clientRetry = ClientFilter::retry($times);
$this->clientRetryStrings = $strings;
$this->clientRetryStatusCodes = $codes;
return $this;
}
/**
* @param Result $result
*
* @return bool
*/
private function shouldServerRetry(Result $result)
{
if ($this->serverRetry <= 0) {
return false;
}
if (in_array($result->getStatusCode(), $this->serverRetryStatusCodes)) {
$this->serverRetry--;
return true;
}
foreach ($this->serverRetryStrings as $message) {
if (Stringy::create($result->getBody())->contains($message)) {
$this->serverRetry--;
return true;
}
}
return false;
}
/**
* @param Exception $exception
*
* @return bool
*/
private function shouldClientRetry(Exception $exception)
{
if ($this->clientRetry <= 0) {
return false;
}
if (in_array($exception->getCode(), $this->clientRetryStatusCodes, true)) {
$this->clientRetry--;
return true;
}
foreach ($this->clientRetryStrings as $message) {
if (Stringy::create($exception->getMessage())->contains($message)) {
$this->clientRetry--;
return true;
}
}
return false;
}
}

View File

@@ -0,0 +1,142 @@
<?php
namespace AlibabaCloud\Client\Request;
use AlibabaCloud\Client\AlibabaCloud;
use AlibabaCloud\Client\Filter\Filter;
use AlibabaCloud\Client\Support\Arrays;
use AlibabaCloud\Client\Exception\ClientException;
/**
* Class UserAgent
*
* @package AlibabaCloud\Client\Request
*/
class UserAgent
{
/**
* @var array
*/
private static $userAgent = [];
/**
* @var array
*/
private static $guard = [
'client',
'php',
];
/**
* @param array $append
*
* @return string
*/
public static function toString(array $append = [])
{
self::defaultFields();
$os = \PHP_OS;
$osVersion = php_uname('r');
$osMode = php_uname('m');
$userAgent = "AlibabaCloud ($os $osVersion; $osMode) ";
$newUserAgent = [];
$append = self::clean($append);
$append = Arrays::merge(
[
self::$userAgent,
$append,
]
);
foreach ($append as $key => $value) {
if ($value === null) {
$newUserAgent[] = $key;
continue;
}
$newUserAgent[] = "$key/$value";
}
return $userAgent . \implode(' ', $newUserAgent);
}
/**
* UserAgent constructor.
*/
private static function defaultFields()
{
if (self::$userAgent === []) {
self::$userAgent = [
'Client' => AlibabaCloud::VERSION,
'PHP' => \PHP_VERSION,
];
}
}
/**
* @param array $append
*
* @return array
*/
public static function clean(array $append)
{
foreach ($append as $key => $value) {
if (self::isGuarded($key)) {
unset($append[$key]);
continue;
}
}
return $append;
}
/**
* @param $name
*
* @return bool
*/
public static function isGuarded($name)
{
return in_array(strtolower($name), self::$guard, true);
}
/**
* set User Agent of Alibaba Cloud.
*
* @param string $name
* @param string $value
*
* @throws ClientException
*/
public static function append($name, $value)
{
Filter::name($name);
Filter::value($value);
self::defaultFields();
if (!self::isGuarded($name)) {
self::$userAgent[$name] = $value;
}
}
/**
* @param array $userAgent
*/
public static function with(array $userAgent)
{
self::$userAgent = self::clean($userAgent);
}
/**
* Clear all of the User Agent.
*/
public static function clear()
{
self::$userAgent = [];
}
}

View File

@@ -0,0 +1,50 @@
<?php
namespace AlibabaCloud\Client\Resolver;
use ReflectionClass;
use ReflectionException;
use AlibabaCloud\Client\AlibabaCloud;
use AlibabaCloud\Client\Request\Request;
use AlibabaCloud\Client\Exception\ClientException;
/**
* @codeCoverageIgnore
* @mixin Rpc
* @mixin Roa
* @mixin Request
* @package AlibabaCloud\Client\Resolver
*/
trait ActionResolverTrait
{
/**
* Resolve Action name from class name
*/
private function resolveActionName()
{
if (!$this->action) {
$array = explode('\\', get_class($this));
$this->action = array_pop($array);
}
}
/**
* Append SDK version into User-Agent
*
* @throws ClientException
* @throws ReflectionException
*/
private function appendSdkUA()
{
if (!(new ReflectionClass(AlibabaCloud::class))->hasMethod('appendUserAgent')) {
return;
}
if (!class_exists('AlibabaCloud\Release')) {
return;
}
AlibabaCloud::appendUserAgent('SDK', \AlibabaCloud\Release::VERSION);
}
}

View File

@@ -0,0 +1,113 @@
<?php
namespace AlibabaCloud\Client\Resolver;
use ReflectionObject;
use AlibabaCloud\Client\Request\Request;
use AlibabaCloud\Client\Exception\ClientException;
/**
* Class ApiResolver
*
* @codeCoverageIgnore
* @package AlibabaCloud\Client\Resolver
*/
abstract class ApiResolver
{
/**
* @param $name
* @param $arguments
*
* @return mixed
*/
public static function __callStatic($name, $arguments)
{
return (new static())->__call($name, $arguments);
}
/**
* @param $api
* @param $arguments
*
* @return mixed
* @throws ClientException
*/
public function __call($api, $arguments)
{
$product_name = $this->getProductName();
$class = $this->getNamespace() . '\\' . \ucfirst($api);
if (\class_exists($class)) {
if (isset($arguments[0])) {
return $this->warpEndpoint(new $class($arguments[0]));
}
return $this->warpEndpoint(new $class());
}
throw new ClientException(
"{$product_name} contains no $api",
'SDK.ApiNotFound'
);
}
/**
* @param Request $request
*
* @return Request
*/
public function warpEndpoint(Request $request)
{
$reflect = new ReflectionObject($request);
$product_dir = dirname(dirname($reflect->getFileName()));
$endpoints_json = "$product_dir/endpoints.json";
if (file_exists($endpoints_json)) {
$endpoints = json_decode(file_get_contents($endpoints_json), true);
if (isset($endpoints['endpoint_map'])) {
$request->endpointMap = $endpoints['endpoint_map'];
}
if (isset($endpoints['endpoint_regional'])) {
$request->endpointRegional = $endpoints['endpoint_regional'];
}
}
return $request;
}
/**
* @return mixed
* @throws ClientException
*/
private function getProductName()
{
$array = \explode('\\', \get_class($this));
if (isset($array[3])) {
return str_replace('ApiResolver', '', $array[3]);
}
throw new ClientException(
'Service name not found.',
'SDK.ServiceNotFound'
);
}
/**
* @return string
* @throws ClientException
*/
private function getNamespace()
{
$array = \explode('\\', \get_class($this));
if (!isset($array[3])) {
throw new ClientException(
'Get namespace error.',
'SDK.ParseError'
);
}
unset($array[3]);
return \implode('\\', $array);
}
}

View File

@@ -0,0 +1,67 @@
<?php
namespace AlibabaCloud\Client\Resolver;
use RuntimeException;
use ArgumentCountError;
/**
* Trait CallTrait
*
* @codeCoverageIgnore
* @package AlibabaCloud\Client\Resolver
*/
trait CallTrait
{
/**
* Magic method for set or get request parameters.
*
* @param string $name
* @param mixed $arguments
*
* @return $this
*/
public function __call($name, $arguments)
{
if (strncmp($name, 'get', 3) === 0) {
$parameter = \mb_strcut($name, 3);
return $this->__get($parameter);
}
if (strncmp($name, 'with', 4) === 0) {
$parameter = \mb_strcut($name, 4);
$value = $this->getCallArguments($name, $arguments);
$this->data[$parameter] = $value;
$this->parameterPosition()[$parameter] = $value;
return $this;
}
if (strncmp($name, 'set', 3) === 0) {
$parameter = \mb_strcut($name, 3);
$with_method = "with$parameter";
return $this->$with_method($this->getCallArguments($name, $arguments));
}
throw new RuntimeException('Call to undefined method ' . __CLASS__ . '::' . $name . '()');
}
/**
* @param string $name
* @param array $arguments
* @param int $index
*
* @return mixed
*/
private function getCallArguments($name, array $arguments, $index = 0)
{
if (!isset($arguments[$index])) {
throw new ArgumentCountError("Missing arguments to method $name");
}
return $arguments[$index];
}
}

View File

@@ -0,0 +1,43 @@
<?php
namespace AlibabaCloud\Client\Resolver;
use AlibabaCloud\Client\AlibabaCloud;
use AlibabaCloud\Client\Exception\ClientException;
use AlibabaCloud\Client\Request\RoaRequest;
use ReflectionClass;
use ReflectionException;
/**
* Class Roa
*
* @codeCoverageIgnore
* @package AlibabaCloud\Client\Resolver
*/
abstract class Roa extends RoaRequest
{
use ActionResolverTrait;
use CallTrait;
/**
* @param array $options
*
* @throws ReflectionException
* @throws ClientException
*/
public function __construct(array $options = [])
{
parent::__construct($options);
$this->resolveActionName();
$this->appendSdkUA();
}
/**
* @return mixed
*/
private function &parameterPosition()
{
return $this->pathParameters;
}
}

View File

@@ -0,0 +1,41 @@
<?php
namespace AlibabaCloud\Client\Resolver;
use AlibabaCloud\Client\Exception\ClientException;
use AlibabaCloud\Client\Request\RpcRequest;
use ReflectionException;
/**
* Class Rpc
*
* @codeCoverageIgnore
* @package AlibabaCloud\Client\Resolver
*/
abstract class Rpc extends RpcRequest
{
use ActionResolverTrait;
use CallTrait;
/**
* @param array $options
*
* @throws ReflectionException
* @throws ClientException
*/
public function __construct(array $options = [])
{
parent::__construct($options);
$this->resolveActionName();
$this->appendSdkUA();
}
/**
* @return mixed
*/
private function &parameterPosition()
{
return $this->options['query'];
}
}

View File

@@ -0,0 +1,73 @@
<?php
namespace AlibabaCloud\Client\Resolver;
use AlibabaCloud\Client\Exception\ClientException;
/**
* Class VersionResolver
*
* @codeCoverageIgnore
* @package AlibabaCloud\Client\Resolver
*/
abstract class VersionResolver
{
/**
* @param string $name
* @param array $arguments
*
* @return mixed
*/
public static function __callStatic($name, $arguments)
{
return (new static())->__call($name, $arguments);
}
/**
* @param string $version
* @param array $arguments
*
* @return mixed
* @throws ClientException
*/
public function __call($version, $arguments)
{
$version = \ucfirst($version);
$product = $this->getProductName();
$position = strpos($product, 'Version');
if ($position !== false && $position !== 0) {
$product = \str_replace('Version', '', $product);
}
$class = "AlibabaCloud\\{$product}\\$version\\{$product}ApiResolver";
if (\class_exists($class)) {
return new $class();
}
throw new ClientException(
"$product Versions contains no {$version}",
'SDK.VersionNotFound'
);
}
/**
* @return mixed
* @throws ClientException
*/
private function getProductName()
{
$array = \explode('\\', \get_class($this));
if (isset($array[1])) {
return $array[1];
}
throw new ClientException(
'Service name not found.',
'SDK.ServiceNotFound'
);
}
}

View File

@@ -0,0 +1,151 @@
<?php
namespace AlibabaCloud\Client\Result;
use Countable;
use Exception;
use ArrayAccess;
use IteratorAggregate;
use InvalidArgumentException;
use GuzzleHttp\Psr7\Response;
use Psr\Http\Message\ResponseInterface;
use AlibabaCloud\Client\Request\Request;
use AlibabaCloud\Client\Traits\HasDataTrait;
/**
* Result from Alibaba Cloud
*
* @property string|null RequestId
*
* @package AlibabaCloud\Client\Result
*/
class Result extends Response implements ArrayAccess, IteratorAggregate, Countable
{
use HasDataTrait;
/**
* Instance of the request.
*
* @var Request
*/
protected $request;
/**
* Result constructor.
*
* @param ResponseInterface $response
* @param Request $request
*/
public function __construct(ResponseInterface $response, Request $request = null)
{
parent::__construct(
$response->getStatusCode(),
$response->getHeaders(),
$response->getBody(),
$response->getProtocolVersion(),
$response->getReasonPhrase()
);
$this->request = $request;
$this->resolveData();
}
private function resolveData()
{
$content = $this->getBody()->getContents();
switch ($this->getRequestFormat()) {
case 'JSON':
$result_data = $this->jsonToArray($content);
break;
case 'XML':
$result_data = $this->xmlToArray($content);
break;
case 'RAW':
$result_data = $this->jsonToArray($content);
break;
default:
$result_data = $this->jsonToArray($content);
}
if (!$result_data) {
$result_data = [];
}
$this->dot($result_data);
}
/**
* @return string
*/
private function getRequestFormat()
{
return ($this->request instanceof Request)
? \strtoupper($this->request->format)
: 'JSON';
}
/**
* @param string $response
*
* @return array
*/
private function jsonToArray($response)
{
try {
return \GuzzleHttp\json_decode($response, true);
} catch (InvalidArgumentException $exception) {
return [];
}
}
/**
* @param string $string
*
* @return array
*/
private function xmlToArray($string)
{
try {
return json_decode(json_encode(simplexml_load_string($string)), true);
} catch (Exception $exception) {
return [];
}
}
/**
* @return string
*/
public function __toString()
{
return (string)$this->getBody();
}
/**
* @return Request
*/
public function getRequest()
{
return $this->request;
}
/**
* @codeCoverageIgnore
* @return Response
* @deprecated
*/
public function getResponse()
{
return $this;
}
/**
* @return bool
*/
public function isSuccess()
{
return 200 <= $this->getStatusCode()
&& 300 > $this->getStatusCode();
}
}

View File

@@ -0,0 +1,57 @@
<?php
namespace AlibabaCloud\Client;
/**
* Class SDK
*
* @package AlibabaCloud\Client
*/
class SDK
{
/**
* Invalid credential
*/
const INVALID_CREDENTIAL = 'SDK.InvalidCredential';
/**
* Client Not Found
*/
const CLIENT_NOT_FOUND = 'SDK.ClientNotFound';
/**
* Host Not Found
*/
const HOST_NOT_FOUND = 'SDK.HostNotFound';
/**
* Server Unreachable
*/
const SERVER_UNREACHABLE = 'SDK.ServerUnreachable';
/**
* Invalid RegionId
*/
const INVALID_REGION_ID = 'SDK.InvalidRegionId';
/**
* Invalid Argument
*/
const INVALID_ARGUMENT = 'SDK.InvalidArgument';
/**
* Service Not Found
*/
const SERVICE_NOT_FOUND = 'SDK.ServiceNotFound';
/**
* Service Unknown Error
*/
const SERVICE_UNKNOWN_ERROR = 'SDK.UnknownError';
/**
* Response Empty
*/
const RESPONSE_EMPTY = 'The response is empty';
}

View File

@@ -0,0 +1,47 @@
<?php
namespace AlibabaCloud\Client\Signature;
/**
* Class BearerTokenSignature
*
* @package AlibabaCloud\Signature
*/
class BearerTokenSignature extends Signature implements SignatureInterface
{
/**
* @return string
*/
public function getMethod()
{
return '';
}
/**
* @return string
*/
public function getType()
{
return 'BEARERTOKEN';
}
/**
* @return string
*/
public function getVersion()
{
return '1.0';
}
/**
* @param string $string
* @param string $accessKeySecret
*
* @return string
*/
public function sign($string, $accessKeySecret)
{
return '';
}
}

View File

@@ -0,0 +1,47 @@
<?php
namespace AlibabaCloud\Client\Signature;
/**
* Class ShaHmac1Signature
*
* @package AlibabaCloud\Signature
*/
class ShaHmac1Signature extends Signature implements SignatureInterface
{
/**
* @return string
*/
public function getMethod()
{
return 'HMAC-SHA1';
}
/**
* @return string
*/
public function getType()
{
return '';
}
/**
* @return string
*/
public function getVersion()
{
return '1.0';
}
/**
* @param string $string
* @param string $accessKeySecret
*
* @return string
*/
public function sign($string, $accessKeySecret)
{
return base64_encode(hash_hmac('sha1', $string, $accessKeySecret, true));
}
}

View File

@@ -0,0 +1,47 @@
<?php
namespace AlibabaCloud\Client\Signature;
/**
* Class ShaHmac256Signature
*
* @package AlibabaCloud\Signature
*/
class ShaHmac256Signature extends Signature implements SignatureInterface
{
/**
* @return string
*/
public function getMethod()
{
return 'HMAC-SHA256';
}
/**
* @return string
*/
public function getType()
{
return '';
}
/**
* @return string
*/
public function getVersion()
{
return '1.0';
}
/**
* @param string $string
* @param string $accessKeySecret
*
* @return string
*/
public function sign($string, $accessKeySecret)
{
return base64_encode(hash_hmac('sha256', $string, $accessKeySecret, true));
}
}

View File

@@ -0,0 +1,67 @@
<?php
namespace AlibabaCloud\Client\Signature;
use Exception;
use AlibabaCloud\Client\SDK;
use AlibabaCloud\Client\Exception\ClientException;
/**
* Class ShaHmac256WithRsaSignature
*
* @package AlibabaCloud\Signature
*/
class ShaHmac256WithRsaSignature extends Signature implements SignatureInterface
{
/**
* @return string
*/
public function getMethod()
{
return 'SHA256withRSA';
}
/**
* @return string
*/
public function getType()
{
return 'PRIVATEKEY';
}
/**
* @return string
*/
public function getVersion()
{
return '1.0';
}
/**
* @param string $string
* @param string $privateKey
*
* @return string
* @throws ClientException
*/
public function sign($string, $privateKey)
{
$binarySignature = '';
try {
openssl_sign(
$string,
$binarySignature,
$privateKey,
\OPENSSL_ALGO_SHA256
);
} catch (Exception $exception) {
throw new ClientException(
$exception->getMessage(),
SDK::INVALID_CREDENTIAL
);
}
return base64_encode($binarySignature);
}
}

View File

@@ -0,0 +1,49 @@
<?php
namespace AlibabaCloud\Client\Signature;
use GuzzleHttp\Psr7\Request;
use AlibabaCloud\Client\Support\Sign;
/**
* Class Signature
*
* @package AlibabaCloud\Client\Signature
*/
abstract class Signature
{
/**
* @codeCoverageIgnore
*
* @param string $accessKeyId
* @param string $accessKeySecret
* @param Request $request
*
* @return string
*/
public function roa($accessKeyId, $accessKeySecret, Request $request)
{
$string = Sign::roaString($request);
$signature = $this->sign($string, $accessKeySecret);
return "acs $accessKeyId:$signature";
}
/**
* @codeCoverageIgnore
*
* @param string $accessKeySecret
* @param string $method
* @param array $parameters
*
* @return string
*/
public function rpc($accessKeySecret, $method, array $parameters)
{
$string = Sign::rpcString($method, $parameters);
return $this->sign($string, $accessKeySecret . '&');
}
}

View File

@@ -0,0 +1,35 @@
<?php
namespace AlibabaCloud\Client\Signature;
/**
* Interface used to provide interchangeable strategies for requests
*
* @package AlibabaCloud\Signature
*/
interface SignatureInterface
{
/**
* @return string
*/
public function getMethod();
/**
* @return string
*/
public function getVersion();
/**
* @param string $string
* @param string $accessKeySecret
*
* @return string
*/
public function sign($string, $accessKeySecret);
/**
* @return string
*/
public function getType();
}

View File

@@ -0,0 +1,41 @@
<?php
namespace AlibabaCloud\Client\Support;
/**
* Class Arrays
*
* @package AlibabaCloud\Client\Support
*/
class Arrays
{
/**
* @param array $arrays
*
* @return array
*/
public static function merge(array $arrays)
{
$result = [];
foreach ($arrays as $array) {
foreach ($array as $key => $value) {
if (is_int($key)) {
$result[] = $value;
continue;
}
if (isset($result[$key]) && is_array($result[$key])) {
$result[$key] = self::merge(
[$result[$key], $value]
);
continue;
}
$result[$key] = $value;
}
}
return $result;
}
}

View File

@@ -0,0 +1,28 @@
<?php
namespace AlibabaCloud\Client\Support;
/**
* Class Path
*
* @package AlibabaCloud\Client\Support
*/
class Path
{
/**
* Assign path parameters to the url.
*
* @param string $pattern
* @param array $parameters
*
* @return string
*/
public static function assign($pattern, array $parameters)
{
foreach ($parameters as $key => $value) {
$pattern = str_replace("[$key]", $value, $pattern);
}
return $pattern;
}
}

View File

@@ -0,0 +1,140 @@
<?php
namespace AlibabaCloud\Client\Support;
use GuzzleHttp\Psr7\Request;
use Psr\Http\Message\UriInterface;
/**
* Class Sign
*
* @package AlibabaCloud\Client\Support
*/
class Sign
{
/**
* @var string
*/
private static $headerSeparator = "\n";
/**
* Construct standard Header for Alibaba Cloud.
*
* @param array $headers
*
* @return string
*/
private static function acsHeaderString(array $headers)
{
$array = [];
foreach ($headers as $headerKey => $headerValue) {
$key = strtolower($headerKey);
if (strncmp($key, 'x-acs-', 6) === 0) {
$array[$key] = $headerValue;
}
}
ksort($array);
$string = '';
foreach ($array as $sortMapKey => $sortMapValue) {
$string .= $sortMapKey . ':' . $sortMapValue[0] . self::$headerSeparator;
}
return $string;
}
/**
* @param UriInterface $uri
*
* @return string
*/
private static function resourceString(UriInterface $uri)
{
return $uri->getPath() . '?' . rawurldecode($uri->getQuery());
}
/**
* @param string $method
* @param array $headers
*
* @return string
*/
private static function headerString($method, array $headers)
{
$string = $method . self::$headerSeparator;
if (isset($headers['Accept'][0])) {
$string .= $headers['Accept'][0];
}
$string .= self::$headerSeparator;
if (isset($headers['Content-MD5'][0])) {
$string .= $headers['Content-MD5'][0];
}
$string .= self::$headerSeparator;
if (isset($headers['Content-Type'][0])) {
$string .= $headers['Content-Type'][0];
}
$string .= self::$headerSeparator;
if (isset($headers['Date'][0])) {
$string .= $headers['Date'][0];
}
$string .= self::$headerSeparator;
$string .= self::acsHeaderString($headers);
return $string;
}
/**
* @param string $string
*
* @return null|string|string[]
*/
private static function percentEncode($string)
{
$result = urlencode($string);
$result = str_replace(['+', '*'], ['%20', '%2A'], $result);
$result = preg_replace('/%7E/', '~', $result);
return $result;
}
/**
* @param string $method
* @param array $parameters
*
* @return string
*/
public static function rpcString($method, array $parameters)
{
ksort($parameters);
$canonicalized = '';
foreach ($parameters as $key => $value) {
$canonicalized .= '&' . self::percentEncode($key) . '=' . self::percentEncode($value);
}
return $method . '&%2F&' . self::percentEncode(substr($canonicalized, 1));
}
/**
* @param Request $request
*
* @return string
*/
public static function roaString(Request $request)
{
return self::headerString($request->getMethod(), $request->getHeaders()) .
self::resourceString($request->getUri());
}
/**
* @param string $salt
*
* @return string
*/
public static function uuid($salt)
{
return md5($salt . uniqid(md5(microtime(true)), true));
}
}

View File

@@ -0,0 +1,57 @@
<?php
namespace AlibabaCloud\Client\Traits;
/**
* Trait ArrayAccessTrait
*
* @package AlibabaCloud\Client\Traits
*/
trait ArrayAccessTrait
{
/**
* This method returns a reference to the variable to allow for indirect
* array modification (e.g., $foo['bar']['baz'] = 'qux').
*
* @param string $offset
*
* @return mixed|null
*/
public function & offsetGet($offset)
{
if (isset($this->data[$offset])) {
return $this->data[$offset];
}
$value = null;
return $value;
}
/**
* @param string $offset
* @param string|mixed $value
*/
public function offsetSet($offset, $value)
{
$this->data[$offset] = $value;
}
/**
* @param string $offset
*
* @return bool
*/
public function offsetExists($offset)
{
return isset($this->data[$offset]);
}
/**
* @param string $offset
*/
public function offsetUnset($offset)
{
unset($this->data[$offset]);
}
}

View File

@@ -0,0 +1,273 @@
<?php
namespace AlibabaCloud\Client\Traits;
use AlibabaCloud\Client\SDK;
use AlibabaCloud\Client\AlibabaCloud;
use AlibabaCloud\Client\Clients\Client;
use AlibabaCloud\Client\Clients\StsClient;
use AlibabaCloud\Client\Filter\ClientFilter;
use AlibabaCloud\Client\Clients\AccessKeyClient;
use AlibabaCloud\Client\Clients\EcsRamRoleClient;
use AlibabaCloud\Client\Clients\RamRoleArnClient;
use AlibabaCloud\Client\Clients\RsaKeyPairClient;
use AlibabaCloud\Client\Clients\BearerTokenClient;
use AlibabaCloud\Client\Exception\ClientException;
use AlibabaCloud\Client\Signature\SignatureInterface;
use AlibabaCloud\Client\Credentials\Ini\IniCredential;
use AlibabaCloud\Client\Credentials\CredentialsInterface;
use AlibabaCloud\Client\Credentials\Providers\CredentialsProvider;
/**
* Trait of the manage clients.
*
* @package AlibabaCloud\Client\Traits
*
* @mixin AlibabaCloud
*/
trait ClientTrait
{
/**
* @var array Containers of Clients
*/
protected static $clients = [];
/**
* @param string $clientName
* @param Client $client
*
* @return Client
* @throws ClientException
*/
public static function set($clientName, Client $client)
{
ClientFilter::clientName($clientName);
return self::$clients[\strtolower($clientName)] = $client;
}
/**
* Get all clients.
*
* @return array
*/
public static function all()
{
return self::$clients;
}
/**
* Delete the client by specifying name.
*
* @param string $clientName
*
* @throws ClientException
*/
public static function del($clientName)
{
ClientFilter::clientName($clientName);
unset(self::$clients[\strtolower($clientName)]);
}
/**
* Delete all clients.
*
* @return void
*/
public static function flush()
{
self::$clients = [];
self::$defaultRegionId = null;
}
/**
* @codeCoverageIgnore
* @throws ClientException
* @deprecated
*/
public static function getGlobalClient()
{
return self::getDefaultClient();
}
/**
* Get the default client.
*
* @return Client
* @throws ClientException
*/
public static function getDefaultClient()
{
return self::get(CredentialsProvider::getDefaultName());
}
/**
* Get the Client instance by name.
*
* @param string $clientName
*
* @return Client
* @throws ClientException
*/
public static function get($clientName)
{
ClientFilter::clientName($clientName);
if (self::has($clientName)) {
return self::$clients[\strtolower($clientName)];
}
throw new ClientException(
"Client '$clientName' not found",
SDK::CLIENT_NOT_FOUND
);
}
/**
* Determine whether there is a client.
*
* @param string $clientName
*
* @return bool
* @throws ClientException
*/
public static function has($clientName)
{
ClientFilter::clientName($clientName);
return isset(self::$clients[\strtolower($clientName)]);
}
/**
* A list of additional files to load.
*
* @return array
* @throws ClientException when a file has a syntax error or does not exist or is not readable
*/
public static function load()
{
if (\func_get_args() === []) {
return (new IniCredential())->load();
}
$list = [];
foreach (\func_get_args() as $filename) {
$list[$filename] = (new IniCredential($filename))->load();
}
return $list;
}
/**
* Custom Client.
*
* @param CredentialsInterface $credentials
* @param SignatureInterface $signature
*
* @return Client
*/
public static function client(CredentialsInterface $credentials, SignatureInterface $signature)
{
return new Client($credentials, $signature);
}
/**
* Use the AccessKey to complete the authentication.
*
* @param string $accessKeyId
* @param string $accessKeySecret
*
* @return AccessKeyClient
* @throws ClientException
*/
public static function accessKeyClient($accessKeyId, $accessKeySecret)
{
if (strpos($accessKeyId, ' ') !== false) {
throw new ClientException(
'AccessKey ID format is invalid',
SDK::INVALID_ARGUMENT
);
}
if (strpos($accessKeySecret, ' ') !== false) {
throw new ClientException(
'AccessKey Secret format is invalid',
SDK::INVALID_ARGUMENT
);
}
return new AccessKeyClient($accessKeyId, $accessKeySecret);
}
/**
* Use the AssumeRole of the RAM account to complete the authentication.
*
* @param string $accessKeyId
* @param string $accessKeySecret
* @param string $roleArn
* @param string $roleSessionName
* @param string|array $policy
*
* @return RamRoleArnClient
* @throws ClientException
*/
public static function ramRoleArnClient($accessKeyId, $accessKeySecret, $roleArn, $roleSessionName, $policy = '')
{
return new RamRoleArnClient($accessKeyId, $accessKeySecret, $roleArn, $roleSessionName, $policy);
}
/**
* Use the RAM role of an ECS instance to complete the authentication.
*
* @param string $roleName
*
* @return EcsRamRoleClient
* @throws ClientException
*/
public static function ecsRamRoleClient($roleName)
{
return new EcsRamRoleClient($roleName);
}
/**
* Use the Bearer Token to complete the authentication.
*
* @param string $bearerToken
*
* @return BearerTokenClient
* @throws ClientException
*/
public static function bearerTokenClient($bearerToken)
{
return new BearerTokenClient($bearerToken);
}
/**
* Use the STS Token to complete the authentication.
*
* @param string $accessKeyId Access key ID
* @param string $accessKeySecret Access Key Secret
* @param string $securityToken Security Token
*
* @return StsClient
* @throws ClientException
*/
public static function stsClient($accessKeyId, $accessKeySecret, $securityToken = '')
{
return new StsClient($accessKeyId, $accessKeySecret, $securityToken);
}
/**
* Use the RSA key pair to complete the authentication (supported only on Japanese site)
*
* @param string $publicKeyId
* @param string $privateKeyFile
*
* @return RsaKeyPairClient
* @throws ClientException
*/
public static function rsaKeyPairClient($publicKeyId, $privateKeyFile)
{
return new RsaKeyPairClient($publicKeyId, $privateKeyFile);
}
}

View File

@@ -0,0 +1,66 @@
<?php
namespace AlibabaCloud\Client\Traits;
use AlibabaCloud\Client\AlibabaCloud;
use AlibabaCloud\Client\Filter\ClientFilter;
use AlibabaCloud\Client\Exception\ClientException;
/**
* Trait DefaultRegionTrait
*
* @package AlibabaCloud\Client\Traits
*
* @mixin AlibabaCloud
*/
trait DefaultRegionTrait
{
/**
* @var string|null Default RegionId
*/
protected static $defaultRegionId;
/**
* @param $regionId
*
* @throws ClientException
* @deprecated
* @codeCoverageIgnore
*/
public static function setGlobalRegionId($regionId)
{
self::setDefaultRegionId($regionId);
}
/**
* @return string|null
* @deprecated
* @codeCoverageIgnore
*/
public static function getGlobalRegionId()
{
return self::getDefaultRegionId();
}
/**
* Get the default RegionId.
*
* @return string|null
*/
public static function getDefaultRegionId()
{
return self::$defaultRegionId;
}
/**
* Set the default RegionId.
*
* @param string $regionId
*
* @throws ClientException
*/
public static function setDefaultRegionId($regionId)
{
self::$defaultRegionId = ClientFilter::regionId($regionId);
}
}

View File

@@ -0,0 +1,104 @@
<?php
namespace AlibabaCloud\Client\Traits;
use AlibabaCloud\Client\AlibabaCloud;
use AlibabaCloud\Client\Config\Config;
use AlibabaCloud\Client\Request\Request;
use AlibabaCloud\Client\Filter\ApiFilter;
use AlibabaCloud\Client\Filter\HttpFilter;
use AlibabaCloud\Client\Filter\ClientFilter;
use AlibabaCloud\Client\Regions\LocationService;
use AlibabaCloud\Client\Exception\ClientException;
use InvalidArgumentException;
/**
* Help developers set up and get host.
*
* @package AlibabaCloud\Client\Traits
*
* @mixin AlibabaCloud
*/
trait EndpointTrait
{
/**
* @var array Host cache.
*/
private static $hosts = [];
/**
* Resolve host based on product name and region.
*
* @param string $product
* @param string $regionId
*
* @return string
* @throws ClientException
*/
public static function resolveHost($product, $regionId = LocationService::GLOBAL_REGION)
{
ApiFilter::product($product);
ClientFilter::regionId($regionId);
if (isset(self::$hosts[$product][$regionId])) {
return self::$hosts[$product][$regionId];
}
$domain = Config::get("endpoints.{$product}.{$regionId}");
if (!$domain) {
$regionId = LocationService::GLOBAL_REGION;
$domain = Config::get("endpoints.{$product}.{$regionId}", '');
}
return $domain;
}
/**
* Add host based on product name and region.
*
* @param string $product
* @param string $host
* @param string $regionId
*
* @return void
* @throws ClientException
*/
public static function addHost($product, $host, $regionId = LocationService::GLOBAL_REGION)
{
ApiFilter::product($product);
HttpFilter::host($host);
ClientFilter::regionId($regionId);
self::$hosts[$product][$regionId] = $host;
LocationService::addHost($product, $host, $regionId);
}
/**
* @param Request $request
*
* @return string
* @throws ClientException
*/
public static function resolveHostByRule(Request $request)
{
$regionId = $request->realRegionId();
$network = $request->network ?: 'public';
$suffix = $request->endpointSuffix;
if ($network === 'public') {
$network = '';
}
if ($request->endpointRegional === 'regional') {
return "{$request->product}{$suffix}{$network}.{$regionId}.aliyuncs.com";
}
if ($request->endpointRegional === 'central') {
return "{$request->product}{$suffix}{$network}.aliyuncs.com";
}
throw new InvalidArgumentException('endpointRegional is invalid.');
}
}

View File

@@ -0,0 +1,317 @@
<?php
namespace AlibabaCloud\Client\Traits;
use Adbar\Dot;
use ArrayIterator;
use JmesPath\Env as JmesPath;
use AlibabaCloud\Client\Result\Result;
/**
* Trait HasDataTrait
*
* @package AlibabaCloud\Client\Traits
* @mixin Result
*/
trait HasDataTrait
{
/**
* Instance of the Dot.
*
* @var Dot
*/
protected $dot;
/**
* @param string $expression
*
* @return mixed|null
*/
public function search($expression)
{
return JmesPath::search($expression, $this->dot->all());
}
/**
* Delete the contents of a given key or keys
*
* @param array|int|string|null $keys
*/
public function clear($keys = null)
{
$this->dot->clear($keys);
}
/**
* Flatten an array with the given character as a key delimiter
*
* @param string $delimiter
* @param array|null $items
* @param string $prepend
*
* @return array
*/
public function flatten($delimiter = '.', $items = null, $prepend = '')
{
return $this->dot->flatten($delimiter, $items, $prepend);
}
/**
* Return the value of a given key
*
* @param int|string|null $key
* @param mixed $default
*
* @return mixed
*/
public function get($key = null, $default = null)
{
return $this->dot->get($key, $default);
}
/**
* Set a given key / value pair or pairs
*
* @param array|int|string $keys
* @param mixed $value
*/
public function set($keys, $value = null)
{
$this->dot->set($keys, $value);
}
/**
* Check if a given key or keys are empty
*
* @param array|int|string|null $keys
*
* @return bool
*/
public function isEmpty($keys = null)
{
return $this->dot->isEmpty($keys);
}
/**
* Replace all items with a given array as a reference
*
* @param array $items
*/
public function setReference(array &$items)
{
$this->dot->setReference($items);
}
/**
* Return the value of a given key or all the values as JSON
*
* @param mixed $key
* @param int $options
*
* @return string
*/
public function toJson($key = null, $options = 0)
{
return $this->dot->toJson($key, $options);
}
/**
* @return array
*/
public function toArray()
{
return $this->dot->all();
}
/**
* Check if a given key exists
*
* @param int|string $key
*
* @return bool
*/
public function offsetExists($key)
{
return $this->dot->has($key);
}
/**
* Return the value of a given key
*
* @param int|string $key
*
* @return mixed
*/
public function offsetGet($key)
{
return $this->dot->offsetGet($key);
}
/**
* Set a given value to the given key
*
* @param int|string|null $key
* @param mixed $value
*/
public function offsetSet($key, $value)
{
$this->dot->offsetSet($key, $value);
}
/**
* Delete the given key
*
* @param int|string $key
*/
public function offsetUnset($key)
{
$this->delete($key);
}
/**
* Delete the given key or keys
*
* @param array|int|string $keys
*/
public function delete($keys)
{
$this->dot->delete($keys);
}
/*
* --------------------------------------------------------------
* ArrayAccess interface
* --------------------------------------------------------------
*/
/**
* Return the number of items in a given key
*
* @param int|string|null $key
*
* @return int
*/
public function count($key = null)
{
return $this->dot->count($key);
}
/**
* Get an iterator for the stored items
*
* @return ArrayIterator
*/
public function getIterator()
{
return $this->dot->getIterator();
}
/**
* Return items for JSON serialization
*
* @return array
*/
public function jsonSerialize()
{
return $this->dot->jsonSerialize();
}
/**
* @param string $name
*
* @return mixed|null
*/
public function __get($name)
{
if (!isset($this->all()[$name])) {
return null;
}
return \json_decode(\json_encode($this->all()))->$name;
}
/*
* --------------------------------------------------------------
* Countable interface
* --------------------------------------------------------------
*/
/**
* Return all the stored items
*
* @return array
*/
public function all()
{
return $this->dot->all();
}
/**
* @param string $name
* @param mixed $value
*/
public function __set($name, $value)
{
$this->add($name, $value);
}
/**
* Set a given key / value pair or pairs
* if the key doesn't exist already
*
* @param array|int|string $keys
* @param mixed $value
*/
public function add($keys, $value = null)
{
$this->dot->add($keys, $value);
}
/*
* --------------------------------------------------------------
* ObjectAccess
* --------------------------------------------------------------
*/
/**
* @param string $name
*
* @return bool
*/
public function __isset($name)
{
return $this->has($name);
}
/**
* Check if a given key or keys exists
*
* @param array|int|string $keys
*
* @return bool
*/
public function has($keys)
{
return $this->dot->has($keys);
}
/**
* @param $name
*
* @return void
*/
public function __unset($name)
{
$this->delete($name);
}
/**
* @param array $data
*/
protected function dot(array $data = [])
{
$this->dot = new Dot($data);
}
}

View File

@@ -0,0 +1,68 @@
<?php
namespace AlibabaCloud\Client\Traits;
/**
* Trait HistoryTrait
*
* @package AlibabaCloud\Client\Traits
*/
trait HistoryTrait
{
/**
* @var array
*/
private static $history = [];
/**
* @var bool
*/
private static $isRememberHistory = false;
/**
* @return array
*/
public static function getHistory()
{
return self::$history;
}
public static function forgetHistory()
{
self::$history = [];
}
public static function notRememberHistory()
{
self::$isRememberHistory = false;
}
public static function rememberHistory()
{
self::$isRememberHistory = true;
}
/**
* @return bool
*/
public static function isRememberHistory()
{
return self::$isRememberHistory;
}
/**
* @return array
*/
public static function &referenceHistory()
{
return self::$history;
}
/**
* @return int
*/
public static function countHistory()
{
return count(self::$history);
}
}

View File

@@ -0,0 +1,141 @@
<?php
namespace AlibabaCloud\Client\Traits;
use AlibabaCloud\Client\Support\Arrays;
use AlibabaCloud\Client\Filter\ClientFilter;
use AlibabaCloud\Client\Exception\ClientException;
/**
* Trait HttpTrait
*
* @package AlibabaCloud\Client\Traits
*/
trait HttpTrait
{
/**
* @var array
*/
public $options = [];
/**
* @param int|float $seconds
*
* @return $this
* @throws ClientException
*/
public function timeout($seconds)
{
$this->options['timeout'] = ClientFilter::timeout($seconds);
return $this;
}
/**
* @param int $milliseconds
*
* @return $this
* @throws ClientException
*/
public function timeoutMilliseconds($milliseconds)
{
ClientFilter::milliseconds($milliseconds);
$seconds = $milliseconds / 1000;
return $this->timeout($seconds);
}
/**
* @param int|float $seconds
*
* @return $this
* @throws ClientException
*/
public function connectTimeout($seconds)
{
$this->options['connect_timeout'] = ClientFilter::connectTimeout($seconds);
return $this;
}
/**
* @param int $milliseconds
*
* @return $this
* @throws ClientException
*/
public function connectTimeoutMilliseconds($milliseconds)
{
ClientFilter::milliseconds($milliseconds);
$seconds = $milliseconds / 1000;
return $this->connectTimeout($seconds);
}
/**
* @param bool $debug
*
* @return $this
*/
public function debug($debug)
{
$this->options['debug'] = $debug;
return $this;
}
/**
* @codeCoverageIgnore
*
* @param array $cert
*
* @return $this
*/
public function cert($cert)
{
$this->options['cert'] = $cert;
return $this;
}
/**
* @codeCoverageIgnore
*
* @param array|string $proxy
*
* @return $this
*/
public function proxy($proxy)
{
$this->options['proxy'] = $proxy;
return $this;
}
/**
* @param mixed $verify
*
* @return $this
*/
public function verify($verify)
{
$this->options['verify'] = $verify;
return $this;
}
/**
* @param array $options
*
* @return $this
*/
public function options(array $options)
{
if ($options !== []) {
$this->options = Arrays::merge([$this->options, $options]);
}
return $this;
}
}

View File

@@ -0,0 +1,64 @@
<?php
namespace AlibabaCloud\Client\Traits;
use Exception;
use Psr\Log\LoggerInterface;
/**
* Trait LogTrait
*
* @package AlibabaCloud\Client\Traits
*/
trait LogTrait
{
/**
* @var LoggerInterface
*/
private static $logger;
/**
* @var string
*/
private static $logFormat;
/**
* @return LoggerInterface
*/
public static function getLogger()
{
return self::$logger;
}
/**
* @param LoggerInterface $logger
*
* @throws Exception
*/
public static function setLogger(LoggerInterface $logger)
{
self::$logger = $logger;
}
/**
* @return string
*/
public static function getLogFormat()
{
return self::$logFormat
?: '"{method} {uri} HTTP/{version}" {code} {cost} {hostname} {pid}';
}
/**
* Apache Common Log Format.
*
* @param string $formatter
*
* @link http://httpd.apache.org/docs/2.4/logs.html#common
* @see \GuzzleHttp\MessageFormatter
*/
public static function setLogFormat($formatter)
{
self::$logFormat = $formatter;
}
}

View File

@@ -0,0 +1,97 @@
<?php
namespace AlibabaCloud\Client\Traits;
use Exception;
use GuzzleHttp\Psr7\Request;
use GuzzleHttp\Psr7\Response;
use GuzzleHttp\Handler\MockHandler;
use Psr\Http\Message\RequestInterface;
use Psr\Http\Message\ResponseInterface;
use GuzzleHttp\Exception\RequestException;
/**
* Class MockTrait
*
* @package AlibabaCloud\Client\Request\Traits
* @mixin Request
*/
trait MockTrait
{
/**
* @var array
*/
private static $mockQueue = [];
/**
* @var MockHandler
*/
private static $mock;
/**
* @param integer $status
* @param array $headers
* @param array|string|object $body
*/
public static function mockResponse($status = 200, array $headers = [], $body = null)
{
if (is_array($body) || is_object($body)) {
$body = json_encode($body);
}
self::$mockQueue[] = new Response($status, $headers, $body);
self::createHandlerStack();
}
private static function createHandlerStack()
{
self::$mock = new MockHandler(self::$mockQueue);
}
/**
* @param string $message
* @param RequestInterface $request
* @param ResponseInterface|null $response
* @param Exception|null $previous
* @param array $handlerContext
*/
public static function mockRequestException(
$message,
RequestInterface $request,
ResponseInterface $response = null,
Exception $previous = null,
array $handlerContext = []
) {
self::$mockQueue[] = new RequestException(
$message,
$request,
$response,
$previous,
$handlerContext
);
self::createHandlerStack();
}
public static function cancelMock()
{
self::$mockQueue = [];
self::$mock = null;
}
/**
* @return bool
*/
public static function hasMock()
{
return (bool)self::$mockQueue;
}
/**
* @return MockHandler
*/
public static function getMock()
{
return self::$mock;
}
}

View File

@@ -0,0 +1,54 @@
<?php
namespace AlibabaCloud\Client\Traits;
/**
* Trait ObjectAccessTrait
*
* @package AlibabaCloud\Client\Traits
*/
trait ObjectAccessTrait
{
/**
* @param string $name
*
* @return mixed|null
*/
public function __get($name)
{
if (!isset($this->data[$name])) {
return null;
}
return \json_decode(\json_encode($this->data))->$name;
}
/**
* @param string $name
* @param mixed $value
*/
public function __set($name, $value)
{
$this->data[$name] = $value;
}
/**
* @param string $name
*
* @return bool
*/
public function __isset($name)
{
return isset($this->data[$name]);
}
/**
* @param $name
*
* @return void
*/
public function __unset($name)
{
unset($this->data[$name]);
}
}

View File

@@ -0,0 +1,33 @@
<?php
namespace AlibabaCloud\Client\Traits;
use AlibabaCloud\Client\Filter\ClientFilter;
use AlibabaCloud\Client\Exception\ClientException;
/**
* Trait RegionTrait
*
* @package AlibabaCloud\Client\Traits
*/
trait RegionTrait
{
/**
* @var string|null
*/
public $regionId;
/**
* @param string $regionId
*
* @return $this
* @throws ClientException
*/
public function regionId($regionId)
{
$this->regionId = ClientFilter::regionId($regionId);
return $this;
}
}

View File

@@ -0,0 +1,90 @@
<?php
namespace AlibabaCloud\Client\Traits;
use AlibabaCloud\Client\AlibabaCloud;
use AlibabaCloud\Client\Filter\Filter;
use AlibabaCloud\Client\Request\UserAgent;
use AlibabaCloud\Client\Request\RpcRequest;
use AlibabaCloud\Client\Request\RoaRequest;
use AlibabaCloud\Client\Exception\ClientException;
/**
* Trait RequestTrait
*
* @package AlibabaCloud\Client\Traits
*
* @mixin AlibabaCloud
*/
trait RequestTrait
{
/**
* @param string $name
* @param string $value
*
* @throws ClientException
*/
public static function appendUserAgent($name, $value)
{
Filter::name($name);
Filter::value($value);
UserAgent::append($name, $value);
}
/**
* @param array $userAgent
*/
public static function withUserAgent(array $userAgent)
{
UserAgent::with($userAgent);
}
/**
* @param array $options
*
* @return RpcRequest
* @throws ClientException
* @deprecated
* @codeCoverageIgnore
*/
public static function rpcRequest(array $options = [])
{
return self::rpc($options);
}
/**
* @param array $options
*
* @return RpcRequest
* @throws ClientException
*/
public static function rpc(array $options = [])
{
return new RpcRequest($options);
}
/**
* @param array $options
*
* @return RoaRequest
* @throws ClientException
* @deprecated
* @codeCoverageIgnore
*/
public static function roaRequest(array $options = [])
{
return self::roa($options);
}
/**
* @param array $options
*
* @return RoaRequest
* @throws ClientException
*/
public static function roa(array $options = [])
{
return new RoaRequest($options);
}
}