update lock clucknut
All checks were successful
Gitea Actions Demo / Explore-Gitea-Actions (push) Successful in 14s
Build, Push and Deploy / build-and-push (push) Successful in 3m14s
Build, Push and Deploy / deploy-staging (push) Successful in 25s
Build, Push and Deploy / deploy-production (push) Has been skipped

This commit is contained in:
2026-04-18 20:32:18 +07:00
parent 4554035227
commit dcaf267458
3359 changed files with 153185 additions and 205489 deletions

View File

@@ -1,6 +1,6 @@
{
"name": "aws/aws-sdk-php",
"homepage": "http://aws.amazon.com/sdkforphp",
"homepage": "https://aws.amazon.com/sdk-for-php",
"description": "AWS SDK for PHP - Use Amazon Web Services in your PHP project",
"keywords": ["aws","amazon","sdk","s3","ec2","dynamodb","cloud","glacier"],
"type": "library",
@@ -8,7 +8,7 @@
"authors": [
{
"name": "Amazon Web Services",
"homepage": "http://aws.amazon.com"
"homepage": "https://aws.amazon.com"
}
],
"support": {
@@ -33,7 +33,7 @@
"ext-openssl": "*",
"ext-dom": "*",
"ext-sockets": "*",
"phpunit/phpunit": "^9.6",
"phpunit/phpunit": "^10.0",
"behat/behat": "~3.0",
"doctrine/cache": "~1.4",
"aws/aws-php-sns-message-validator": "~1.0",
@@ -42,7 +42,7 @@
"psr/simple-cache": "^2.0 || ^3.0",
"sebastian/comparator": "^1.2.3 || ^4.0 || ^5.0",
"yoast/phpunit-polyfills": "^2.0",
"dms/phpunit-arraysubset-asserts": "^0.4.0"
"dms/phpunit-arraysubset-asserts": "^v0.5.0"
},
"suggest": {
"ext-openssl": "Allows working with CloudFront private distributions and verifying received SNS messages",

View File

@@ -36,6 +36,8 @@
* @method \GuzzleHttp\Promise\Promise resendValidationEmailAsync(array $args = [])
* @method \Aws\Result revokeCertificate(array $args = [])
* @method \GuzzleHttp\Promise\Promise revokeCertificateAsync(array $args = [])
* @method \Aws\Result searchCertificates(array $args = [])
* @method \GuzzleHttp\Promise\Promise searchCertificatesAsync(array $args = [])
* @method \Aws\Result updateCertificateOptions(array $args = [])
* @method \GuzzleHttp\Promise\Promise updateCertificateOptionsAsync(array $args = [])
*/

View File

@@ -0,0 +1,664 @@
<?php
namespace Aws\Api\Cbor;
use Aws\Api\Cbor\Exception\CborException;
/**
* Decodes Concise Binary Object Representation encoded strings
* into PHP values according to RFC 8949
*
* https://www.rfc-editor.org/rfc/rfc8949.html
*
* Supports Major types 0-7 including:
* - Type 0: Unsigned integers
* - Type 1: Negative integers
* - Type 2: Byte strings
* - Type 3: Text strings (UTF-8)
* - Type 4: Arrays
* - Type 5: Maps
* - Type 6: Tagged values (timestamps)
* - Type 7: Simple values (null, bool, float)
*
* @internal
*/
final class CborDecoder
{
private int $offset;
private int $length;
/**
* Decode CBOR binary data to PHP value
*
* @param string $data The CBOR-encoded binary data to decode
*
* @return mixed The decoded PHP value (can be any type: int, string, array, bool, null, float)
* @throws CborException If data is empty or malformed CBOR
*/
public function decode(string $data): mixed
{
if ($data === '') {
throw new CborException("No data to decode");
}
$this->offset = 0;
$this->length = strlen($data);
return $this->decodeValue($data);
}
/**
* Decode multiple CBOR values from sequential binary data
*
* @param string $data The CBOR-encoded binary data containing multiple values
*
* @return array Array of decoded PHP values in the order they appear in the data
* @throws CborException If data is malformed CBOR
*/
public function decodeAll(string $data): array
{
$this->length = strlen($data);
$this->offset = 0;
$values = [];
while ($this->offset < $this->length) {
$values[] = $this->decodeValue($data);
}
return $values;
}
/**
* Decodes a single CBOR value at the current offset
*
* @param string $data Reference to the CBOR data being decoded
*
* @return mixed The decoded value
* @throws CborException If unexpected end of data or invalid CBOR format
*/
private function decodeValue(string &$data): mixed
{
$offset = $this->offset;
$length = $this->length;
if ($offset >= $length) {
throw new CborException("Unexpected end of data");
}
$byte = ord($data[$offset++]);
$majorType = $byte >> 5;
$info = $byte & 0x1F;
switch ($majorType) {
case 0: // Unsigned integer
if ($info < 24) {
$this->offset = $offset;
return $info;
}
switch ($info) {
case 24:
if ($offset >= $length) {
throw new CborException("Not enough data");
}
$this->offset = $offset + 1;
return ord($data[$offset]);
case 25:
if ($offset + 2 > $length) {
throw new CborException("Not enough data");
}
$this->offset = $offset + 2;
return (ord($data[$offset]) << 8) | ord($data[$offset + 1]);
case 26:
if ($offset + 4 > $length) {
throw new CborException("Not enough data");
}
$this->offset = $offset + 4;
return unpack('N', $data, $offset)[1];
case 27:
if ($offset + 8 > $length) {
throw new CborException("Not enough data");
}
$this->offset = $offset + 8;
return unpack('J', $data, $offset)[1];
default:
throw new CborException("Invalid additional info for integer: $info");
}
case 1: // Negative integer
if ($info < 24) {
$this->offset = $offset;
return -1 - $info;
}
switch ($info) {
case 24:
if ($offset >= $length) {
throw new CborException("Not enough data");
}
$this->offset = $offset + 1;
return -1 - ord($data[$offset]);
case 25:
if ($offset + 2 > $length) {
throw new CborException("Not enough data");
}
$this->offset = $offset + 2;
return -1 - ((ord($data[$offset]) << 8) | ord($data[$offset + 1]));
case 26:
if ($offset + 4 > $length) {
throw new CborException("Not enough data");
}
$this->offset = $offset + 4;
return -1 - unpack('N', $data, $offset)[1];
case 27:
if ($offset + 8 > $length) {
throw new CborException("Not enough data");
}
$this->offset = $offset + 8;
$unsigned = unpack('J', $data, $offset)[1];
return ($unsigned === 9223372036854775807) ? PHP_INT_MIN : -1 - $unsigned;
default:
throw new CborException("Invalid additional info for integer: $info");
}
case 2: // Byte string
if ($info < 24) {
$len = $info;
} else {
switch ($info) {
case 24:
if ($offset >= $length) {
throw new CborException("Not enough data");
}
$len = ord($data[$offset++]);
break;
case 25:
if ($offset + 2 > $length) {
throw new CborException("Not enough data");
}
$len = (ord($data[$offset]) << 8) | ord($data[$offset + 1]);
$offset += 2;
break;
case 26:
if ($offset + 4 > $length) {
throw new CborException("Not enough data");
}
$len = unpack('N', $data, $offset)[1];
$offset += 4;
break;
case 27:
if ($offset + 8 > $length) {
throw new CborException("Not enough data");
}
$len = unpack('J', $data, $offset)[1];
$offset += 8;
break;
case 31:
$this->offset = $offset;
return $this->decodeIndefiniteString($data, 0x40);
default:
throw new CborException("Invalid additional info for byte string: $info");
}
}
if ($offset + $len > $length) {
throw new CborException("Not enough data");
}
$this->offset = $offset + $len;
return substr($data, $offset, $len);
case 3: // Text string
if ($info < 24) {
$len = $info;
} else {
switch ($info) {
case 24:
if ($offset >= $length) {
throw new CborException("Not enough data");
}
$len = ord($data[$offset++]);
break;
case 25:
if ($offset + 2 > $length) {
throw new CborException("Not enough data");
}
$len = (ord($data[$offset]) << 8) | ord($data[$offset + 1]);
$offset += 2;
break;
case 26:
if ($offset + 4 > $length) {
throw new CborException("Not enough data");
}
$len = unpack('N', $data, $offset)[1];
$offset += 4;
break;
case 27:
if ($offset + 8 > $length) {
throw new CborException("Not enough data");
}
$len = unpack('J', $data, $offset)[1];
$offset += 8;
break;
case 31:
$this->offset = $offset;
return $this->decodeIndefiniteString($data, 0x60);
default:
throw new CborException("Invalid additional info for text string: $info");
}
}
if ($offset + $len > $length) {
throw new CborException("Not enough data");
}
$this->offset = $offset + $len;
return substr($data, $offset, $len);
case 4: // Array
if ($info < 24) {
$count = $info;
} else {
switch ($info) {
case 24:
if ($offset >= $length) {
throw new CborException("Not enough data");
}
$count = ord($data[$offset++]);
break;
case 25:
if ($offset + 2 > $length) {
throw new CborException("Not enough data");
}
$count = (ord($data[$offset]) << 8) | ord($data[$offset + 1]);
$offset += 2;
break;
case 26:
if ($offset + 4 > $length) {
throw new CborException("Not enough data");
}
$count = unpack('N', $data, $offset)[1];
$offset += 4;
break;
case 27:
if ($offset + 8 > $length) {
throw new CborException("Not enough data");
}
$count = unpack('J', $data, $offset)[1];
$offset += 8;
break;
case 31:
$this->offset = $offset;
return $this->decodeIndefiniteArray($data);
default:
throw new CborException("Invalid additional info for array: $info");
}
}
$this->offset = $offset;
$arr = [];
for ($i = 0; $i < $count; $i++) {
$arr[] = $this->decodeValue($data);
}
return $arr;
case 5: // Map
if ($info < 24) {
$count = $info;
} else {
switch ($info) {
case 24:
if ($offset >= $length) {
throw new CborException("Not enough data");
}
$count = ord($data[$offset++]);
break;
case 25:
if ($offset + 2 > $length) {
throw new CborException("Not enough data");
}
$count = (ord($data[$offset]) << 8) | ord($data[$offset + 1]);
$offset += 2;
break;
case 26:
if ($offset + 4 > $length) {
throw new CborException("Not enough data");
}
$count = unpack('N', $data, $offset)[1];
$offset += 4;
break;
case 27:
if ($offset + 8 > $length) {
throw new CborException("Not enough data");
}
$count = unpack('J', $data, $offset)[1];
$offset += 8;
break;
case 31:
$this->offset = $offset;
return $this->decodeIndefiniteMap($data);
default:
throw new CborException("Invalid additional info for map: $info");
}
}
$this->offset = $offset;
$map = [];
for ($i = 0; $i < $count; $i++) {
$key = $this->decodeValue($data);
$map[$key] = $this->decodeValue($data);
}
return $map;
case 6: // Tag
switch ($info) {
case 24:
$offset++;
break;
case 25:
$offset += 2;
break;
case 26:
$offset += 4;
break;
case 27:
$offset += 8;
break;
}
$this->offset = $offset;
return $this->decodeValue($data);
case 7: // Simple/float
switch ($info) {
case 20:
$this->offset = $offset;
return false;
case 21:
$this->offset = $offset;
return true;
case 22:
case 23:
$this->offset = $offset;
return null;
case 25: // Half-precision float
if ($offset + 2 > $length) {
throw new CborException("Not enough data");
}
$this->offset = $offset + 2;
$half = (ord($data[$offset]) << 8) | ord($data[$offset + 1]);
$sign = ($half >> 15) & 0x01;
$exp = ($half >> 10) & 0x1F;
$mant = $half & 0x3FF;
if ($exp === 0) {
return $mant === 0
? ($sign ? -0.0 : 0.0)
: ($sign ? -1 : 1) * pow(2, -14) * ($mant / 1024);
}
if ($exp === 31) {
return $mant === 0 ? ($sign ? -INF : INF) : NAN;
}
return (float) (($sign ? -1 : 1) * pow(2, $exp - 15) * (1 + $mant / 1024));
case 26: // Single-precision float
if ($offset + 4 > $length) {
throw new CborException("Not enough data");
}
$this->offset = $offset + 4;
return unpack('G', $data, $offset)[1];
case 27: // Double-precision float
if ($offset + 8 > $length) {
throw new CborException("Not enough data");
}
$this->offset = $offset + 8;
return unpack('E', $data, $offset)[1];
case 31:
throw new CborException("Unexpected break");
default:
throw new CborException("Unknown simple value: $info");
}
default:
throw new CborException("Unknown major type: $majorType");
}
}
/**
* Decode indefinite-length string (byte or text)
*
* @param string $data Reference to the CBOR data being decoded
* @param int $expectedMajor Expected major type (0x40 for byte string, 0x60 for text string)
*
* @return string The concatenated string from all chunks
* @throws CborException If invalid chunk format or unexpected end of data
*/
private function decodeIndefiniteString(string &$data, int $expectedMajor): string
{
$chunks = [];
while (true) {
$offset = $this->offset;
$length = $this->length;
if ($offset >= $length) {
throw new CborException("Unexpected end of data");
}
$byte = ord($data[$offset++]);
if ($byte === 0xFF) {
$this->offset = $offset;
return implode('', $chunks);
}
if (($byte & 0xE0) !== $expectedMajor) {
throw new CborException("Invalid chunk in indefinite string");
}
$info = $byte & 0x1F;
if ($info === 31) {
throw new CborException("Nested indefinite string");
}
if ($info < 24) {
$len = $info;
} else {
switch ($info) {
case 24:
if ($offset >= $length) {
throw new CborException("Not enough data");
}
$len = ord($data[$offset++]);
break;
case 25:
if ($offset + 2 > $length) {
throw new CborException("Not enough data");
}
$len = (ord($data[$offset]) << 8) | ord($data[$offset + 1]);
$offset += 2;
break;
case 26:
if ($offset + 4 > $length) {
throw new CborException("Not enough data");
}
$len = unpack('N', $data, $offset)[1];
$offset += 4;
break;
case 27:
if ($offset + 8 > $length) {
throw new CborException("Not enough data");
}
$len = unpack('J', $data, $offset)[1];
$offset += 8;
break;
default:
throw new CborException("Invalid chunk length info: $info");
}
}
if ($offset + $len > $length) {
throw new CborException("Not enough data for chunk");
}
$chunks[] = substr($data, $offset, $len);
$this->offset = $offset + $len;
}
}
/**
* Decode indefinite-length array
*
* @param string $data Reference to the CBOR data being decoded
*
* @return array The decoded array elements
* @throws CborException If unexpected end of data
*/
private function decodeIndefiniteArray(string &$data): array
{
$result = [];
while (true) {
if ($this->offset >= $this->length) {
throw new CborException("Unexpected end of data");
}
if (ord($data[$this->offset]) === 0xFF) {
$this->offset++;
return $result;
}
$result[] = $this->decodeValue($data);
}
}
/**
* Decode indefinite-length map
*
* @param string $data Reference to the CBOR data being decoded
*
* @return array The decoded map as associative array
* @throws CborException If unexpected end of data or odd number of items
*/
private function decodeIndefiniteMap(string &$data): array
{
$result = [];
while (true) {
if ($this->offset >= $this->length) {
throw new CborException("Unexpected end of data");
}
if (ord($data[$this->offset]) === 0xFF) {
$this->offset++;
return $result;
}
$key = $this->decodeValue($data);
$result[$key] = $this->decodeValue($data);
}
}
}

View File

@@ -0,0 +1,345 @@
<?php
namespace Aws\Api\Cbor;
use Aws\Api\Cbor\Exception\CborException;
/**
* Encodes PHP values to Concise Binary Object Representation according to RFC 8949
* https://www.rfc-editor.org/rfc/rfc8949.html
*
* Supports Major types 0-7 including:
* - Type 0: Unsigned integers
* - Type 1: Negative integers
* - Type 2: Byte strings (via ['__cbor_bytes' => $data] wrappers)
* - Type 3: Text strings (UTF-8)
* - Type 4: Arrays
* - Type 5: Maps
* - Type 6: Tagged values (timestamps)
* - Type 7: Simple values (null, bool, float)
*
* @internal
*/
final class CborEncoder
{
/**
* Pre-encoded integers 0-23 (single byte) and common larger values
* CBOR major type 0 (unsigned integer)
*/
private const INT_CACHE = [
0 => "\x00", 1 => "\x01", 2 => "\x02", 3 => "\x03",
4 => "\x04", 5 => "\x05", 6 => "\x06", 7 => "\x07",
8 => "\x08", 9 => "\x09", 10 => "\x0A", 11 => "\x0B",
12 => "\x0C", 13 => "\x0D", 14 => "\x0E", 15 => "\x0F",
16 => "\x10", 17 => "\x11", 18 => "\x12", 19 => "\x13",
20 => "\x14", 21 => "\x15", 22 => "\x16", 23 => "\x17",
24 => "\x18\x18", 25 => "\x18\x19", 26 => "\x18\x1A",
32 => "\x18\x20", 50 => "\x18\x32", 64 => "\x18\x40",
100 => "\x18\x64", 128 => "\x18\x80", 200 => "\x18\xC8",
255 => "\x18\xFF", 256 => "\x19\x01\x00", 500 => "\x19\x01\xF4",
1000 => "\x19\x03\xE8", 1023 => "\x19\x03\xFF",
];
/**
* Pre-encoded negative integers -1 to -24 and common larger values
* CBOR major type 1 (negative integer)
*/
private const NEG_CACHE = [
-1 => "\x20", -2 => "\x21", -3 => "\x22", -4 => "\x23",
-5 => "\x24", -10 => "\x29", -20 => "\x33", -24 => "\x37",
-25 => "\x38\x18", -50 => "\x38\x31", -100 => "\x38\x63",
];
/**
* Encode a PHP value to CBOR binary string
*
* @param mixed $value The value to encode
*
* @return string
*/
public function encode(mixed $value): string
{
return $this->encodeValue($value);
}
/**
* Recursively encode a value to CBOR
*
* @param mixed $value Value to encode
* @return string Encoded CBOR bytes
*/
private function encodeValue(mixed $value): string
{
switch (gettype($value)) {
case 'string':
$len = strlen($value);
if ($len < 24) {
return chr(0x60 | $len) . $value;
}
if ($len < 0x100) {
return "\x78" . chr($len) . $value;
}
return $this->encodeTextString($value);
case 'array':
if (isset($value['__cbor_timestamp'])) {
return "\xC1\xFB" . pack('E', $value['__cbor_timestamp']);
}
// Encode a byte string (major type 2)
if (isset($value['__cbor_bytes'])) {
$bytes = $value['__cbor_bytes'];
$len = strlen($bytes);
if ($len < 24) {
return chr(0x40 | $len) . $bytes;
}
if ($len < 0x100) {
return "\x58" . chr($len) . $bytes;
}
if ($len < 0x10000) {
return "\x59" . pack('n', $len) . $bytes;
}
return "\x5A" . pack('N', $len) . $bytes;
}
if (array_is_list($value)) {
return $this->encodeArray($value);
}
return $this->encodeMap($value);
case 'integer':
if (isset(self::INT_CACHE[$value])) {
return self::INT_CACHE[$value];
}
if (isset(self::NEG_CACHE[$value])) {
return self::NEG_CACHE[$value];
}
// Fast path for positive integers
// Major type 0: unsigned integer
if ($value >= 0) {
if ($value < 24) {
return chr($value);
}
if ($value < 0x100) {
return "\x18" . chr($value);
}
if ($value < 0x10000) {
return "\x19" . pack('n', $value);
}
if ($value < 0x100000000) {
return "\x1A" . pack('N', $value);
}
return "\x1B" . pack('J', $value);
}
return $this->encodeInteger($value);
case 'double':
// Encode a float (major type 7, float 64)
return "\xFB" . pack('E', $value);
case 'boolean':
// Encode a boolean (major type 7, simple)
return $value ? "\xF5" : "\xF4";
case 'NULL':
// Encode null (major type 7, simple)
return "\xF6";
case 'object':
throw new CborException("Cannot encode object of type: " . get_class($value));
default:
throw new CborException("Cannot encode value of type: " . gettype($value));
}
}
/**
* Encode an integer (major type 0 or 1)
*
* @param int $value
* @return string
*/
private function encodeInteger(int $value): string
{
if (isset(self::INT_CACHE[$value])) {
return self::INT_CACHE[$value];
}
if (isset(self::NEG_CACHE[$value])) {
return self::NEG_CACHE[$value];
}
if ($value >= 0) {
// Major type 0: unsigned integer
if ($value < 24) {
return chr($value);
}
if ($value < 0x100) {
return "\x18" . chr($value);
}
if ($value < 0x10000) {
return "\x19" . pack('n', $value);
}
if ($value < 0x100000000) {
return "\x1A" . pack('N', $value);
}
return "\x1B" . pack('J', $value);
}
// Major type 1: negative integer (-1 - n)
$value = -1 - $value;
if ($value < 24) {
return chr(0x20 | $value);
}
if ($value < 0x100) {
return "\x38" . chr($value);
}
if ($value < 0x10000) {
return "\x39" . pack('n', $value);
}
if ($value < 0x100000000) {
return "\x3A" . pack('N', $value);
}
return "\x3B" . pack('J', $value);
}
/**
* Encode a text string (major type 3)
*
* @param string $value
* @return string
*/
private function encodeTextString(string $value): string
{
$len = strlen($value);
if ($len < 24) {
return chr(0x60 | $len) . $value;
}
if ($len < 0x100) {
return "\x78" . chr($len) . $value;
}
if ($len < 0x10000) {
return "\x79" . pack('n', $len) . $value;
}
if ($len < 0x100000000) {
return "\x7A" . pack('N', $len) . $value;
}
return "\x7B" . pack('J', $len) . $value;
}
/**
* Encode an array (major type 4)
*
* @param array $value
* @return string
*/
private function encodeArray(array $value): string
{
$count = count($value);
if ($count < 24) {
$result = chr(0x80 | $count);
} elseif ($count < 0x100) {
$result = "\x98" . chr($count);
} elseif ($count < 0x10000) {
$result = "\x99" . pack('n', $count);
} elseif ($count < 0x100000000) {
$result = "\x9A" . pack('N', $count);
} else {
$result = "\x9B" . pack('J', $count);
}
foreach ($value as $item) {
$result .= $this->encodeValue($item);
}
return $result;
}
/**
* Encode a map (major type 5)
*
* @param array $value
* @return string
*/
private function encodeMap(array $value): string
{
$count = count($value);
if ($count < 24) {
$result = chr(0xA0 | $count);
} elseif ($count < 0x100) {
$result = "\xB8" . chr($count);
} elseif ($count < 0x10000) {
$result = "\xB9" . pack('n', $count);
} elseif ($count < 0x100000000) {
$result = "\xBA" . pack('N', $count);
} else {
$result = "\xBB" . pack('J', $count);
}
foreach ($value as $k => $v) {
if (is_int($k)) {
$result .= $this->encodeInteger($k);
} else {
$len = strlen($k);
if ($len < 24) {
$result .= chr(0x60 | $len) . $k;
} elseif ($len < 0x100) {
$result .= "\x78" . chr($len) . $k;
} else {
$result .= "\x79" . pack('n', $len) . $k;
}
}
$result .= $this->encodeValue($v);
}
return $result;
}
/**
* Create an empty map (major type 5 with 0 elements)
*
* @return string
*/
public function encodeEmptyMap(): string
{
return "\xA0";
}
/**
* Create an empty indefinite map (major type 5 indefinite length)
*
* @return string
*/
public function encodeEmptyIndefiniteMap(): string
{
return "\xBF\xFF";
}
}

View File

@@ -0,0 +1,6 @@
<?php
namespace Aws\Api\Cbor\Exception;
use RuntimeException;
class CborException extends RuntimeException {}

View File

@@ -30,11 +30,6 @@ public static function fromEpoch($unixTimestamp)
throw new ParserException('Invalid timestamp value passed to DateTimeResult::fromEpoch');
}
// PHP 5.5 does not support sub-second precision
if (\PHP_VERSION_ID < 56000) {
return new self(gmdate('c', $unixTimestamp));
}
$decimalSeparator = isset(localeconv()['decimal_point']) ? localeconv()['decimal_point'] : ".";
$formatString = "U" . $decimalSeparator . "u";
$dateTime = DateTime::createFromFormat(

View File

@@ -31,19 +31,6 @@ abstract protected function payload(
StructureShape $member
);
protected function extractPayload(
StructureShape $member,
ResponseInterface $response
) {
if ($member instanceof StructureShape) {
// Structure members parse top-level data into a specific key.
return $this->payload($response, $member);
} else {
// Streaming data is just the stream from the response body.
return $response->getBody();
}
}
protected function populateShape(
array &$data,
ResponseInterface $response,
@@ -57,16 +44,15 @@ protected function populateShape(
if (!empty($data['code'])) {
$errors = $this->api->getOperation($command->getName())->getErrors();
foreach ($errors as $key => $error) {
foreach ($errors as $error) {
// If error code matches a known error shape, populate the body
if ($this->errorCodeMatches($data, $error)) {
$modeledError = $error;
$data['body'] = $this->extractPayload(
$modeledError,
$response
$data['body'] = $this->payload(
$response,
$error
);
$data['error_shape'] = $modeledError;
$data['error_shape'] = $error;
foreach ($error->getMembers() as $name => $member) {
switch ($member['location']) {

View File

@@ -0,0 +1,159 @@
<?php
namespace Aws\Api\ErrorParser;
use Aws\Api\Parser\AbstractParser;
use Aws\Api\StructureShape;
use Aws\CommandInterface;
use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\StreamInterface;
/**
* Base implementation for Smithy RPC V2 protocol error parsers.
*
* @internal
*/
abstract class AbstractRpcV2ErrorParser extends AbstractErrorParser
{
private const HEADER_QUERY_ERROR = 'x-amzn-query-error';
private const HEADER_ERROR_TYPE = 'x-amzn-errortype';
private const HEADER_REQUEST_ID = 'x-amzn-requestid';
/**
* @param ResponseInterface $response
* @param CommandInterface|null $command
*
* @return array
*/
public function __invoke(
ResponseInterface $response,
?CommandInterface $command = null
) {
$response = AbstractParser::getResponseWithCachingStream($response);
$data = $this->parseError($response);
if (isset($data['parsed']['__type'])) {
$data['message'] = $data['parsed']['message'] ?? null;
}
$this->populateShape($data, $response, $command);
return $data;
}
/**
* @param ResponseInterface $response
* @param StructureShape $member
*
* @return array
*/
abstract protected function payload(
ResponseInterface $response,
StructureShape $member
): array;
/**
* @param StreamInterface $body
* @param ResponseInterface $response
*
* @return mixed
*/
abstract protected function parseBody(
StreamInterface $body,
ResponseInterface $response
): mixed;
/**
* @param ResponseInterface $response
*
* @return array
*/
private function parseError(ResponseInterface $response): array
{
$statusCode = (string) $response->getStatusCode();
$errorCode = null;
$errorType = null;
if ($this->api?->getMetadata('awsQueryCompatible') !== null
&& $response->hasHeader(self::HEADER_QUERY_ERROR)
&& $awsQueryError = $this->parseQueryCompatibleHeader($response)
) {
$errorCode = $awsQueryError['code'];
$errorType = $awsQueryError['type'];
}
if (!$errorCode && $response->hasHeader(self::HEADER_ERROR_TYPE)) {
$errorCode = $this->extractErrorCode(
$response->getHeaderLine(self::HEADER_ERROR_TYPE)
);
}
$parsedBody = null;
$body = $response->getBody();
if ($body->getSize()) {
//TODO handle unseekable streams with CachingStream
$parsedBody = array_change_key_case($this->parseBody($body, $response));
}
if (!$errorCode && $parsedBody) {
$errorCode = $this->extractErrorCode(
$parsedBody['code'] ?? $parsedBody['__type'] ?? ''
);
}
return [
'request_id' => $response->getHeaderLine(self::HEADER_REQUEST_ID),
'code' => $errorCode ?: null,
'message' => null,
'type' => $errorType ?? ($statusCode[0] === '4' ? 'client' : 'server'),
'parsed' => $parsedBody,
];
}
/**
* Parse AWS Query Compatible error from header
*
* @param ResponseInterface $response
*
* @return array|null Returns ['code' => string, 'type' => string] or null
*/
private function parseQueryCompatibleHeader(ResponseInterface $response): ?array
{
$parts = explode(';', $response->getHeaderLine(self::HEADER_QUERY_ERROR));
if (count($parts) === 2 && $parts[0] && $parts[1]) {
return [
'code' => $parts[0],
'type' => $parts[1],
];
}
return null;
}
/**
* Extract error code from raw error string containing # and/or : delimiters
*
* @param string $rawErrorCode
* @return string
*/
private function extractErrorCode(string $rawErrorCode): string
{
// Handle format with both # and uri (e.g., "namespace#ErrorCode:http://foo-bar")
if (str_contains($rawErrorCode, ':') && str_contains($rawErrorCode, '#')) {
$start = strpos($rawErrorCode, '#') + 1;
$end = strpos($rawErrorCode, ':', $start);
return substr($rawErrorCode, $start, $end - $start);
}
// Handle format with uri only : (e.g., "ErrorCode:http://foo-bar.com/baz")
if (str_contains($rawErrorCode, ':')) {
return substr($rawErrorCode, 0, strpos($rawErrorCode, ':'));
}
// Handle format with only # (e.g., "namespace#ErrorCode")
if (str_contains($rawErrorCode, '#')) {
return substr($rawErrorCode, strpos($rawErrorCode, '#') + 1);
}
return $rawErrorCode;
}
}

View File

@@ -1,6 +1,7 @@
<?php
namespace Aws\Api\ErrorParser;
use Aws\Api\Parser\AbstractParser;
use Aws\Api\Parser\PayloadParserTrait;
use Aws\Api\StructureShape;
use Psr\Http\Message\ResponseInterface;
@@ -38,9 +39,10 @@ private function genericHandler(ResponseInterface $response): array
}
$parsedBody = null;
$body = $response->getBody();
if (!$body->isSeekable() || $body->getSize()) {
$parsedBody = $this->parseJson((string) $body, $response);
$rawBody = AbstractParser::getBodyContents($response);
if (!empty($rawBody)) {
$parsedBody = $this->parseJson($rawBody, $response);
}
// Parse error code from response body
@@ -132,11 +134,12 @@ protected function payload(
ResponseInterface $response,
StructureShape $member
) {
$body = $response->getBody();
if (!$body->isSeekable() || $body->getSize()) {
$jsonBody = $this->parseJson($body, $response);
$rawBody = AbstractParser::getBodyContents($response);
if (!empty($rawBody)) {
$jsonBody = $this->parseJson($rawBody, $response);
} else {
$jsonBody = (string) $body;
$jsonBody = $rawBody;
}
return $this->parser->parse($member, $jsonBody);

View File

@@ -1,6 +1,7 @@
<?php
namespace Aws\Api\ErrorParser;
use Aws\Api\Parser\AbstractParser;
use Aws\Api\Parser\JsonParser;
use Aws\Api\Service;
use Aws\CommandInterface;
@@ -25,6 +26,7 @@ public function __invoke(
ResponseInterface $response,
?CommandInterface $command = null
) {
$response = AbstractParser::getResponseWithCachingStream($response);
$data = $this->genericHandler($response);
// Make the casing consistent across services.

View File

@@ -1,6 +1,7 @@
<?php
namespace Aws\Api\ErrorParser;
use Aws\Api\Parser\AbstractParser;
use Aws\Api\Parser\JsonParser;
use Aws\Api\Service;
use Aws\Api\StructureShape;
@@ -26,6 +27,7 @@ public function __invoke(
ResponseInterface $response,
?CommandInterface $command = null
) {
$response = AbstractParser::getResponseWithCachingStream($response);
$data = $this->genericHandler($response);
// Merge in error data from the JSON body
@@ -40,7 +42,9 @@ public function __invoke(
// Retrieve error message directly
$data['message'] = $data['parsed']['message']
?? ($data['parsed']['Message'] ?? null);
?? $data['parsed']['Message']
?? $data['parsed']['error_description']
?? null;
$this->populateShape($data, $response, $command);

View File

@@ -0,0 +1,65 @@
<?php
namespace Aws\Api\ErrorParser;
use Aws\Api\Cbor\CborDecoder;
use Aws\Api\Parser\RpcV2ParserTrait;
use Aws\Api\Service;
use Aws\Api\StructureShape;
use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\StreamInterface;
/**
* Parses errors according to Smithy RPC V2 CBOR protocol standards.
*
* https://smithy.io/2.0/additional-specs/protocols/smithy-rpc-v2.html
*
* @internal
*/
final class RpcV2CborErrorParser extends AbstractRpcV2ErrorParser
{
/** @var CborDecoder */
private CborDecoder $decoder;
use RpcV2ParserTrait;
/**
* @param Service|null $api
*/
public function __construct(?Service $api = null)
{
$this->decoder = new CborDecoder();
parent::__construct($api);
}
/**
* @param ResponseInterface $response
* @param StructureShape $member
*
* @return array
* @throws \Exception
*/
protected function payload(
ResponseInterface $response,
StructureShape $member
): array
{
$body = $response->getBody();
$cborBody = $this->parseCbor($body, $response);
return $this->resolveOutputShape($member, $cborBody);
}
/**
* @param StreamInterface $body
* @param ResponseInterface $response
*
* @return mixed
*/
protected function parseBody(
StreamInterface $body,
ResponseInterface $response
): mixed
{
return $this->parseCbor($body, $response);
}
}

View File

@@ -1,6 +1,7 @@
<?php
namespace Aws\Api\ErrorParser;
use Aws\Api\Parser\AbstractParser;
use Aws\Api\Parser\PayloadParserTrait;
use Aws\Api\Parser\XmlParser;
use Aws\Api\Service;
@@ -27,6 +28,7 @@ public function __invoke(
ResponseInterface $response,
?CommandInterface $command = null
) {
$response = AbstractParser::getResponseWithCachingStream($response);
$code = (string) $response->getStatusCode();
$data = [
@@ -37,9 +39,9 @@ public function __invoke(
'parsed' => null
];
$body = $response->getBody();
if ($body->getSize() > 0) {
$this->parseBody($this->parseXml($body, $response), $data);
$rawBody = AbstractParser::getBodyContents($response);
if (!empty($rawBody)) {
$this->parseBody($this->parseXml($rawBody, $response), $data);
} else {
$this->parseHeaders($response, $data);
}
@@ -100,12 +102,20 @@ protected function payload(
ResponseInterface $response,
StructureShape $member
) {
$xmlBody = $this->parseXml($response->getBody(), $response);
$rawBody = AbstractParser::getBodyContents($response);
if (empty($rawBody)) {
return $rawBody;
}
$xmlBody = $this->parseXml($rawBody, $response);
$prefix = $this->registerNamespacePrefix($xmlBody);
$errorBody = $xmlBody->xpath("//{$prefix}Error");
if (is_array($errorBody) && !empty($errorBody[0])) {
return $this->parser->parse($member, $errorBody[0]);
}
return $rawBody;
}
}

View File

@@ -0,0 +1,11 @@
<?php
namespace Aws\Api\Exception;
use Aws\HasMonitoringEventsTrait;
use Aws\MonitoringEventsInterface;
class RpcV2CborException extends \RuntimeException implements
MonitoringEventsInterface
{
use HasMonitoringEventsTrait;
}

View File

@@ -89,7 +89,7 @@ public function getOutput()
/**
* Get an array of operation error shapes.
*
* @return Shape[]
* @return StructureShape[]
*/
public function getErrors()
{

View File

@@ -5,6 +5,7 @@
use Aws\Api\StructureShape;
use Aws\CommandInterface;
use Aws\ResultInterface;
use GuzzleHttp\Psr7\CachingStream;
use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\StreamInterface;
@@ -43,4 +44,27 @@ abstract public function parseMemberFromStream(
StructureShape $member,
$response
);
public static function getBodyContents(ResponseInterface $response): string
{
$body = $response->getBody();
if ($body->isSeekable()) {
$body->rewind();
}
return $body->getContents();
}
public static function getResponseWithCachingStream(
ResponseInterface $response
): ResponseInterface
{
if (!$response->getBody()->isSeekable()) {
return $response->withBody(
new CachingStream($response->getBody())
);
}
return $response;
}
}

View File

@@ -39,6 +39,21 @@ public function __invoke(
if ($payload = $output['payload']) {
$this->extractPayload($payload, $output, $response, $result);
} else {
$response = AbstractParser::getResponseWithCachingStream($response);
if ($response->getBody()->getSize() === null) {
$rawBody = AbstractParser::getBodyContents($response);
$isEmpty = empty($rawBody);
} else {
$isEmpty = $response->getBody()->getSize() === 0;
}
if (!$isEmpty && count($output->getMembers()) > 0
) {
// if no payload was found, then parse the contents of the body
$this->payload($response, $output, $result);
}
}
foreach ($output->getMembers() as $name => $member) {
@@ -55,15 +70,6 @@ public function __invoke(
}
}
$body = $response->getBody();
if (!$payload
&& (!$body->isSeekable() || $body->getSize())
&& count($output->getMembers()) > 0
) {
// if no payload was found, then parse the contents of the body
$this->payload($response, $output, $result);
}
return new Result($result);
}
@@ -75,17 +81,29 @@ private function extractPayload(
) {
$member = $output->getMember($payload);
$body = $response->getBody();
if (!empty($member['eventstream'])) {
$result[$payload] = new EventParsingIterator(
$body,
$member,
$this
);
} elseif ($member instanceof StructureShape) {
return;
}
$response = AbstractParser::getResponseWithCachingStream($response);
if ($member instanceof StructureShape) {
//Unions must have at least one member set to a non-null value
// If the body is empty, we can assume it is unset
if (!empty($member['union']) && ($body->isSeekable() && !$body->getSize())) {
if ($response->getBody()->getSize() === null) {
$rawBody = AbstractParser::getBodyContents($response);
$isEmpty = empty($rawBody);
} else {
$isEmpty = $response->getBody()->getSize() === 0;
}
if (!empty($member['union']) && $isEmpty) {
return;
}

View File

@@ -0,0 +1,83 @@
<?php
namespace Aws\Api\Parser;
use Aws\Api\Operation;
use Aws\Api\Parser\Exception\ParserException;
use Aws\Result;
use Aws\CommandInterface;
use Psr\Http\Message\ResponseInterface;
/**
* Base implementation for Smithy RPC V2 protocol parsers.
*
* Implementers MUST define the following static property representing
* the `Smithy-Protocol` header value:
* self::HEADER_SMITHY_PROTOCOL => static::$smithyProtocol
*
* @internal
*/
abstract class AbstractRpcV2Parser extends AbstractParser
{
private const HEADER_SMITHY_PROTOCOL = 'Smithy-Protocol';
/** @var string */
protected static string $smithyProtocol;
public function __invoke(
CommandInterface $command,
ResponseInterface $response
) {
$operation = $this->api->getOperation($command->getName());
return $this->parseResponse($response, $operation);
}
/**
* Parses a response according to Smithy RPC V2 protocol standards.
*
* @param ResponseInterface $response the response to parse.
* @param Operation $operation the operation which holds information for
* parsing the response.
*
* @return Result
*/
private function parseResponse(
ResponseInterface $response,
Operation $operation
): Result
{
$smithyProtocolHeader = $response->getHeaderLine(self::HEADER_SMITHY_PROTOCOL);
if ($smithyProtocolHeader !== static::$smithyProtocol) {
$statusCode = $response->getStatusCode();
throw new ParserException(
"Malformed response: Smithy-Protocol header mismatch (HTTP {$statusCode}). "
. 'Expected ' . static::$smithyProtocol
);
}
if ($operation['output'] === null) {
return new Result([]);
}
$outputShape = $operation->getOutput();
foreach ($outputShape->getMembers() as $memberName => $memberProps) {
if (!empty($memberProps['eventstream'])) {
return new Result([
$memberName => new EventParsingIterator(
$response->getBody(),
$outputShape->getMember($memberName),
$this
)
]);
}
}
$result = $this->parseMemberFromStream(
$response->getBody(),
$outputShape,
$response
);
return new Result(is_null($result) ? [] : $result);
}
}

View File

@@ -63,11 +63,16 @@ private function parseResponse(ResponseInterface $response, Operation $operation
}
}
$body = $response->getBody();
if ($body->isSeekable()) {
$body->rewind();
}
$result = $this->parseMemberFromStream(
$response->getBody(),
$operation->getOutput(),
$response
);
$body,
$operation->getOutput(),
$response
);
return new Result(is_null($result) ? [] : $result);
}

View File

@@ -2,7 +2,6 @@
namespace Aws\Api\Parser;
use Aws\Api\Parser\Exception\ParserException;
use Psr\Http\Message\ResponseInterface;
trait PayloadParserTrait
{

View File

@@ -40,9 +40,11 @@ public function __invoke(
ResponseInterface $response
) {
$output = $this->api->getOperation($command->getName())->getOutput();
$body = $response->getBody();
$xml = !$body->isSeekable() || $body->getSize()
? $this->parseXml($body, $response)
// Read the full payload, even in non-seekable streams
$rawBody = AbstractParser::getBodyContents($response);
// Just parse when the body is not empty
$xml = !empty($rawBody)
? $this->parseXml($rawBody, $response)
: null;
// Empty request bodies should not be deserialized.

View File

@@ -28,15 +28,14 @@ protected function payload(
StructureShape $member,
array &$result
) {
$responseBody = (string) $response->getBody();
$rawBody = AbstractParser::getBodyContents($response);
// Parse JSON if we have content
$parsedJson = null;
if (!empty($responseBody)) {
$parsedJson = $this->parseJson($responseBody, $response);
if (!empty($rawBody)) {
$parsedJson = $this->parseJson($rawBody, $response);
} else {
// An empty response body should be deserialized as null
$result = $parsedJson;
$result = null;
return;
}

View File

@@ -28,7 +28,12 @@ protected function payload(
StructureShape $member,
array &$result
) {
$result += $this->parseMemberFromStream($response->getBody(), $member, $response);
$body = $response->getBody();
if ($body->isSeekable()) {
$body->rewind();
}
$result += $this->parseMemberFromStream($body, $member, $response);
}
public function parseMemberFromStream(

View File

@@ -0,0 +1,50 @@
<?php
namespace Aws\Api\Parser;
use Aws\Api\Cbor\CborDecoder;
use Aws\Api\Service;
use Aws\Api\StructureShape;
use Psr\Http\Message\StreamInterface;
/**
* Parses responses according to Smithy RPC V2 CBOR protocol standards.
*
* https://smithy.io/2.0/additional-specs/protocols/smithy-rpc-v2.html
*
* @internal
*/
final class RpcV2CborParser extends AbstractRpcV2Parser
{
/** @var string */
protected static string $smithyProtocol = 'rpc-v2-cbor';
/** @var CborDecoder */
private CborDecoder $decoder;
use RpcV2ParserTrait;
/**
* @param Service $api Service description
*/
public function __construct(Service $api)
{
$this->decoder = new CborDecoder();
parent::__construct($api);
}
/**
* @param StreamInterface $stream
* @param StructureShape $member
* @param $response
*
* @return mixed
*/
public function parseMemberFromStream(
StreamInterface $stream,
StructureShape $member,
$response
): mixed
{
return $this->resolveOutputShape($member, $this->parseCbor($stream, $response));
}
}

View File

@@ -0,0 +1,105 @@
<?php
namespace Aws\Api\Parser;
use Aws\Api\Cbor\Exception\CborException;
use Aws\Api\DateTimeResult;
use Aws\Api\Parser\Exception\ParserException;
use Aws\Api\Shape;
use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\StreamInterface;
/**
* Shared parsing logic for RPC V2 Parsers.
*
* @internal
*/
trait RpcV2ParserTrait
{
/**
* Resolves output shape fields that are present in the response
*
* @param Shape $shape
* @param mixed $value
*
* @return mixed
*/
protected function resolveOutputShape(Shape $shape, mixed $value): mixed
{
if ($value === null) {
return $value;
}
switch ($shape['type']) {
case 'structure':
$target = [];
foreach ($shape->getMembers() as $name => $member) {
$locationName = $member['locationName'] ?: $name;
if (isset($value[$locationName])) {
$target[$name] = $this->resolveOutputShape($member, $value[$locationName]);
}
}
return $target;
case 'list':
$target = [];
foreach ($value as $v) {
$target[] = $this->resolveOutputShape($shape->getMember(), $v);
}
return $target;
case 'map':
$target = [];
foreach ($value as $k => $v) {
if ($v !== null) {
$target[$k] = $this->resolveOutputShape($shape->getValue(), $v);
}
}
return $target;
case 'timestamp':
try {
$value = DateTimeResult::fromEpoch($value);
} catch (\Exception $e) {
trigger_error(
'Unable to parse timestamp value for '
. $shape->getName()
. ': ' . $e->getMessage(),
E_USER_WARNING
);
}
return $value;
default:
return $value;
}
}
/**
* Parses CBOR-encoded response data from RPC V2 CBOR services.
*
* @param StreamInterface $stream
* @param ResponseInterface $response
*
* @return mixed
*/
protected function parseCbor(
StreamInterface $stream,
ResponseInterface $response
): mixed
{
try {
$cborString = (string) $stream;
return empty($cborString)
? null
: $this->decoder->decode($cborString);
} catch (CborException $e) {
throw new ParserException(
"Malformed Response: error parsing CBOR: {$e->getMessage()}",
0,
$e,
['response' => $response]
);
}
}
}

View File

@@ -0,0 +1,220 @@
<?php
namespace Aws\Api\Serializer;
use Aws\Api\Service;
use Aws\Api\Shape;
use Aws\Api\StructureShape;
use Aws\CommandInterface;
use Aws\EndpointV2\EndpointV2SerializerTrait;
use Aws\EndpointV2\Ruleset\RulesetEndpoint;
use DateTimeInterface;
use GuzzleHttp\Psr7;
use GuzzleHttp\Psr7\Request;
use GuzzleHttp\Psr7\Uri;
use Psr\Http\Message\RequestInterface;
/**
* Base implementation for Smithy RPC V2 protocol serializers.
*
* Implementers MUST override the defaultHeader property to represent
* protocol-specific default header values:
* self::HEADER_SMITHY_PROTOCOL => static::SMITHY_PROTOCOL,
* self::HEADER_CONTENT_TYPE => static::DEFAULT_CONTENT_TYPE,
* self::HEADER_ACCEPT => static::DEFAULT_ACCEPT
*
* Implementers must also implement `serialize()`, `resolveBlob()`, and `resolveTimestamp()
* according to their respective protocol specifications.
*
* @internal
*/
abstract class AbstractRpcV2Serializer
{
protected const HEADER_SMITHY_PROTOCOL = 'Smithy-Protocol';
protected const HEADER_CONTENT_TYPE = 'Content-Type';
protected const HEADER_ACCEPT = 'Accept';
/** @var array */
protected static array $defaultHeaders;
/** @var Service */
private Service $api;
/** @var string|Uri */
private string|Uri $endpoint;
/** @var bool */
private bool $isUseEndpointV2;
use EndpointV2SerializerTrait;
/**
* @param Service $api Service API description
* @param string $endpoint Endpoint to connect to
*/
public function __construct(Service $api, string|Uri $endpoint)
{
$this->api = $api;
$this->endpoint = Psr7\Utils::uriFor($endpoint);
}
/**
* @param CommandInterface $command Command to serialize into a request.
* @param mixed|null $endpoint
*
* @return RequestInterface
*/
public function __invoke(
CommandInterface $command,
mixed $endpoint = null
)
{
$commandArgs = $command->toArray();
$commandName = $command->getName();
$operation = $this->api->getOperation($commandName);
$headers = static::$defaultHeaders;
// Operations with no defined input type must not contain bodies
// Content-Type must not be set
if ($operation['input'] !== null) {
$body = $this->serialize($operation->getInput(), $commandArgs);
$headers['Content-Length'] = strlen($body);
} else {
unset($headers['Content-Type']);
}
if ($endpoint instanceof RulesetEndpoint) {
$this->isUseEndpointV2 = true;
$this->setEndpointV2RequestOptions($endpoint, $headers);
$this->endpoint = $endpoint->getUrl();
}
$requestTarget = $this->buildRequestTarget(
$commandName,
$operation['http']['requestUri'] ?? ''
);
$uri = new Uri($this->endpoint . $requestTarget);
return new Request(
$operation['http']['method'],
$uri,
$headers,
$body ?? null
);
}
/**
* @param StructureShape $inputShape
* @param array $commandArgs
*
* @return string
*/
abstract public function serialize(
StructureShape $inputShape,
array $commandArgs
): string;
/**
* Resolves arguments for blob shapes present in the request arguments
* into a protocol-specific format.
*
* @param mixed $value
*
* @return array
*/
abstract protected function resolveBlob(mixed $value): array;
/**
* Resolves arguments for timestamp shapes present in the request arguments
* into a protocol-specific format.
*
* @param mixed $value
*
* @return array
*/
abstract protected function resolveTimestamp(
int|float|string|DateTimeInterface $value
): array;
/**
* Resolves input shape fields that are present in the request arguments
*
* @param Shape $shape
* @param mixed $value
*
* @return mixed
*/
protected function resolveInputShape(Shape $shape, mixed $value): mixed
{
switch ($shape->getType()) {
case 'structure':
$data = [];
foreach ($value as $k => $v) {
if ($v !== null && $shape->hasMember($k)) {
$valueShape = $shape->getMember($k);
$data[$valueShape['locationName'] ?: $k]
= $this->resolveInputShape($valueShape, $v);
}
}
return $data;
case 'list':
$items = $shape->getMember();
foreach ($value as $k => $v) {
$value[$k] = $this->resolveInputShape($items, $v);
}
return $value;
case 'map':
$values = $shape->getValue();
foreach ($value as $k => $v) {
$value[$k] = $this->resolveInputShape($values, $v);
}
return $value;
case 'timestamp':
return $this->resolveTimestamp($value);
case 'string':
return (string) $value;
case 'integer':
case 'long':
return (int) $value;
case 'double':
case 'float':
return (float) $value;
case 'blob':
return $this->resolveBlob($value);
default:
return $value;
}
}
/**
* Builds request URI absolute path
*
* @param string $commandName
* @param string $requestUri
*
* @return string
*/
private function buildRequestTarget(
string $commandName,
string $requestUri
): string
{
$requestUri = str_ends_with($requestUri, '/')
? $requestUri
: $requestUri . '/';
$targetPrefix = $this->api->getMetadata('targetPrefix');
return "{$requestUri}service/{$targetPrefix}/operation/{$commandName}";
}
}

View File

@@ -0,0 +1,124 @@
<?php
namespace Aws\Api\Serializer;
use Aws\Api\Cbor\CborEncoder;
use Aws\Api\Cbor\Exception\CborException;
use Aws\Api\Exception\RpcV2CborException;
use Aws\Api\Service;
use Aws\Api\StructureShape;
use DateTimeInterface;
/**
* Serializes requests according to Smithy RPC-V2 CBOR protocol standards.
*
* https://smithy.io/2.0/additional-specs/protocols/smithy-rpc-v2.html
*
* @internal
*/
final class RpcV2CborSerializer extends AbstractRpcV2Serializer
{
/** @var array|string[] */
protected static array $defaultHeaders = [
self::HEADER_SMITHY_PROTOCOL => 'rpc-v2-cbor',
self::HEADER_CONTENT_TYPE => 'application/cbor',
self::HEADER_ACCEPT => 'application/cbor',
];
/** @var CborEncoder */
private CborEncoder $encoder;
/**
* @param Service $api Service API description
* @param string $endpoint Endpoint to connect to
*/
public function __construct(Service $api, string $endpoint)
{
$this->encoder = new CborEncoder();
parent::__construct($api, $endpoint);
}
/**
* @param StructureShape $inputShape
* @param array $commandArgs
*
* @return string
* @throws RpcV2CborException
*/
public function serialize(
StructureShape $inputShape,
array $commandArgs
): string
{
try {
$resolvedInput = $this->resolveInputShape($inputShape, $commandArgs);
return !empty($resolvedInput)
? $this->encoder->encode($resolvedInput)
: $this->encoder->encodeEmptyIndefiniteMap();
} catch (CborException $e) {
throw new RpcV2CborException(
'Unable to encode CBOR document ' . $inputShape->getName() . ': ' .
$e->getMessage() . PHP_EOL
);
}
}
/**
* Wraps blob values in order to be encoded properly into
* byte strings.
*
* @param mixed $value
*
* @return string[]
* @throws RpcV2CborException
*/
protected function resolveBlob(mixed $value): array
{
if (is_resource($value)) {
$value = stream_get_contents($value);
if ($value === false) {
throw new RpcV2CborException(
'Failed to read resource stream value during serialization',
);
}
}
// Wrapper to differentiate byte string values during encoding
return ['__cbor_bytes' => (string) $value];
}
/**
* Wraps timestamp values in order to be encoded properly into
* value tag 1.
*
* @param mixed $value
*
* @return string[]
* @throws RpcV2CborException
*/
protected function resolveTimestamp(
int|float|string|DateTimeInterface $value
): array
{
if (is_numeric($value)) {
return ['__cbor_timestamp' => $value];
}
if ($value instanceof DateTimeInterface) {
// Preserve milliseconds
$micro = (int) $value->format('u');
$value = $value->getTimestamp() + $micro / 1e6;
} else {
$timestamp = strtotime($value);
if ($timestamp === false) {
throw new RpcV2CborException(
'Request serialization failed: Invalid date/time: ' . $value,
);
}
$value = $timestamp;
}
// Wrapper to differentiate timestamp values during encoding
return ['__cbor_timestamp' => $value];
}
}

View File

@@ -91,7 +91,8 @@ public static function createSerializer(Service $api, $endpoint)
'json' => Serializer\JsonRpcSerializer::class,
'query' => Serializer\QuerySerializer::class,
'rest-json' => Serializer\RestJsonSerializer::class,
'rest-xml' => Serializer\RestXmlSerializer::class
'rest-xml' => Serializer\RestXmlSerializer::class,
'smithy-rpc-v2-cbor' => Serializer\RpcV2CborSerializer::class
];
$proto = $api->getProtocol();
@@ -126,7 +127,8 @@ public static function createErrorParser($protocol, ?Service $api = null)
'query' => ErrorParser\XmlErrorParser::class,
'rest-json' => ErrorParser\RestJsonErrorParser::class,
'rest-xml' => ErrorParser\XmlErrorParser::class,
'ec2' => ErrorParser\XmlErrorParser::class
'ec2' => ErrorParser\XmlErrorParser::class,
'smithy-rpc-v2-cbor' => ErrorParser\RpcV2CborErrorParser::class
];
if (isset($mapping[$protocol])) {
@@ -149,7 +151,8 @@ public static function createParser(Service $api)
'json' => Parser\JsonRpcParser::class,
'query' => Parser\QueryParser::class,
'rest-json' => Parser\RestJsonParser::class,
'rest-xml' => Parser\RestXmlParser::class
'rest-xml' => Parser\RestXmlParser::class,
'smithy-rpc-v2-cbor' => Parser\RpcV2CborParser::class
];
$proto = $api->getProtocol();

View File

@@ -8,6 +8,7 @@
enum SupportedProtocols: string
{
case JSON = 'json';
case CBOR = 'smithy-rpc-v2-cbor';
case REST_JSON = 'rest-json';
case REST_XML = 'rest-xml';
case QUERY = 'query';

View File

@@ -28,16 +28,16 @@ public static function format($value, $format)
$value = $value->getTimestamp();
} elseif (is_string($value)) {
$value = strtotime($value);
} elseif (!is_int($value)) {
} elseif (!is_int($value) && !is_float($value)) {
throw new \InvalidArgumentException('Unable to handle the provided'
. ' timestamp type: ' . gettype($value));
}
switch ($format) {
case 'iso8601':
return gmdate('Y-m-d\TH:i:s\Z', $value);
return gmdate('Y-m-d\TH:i:s\Z', (int) $value);
case 'rfc822':
return gmdate('D, d M Y H:i:s \G\M\T', $value);
return gmdate('D, d M Y H:i:s \G\M\T', (int) $value);
case 'unixTimestamp':
return $value;
default:

View File

@@ -131,6 +131,8 @@
* @method \GuzzleHttp\Promise\Promise disassociateFleetAsync(array $args = [])
* @method \Aws\Result disassociateSoftwareFromImageBuilder(array $args = [])
* @method \GuzzleHttp\Promise\Promise disassociateSoftwareFromImageBuilderAsync(array $args = [])
* @method \Aws\Result drainSessionInstance(array $args = [])
* @method \GuzzleHttp\Promise\Promise drainSessionInstanceAsync(array $args = [])
* @method \Aws\Result enableUser(array $args = [])
* @method \GuzzleHttp\Promise\Promise enableUserAsync(array $args = [])
* @method \Aws\Result expireSession(array $args = [])

View File

@@ -283,6 +283,7 @@ public function __construct(array $args)
$args['with_resolved']($config);
}
$this->addUserAgentMiddleware($config);
$this->addEventStreamHttpFlagMiddleware();
}
public function getHandlerList()
@@ -649,6 +650,33 @@ private function addUserAgentMiddleware($args)
);
}
/**
* Enables streaming the response by using the stream flag.
*
* @return void
*/
private function addEventStreamHttpFlagMiddleware(): void
{
$this->getHandlerList()
-> appendInit(
function (callable $handler) {
return function (CommandInterface $command, $request = null) use ($handler) {
$operation = $this->getApi()->getOperation($command->getName());
$output = $operation->getOutput();
foreach ($output->getMembers() as $memberProps) {
if (!empty($memberProps['eventstream'])) {
$command['@http']['stream'] = true;
break;
}
}
return $handler($command, $request);
};
},
'event-streaming-flag-middleware'
);
}
/**
* Retrieves client context param definition from service model,
* creates mapping of client context param names with client-provided
@@ -737,29 +765,6 @@ protected function isUseEndpointV2()
return $this->endpointProvider instanceof EndpointProviderV2;
}
public static function emitDeprecationWarning() {
trigger_error(
"This method is deprecated. It will be removed in an upcoming release."
, E_USER_DEPRECATED
);
$phpVersion = PHP_VERSION_ID;
if ($phpVersion < 70205) {
$phpVersionString = phpversion();
@trigger_error(
"This installation of the SDK is using PHP version"
. " {$phpVersionString}, which will be deprecated on August"
. " 15th, 2023. Please upgrade your PHP version to a minimum of"
. " 7.2.5 before then to continue receiving updates to the AWS"
. " SDK for PHP. To disable this warning, set"
. " suppress_php_deprecation_warning to true on the client constructor"
. " or set the environment variable AWS_SUPPRESS_PHP_DEPRECATION_WARNING"
. " to true.",
E_USER_DEPRECATED
);
}
}
/**
* Returns a service model and doc model with any necessary changes

View File

@@ -75,7 +75,7 @@ public function __call($name, array $args)
$name = $this->aliases[ucfirst($name)];
}
$params = isset($args[0]) ? $args[0] : [];
$params = $args['args'] ?? $args[0] ?? [];
if (!empty($isAsync)) {
return $this->executeAsync(

View File

@@ -7,14 +7,24 @@
* This client is used to interact with the **AWS Billing and Cost Management Dashboards** service.
* @method \Aws\Result createDashboard(array $args = [])
* @method \GuzzleHttp\Promise\Promise createDashboardAsync(array $args = [])
* @method \Aws\Result createScheduledReport(array $args = [])
* @method \GuzzleHttp\Promise\Promise createScheduledReportAsync(array $args = [])
* @method \Aws\Result deleteDashboard(array $args = [])
* @method \GuzzleHttp\Promise\Promise deleteDashboardAsync(array $args = [])
* @method \Aws\Result deleteScheduledReport(array $args = [])
* @method \GuzzleHttp\Promise\Promise deleteScheduledReportAsync(array $args = [])
* @method \Aws\Result executeScheduledReport(array $args = [])
* @method \GuzzleHttp\Promise\Promise executeScheduledReportAsync(array $args = [])
* @method \Aws\Result getDashboard(array $args = [])
* @method \GuzzleHttp\Promise\Promise getDashboardAsync(array $args = [])
* @method \Aws\Result getResourcePolicy(array $args = [])
* @method \GuzzleHttp\Promise\Promise getResourcePolicyAsync(array $args = [])
* @method \Aws\Result getScheduledReport(array $args = [])
* @method \GuzzleHttp\Promise\Promise getScheduledReportAsync(array $args = [])
* @method \Aws\Result listDashboards(array $args = [])
* @method \GuzzleHttp\Promise\Promise listDashboardsAsync(array $args = [])
* @method \Aws\Result listScheduledReports(array $args = [])
* @method \GuzzleHttp\Promise\Promise listScheduledReportsAsync(array $args = [])
* @method \Aws\Result listTagsForResource(array $args = [])
* @method \GuzzleHttp\Promise\Promise listTagsForResourceAsync(array $args = [])
* @method \Aws\Result tagResource(array $args = [])
@@ -23,5 +33,7 @@
* @method \GuzzleHttp\Promise\Promise untagResourceAsync(array $args = [])
* @method \Aws\Result updateDashboard(array $args = [])
* @method \GuzzleHttp\Promise\Promise updateDashboardAsync(array $args = [])
* @method \Aws\Result updateScheduledReport(array $args = [])
* @method \GuzzleHttp\Promise\Promise updateScheduledReportAsync(array $args = [])
*/
class BCMDashboardsClient extends AwsClient {}

View File

@@ -13,6 +13,8 @@
* @method \GuzzleHttp\Promise\Promise createConsumableResourceAsync(array $args = [])
* @method \Aws\Result createJobQueue(array $args = [])
* @method \GuzzleHttp\Promise\Promise createJobQueueAsync(array $args = [])
* @method \Aws\Result createQuotaShare(array $args = [])
* @method \GuzzleHttp\Promise\Promise createQuotaShareAsync(array $args = [])
* @method \Aws\Result createSchedulingPolicy(array $args = [])
* @method \GuzzleHttp\Promise\Promise createSchedulingPolicyAsync(array $args = [])
* @method \Aws\Result createServiceEnvironment(array $args = [])
@@ -23,6 +25,8 @@
* @method \GuzzleHttp\Promise\Promise deleteConsumableResourceAsync(array $args = [])
* @method \Aws\Result deleteJobQueue(array $args = [])
* @method \GuzzleHttp\Promise\Promise deleteJobQueueAsync(array $args = [])
* @method \Aws\Result deleteQuotaShare(array $args = [])
* @method \GuzzleHttp\Promise\Promise deleteQuotaShareAsync(array $args = [])
* @method \Aws\Result deleteSchedulingPolicy(array $args = [])
* @method \GuzzleHttp\Promise\Promise deleteSchedulingPolicyAsync(array $args = [])
* @method \Aws\Result deleteServiceEnvironment(array $args = [])
@@ -39,6 +43,8 @@
* @method \GuzzleHttp\Promise\Promise describeJobQueuesAsync(array $args = [])
* @method \Aws\Result describeJobs(array $args = [])
* @method \GuzzleHttp\Promise\Promise describeJobsAsync(array $args = [])
* @method \Aws\Result describeQuotaShare(array $args = [])
* @method \GuzzleHttp\Promise\Promise describeQuotaShareAsync(array $args = [])
* @method \Aws\Result describeSchedulingPolicies(array $args = [])
* @method \GuzzleHttp\Promise\Promise describeSchedulingPoliciesAsync(array $args = [])
* @method \Aws\Result describeServiceEnvironments(array $args = [])
@@ -53,6 +59,8 @@
* @method \GuzzleHttp\Promise\Promise listJobsAsync(array $args = [])
* @method \Aws\Result listJobsByConsumableResource(array $args = [])
* @method \GuzzleHttp\Promise\Promise listJobsByConsumableResourceAsync(array $args = [])
* @method \Aws\Result listQuotaShares(array $args = [])
* @method \GuzzleHttp\Promise\Promise listQuotaSharesAsync(array $args = [])
* @method \Aws\Result listSchedulingPolicies(array $args = [])
* @method \GuzzleHttp\Promise\Promise listSchedulingPoliciesAsync(array $args = [])
* @method \Aws\Result listServiceJobs(array $args = [])
@@ -79,9 +87,13 @@
* @method \GuzzleHttp\Promise\Promise updateConsumableResourceAsync(array $args = [])
* @method \Aws\Result updateJobQueue(array $args = [])
* @method \GuzzleHttp\Promise\Promise updateJobQueueAsync(array $args = [])
* @method \Aws\Result updateQuotaShare(array $args = [])
* @method \GuzzleHttp\Promise\Promise updateQuotaShareAsync(array $args = [])
* @method \Aws\Result updateSchedulingPolicy(array $args = [])
* @method \GuzzleHttp\Promise\Promise updateSchedulingPolicyAsync(array $args = [])
* @method \Aws\Result updateServiceEnvironment(array $args = [])
* @method \GuzzleHttp\Promise\Promise updateServiceEnvironmentAsync(array $args = [])
* @method \Aws\Result updateServiceJob(array $args = [])
* @method \GuzzleHttp\Promise\Promise updateServiceJobAsync(array $args = [])
*/
class BatchClient extends AwsClient {}

View File

@@ -71,6 +71,8 @@
* @method \GuzzleHttp\Promise\Promise deletePromptRouterAsync(array $args = [])
* @method \Aws\Result deleteProvisionedModelThroughput(array $args = [])
* @method \GuzzleHttp\Promise\Promise deleteProvisionedModelThroughputAsync(array $args = [])
* @method \Aws\Result deleteResourcePolicy(array $args = [])
* @method \GuzzleHttp\Promise\Promise deleteResourcePolicyAsync(array $args = [])
* @method \Aws\Result deregisterMarketplaceModelEndpoint(array $args = [])
* @method \GuzzleHttp\Promise\Promise deregisterMarketplaceModelEndpointAsync(array $args = [])
* @method \Aws\Result exportAutomatedReasoningPolicyVersion(array $args = [])
@@ -121,6 +123,8 @@
* @method \GuzzleHttp\Promise\Promise getPromptRouterAsync(array $args = [])
* @method \Aws\Result getProvisionedModelThroughput(array $args = [])
* @method \GuzzleHttp\Promise\Promise getProvisionedModelThroughputAsync(array $args = [])
* @method \Aws\Result getResourcePolicy(array $args = [])
* @method \GuzzleHttp\Promise\Promise getResourcePolicyAsync(array $args = [])
* @method \Aws\Result getUseCaseForModelAccess(array $args = [])
* @method \GuzzleHttp\Promise\Promise getUseCaseForModelAccessAsync(array $args = [])
* @method \Aws\Result listAutomatedReasoningPolicies(array $args = [])
@@ -169,6 +173,8 @@
* @method \GuzzleHttp\Promise\Promise putEnforcedGuardrailConfigurationAsync(array $args = [])
* @method \Aws\Result putModelInvocationLoggingConfiguration(array $args = [])
* @method \GuzzleHttp\Promise\Promise putModelInvocationLoggingConfigurationAsync(array $args = [])
* @method \Aws\Result putResourcePolicy(array $args = [])
* @method \GuzzleHttp\Promise\Promise putResourcePolicyAsync(array $args = [])
* @method \Aws\Result putUseCaseForModelAccess(array $args = [])
* @method \GuzzleHttp\Promise\Promise putUseCaseForModelAccessAsync(array $args = [])
* @method \Aws\Result registerMarketplaceModelEndpoint(array $args = [])

View File

@@ -43,6 +43,10 @@
* @method \GuzzleHttp\Promise\Promise getWorkloadAccessTokenForUserIdAsync(array $args = [])
* @method \Aws\Result invokeAgentRuntime(array $args = [])
* @method \GuzzleHttp\Promise\Promise invokeAgentRuntimeAsync(array $args = [])
* @method \Aws\Result invokeAgentRuntimeCommand(array $args = [])
* @method \GuzzleHttp\Promise\Promise invokeAgentRuntimeCommandAsync(array $args = [])
* @method \Aws\Result invokeBrowser(array $args = [])
* @method \GuzzleHttp\Promise\Promise invokeBrowserAsync(array $args = [])
* @method \Aws\Result invokeCodeInterpreter(array $args = [])
* @method \GuzzleHttp\Promise\Promise invokeCodeInterpreterAsync(array $args = [])
* @method \Aws\Result listActors(array $args = [])
@@ -61,6 +65,10 @@
* @method \GuzzleHttp\Promise\Promise listSessionsAsync(array $args = [])
* @method \Aws\Result retrieveMemoryRecords(array $args = [])
* @method \GuzzleHttp\Promise\Promise retrieveMemoryRecordsAsync(array $args = [])
* @method \Aws\Result saveBrowserSessionProfile(array $args = [])
* @method \GuzzleHttp\Promise\Promise saveBrowserSessionProfileAsync(array $args = [])
* @method \Aws\Result searchRegistryRecords(array $args = [])
* @method \GuzzleHttp\Promise\Promise searchRegistryRecordsAsync(array $args = [])
* @method \Aws\Result startBrowserSession(array $args = [])
* @method \GuzzleHttp\Promise\Promise startBrowserSessionAsync(array $args = [])
* @method \Aws\Result startCodeInterpreterSession(array $args = [])

View File

@@ -13,6 +13,8 @@
* @method \GuzzleHttp\Promise\Promise createApiKeyCredentialProviderAsync(array $args = [])
* @method \Aws\Result createBrowser(array $args = [])
* @method \GuzzleHttp\Promise\Promise createBrowserAsync(array $args = [])
* @method \Aws\Result createBrowserProfile(array $args = [])
* @method \GuzzleHttp\Promise\Promise createBrowserProfileAsync(array $args = [])
* @method \Aws\Result createCodeInterpreter(array $args = [])
* @method \GuzzleHttp\Promise\Promise createCodeInterpreterAsync(array $args = [])
* @method \Aws\Result createEvaluator(array $args = [])
@@ -31,6 +33,10 @@
* @method \GuzzleHttp\Promise\Promise createPolicyAsync(array $args = [])
* @method \Aws\Result createPolicyEngine(array $args = [])
* @method \GuzzleHttp\Promise\Promise createPolicyEngineAsync(array $args = [])
* @method \Aws\Result createRegistry(array $args = [])
* @method \GuzzleHttp\Promise\Promise createRegistryAsync(array $args = [])
* @method \Aws\Result createRegistryRecord(array $args = [])
* @method \GuzzleHttp\Promise\Promise createRegistryRecordAsync(array $args = [])
* @method \Aws\Result createWorkloadIdentity(array $args = [])
* @method \GuzzleHttp\Promise\Promise createWorkloadIdentityAsync(array $args = [])
* @method \Aws\Result deleteAgentRuntime(array $args = [])
@@ -41,6 +47,8 @@
* @method \GuzzleHttp\Promise\Promise deleteApiKeyCredentialProviderAsync(array $args = [])
* @method \Aws\Result deleteBrowser(array $args = [])
* @method \GuzzleHttp\Promise\Promise deleteBrowserAsync(array $args = [])
* @method \Aws\Result deleteBrowserProfile(array $args = [])
* @method \GuzzleHttp\Promise\Promise deleteBrowserProfileAsync(array $args = [])
* @method \Aws\Result deleteCodeInterpreter(array $args = [])
* @method \GuzzleHttp\Promise\Promise deleteCodeInterpreterAsync(array $args = [])
* @method \Aws\Result deleteEvaluator(array $args = [])
@@ -59,6 +67,10 @@
* @method \GuzzleHttp\Promise\Promise deletePolicyAsync(array $args = [])
* @method \Aws\Result deletePolicyEngine(array $args = [])
* @method \GuzzleHttp\Promise\Promise deletePolicyEngineAsync(array $args = [])
* @method \Aws\Result deleteRegistry(array $args = [])
* @method \GuzzleHttp\Promise\Promise deleteRegistryAsync(array $args = [])
* @method \Aws\Result deleteRegistryRecord(array $args = [])
* @method \GuzzleHttp\Promise\Promise deleteRegistryRecordAsync(array $args = [])
* @method \Aws\Result deleteResourcePolicy(array $args = [])
* @method \GuzzleHttp\Promise\Promise deleteResourcePolicyAsync(array $args = [])
* @method \Aws\Result deleteWorkloadIdentity(array $args = [])
@@ -71,6 +83,8 @@
* @method \GuzzleHttp\Promise\Promise getApiKeyCredentialProviderAsync(array $args = [])
* @method \Aws\Result getBrowser(array $args = [])
* @method \GuzzleHttp\Promise\Promise getBrowserAsync(array $args = [])
* @method \Aws\Result getBrowserProfile(array $args = [])
* @method \GuzzleHttp\Promise\Promise getBrowserProfileAsync(array $args = [])
* @method \Aws\Result getCodeInterpreter(array $args = [])
* @method \GuzzleHttp\Promise\Promise getCodeInterpreterAsync(array $args = [])
* @method \Aws\Result getEvaluator(array $args = [])
@@ -91,6 +105,10 @@
* @method \GuzzleHttp\Promise\Promise getPolicyEngineAsync(array $args = [])
* @method \Aws\Result getPolicyGeneration(array $args = [])
* @method \GuzzleHttp\Promise\Promise getPolicyGenerationAsync(array $args = [])
* @method \Aws\Result getRegistry(array $args = [])
* @method \GuzzleHttp\Promise\Promise getRegistryAsync(array $args = [])
* @method \Aws\Result getRegistryRecord(array $args = [])
* @method \GuzzleHttp\Promise\Promise getRegistryRecordAsync(array $args = [])
* @method \Aws\Result getResourcePolicy(array $args = [])
* @method \GuzzleHttp\Promise\Promise getResourcePolicyAsync(array $args = [])
* @method \Aws\Result getTokenVault(array $args = [])
@@ -105,6 +123,8 @@
* @method \GuzzleHttp\Promise\Promise listAgentRuntimesAsync(array $args = [])
* @method \Aws\Result listApiKeyCredentialProviders(array $args = [])
* @method \GuzzleHttp\Promise\Promise listApiKeyCredentialProvidersAsync(array $args = [])
* @method \Aws\Result listBrowserProfiles(array $args = [])
* @method \GuzzleHttp\Promise\Promise listBrowserProfilesAsync(array $args = [])
* @method \Aws\Result listBrowsers(array $args = [])
* @method \GuzzleHttp\Promise\Promise listBrowsersAsync(array $args = [])
* @method \Aws\Result listCodeInterpreters(array $args = [])
@@ -129,6 +149,10 @@
* @method \GuzzleHttp\Promise\Promise listPolicyGenerationAssetsAsync(array $args = [])
* @method \Aws\Result listPolicyGenerations(array $args = [])
* @method \GuzzleHttp\Promise\Promise listPolicyGenerationsAsync(array $args = [])
* @method \Aws\Result listRegistries(array $args = [])
* @method \GuzzleHttp\Promise\Promise listRegistriesAsync(array $args = [])
* @method \Aws\Result listRegistryRecords(array $args = [])
* @method \GuzzleHttp\Promise\Promise listRegistryRecordsAsync(array $args = [])
* @method \Aws\Result listTagsForResource(array $args = [])
* @method \GuzzleHttp\Promise\Promise listTagsForResourceAsync(array $args = [])
* @method \Aws\Result listWorkloadIdentities(array $args = [])
@@ -139,6 +163,8 @@
* @method \GuzzleHttp\Promise\Promise setTokenVaultCMKAsync(array $args = [])
* @method \Aws\Result startPolicyGeneration(array $args = [])
* @method \GuzzleHttp\Promise\Promise startPolicyGenerationAsync(array $args = [])
* @method \Aws\Result submitRegistryRecordForApproval(array $args = [])
* @method \GuzzleHttp\Promise\Promise submitRegistryRecordForApprovalAsync(array $args = [])
* @method \Aws\Result synchronizeGatewayTargets(array $args = [])
* @method \GuzzleHttp\Promise\Promise synchronizeGatewayTargetsAsync(array $args = [])
* @method \Aws\Result tagResource(array $args = [])
@@ -167,6 +193,12 @@
* @method \GuzzleHttp\Promise\Promise updatePolicyAsync(array $args = [])
* @method \Aws\Result updatePolicyEngine(array $args = [])
* @method \GuzzleHttp\Promise\Promise updatePolicyEngineAsync(array $args = [])
* @method \Aws\Result updateRegistry(array $args = [])
* @method \GuzzleHttp\Promise\Promise updateRegistryAsync(array $args = [])
* @method \Aws\Result updateRegistryRecord(array $args = [])
* @method \GuzzleHttp\Promise\Promise updateRegistryRecordAsync(array $args = [])
* @method \Aws\Result updateRegistryRecordStatus(array $args = [])
* @method \GuzzleHttp\Promise\Promise updateRegistryRecordStatusAsync(array $args = [])
* @method \Aws\Result updateWorkloadIdentity(array $args = [])
* @method \GuzzleHttp\Promise\Promise updateWorkloadIdentityAsync(array $args = [])
*/

View File

@@ -11,22 +11,40 @@
* @method \GuzzleHttp\Promise\Promise createBlueprintAsync(array $args = [])
* @method \Aws\Result createBlueprintVersion(array $args = [])
* @method \GuzzleHttp\Promise\Promise createBlueprintVersionAsync(array $args = [])
* @method \Aws\Result createDataAutomationLibrary(array $args = [])
* @method \GuzzleHttp\Promise\Promise createDataAutomationLibraryAsync(array $args = [])
* @method \Aws\Result createDataAutomationProject(array $args = [])
* @method \GuzzleHttp\Promise\Promise createDataAutomationProjectAsync(array $args = [])
* @method \Aws\Result deleteBlueprint(array $args = [])
* @method \GuzzleHttp\Promise\Promise deleteBlueprintAsync(array $args = [])
* @method \Aws\Result deleteDataAutomationLibrary(array $args = [])
* @method \GuzzleHttp\Promise\Promise deleteDataAutomationLibraryAsync(array $args = [])
* @method \Aws\Result deleteDataAutomationProject(array $args = [])
* @method \GuzzleHttp\Promise\Promise deleteDataAutomationProjectAsync(array $args = [])
* @method \Aws\Result getBlueprint(array $args = [])
* @method \GuzzleHttp\Promise\Promise getBlueprintAsync(array $args = [])
* @method \Aws\Result getBlueprintOptimizationStatus(array $args = [])
* @method \GuzzleHttp\Promise\Promise getBlueprintOptimizationStatusAsync(array $args = [])
* @method \Aws\Result getDataAutomationLibrary(array $args = [])
* @method \GuzzleHttp\Promise\Promise getDataAutomationLibraryAsync(array $args = [])
* @method \Aws\Result getDataAutomationLibraryEntity(array $args = [])
* @method \GuzzleHttp\Promise\Promise getDataAutomationLibraryEntityAsync(array $args = [])
* @method \Aws\Result getDataAutomationLibraryIngestionJob(array $args = [])
* @method \GuzzleHttp\Promise\Promise getDataAutomationLibraryIngestionJobAsync(array $args = [])
* @method \Aws\Result getDataAutomationProject(array $args = [])
* @method \GuzzleHttp\Promise\Promise getDataAutomationProjectAsync(array $args = [])
* @method \Aws\Result invokeBlueprintOptimizationAsync(array $args = [])
* @method \GuzzleHttp\Promise\Promise invokeBlueprintOptimizationAsyncAsync(array $args = [])
* @method \Aws\Result invokeDataAutomationLibraryIngestionJob(array $args = [])
* @method \GuzzleHttp\Promise\Promise invokeDataAutomationLibraryIngestionJobAsync(array $args = [])
* @method \Aws\Result listBlueprints(array $args = [])
* @method \GuzzleHttp\Promise\Promise listBlueprintsAsync(array $args = [])
* @method \Aws\Result listDataAutomationLibraries(array $args = [])
* @method \GuzzleHttp\Promise\Promise listDataAutomationLibrariesAsync(array $args = [])
* @method \Aws\Result listDataAutomationLibraryEntities(array $args = [])
* @method \GuzzleHttp\Promise\Promise listDataAutomationLibraryEntitiesAsync(array $args = [])
* @method \Aws\Result listDataAutomationLibraryIngestionJobs(array $args = [])
* @method \GuzzleHttp\Promise\Promise listDataAutomationLibraryIngestionJobsAsync(array $args = [])
* @method \Aws\Result listDataAutomationProjects(array $args = [])
* @method \GuzzleHttp\Promise\Promise listDataAutomationProjectsAsync(array $args = [])
* @method \Aws\Result listTagsForResource(array $args = [])
@@ -37,6 +55,8 @@
* @method \GuzzleHttp\Promise\Promise untagResourceAsync(array $args = [])
* @method \Aws\Result updateBlueprint(array $args = [])
* @method \GuzzleHttp\Promise\Promise updateBlueprintAsync(array $args = [])
* @method \Aws\Result updateDataAutomationLibrary(array $args = [])
* @method \GuzzleHttp\Promise\Promise updateDataAutomationLibraryAsync(array $args = [])
* @method \Aws\Result updateDataAutomationProject(array $args = [])
* @method \GuzzleHttp\Promise\Promise updateDataAutomationProjectAsync(array $args = [])
*/

View File

@@ -0,0 +1,664 @@
<?php
namespace Aws\Cbor;
use Aws\Cbor\Exception\CborException;
/**
* Decodes Concise Binary Object Representation encoded strings
* into PHP values according to RFC 8949
*
* https://www.rfc-editor.org/rfc/rfc8949.html
*
* Supports Major types 0-7 including:
* - Type 0: Unsigned integers
* - Type 1: Negative integers
* - Type 2: Byte strings
* - Type 3: Text strings (UTF-8)
* - Type 4: Arrays
* - Type 5: Maps
* - Type 6: Tagged values (timestamps)
* - Type 7: Simple values (null, bool, float)
*
* @internal
*/
final class CborDecoder
{
private int $offset;
private int $length;
/**
* Decode CBOR binary data to PHP value
*
* @param string $data The CBOR-encoded binary data to decode
*
* @return mixed The decoded PHP value (can be any type: int, string, array, bool, null, float)
* @throws CborException If data is empty or malformed CBOR
*/
public function decode(string $data): mixed
{
if ($data === '') {
throw new CborException("No data to decode");
}
$this->offset = 0;
$this->length = strlen($data);
return $this->decodeValue($data);
}
/**
* Decode multiple CBOR values from sequential binary data
*
* @param string $data The CBOR-encoded binary data containing multiple values
*
* @return array Array of decoded PHP values in the order they appear in the data
* @throws CborException If data is malformed CBOR
*/
public function decodeAll(string $data): array
{
$this->length = strlen($data);
$this->offset = 0;
$values = [];
while ($this->offset < $this->length) {
$values[] = $this->decodeValue($data);
}
return $values;
}
/**
* Decodes a single CBOR value at the current offset
*
* @param string $data Reference to the CBOR data being decoded
*
* @return mixed The decoded value
* @throws CborException If unexpected end of data or invalid CBOR format
*/
private function decodeValue(string &$data): mixed
{
$offset = $this->offset;
$length = $this->length;
if ($offset >= $length) {
throw new CborException("Unexpected end of data");
}
$byte = ord($data[$offset++]);
$majorType = $byte >> 5;
$info = $byte & 0x1F;
switch ($majorType) {
case 0: // Unsigned integer
if ($info < 24) {
$this->offset = $offset;
return $info;
}
switch ($info) {
case 24:
if ($offset >= $length) {
throw new CborException("Not enough data");
}
$this->offset = $offset + 1;
return ord($data[$offset]);
case 25:
if ($offset + 2 > $length) {
throw new CborException("Not enough data");
}
$this->offset = $offset + 2;
return (ord($data[$offset]) << 8) | ord($data[$offset + 1]);
case 26:
if ($offset + 4 > $length) {
throw new CborException("Not enough data");
}
$this->offset = $offset + 4;
return unpack('N', $data, $offset)[1];
case 27:
if ($offset + 8 > $length) {
throw new CborException("Not enough data");
}
$this->offset = $offset + 8;
return unpack('J', $data, $offset)[1];
default:
throw new CborException("Invalid additional info for integer: $info");
}
case 1: // Negative integer
if ($info < 24) {
$this->offset = $offset;
return -1 - $info;
}
switch ($info) {
case 24:
if ($offset >= $length) {
throw new CborException("Not enough data");
}
$this->offset = $offset + 1;
return -1 - ord($data[$offset]);
case 25:
if ($offset + 2 > $length) {
throw new CborException("Not enough data");
}
$this->offset = $offset + 2;
return -1 - ((ord($data[$offset]) << 8) | ord($data[$offset + 1]));
case 26:
if ($offset + 4 > $length) {
throw new CborException("Not enough data");
}
$this->offset = $offset + 4;
return -1 - unpack('N', $data, $offset)[1];
case 27:
if ($offset + 8 > $length) {
throw new CborException("Not enough data");
}
$this->offset = $offset + 8;
$unsigned = unpack('J', $data, $offset)[1];
return ($unsigned === 9223372036854775807) ? PHP_INT_MIN : -1 - $unsigned;
default:
throw new CborException("Invalid additional info for integer: $info");
}
case 2: // Byte string
if ($info < 24) {
$len = $info;
} else {
switch ($info) {
case 24:
if ($offset >= $length) {
throw new CborException("Not enough data");
}
$len = ord($data[$offset++]);
break;
case 25:
if ($offset + 2 > $length) {
throw new CborException("Not enough data");
}
$len = (ord($data[$offset]) << 8) | ord($data[$offset + 1]);
$offset += 2;
break;
case 26:
if ($offset + 4 > $length) {
throw new CborException("Not enough data");
}
$len = unpack('N', $data, $offset)[1];
$offset += 4;
break;
case 27:
if ($offset + 8 > $length) {
throw new CborException("Not enough data");
}
$len = unpack('J', $data, $offset)[1];
$offset += 8;
break;
case 31:
$this->offset = $offset;
return $this->decodeIndefiniteString($data, 0x40);
default:
throw new CborException("Invalid additional info for byte string: $info");
}
}
if ($offset + $len > $length) {
throw new CborException("Not enough data");
}
$this->offset = $offset + $len;
return substr($data, $offset, $len);
case 3: // Text string
if ($info < 24) {
$len = $info;
} else {
switch ($info) {
case 24:
if ($offset >= $length) {
throw new CborException("Not enough data");
}
$len = ord($data[$offset++]);
break;
case 25:
if ($offset + 2 > $length) {
throw new CborException("Not enough data");
}
$len = (ord($data[$offset]) << 8) | ord($data[$offset + 1]);
$offset += 2;
break;
case 26:
if ($offset + 4 > $length) {
throw new CborException("Not enough data");
}
$len = unpack('N', $data, $offset)[1];
$offset += 4;
break;
case 27:
if ($offset + 8 > $length) {
throw new CborException("Not enough data");
}
$len = unpack('J', $data, $offset)[1];
$offset += 8;
break;
case 31:
$this->offset = $offset;
return $this->decodeIndefiniteString($data, 0x60);
default:
throw new CborException("Invalid additional info for text string: $info");
}
}
if ($offset + $len > $length) {
throw new CborException("Not enough data");
}
$this->offset = $offset + $len;
return substr($data, $offset, $len);
case 4: // Array
if ($info < 24) {
$count = $info;
} else {
switch ($info) {
case 24:
if ($offset >= $length) {
throw new CborException("Not enough data");
}
$count = ord($data[$offset++]);
break;
case 25:
if ($offset + 2 > $length) {
throw new CborException("Not enough data");
}
$count = (ord($data[$offset]) << 8) | ord($data[$offset + 1]);
$offset += 2;
break;
case 26:
if ($offset + 4 > $length) {
throw new CborException("Not enough data");
}
$count = unpack('N', $data, $offset)[1];
$offset += 4;
break;
case 27:
if ($offset + 8 > $length) {
throw new CborException("Not enough data");
}
$count = unpack('J', $data, $offset)[1];
$offset += 8;
break;
case 31:
$this->offset = $offset;
return $this->decodeIndefiniteArray($data);
default:
throw new CborException("Invalid additional info for array: $info");
}
}
$this->offset = $offset;
$arr = [];
for ($i = 0; $i < $count; $i++) {
$arr[] = $this->decodeValue($data);
}
return $arr;
case 5: // Map
if ($info < 24) {
$count = $info;
} else {
switch ($info) {
case 24:
if ($offset >= $length) {
throw new CborException("Not enough data");
}
$count = ord($data[$offset++]);
break;
case 25:
if ($offset + 2 > $length) {
throw new CborException("Not enough data");
}
$count = (ord($data[$offset]) << 8) | ord($data[$offset + 1]);
$offset += 2;
break;
case 26:
if ($offset + 4 > $length) {
throw new CborException("Not enough data");
}
$count = unpack('N', $data, $offset)[1];
$offset += 4;
break;
case 27:
if ($offset + 8 > $length) {
throw new CborException("Not enough data");
}
$count = unpack('J', $data, $offset)[1];
$offset += 8;
break;
case 31:
$this->offset = $offset;
return $this->decodeIndefiniteMap($data);
default:
throw new CborException("Invalid additional info for map: $info");
}
}
$this->offset = $offset;
$map = [];
for ($i = 0; $i < $count; $i++) {
$key = $this->decodeValue($data);
$map[$key] = $this->decodeValue($data);
}
return $map;
case 6: // Tag
switch ($info) {
case 24:
$offset++;
break;
case 25:
$offset += 2;
break;
case 26:
$offset += 4;
break;
case 27:
$offset += 8;
break;
}
$this->offset = $offset;
return $this->decodeValue($data);
case 7: // Simple/float
switch ($info) {
case 20:
$this->offset = $offset;
return false;
case 21:
$this->offset = $offset;
return true;
case 22:
case 23:
$this->offset = $offset;
return null;
case 25: // Half-precision float
if ($offset + 2 > $length) {
throw new CborException("Not enough data");
}
$this->offset = $offset + 2;
$half = (ord($data[$offset]) << 8) | ord($data[$offset + 1]);
$sign = ($half >> 15) & 0x01;
$exp = ($half >> 10) & 0x1F;
$mant = $half & 0x3FF;
if ($exp === 0) {
return $mant === 0
? ($sign ? -0.0 : 0.0)
: ($sign ? -1 : 1) * pow(2, -14) * ($mant / 1024);
}
if ($exp === 31) {
return $mant === 0 ? ($sign ? -INF : INF) : NAN;
}
return (float) (($sign ? -1 : 1) * pow(2, $exp - 15) * (1 + $mant / 1024));
case 26: // Single-precision float
if ($offset + 4 > $length) {
throw new CborException("Not enough data");
}
$this->offset = $offset + 4;
return unpack('G', $data, $offset)[1];
case 27: // Double-precision float
if ($offset + 8 > $length) {
throw new CborException("Not enough data");
}
$this->offset = $offset + 8;
return unpack('E', $data, $offset)[1];
case 31:
throw new CborException("Unexpected break");
default:
throw new CborException("Unknown simple value: $info");
}
default:
throw new CborException("Unknown major type: $majorType");
}
}
/**
* Decode indefinite-length string (byte or text)
*
* @param string $data Reference to the CBOR data being decoded
* @param int $expectedMajor Expected major type (0x40 for byte string, 0x60 for text string)
*
* @return string The concatenated string from all chunks
* @throws CborException If invalid chunk format or unexpected end of data
*/
private function decodeIndefiniteString(string &$data, int $expectedMajor): string
{
$chunks = [];
while (true) {
$offset = $this->offset;
$length = $this->length;
if ($offset >= $length) {
throw new CborException("Unexpected end of data");
}
$byte = ord($data[$offset++]);
if ($byte === 0xFF) {
$this->offset = $offset;
return implode('', $chunks);
}
if (($byte & 0xE0) !== $expectedMajor) {
throw new CborException("Invalid chunk in indefinite string");
}
$info = $byte & 0x1F;
if ($info === 31) {
throw new CborException("Nested indefinite string");
}
if ($info < 24) {
$len = $info;
} else {
switch ($info) {
case 24:
if ($offset >= $length) {
throw new CborException("Not enough data");
}
$len = ord($data[$offset++]);
break;
case 25:
if ($offset + 2 > $length) {
throw new CborException("Not enough data");
}
$len = (ord($data[$offset]) << 8) | ord($data[$offset + 1]);
$offset += 2;
break;
case 26:
if ($offset + 4 > $length) {
throw new CborException("Not enough data");
}
$len = unpack('N', $data, $offset)[1];
$offset += 4;
break;
case 27:
if ($offset + 8 > $length) {
throw new CborException("Not enough data");
}
$len = unpack('J', $data, $offset)[1];
$offset += 8;
break;
default:
throw new CborException("Invalid chunk length info: $info");
}
}
if ($offset + $len > $length) {
throw new CborException("Not enough data for chunk");
}
$chunks[] = substr($data, $offset, $len);
$this->offset = $offset + $len;
}
}
/**
* Decode indefinite-length array
*
* @param string $data Reference to the CBOR data being decoded
*
* @return array The decoded array elements
* @throws CborException If unexpected end of data
*/
private function decodeIndefiniteArray(string &$data): array
{
$result = [];
while (true) {
if ($this->offset >= $this->length) {
throw new CborException("Unexpected end of data");
}
if (ord($data[$this->offset]) === 0xFF) {
$this->offset++;
return $result;
}
$result[] = $this->decodeValue($data);
}
}
/**
* Decode indefinite-length map
*
* @param string $data Reference to the CBOR data being decoded
*
* @return array The decoded map as associative array
* @throws CborException If unexpected end of data or odd number of items
*/
private function decodeIndefiniteMap(string &$data): array
{
$result = [];
while (true) {
if ($this->offset >= $this->length) {
throw new CborException("Unexpected end of data");
}
if (ord($data[$this->offset]) === 0xFF) {
$this->offset++;
return $result;
}
$key = $this->decodeValue($data);
$result[$key] = $this->decodeValue($data);
}
}
}

View File

@@ -0,0 +1,357 @@
<?php
namespace Aws\Cbor;
use Aws\Cbor\Exception\CborException;
use DateTimeInterface;
/**
* Encodes PHP values to Concise Binary Object Representation according to RFC 8949
* https://www.rfc-editor.org/rfc/rfc8949.html
*
* Supports Major types 0-7 including:
* - Type 0: Unsigned integers
* - Type 1: Negative integers
* - Type 2: Byte strings (via ['__cbor_bytes' => $data] wrappers)
* - Type 3: Text strings (UTF-8)
* - Type 4: Arrays
* - Type 5: Maps
* - Type 6: Tagged values (timestamps)
* - Type 7: Simple values (null, bool, float)
*
* @internal
*/
final class CborEncoder
{
/**
* Pre-encoded integers 0-23 (single byte) and common larger values
* CBOR major type 0 (unsigned integer)
*/
private const INT_CACHE = [
0 => "\x00", 1 => "\x01", 2 => "\x02", 3 => "\x03",
4 => "\x04", 5 => "\x05", 6 => "\x06", 7 => "\x07",
8 => "\x08", 9 => "\x09", 10 => "\x0A", 11 => "\x0B",
12 => "\x0C", 13 => "\x0D", 14 => "\x0E", 15 => "\x0F",
16 => "\x10", 17 => "\x11", 18 => "\x12", 19 => "\x13",
20 => "\x14", 21 => "\x15", 22 => "\x16", 23 => "\x17",
24 => "\x18\x18", 25 => "\x18\x19", 26 => "\x18\x1A",
32 => "\x18\x20", 50 => "\x18\x32", 64 => "\x18\x40",
100 => "\x18\x64", 128 => "\x18\x80", 200 => "\x18\xC8",
255 => "\x18\xFF", 256 => "\x19\x01\x00", 500 => "\x19\x01\xF4",
1000 => "\x19\x03\xE8", 1023 => "\x19\x03\xFF",
];
/**
* Pre-encoded negative integers -1 to -24 and common larger values
* CBOR major type 1 (negative integer)
*/
private const NEG_CACHE = [
-1 => "\x20", -2 => "\x21", -3 => "\x22", -4 => "\x23",
-5 => "\x24", -10 => "\x29", -20 => "\x33", -24 => "\x37",
-25 => "\x38\x18", -50 => "\x38\x31", -100 => "\x38\x63",
];
/**
* Encode a PHP value to CBOR binary string
*
* @param mixed $value The value to encode
*
* @return string
*/
public function encode(mixed $value): string
{
return $this->encodeValue($value);
}
/**
* Recursively encode a value to CBOR
*
* @param mixed $value Value to encode
* @return string Encoded CBOR bytes
*/
private function encodeValue(mixed $value): string
{
switch (gettype($value)) {
case 'string':
$len = strlen($value);
if ($len < 24) {
return chr(0x60 | $len) . $value;
}
if ($len < 0x100) {
return "\x78" . chr($len) . $value;
}
return $this->encodeTextString($value);
case 'array':
// Encode a byte string (major type 2)
if (isset($value['__cbor_bytes'])) {
$bytes = $value['__cbor_bytes'];
$len = strlen($bytes);
if ($len < 24) {
return chr(0x40 | $len) . $bytes;
}
if ($len < 0x100) {
return "\x58" . chr($len) . $bytes;
}
if ($len < 0x10000) {
return "\x59" . pack('n', $len) . $bytes;
}
return "\x5A" . pack('N', $len) . $bytes;
}
if (array_is_list($value)) {
return $this->encodeArray($value);
}
return $this->encodeMap($value);
case 'integer':
if (isset(self::INT_CACHE[$value])) {
return self::INT_CACHE[$value];
}
if (isset(self::NEG_CACHE[$value])) {
return self::NEG_CACHE[$value];
}
// Fast path for positive integers
// Major type 0: unsigned integer
if ($value >= 0) {
if ($value < 24) {
return chr($value);
}
if ($value < 0x100) {
return "\x18" . chr($value);
}
if ($value < 0x10000) {
return "\x19" . pack('n', $value);
}
if ($value < 0x100000000) {
return "\x1A" . pack('N', $value);
}
return "\x1B" . pack('J', $value);
}
return $this->encodeInteger($value);
case 'double':
// Encode a float (major type 7, float 64)
return "\xFB" . pack('E', $value);
case 'boolean':
// Encode a boolean (major type 7, simple)
return $value ? "\xF5" : "\xF4";
case 'NULL':
// Encode null (major type 7, simple)
return "\xF6";
case 'object':
// Encode timestamp (major type 6, tag 1)
if ($value instanceof DateTimeInterface) {
$timestamp = $value->getTimestamp();
$micro = (int) $value->format('u');
if ($micro === 0) {
if ($timestamp >= 0 && $timestamp < 0x100000000) {
return "\xC1\x1A" . pack('N', $timestamp);
}
return "\xC1" . $this->encodeInteger($timestamp);
}
return "\xC1\xFB" . pack('E', $timestamp + $micro / 1e6);
}
throw new CborException("Cannot encode object of type: " . get_class($value));
default:
throw new CborException("Cannot encode value of type: " . gettype($value));
}
}
/**
* Encode an integer (major type 0 or 1)
*
* @param int $value
* @return string
*/
private function encodeInteger(int $value): string
{
if (isset(self::INT_CACHE[$value])) {
return self::INT_CACHE[$value];
}
if (isset(self::NEG_CACHE[$value])) {
return self::NEG_CACHE[$value];
}
if ($value >= 0) {
// Major type 0: unsigned integer
if ($value < 24) {
return chr($value);
}
if ($value < 0x100) {
return "\x18" . chr($value);
}
if ($value < 0x10000) {
return "\x19" . pack('n', $value);
}
if ($value < 0x100000000) {
return "\x1A" . pack('N', $value);
}
return "\x1B" . pack('J', $value);
}
// Major type 1: negative integer (-1 - n)
$value = -1 - $value;
if ($value < 24) {
return chr(0x20 | $value);
}
if ($value < 0x100) {
return "\x38" . chr($value);
}
if ($value < 0x10000) {
return "\x39" . pack('n', $value);
}
if ($value < 0x100000000) {
return "\x3A" . pack('N', $value);
}
return "\x3B" . pack('J', $value);
}
/**
* Encode a text string (major type 3)
*
* @param string $value
* @return string
*/
private function encodeTextString(string $value): string
{
$len = strlen($value);
if ($len < 24) {
return chr(0x60 | $len) . $value;
}
if ($len < 0x100) {
return "\x78" . chr($len) . $value;
}
if ($len < 0x10000) {
return "\x79" . pack('n', $len) . $value;
}
if ($len < 0x100000000) {
return "\x7A" . pack('N', $len) . $value;
}
return "\x7B" . pack('J', $len) . $value;
}
/**
* Encode an array (major type 4)
*
* @param array $value
* @return string
*/
private function encodeArray(array $value): string
{
$count = count($value);
if ($count < 24) {
$result = chr(0x80 | $count);
} elseif ($count < 0x100) {
$result = "\x98" . chr($count);
} elseif ($count < 0x10000) {
$result = "\x99" . pack('n', $count);
} elseif ($count < 0x100000000) {
$result = "\x9A" . pack('N', $count);
} else {
$result = "\x9B" . pack('J', $count);
}
foreach ($value as $item) {
$result .= $this->encodeValue($item);
}
return $result;
}
/**
* Encode a map (major type 5)
*
* @param array $value
* @return string
*/
private function encodeMap(array $value): string
{
$count = count($value);
if ($count < 24) {
$result = chr(0xA0 | $count);
} elseif ($count < 0x100) {
$result = "\xB8" . chr($count);
} elseif ($count < 0x10000) {
$result = "\xB9" . pack('n', $count);
} elseif ($count < 0x100000000) {
$result = "\xBA" . pack('N', $count);
} else {
$result = "\xBB" . pack('J', $count);
}
foreach ($value as $k => $v) {
if (is_int($k)) {
$result .= $this->encodeInteger($k);
} else {
$len = strlen($k);
if ($len < 24) {
$result .= chr(0x60 | $len) . $k;
} elseif ($len < 0x100) {
$result .= "\x78" . chr($len) . $k;
} else {
$result .= "\x79" . pack('n', $len) . $k;
}
}
$result .= $this->encodeValue($v);
}
return $result;
}
/**
* Create an empty map (major type 5 with 0 elements)
*
* @return string
*/
public function encodeEmptyMap(): string
{
return "\xA0";
}
/**
* Create an empty indefinite map (major type 5 indefinite length)
*
* @return string
*/
public function encodeEmptyIndefiniteMap(): string
{
return "\xBF\xFF";
}
}

View File

@@ -0,0 +1,6 @@
<?php
namespace Aws\Cbor\Exception;
use RuntimeException;
class CborException extends RuntimeException {}

View File

@@ -1167,7 +1167,7 @@ public static function _apply_auth_scheme_preference(
}
// Assign user's preferred auth scheme list
$args['auth_scheme_preference'] = $value;
$args['config']['auth_scheme_preference'] = $value;
}
public static function _default_signature_version(array &$args)
@@ -1247,12 +1247,6 @@ public static function _apply_suppress_php_deprecation_warning($value, &$args)
$args['suppress_php_deprecation_warning'] =
\Aws\boolean_value($_ENV["AWS_SUPPRESS_PHP_DEPRECATION_WARNING"]);
}
if ($args['suppress_php_deprecation_warning'] === false
&& PHP_VERSION_ID < 80100
) {
self::emitDeprecationWarning();
}
}
public static function _default_endpoint(array &$args)
@@ -1440,21 +1434,4 @@ private static function isValidApiVersion($service, $apiVersion)
__DIR__ . "/data/{$service}/$apiVersion"
);
}
private static function emitDeprecationWarning()
{
$phpVersionString = phpversion();
trigger_error(
"This installation of the SDK is using PHP version"
. " {$phpVersionString}, which will be deprecated on January"
. " 13th, 2025.\nPlease upgrade your PHP version to a minimum of"
. " 8.1.x to continue receiving updates for the AWS"
. " SDK for PHP.\nTo disable this warning, set"
. " suppress_php_deprecation_warning to true on the client constructor"
. " or set the environment variable AWS_SUPPRESS_PHP_DEPRECATION_WARNING"
. " to true.\nMore information can be found at: "
. "https://aws.amazon.com/blogs/developer/announcing-the-end-of-support-for-php-runtimes-8-0-x-and-below-in-the-aws-sdk-for-php/\n",
E_USER_DEPRECATED
);
}
}

View File

@@ -81,8 +81,10 @@ public function getSignature($resource = null, $expires = null, $policy = null)
$signatureHash = [];
if ($policy) {
$policy = preg_replace('/\s/s', '', $policy);
self::validatePolicy($policy);
$signatureHash['Policy'] = $this->encode($policy);
} elseif ($resource && $expires) {
self::validateResourceUrl($resource);
$expires = (int) $expires; // Handle epoch passed as string
$policy = $this->createCannedPolicy($resource, $expires);
$signatureHash['Expires'] = $expires;
@@ -136,4 +138,35 @@ private function encode($policy)
{
return strtr(base64_encode($policy), '+=/', '-_~');
}
/**
* Validates a customer provided json document.
*
* @param string $jsonPolicy
*
* @return void
*/
private static function validatePolicy(string $jsonPolicy): void
{
$policy = json_decode($jsonPolicy, true);
foreach ($policy['Statement'] ?? [] as $statement) {
if (isset($statement['Resource'])) {
self::validateResourceUrl($statement['Resource']);
}
}
}
/**
* @param string $url
*
* @return void
*/
private static function validateResourceUrl(string $url): void
{
if (preg_match('/["\\\\\x00-\x1F]/', $url)) {
throw new \InvalidArgumentException(
'URL contains invalid characters: ", \\, or control characters'
);
}
}
}

View File

@@ -101,7 +101,7 @@ private function createResource($scheme, $url)
$parts = parse_url($url);
$pathParts = pathinfo($parts['path']);
$resource = ltrim(
$pathParts['dirname'] . '/' . $pathParts['basename'],
str_replace('\\', '/', $pathParts['dirname']) . '/' . $pathParts['basename'],
'/'
);

View File

@@ -6,6 +6,8 @@
/**
* This client is used to interact with the **Amazon CloudWatch** service.
*
* @method \Aws\Result deleteAlarmMuteRule(array $args = [])
* @method \GuzzleHttp\Promise\Promise deleteAlarmMuteRuleAsync(array $args = [])
* @method \Aws\Result deleteAlarms(array $args = [])
* @method \GuzzleHttp\Promise\Promise deleteAlarmsAsync(array $args = [])
* @method \Aws\Result deleteAnomalyDetector(array $args = [])
@@ -36,6 +38,8 @@
* @method \GuzzleHttp\Promise\Promise enableAlarmActionsAsync(array $args = [])
* @method \Aws\Result enableInsightRules(array $args = [])
* @method \GuzzleHttp\Promise\Promise enableInsightRulesAsync(array $args = [])
* @method \Aws\Result getAlarmMuteRule(array $args = [])
* @method \GuzzleHttp\Promise\Promise getAlarmMuteRuleAsync(array $args = [])
* @method \Aws\Result getDashboard(array $args = [])
* @method \GuzzleHttp\Promise\Promise getDashboardAsync(array $args = [])
* @method \Aws\Result getInsightRuleReport(array $args = [])
@@ -48,6 +52,10 @@
* @method \GuzzleHttp\Promise\Promise getMetricStreamAsync(array $args = [])
* @method \Aws\Result getMetricWidgetImage(array $args = [])
* @method \GuzzleHttp\Promise\Promise getMetricWidgetImageAsync(array $args = [])
* @method \Aws\Result getOTelEnrichment(array $args = [])
* @method \GuzzleHttp\Promise\Promise getOTelEnrichmentAsync(array $args = [])
* @method \Aws\Result listAlarmMuteRules(array $args = [])
* @method \GuzzleHttp\Promise\Promise listAlarmMuteRulesAsync(array $args = [])
* @method \Aws\Result listDashboards(array $args = [])
* @method \GuzzleHttp\Promise\Promise listDashboardsAsync(array $args = [])
* @method \Aws\Result listManagedInsightRules(array $args = [])
@@ -58,6 +66,8 @@
* @method \GuzzleHttp\Promise\Promise listMetricsAsync(array $args = [])
* @method \Aws\Result listTagsForResource(array $args = [])
* @method \GuzzleHttp\Promise\Promise listTagsForResourceAsync(array $args = [])
* @method \Aws\Result putAlarmMuteRule(array $args = [])
* @method \GuzzleHttp\Promise\Promise putAlarmMuteRuleAsync(array $args = [])
* @method \Aws\Result putAnomalyDetector(array $args = [])
* @method \GuzzleHttp\Promise\Promise putAnomalyDetectorAsync(array $args = [])
* @method \Aws\Result putCompositeAlarm(array $args = [])
@@ -78,8 +88,12 @@
* @method \GuzzleHttp\Promise\Promise setAlarmStateAsync(array $args = [])
* @method \Aws\Result startMetricStreams(array $args = [])
* @method \GuzzleHttp\Promise\Promise startMetricStreamsAsync(array $args = [])
* @method \Aws\Result startOTelEnrichment(array $args = [])
* @method \GuzzleHttp\Promise\Promise startOTelEnrichmentAsync(array $args = [])
* @method \Aws\Result stopMetricStreams(array $args = [])
* @method \GuzzleHttp\Promise\Promise stopMetricStreamsAsync(array $args = [])
* @method \Aws\Result stopOTelEnrichment(array $args = [])
* @method \GuzzleHttp\Promise\Promise stopOTelEnrichmentAsync(array $args = [])
* @method \Aws\Result tagResource(array $args = [])
* @method \GuzzleHttp\Promise\Promise tagResourceAsync(array $args = [])
* @method \Aws\Result untagResource(array $args = [])

View File

@@ -1,85 +0,0 @@
<?php
namespace Aws\CloudWatchEvidently;
use Aws\AwsClient;
/**
* This client is used to interact with the **Amazon CloudWatch Evidently** service.
* @method \Aws\Result batchEvaluateFeature(array $args = [])
* @method \GuzzleHttp\Promise\Promise batchEvaluateFeatureAsync(array $args = [])
* @method \Aws\Result createExperiment(array $args = [])
* @method \GuzzleHttp\Promise\Promise createExperimentAsync(array $args = [])
* @method \Aws\Result createFeature(array $args = [])
* @method \GuzzleHttp\Promise\Promise createFeatureAsync(array $args = [])
* @method \Aws\Result createLaunch(array $args = [])
* @method \GuzzleHttp\Promise\Promise createLaunchAsync(array $args = [])
* @method \Aws\Result createProject(array $args = [])
* @method \GuzzleHttp\Promise\Promise createProjectAsync(array $args = [])
* @method \Aws\Result createSegment(array $args = [])
* @method \GuzzleHttp\Promise\Promise createSegmentAsync(array $args = [])
* @method \Aws\Result deleteExperiment(array $args = [])
* @method \GuzzleHttp\Promise\Promise deleteExperimentAsync(array $args = [])
* @method \Aws\Result deleteFeature(array $args = [])
* @method \GuzzleHttp\Promise\Promise deleteFeatureAsync(array $args = [])
* @method \Aws\Result deleteLaunch(array $args = [])
* @method \GuzzleHttp\Promise\Promise deleteLaunchAsync(array $args = [])
* @method \Aws\Result deleteProject(array $args = [])
* @method \GuzzleHttp\Promise\Promise deleteProjectAsync(array $args = [])
* @method \Aws\Result deleteSegment(array $args = [])
* @method \GuzzleHttp\Promise\Promise deleteSegmentAsync(array $args = [])
* @method \Aws\Result evaluateFeature(array $args = [])
* @method \GuzzleHttp\Promise\Promise evaluateFeatureAsync(array $args = [])
* @method \Aws\Result getExperiment(array $args = [])
* @method \GuzzleHttp\Promise\Promise getExperimentAsync(array $args = [])
* @method \Aws\Result getExperimentResults(array $args = [])
* @method \GuzzleHttp\Promise\Promise getExperimentResultsAsync(array $args = [])
* @method \Aws\Result getFeature(array $args = [])
* @method \GuzzleHttp\Promise\Promise getFeatureAsync(array $args = [])
* @method \Aws\Result getLaunch(array $args = [])
* @method \GuzzleHttp\Promise\Promise getLaunchAsync(array $args = [])
* @method \Aws\Result getProject(array $args = [])
* @method \GuzzleHttp\Promise\Promise getProjectAsync(array $args = [])
* @method \Aws\Result getSegment(array $args = [])
* @method \GuzzleHttp\Promise\Promise getSegmentAsync(array $args = [])
* @method \Aws\Result listExperiments(array $args = [])
* @method \GuzzleHttp\Promise\Promise listExperimentsAsync(array $args = [])
* @method \Aws\Result listFeatures(array $args = [])
* @method \GuzzleHttp\Promise\Promise listFeaturesAsync(array $args = [])
* @method \Aws\Result listLaunches(array $args = [])
* @method \GuzzleHttp\Promise\Promise listLaunchesAsync(array $args = [])
* @method \Aws\Result listProjects(array $args = [])
* @method \GuzzleHttp\Promise\Promise listProjectsAsync(array $args = [])
* @method \Aws\Result listSegmentReferences(array $args = [])
* @method \GuzzleHttp\Promise\Promise listSegmentReferencesAsync(array $args = [])
* @method \Aws\Result listSegments(array $args = [])
* @method \GuzzleHttp\Promise\Promise listSegmentsAsync(array $args = [])
* @method \Aws\Result listTagsForResource(array $args = [])
* @method \GuzzleHttp\Promise\Promise listTagsForResourceAsync(array $args = [])
* @method \Aws\Result putProjectEvents(array $args = [])
* @method \GuzzleHttp\Promise\Promise putProjectEventsAsync(array $args = [])
* @method \Aws\Result startExperiment(array $args = [])
* @method \GuzzleHttp\Promise\Promise startExperimentAsync(array $args = [])
* @method \Aws\Result startLaunch(array $args = [])
* @method \GuzzleHttp\Promise\Promise startLaunchAsync(array $args = [])
* @method \Aws\Result stopExperiment(array $args = [])
* @method \GuzzleHttp\Promise\Promise stopExperimentAsync(array $args = [])
* @method \Aws\Result stopLaunch(array $args = [])
* @method \GuzzleHttp\Promise\Promise stopLaunchAsync(array $args = [])
* @method \Aws\Result tagResource(array $args = [])
* @method \GuzzleHttp\Promise\Promise tagResourceAsync(array $args = [])
* @method \Aws\Result testSegmentPattern(array $args = [])
* @method \GuzzleHttp\Promise\Promise testSegmentPatternAsync(array $args = [])
* @method \Aws\Result untagResource(array $args = [])
* @method \GuzzleHttp\Promise\Promise untagResourceAsync(array $args = [])
* @method \Aws\Result updateExperiment(array $args = [])
* @method \GuzzleHttp\Promise\Promise updateExperimentAsync(array $args = [])
* @method \Aws\Result updateFeature(array $args = [])
* @method \GuzzleHttp\Promise\Promise updateFeatureAsync(array $args = [])
* @method \Aws\Result updateLaunch(array $args = [])
* @method \GuzzleHttp\Promise\Promise updateLaunchAsync(array $args = [])
* @method \Aws\Result updateProject(array $args = [])
* @method \GuzzleHttp\Promise\Promise updateProjectAsync(array $args = [])
* @method \Aws\Result updateProjectDataDelivery(array $args = [])
* @method \GuzzleHttp\Promise\Promise updateProjectDataDeliveryAsync(array $args = [])
*/
class CloudWatchEvidentlyClient extends AwsClient {}

View File

@@ -1,9 +0,0 @@
<?php
namespace Aws\CloudWatchEvidently\Exception;
use Aws\Exception\AwsException;
/**
* Represents an error interacting with the **Amazon CloudWatch Evidently** service.
*/
class CloudWatchEvidentlyException extends AwsException {}

View File

@@ -28,6 +28,8 @@
* @method \GuzzleHttp\Promise\Promise createLogGroupAsync(array $args = [])
* @method \Aws\Result createLogStream(array $args = [])
* @method \GuzzleHttp\Promise\Promise createLogStreamAsync(array $args = [])
* @method \Aws\Result createLookupTable(array $args = [])
* @method \GuzzleHttp\Promise\Promise createLookupTableAsync(array $args = [])
* @method \Aws\Result createScheduledQuery(array $args = [])
* @method \GuzzleHttp\Promise\Promise createScheduledQueryAsync(array $args = [])
* @method \Aws\Result deleteAccountPolicy(array $args = [])
@@ -54,6 +56,8 @@
* @method \GuzzleHttp\Promise\Promise deleteLogGroupAsync(array $args = [])
* @method \Aws\Result deleteLogStream(array $args = [])
* @method \GuzzleHttp\Promise\Promise deleteLogStreamAsync(array $args = [])
* @method \Aws\Result deleteLookupTable(array $args = [])
* @method \GuzzleHttp\Promise\Promise deleteLookupTableAsync(array $args = [])
* @method \Aws\Result deleteMetricFilter(array $args = [])
* @method \GuzzleHttp\Promise\Promise deleteMetricFilterAsync(array $args = [])
* @method \Aws\Result deleteQueryDefinition(array $args = [])
@@ -94,6 +98,8 @@
* @method \GuzzleHttp\Promise\Promise describeLogGroupsAsync(array $args = [])
* @method \Aws\Result describeLogStreams(array $args = [])
* @method \GuzzleHttp\Promise\Promise describeLogStreamsAsync(array $args = [])
* @method \Aws\Result describeLookupTables(array $args = [])
* @method \GuzzleHttp\Promise\Promise describeLookupTablesAsync(array $args = [])
* @method \Aws\Result describeMetricFilters(array $args = [])
* @method \GuzzleHttp\Promise\Promise describeMetricFiltersAsync(array $args = [])
* @method \Aws\Result describeQueries(array $args = [])
@@ -134,6 +140,8 @@
* @method \GuzzleHttp\Promise\Promise getLogObjectAsync(array $args = [])
* @method \Aws\Result getLogRecord(array $args = [])
* @method \GuzzleHttp\Promise\Promise getLogRecordAsync(array $args = [])
* @method \Aws\Result getLookupTable(array $args = [])
* @method \GuzzleHttp\Promise\Promise getLookupTableAsync(array $args = [])
* @method \Aws\Result getQueryResults(array $args = [])
* @method \GuzzleHttp\Promise\Promise getQueryResultsAsync(array $args = [])
* @method \Aws\Result getScheduledQuery(array $args = [])
@@ -164,6 +172,8 @@
* @method \GuzzleHttp\Promise\Promise listTagsLogGroupAsync(array $args = [])
* @method \Aws\Result putAccountPolicy(array $args = [])
* @method \GuzzleHttp\Promise\Promise putAccountPolicyAsync(array $args = [])
* @method \Aws\Result putBearerTokenAuthentication(array $args = [])
* @method \GuzzleHttp\Promise\Promise putBearerTokenAuthenticationAsync(array $args = [])
* @method \Aws\Result putDataProtectionPolicy(array $args = [])
* @method \GuzzleHttp\Promise\Promise putDataProtectionPolicyAsync(array $args = [])
* @method \Aws\Result putDeliveryDestination(array $args = [])
@@ -220,41 +230,12 @@
* @method \GuzzleHttp\Promise\Promise updateDeliveryConfigurationAsync(array $args = [])
* @method \Aws\Result updateLogAnomalyDetector(array $args = [])
* @method \GuzzleHttp\Promise\Promise updateLogAnomalyDetectorAsync(array $args = [])
* @method \Aws\Result updateLookupTable(array $args = [])
* @method \GuzzleHttp\Promise\Promise updateLookupTableAsync(array $args = [])
* @method \Aws\Result updateScheduledQuery(array $args = [])
* @method \GuzzleHttp\Promise\Promise updateScheduledQueryAsync(array $args = [])
*/
class CloudWatchLogsClient extends AwsClient {
static $streamingCommands = [
'StartLiveTail' => true
];
public function __construct(array $args)
{
parent::__construct($args);
$this->addStreamingFlagMiddleware();
}
private function addStreamingFlagMiddleware()
{
$this->getHandlerList()
-> appendInit(
$this->getStreamingFlagMiddleware(),
'streaming-flag-middleware'
);
}
private function getStreamingFlagMiddleware(): callable
{
return function (callable $handler) {
return function (CommandInterface $command, $request = null) use ($handler) {
if (!empty(self::$streamingCommands[$command->getName()])) {
$command['@http']['stream'] = true;
}
return $handler($command, $request);
};
};
}
/**
* Helper method for 'startLiveTail' operation that checks for results.

View File

@@ -8,6 +8,8 @@
*
* @method \Aws\Result addCustomAttributes(array $args = [])
* @method \GuzzleHttp\Promise\Promise addCustomAttributesAsync(array $args = [])
* @method \Aws\Result addUserPoolClientSecret(array $args = [])
* @method \GuzzleHttp\Promise\Promise addUserPoolClientSecretAsync(array $args = [])
* @method \Aws\Result adminAddUserToGroup(array $args = [])
* @method \GuzzleHttp\Promise\Promise adminAddUserToGroupAsync(array $args = [])
* @method \Aws\Result adminConfirmSignUp(array $args = [])
@@ -108,6 +110,8 @@
* @method \GuzzleHttp\Promise\Promise deleteUserPoolAsync(array $args = [])
* @method \Aws\Result deleteUserPoolClient(array $args = [])
* @method \GuzzleHttp\Promise\Promise deleteUserPoolClientAsync(array $args = [])
* @method \Aws\Result deleteUserPoolClientSecret(array $args = [])
* @method \GuzzleHttp\Promise\Promise deleteUserPoolClientSecretAsync(array $args = [])
* @method \Aws\Result deleteUserPoolDomain(array $args = [])
* @method \GuzzleHttp\Promise\Promise deleteUserPoolDomainAsync(array $args = [])
* @method \Aws\Result deleteWebAuthnCredential(array $args = [])
@@ -178,6 +182,8 @@
* @method \GuzzleHttp\Promise\Promise listTermsAsync(array $args = [])
* @method \Aws\Result listUserImportJobs(array $args = [])
* @method \GuzzleHttp\Promise\Promise listUserImportJobsAsync(array $args = [])
* @method \Aws\Result listUserPoolClientSecrets(array $args = [])
* @method \GuzzleHttp\Promise\Promise listUserPoolClientSecretsAsync(array $args = [])
* @method \Aws\Result listUserPoolClients(array $args = [])
* @method \GuzzleHttp\Promise\Promise listUserPoolClientsAsync(array $args = [])
* @method \Aws\Result listUserPools(array $args = [])

View File

@@ -21,6 +21,8 @@
* @method \GuzzleHttp\Promise\Promise associateEmailAddressAliasAsync(array $args = [])
* @method \Aws\Result associateFlow(array $args = [])
* @method \GuzzleHttp\Promise\Promise associateFlowAsync(array $args = [])
* @method \Aws\Result associateHoursOfOperations(array $args = [])
* @method \GuzzleHttp\Promise\Promise associateHoursOfOperationsAsync(array $args = [])
* @method \Aws\Result associateInstanceStorageConfig(array $args = [])
* @method \GuzzleHttp\Promise\Promise associateInstanceStorageConfigAsync(array $args = [])
* @method \Aws\Result associateLambdaFunction(array $args = [])
@@ -29,6 +31,8 @@
* @method \GuzzleHttp\Promise\Promise associateLexBotAsync(array $args = [])
* @method \Aws\Result associatePhoneNumberContactFlow(array $args = [])
* @method \GuzzleHttp\Promise\Promise associatePhoneNumberContactFlowAsync(array $args = [])
* @method \Aws\Result associateQueueEmailAddresses(array $args = [])
* @method \GuzzleHttp\Promise\Promise associateQueueEmailAddressesAsync(array $args = [])
* @method \Aws\Result associateQueueQuickConnects(array $args = [])
* @method \GuzzleHttp\Promise\Promise associateQueueQuickConnectsAsync(array $args = [])
* @method \Aws\Result associateRoutingProfileQueues(array $args = [])
@@ -95,6 +99,8 @@
* @method \GuzzleHttp\Promise\Promise createInstanceAsync(array $args = [])
* @method \Aws\Result createIntegrationAssociation(array $args = [])
* @method \GuzzleHttp\Promise\Promise createIntegrationAssociationAsync(array $args = [])
* @method \Aws\Result createNotification(array $args = [])
* @method \GuzzleHttp\Promise\Promise createNotificationAsync(array $args = [])
* @method \Aws\Result createParticipant(array $args = [])
* @method \GuzzleHttp\Promise\Promise createParticipantAsync(array $args = [])
* @method \Aws\Result createPersistentContactAssociation(array $args = [])
@@ -117,6 +123,8 @@
* @method \GuzzleHttp\Promise\Promise createSecurityProfileAsync(array $args = [])
* @method \Aws\Result createTaskTemplate(array $args = [])
* @method \GuzzleHttp\Promise\Promise createTaskTemplateAsync(array $args = [])
* @method \Aws\Result createTestCase(array $args = [])
* @method \GuzzleHttp\Promise\Promise createTestCaseAsync(array $args = [])
* @method \Aws\Result createTrafficDistributionGroup(array $args = [])
* @method \GuzzleHttp\Promise\Promise createTrafficDistributionGroupAsync(array $args = [])
* @method \Aws\Result createUseCase(array $args = [])
@@ -167,6 +175,8 @@
* @method \GuzzleHttp\Promise\Promise deleteInstanceAsync(array $args = [])
* @method \Aws\Result deleteIntegrationAssociation(array $args = [])
* @method \GuzzleHttp\Promise\Promise deleteIntegrationAssociationAsync(array $args = [])
* @method \Aws\Result deleteNotification(array $args = [])
* @method \GuzzleHttp\Promise\Promise deleteNotificationAsync(array $args = [])
* @method \Aws\Result deletePredefinedAttribute(array $args = [])
* @method \GuzzleHttp\Promise\Promise deletePredefinedAttributeAsync(array $args = [])
* @method \Aws\Result deletePrompt(array $args = [])
@@ -185,6 +195,8 @@
* @method \GuzzleHttp\Promise\Promise deleteSecurityProfileAsync(array $args = [])
* @method \Aws\Result deleteTaskTemplate(array $args = [])
* @method \GuzzleHttp\Promise\Promise deleteTaskTemplateAsync(array $args = [])
* @method \Aws\Result deleteTestCase(array $args = [])
* @method \GuzzleHttp\Promise\Promise deleteTestCaseAsync(array $args = [])
* @method \Aws\Result deleteTrafficDistributionGroup(array $args = [])
* @method \GuzzleHttp\Promise\Promise deleteTrafficDistributionGroupAsync(array $args = [])
* @method \Aws\Result deleteUseCase(array $args = [])
@@ -237,6 +249,8 @@
* @method \GuzzleHttp\Promise\Promise describeInstanceAttributeAsync(array $args = [])
* @method \Aws\Result describeInstanceStorageConfig(array $args = [])
* @method \GuzzleHttp\Promise\Promise describeInstanceStorageConfigAsync(array $args = [])
* @method \Aws\Result describeNotification(array $args = [])
* @method \GuzzleHttp\Promise\Promise describeNotificationAsync(array $args = [])
* @method \Aws\Result describePhoneNumber(array $args = [])
* @method \GuzzleHttp\Promise\Promise describePhoneNumberAsync(array $args = [])
* @method \Aws\Result describePredefinedAttribute(array $args = [])
@@ -253,6 +267,8 @@
* @method \GuzzleHttp\Promise\Promise describeRuleAsync(array $args = [])
* @method \Aws\Result describeSecurityProfile(array $args = [])
* @method \GuzzleHttp\Promise\Promise describeSecurityProfileAsync(array $args = [])
* @method \Aws\Result describeTestCase(array $args = [])
* @method \GuzzleHttp\Promise\Promise describeTestCaseAsync(array $args = [])
* @method \Aws\Result describeTrafficDistributionGroup(array $args = [])
* @method \GuzzleHttp\Promise\Promise describeTrafficDistributionGroupAsync(array $args = [])
* @method \Aws\Result describeUser(array $args = [])
@@ -277,6 +293,8 @@
* @method \GuzzleHttp\Promise\Promise disassociateEmailAddressAliasAsync(array $args = [])
* @method \Aws\Result disassociateFlow(array $args = [])
* @method \GuzzleHttp\Promise\Promise disassociateFlowAsync(array $args = [])
* @method \Aws\Result disassociateHoursOfOperations(array $args = [])
* @method \GuzzleHttp\Promise\Promise disassociateHoursOfOperationsAsync(array $args = [])
* @method \Aws\Result disassociateInstanceStorageConfig(array $args = [])
* @method \GuzzleHttp\Promise\Promise disassociateInstanceStorageConfigAsync(array $args = [])
* @method \Aws\Result disassociateLambdaFunction(array $args = [])
@@ -285,6 +303,8 @@
* @method \GuzzleHttp\Promise\Promise disassociateLexBotAsync(array $args = [])
* @method \Aws\Result disassociatePhoneNumberContactFlow(array $args = [])
* @method \GuzzleHttp\Promise\Promise disassociatePhoneNumberContactFlowAsync(array $args = [])
* @method \Aws\Result disassociateQueueEmailAddresses(array $args = [])
* @method \GuzzleHttp\Promise\Promise disassociateQueueEmailAddressesAsync(array $args = [])
* @method \Aws\Result disassociateQueueQuickConnects(array $args = [])
* @method \GuzzleHttp\Promise\Promise disassociateQueueQuickConnectsAsync(array $args = [])
* @method \Aws\Result disassociateRoutingProfileQueues(array $args = [])
@@ -327,6 +347,8 @@
* @method \GuzzleHttp\Promise\Promise getPromptFileAsync(array $args = [])
* @method \Aws\Result getTaskTemplate(array $args = [])
* @method \GuzzleHttp\Promise\Promise getTaskTemplateAsync(array $args = [])
* @method \Aws\Result getTestCaseExecutionSummary(array $args = [])
* @method \GuzzleHttp\Promise\Promise getTestCaseExecutionSummaryAsync(array $args = [])
* @method \Aws\Result getTrafficDistribution(array $args = [])
* @method \GuzzleHttp\Promise\Promise getTrafficDistributionAsync(array $args = [])
* @method \Aws\Result importPhoneNumber(array $args = [])
@@ -347,6 +369,8 @@
* @method \GuzzleHttp\Promise\Promise listAuthenticationProfilesAsync(array $args = [])
* @method \Aws\Result listBots(array $args = [])
* @method \GuzzleHttp\Promise\Promise listBotsAsync(array $args = [])
* @method \Aws\Result listChildHoursOfOperations(array $args = [])
* @method \GuzzleHttp\Promise\Promise listChildHoursOfOperationsAsync(array $args = [])
* @method \Aws\Result listContactEvaluations(array $args = [])
* @method \GuzzleHttp\Promise\Promise listContactEvaluationsAsync(array $args = [])
* @method \Aws\Result listContactFlowModuleAliases(array $args = [])
@@ -395,6 +419,8 @@
* @method \GuzzleHttp\Promise\Promise listLambdaFunctionsAsync(array $args = [])
* @method \Aws\Result listLexBots(array $args = [])
* @method \GuzzleHttp\Promise\Promise listLexBotsAsync(array $args = [])
* @method \Aws\Result listNotifications(array $args = [])
* @method \GuzzleHttp\Promise\Promise listNotificationsAsync(array $args = [])
* @method \Aws\Result listPhoneNumbers(array $args = [])
* @method \GuzzleHttp\Promise\Promise listPhoneNumbersAsync(array $args = [])
* @method \Aws\Result listPhoneNumbersV2(array $args = [])
@@ -403,6 +429,8 @@
* @method \GuzzleHttp\Promise\Promise listPredefinedAttributesAsync(array $args = [])
* @method \Aws\Result listPrompts(array $args = [])
* @method \GuzzleHttp\Promise\Promise listPromptsAsync(array $args = [])
* @method \Aws\Result listQueueEmailAddresses(array $args = [])
* @method \GuzzleHttp\Promise\Promise listQueueEmailAddressesAsync(array $args = [])
* @method \Aws\Result listQueueQuickConnects(array $args = [])
* @method \GuzzleHttp\Promise\Promise listQueueQuickConnectsAsync(array $args = [])
* @method \Aws\Result listQueues(array $args = [])
@@ -433,6 +461,12 @@
* @method \GuzzleHttp\Promise\Promise listTagsForResourceAsync(array $args = [])
* @method \Aws\Result listTaskTemplates(array $args = [])
* @method \GuzzleHttp\Promise\Promise listTaskTemplatesAsync(array $args = [])
* @method \Aws\Result listTestCaseExecutionRecords(array $args = [])
* @method \GuzzleHttp\Promise\Promise listTestCaseExecutionRecordsAsync(array $args = [])
* @method \Aws\Result listTestCaseExecutions(array $args = [])
* @method \GuzzleHttp\Promise\Promise listTestCaseExecutionsAsync(array $args = [])
* @method \Aws\Result listTestCases(array $args = [])
* @method \GuzzleHttp\Promise\Promise listTestCasesAsync(array $args = [])
* @method \Aws\Result listTrafficDistributionGroupUsers(array $args = [])
* @method \GuzzleHttp\Promise\Promise listTrafficDistributionGroupUsersAsync(array $args = [])
* @method \Aws\Result listTrafficDistributionGroups(array $args = [])
@@ -441,6 +475,8 @@
* @method \GuzzleHttp\Promise\Promise listUseCasesAsync(array $args = [])
* @method \Aws\Result listUserHierarchyGroups(array $args = [])
* @method \GuzzleHttp\Promise\Promise listUserHierarchyGroupsAsync(array $args = [])
* @method \Aws\Result listUserNotifications(array $args = [])
* @method \GuzzleHttp\Promise\Promise listUserNotificationsAsync(array $args = [])
* @method \Aws\Result listUserProficiencies(array $args = [])
* @method \GuzzleHttp\Promise\Promise listUserProficienciesAsync(array $args = [])
* @method \Aws\Result listUsers(array $args = [])
@@ -491,6 +527,8 @@
* @method \GuzzleHttp\Promise\Promise searchHoursOfOperationOverridesAsync(array $args = [])
* @method \Aws\Result searchHoursOfOperations(array $args = [])
* @method \GuzzleHttp\Promise\Promise searchHoursOfOperationsAsync(array $args = [])
* @method \Aws\Result searchNotifications(array $args = [])
* @method \GuzzleHttp\Promise\Promise searchNotificationsAsync(array $args = [])
* @method \Aws\Result searchPredefinedAttributes(array $args = [])
* @method \GuzzleHttp\Promise\Promise searchPredefinedAttributesAsync(array $args = [])
* @method \Aws\Result searchPrompts(array $args = [])
@@ -505,6 +543,8 @@
* @method \GuzzleHttp\Promise\Promise searchRoutingProfilesAsync(array $args = [])
* @method \Aws\Result searchSecurityProfiles(array $args = [])
* @method \GuzzleHttp\Promise\Promise searchSecurityProfilesAsync(array $args = [])
* @method \Aws\Result searchTestCases(array $args = [])
* @method \GuzzleHttp\Promise\Promise searchTestCasesAsync(array $args = [])
* @method \Aws\Result searchUserHierarchyGroups(array $args = [])
* @method \GuzzleHttp\Promise\Promise searchUserHierarchyGroupsAsync(array $args = [])
* @method \Aws\Result searchUsers(array $args = [])
@@ -545,6 +585,8 @@
* @method \GuzzleHttp\Promise\Promise startScreenSharingAsync(array $args = [])
* @method \Aws\Result startTaskContact(array $args = [])
* @method \GuzzleHttp\Promise\Promise startTaskContactAsync(array $args = [])
* @method \Aws\Result startTestCaseExecution(array $args = [])
* @method \GuzzleHttp\Promise\Promise startTestCaseExecutionAsync(array $args = [])
* @method \Aws\Result startWebRTCContact(array $args = [])
* @method \GuzzleHttp\Promise\Promise startWebRTCContactAsync(array $args = [])
* @method \Aws\Result stopContact(array $args = [])
@@ -555,6 +597,8 @@
* @method \GuzzleHttp\Promise\Promise stopContactRecordingAsync(array $args = [])
* @method \Aws\Result stopContactStreaming(array $args = [])
* @method \GuzzleHttp\Promise\Promise stopContactStreamingAsync(array $args = [])
* @method \Aws\Result stopTestCaseExecution(array $args = [])
* @method \GuzzleHttp\Promise\Promise stopTestCaseExecutionAsync(array $args = [])
* @method \Aws\Result submitContactEvaluation(array $args = [])
* @method \GuzzleHttp\Promise\Promise submitContactEvaluationAsync(array $args = [])
* @method \Aws\Result suspendContactRecording(array $args = [])
@@ -613,6 +657,8 @@
* @method \GuzzleHttp\Promise\Promise updateInstanceAttributeAsync(array $args = [])
* @method \Aws\Result updateInstanceStorageConfig(array $args = [])
* @method \GuzzleHttp\Promise\Promise updateInstanceStorageConfigAsync(array $args = [])
* @method \Aws\Result updateNotificationContent(array $args = [])
* @method \GuzzleHttp\Promise\Promise updateNotificationContentAsync(array $args = [])
* @method \Aws\Result updateParticipantAuthentication(array $args = [])
* @method \GuzzleHttp\Promise\Promise updateParticipantAuthenticationAsync(array $args = [])
* @method \Aws\Result updateParticipantRoleConfig(array $args = [])
@@ -657,8 +703,12 @@
* @method \GuzzleHttp\Promise\Promise updateSecurityProfileAsync(array $args = [])
* @method \Aws\Result updateTaskTemplate(array $args = [])
* @method \GuzzleHttp\Promise\Promise updateTaskTemplateAsync(array $args = [])
* @method \Aws\Result updateTestCase(array $args = [])
* @method \GuzzleHttp\Promise\Promise updateTestCaseAsync(array $args = [])
* @method \Aws\Result updateTrafficDistribution(array $args = [])
* @method \GuzzleHttp\Promise\Promise updateTrafficDistributionAsync(array $args = [])
* @method \Aws\Result updateUserConfig(array $args = [])
* @method \GuzzleHttp\Promise\Promise updateUserConfigAsync(array $args = [])
* @method \Aws\Result updateUserHierarchy(array $args = [])
* @method \GuzzleHttp\Promise\Promise updateUserHierarchyAsync(array $args = [])
* @method \Aws\Result updateUserHierarchyGroupName(array $args = [])
@@ -667,6 +717,8 @@
* @method \GuzzleHttp\Promise\Promise updateUserHierarchyStructureAsync(array $args = [])
* @method \Aws\Result updateUserIdentityInfo(array $args = [])
* @method \GuzzleHttp\Promise\Promise updateUserIdentityInfoAsync(array $args = [])
* @method \Aws\Result updateUserNotificationStatus(array $args = [])
* @method \GuzzleHttp\Promise\Promise updateUserNotificationStatusAsync(array $args = [])
* @method \Aws\Result updateUserPhoneConfig(array $args = [])
* @method \GuzzleHttp\Promise\Promise updateUserPhoneConfigAsync(array $args = [])
* @method \Aws\Result updateUserProficiencies(array $args = [])

View File

@@ -15,6 +15,8 @@
* @method \GuzzleHttp\Promise\Promise deleteCampaignCommunicationLimitsAsync(array $args = [])
* @method \Aws\Result deleteCampaignCommunicationTime(array $args = [])
* @method \GuzzleHttp\Promise\Promise deleteCampaignCommunicationTimeAsync(array $args = [])
* @method \Aws\Result deleteCampaignEntryLimits(array $args = [])
* @method \GuzzleHttp\Promise\Promise deleteCampaignEntryLimitsAsync(array $args = [])
* @method \Aws\Result deleteConnectInstanceConfig(array $args = [])
* @method \GuzzleHttp\Promise\Promise deleteConnectInstanceConfigAsync(array $args = [])
* @method \Aws\Result deleteConnectInstanceIntegration(array $args = [])
@@ -67,6 +69,8 @@
* @method \GuzzleHttp\Promise\Promise updateCampaignCommunicationLimitsAsync(array $args = [])
* @method \Aws\Result updateCampaignCommunicationTime(array $args = [])
* @method \GuzzleHttp\Promise\Promise updateCampaignCommunicationTimeAsync(array $args = [])
* @method \Aws\Result updateCampaignEntryLimits(array $args = [])
* @method \GuzzleHttp\Promise\Promise updateCampaignEntryLimitsAsync(array $args = [])
* @method \Aws\Result updateCampaignFlowAssociation(array $args = [])
* @method \GuzzleHttp\Promise\Promise updateCampaignFlowAssociationAsync(array $args = [])
* @method \Aws\Result updateCampaignName(array $args = [])

View File

@@ -87,6 +87,8 @@
* @method \GuzzleHttp\Promise\Promise updateFieldAsync(array $args = [])
* @method \Aws\Result updateLayout(array $args = [])
* @method \GuzzleHttp\Promise\Promise updateLayoutAsync(array $args = [])
* @method \Aws\Result updateRelatedItem(array $args = [])
* @method \GuzzleHttp\Promise\Promise updateRelatedItemAsync(array $args = [])
* @method \Aws\Result updateTemplate(array $args = [])
* @method \GuzzleHttp\Promise\Promise updateTemplateAsync(array $args = [])
*/

View File

@@ -0,0 +1,39 @@
<?php
namespace Aws\ConnectHealth;
use Aws\AwsClient;
/**
* This client is used to interact with the **Connect Health** service.
* @method \Aws\Result activateSubscription(array $args = [])
* @method \GuzzleHttp\Promise\Promise activateSubscriptionAsync(array $args = [])
* @method \Aws\Result createDomain(array $args = [])
* @method \GuzzleHttp\Promise\Promise createDomainAsync(array $args = [])
* @method \Aws\Result createSubscription(array $args = [])
* @method \GuzzleHttp\Promise\Promise createSubscriptionAsync(array $args = [])
* @method \Aws\Result deactivateSubscription(array $args = [])
* @method \GuzzleHttp\Promise\Promise deactivateSubscriptionAsync(array $args = [])
* @method \Aws\Result deleteDomain(array $args = [])
* @method \GuzzleHttp\Promise\Promise deleteDomainAsync(array $args = [])
* @method \Aws\Result getDomain(array $args = [])
* @method \GuzzleHttp\Promise\Promise getDomainAsync(array $args = [])
* @method \Aws\Result getMedicalScribeListeningSession(array $args = [])
* @method \GuzzleHttp\Promise\Promise getMedicalScribeListeningSessionAsync(array $args = [])
* @method \Aws\Result getPatientInsightsJob(array $args = [])
* @method \GuzzleHttp\Promise\Promise getPatientInsightsJobAsync(array $args = [])
* @method \Aws\Result getSubscription(array $args = [])
* @method \GuzzleHttp\Promise\Promise getSubscriptionAsync(array $args = [])
* @method \Aws\Result listDomains(array $args = [])
* @method \GuzzleHttp\Promise\Promise listDomainsAsync(array $args = [])
* @method \Aws\Result listSubscriptions(array $args = [])
* @method \GuzzleHttp\Promise\Promise listSubscriptionsAsync(array $args = [])
* @method \Aws\Result listTagsForResource(array $args = [])
* @method \GuzzleHttp\Promise\Promise listTagsForResourceAsync(array $args = [])
* @method \Aws\Result startPatientInsightsJob(array $args = [])
* @method \GuzzleHttp\Promise\Promise startPatientInsightsJobAsync(array $args = [])
* @method \Aws\Result tagResource(array $args = [])
* @method \GuzzleHttp\Promise\Promise tagResourceAsync(array $args = [])
* @method \Aws\Result untagResource(array $args = [])
* @method \GuzzleHttp\Promise\Promise untagResourceAsync(array $args = [])
*/
class ConnectHealthClient extends AwsClient {}

View File

@@ -0,0 +1,9 @@
<?php
namespace Aws\ConnectHealth\Exception;
use Aws\Exception\AwsException;
/**
* Represents an error interacting with the **Connect Health** service.
*/
class ConnectHealthException extends AwsException {}

View File

@@ -27,6 +27,10 @@
* @method \GuzzleHttp\Promise\Promise createProfileAsync(array $args = [])
* @method \Aws\Result createRecommender(array $args = [])
* @method \GuzzleHttp\Promise\Promise createRecommenderAsync(array $args = [])
* @method \Aws\Result createRecommenderFilter(array $args = [])
* @method \GuzzleHttp\Promise\Promise createRecommenderFilterAsync(array $args = [])
* @method \Aws\Result createRecommenderSchema(array $args = [])
* @method \GuzzleHttp\Promise\Promise createRecommenderSchemaAsync(array $args = [])
* @method \Aws\Result createSegmentDefinition(array $args = [])
* @method \GuzzleHttp\Promise\Promise createSegmentDefinitionAsync(array $args = [])
* @method \Aws\Result createSegmentEstimate(array $args = [])
@@ -59,6 +63,10 @@
* @method \GuzzleHttp\Promise\Promise deleteProfileObjectTypeAsync(array $args = [])
* @method \Aws\Result deleteRecommender(array $args = [])
* @method \GuzzleHttp\Promise\Promise deleteRecommenderAsync(array $args = [])
* @method \Aws\Result deleteRecommenderFilter(array $args = [])
* @method \GuzzleHttp\Promise\Promise deleteRecommenderFilterAsync(array $args = [])
* @method \Aws\Result deleteRecommenderSchema(array $args = [])
* @method \GuzzleHttp\Promise\Promise deleteRecommenderSchemaAsync(array $args = [])
* @method \Aws\Result deleteSegmentDefinition(array $args = [])
* @method \GuzzleHttp\Promise\Promise deleteSegmentDefinitionAsync(array $args = [])
* @method \Aws\Result deleteWorkflow(array $args = [])
@@ -99,6 +107,10 @@
* @method \GuzzleHttp\Promise\Promise getProfileRecommendationsAsync(array $args = [])
* @method \Aws\Result getRecommender(array $args = [])
* @method \GuzzleHttp\Promise\Promise getRecommenderAsync(array $args = [])
* @method \Aws\Result getRecommenderFilter(array $args = [])
* @method \GuzzleHttp\Promise\Promise getRecommenderFilterAsync(array $args = [])
* @method \Aws\Result getRecommenderSchema(array $args = [])
* @method \GuzzleHttp\Promise\Promise getRecommenderSchemaAsync(array $args = [])
* @method \Aws\Result getSegmentDefinition(array $args = [])
* @method \GuzzleHttp\Promise\Promise getSegmentDefinitionAsync(array $args = [])
* @method \Aws\Result getSegmentEstimate(array $args = [])
@@ -151,8 +163,12 @@
* @method \GuzzleHttp\Promise\Promise listProfileObjectTypesAsync(array $args = [])
* @method \Aws\Result listProfileObjects(array $args = [])
* @method \GuzzleHttp\Promise\Promise listProfileObjectsAsync(array $args = [])
* @method \Aws\Result listRecommenderFilters(array $args = [])
* @method \GuzzleHttp\Promise\Promise listRecommenderFiltersAsync(array $args = [])
* @method \Aws\Result listRecommenderRecipes(array $args = [])
* @method \GuzzleHttp\Promise\Promise listRecommenderRecipesAsync(array $args = [])
* @method \Aws\Result listRecommenderSchemas(array $args = [])
* @method \GuzzleHttp\Promise\Promise listRecommenderSchemasAsync(array $args = [])
* @method \Aws\Result listRecommenders(array $args = [])
* @method \GuzzleHttp\Promise\Promise listRecommendersAsync(array $args = [])
* @method \Aws\Result listRuleBasedMatches(array $args = [])

View File

@@ -91,6 +91,8 @@
* @method \GuzzleHttp\Promise\Promise deleteAssetTypeAsync(array $args = [])
* @method \Aws\Result deleteConnection(array $args = [])
* @method \GuzzleHttp\Promise\Promise deleteConnectionAsync(array $args = [])
* @method \Aws\Result deleteDataExportConfiguration(array $args = [])
* @method \GuzzleHttp\Promise\Promise deleteDataExportConfigurationAsync(array $args = [])
* @method \Aws\Result deleteDataProduct(array $args = [])
* @method \GuzzleHttp\Promise\Promise deleteDataProductAsync(array $args = [])
* @method \Aws\Result deleteDataSource(array $args = [])
@@ -283,6 +285,8 @@
* @method \GuzzleHttp\Promise\Promise putDataExportConfigurationAsync(array $args = [])
* @method \Aws\Result putEnvironmentBlueprintConfiguration(array $args = [])
* @method \GuzzleHttp\Promise\Promise putEnvironmentBlueprintConfigurationAsync(array $args = [])
* @method \Aws\Result queryGraph(array $args = [])
* @method \GuzzleHttp\Promise\Promise queryGraphAsync(array $args = [])
* @method \Aws\Result rejectPredictions(array $args = [])
* @method \GuzzleHttp\Promise\Promise rejectPredictionsAsync(array $args = [])
* @method \Aws\Result rejectSubscriptionRequest(array $args = [])

View File

@@ -23,8 +23,24 @@
* @method \GuzzleHttp\Promise\Promise assumeQueueRoleForUserAsync(array $args = [])
* @method \Aws\Result assumeQueueRoleForWorker(array $args = [])
* @method \GuzzleHttp\Promise\Promise assumeQueueRoleForWorkerAsync(array $args = [])
* @method \Aws\Result batchGetJob(array $args = [])
* @method \GuzzleHttp\Promise\Promise batchGetJobAsync(array $args = [])
* @method \Aws\Result batchGetJobEntity(array $args = [])
* @method \GuzzleHttp\Promise\Promise batchGetJobEntityAsync(array $args = [])
* @method \Aws\Result batchGetSession(array $args = [])
* @method \GuzzleHttp\Promise\Promise batchGetSessionAsync(array $args = [])
* @method \Aws\Result batchGetSessionAction(array $args = [])
* @method \GuzzleHttp\Promise\Promise batchGetSessionActionAsync(array $args = [])
* @method \Aws\Result batchGetStep(array $args = [])
* @method \GuzzleHttp\Promise\Promise batchGetStepAsync(array $args = [])
* @method \Aws\Result batchGetTask(array $args = [])
* @method \GuzzleHttp\Promise\Promise batchGetTaskAsync(array $args = [])
* @method \Aws\Result batchGetWorker(array $args = [])
* @method \GuzzleHttp\Promise\Promise batchGetWorkerAsync(array $args = [])
* @method \Aws\Result batchUpdateJob(array $args = [])
* @method \GuzzleHttp\Promise\Promise batchUpdateJobAsync(array $args = [])
* @method \Aws\Result batchUpdateTask(array $args = [])
* @method \GuzzleHttp\Promise\Promise batchUpdateTaskAsync(array $args = [])
* @method \Aws\Result copyJobTemplate(array $args = [])
* @method \GuzzleHttp\Promise\Promise copyJobTemplateAsync(array $args = [])
* @method \Aws\Result createBudget(array $args = [])
@@ -101,6 +117,8 @@
* @method \GuzzleHttp\Promise\Promise getLimitAsync(array $args = [])
* @method \Aws\Result getMonitor(array $args = [])
* @method \GuzzleHttp\Promise\Promise getMonitorAsync(array $args = [])
* @method \Aws\Result getMonitorSettings(array $args = [])
* @method \GuzzleHttp\Promise\Promise getMonitorSettingsAsync(array $args = [])
* @method \Aws\Result getQueue(array $args = [])
* @method \GuzzleHttp\Promise\Promise getQueueAsync(array $args = [])
* @method \Aws\Result getQueueEnvironment(array $args = [])
@@ -211,6 +229,8 @@
* @method \GuzzleHttp\Promise\Promise updateLimitAsync(array $args = [])
* @method \Aws\Result updateMonitor(array $args = [])
* @method \GuzzleHttp\Promise\Promise updateMonitorAsync(array $args = [])
* @method \Aws\Result updateMonitorSettings(array $args = [])
* @method \GuzzleHttp\Promise\Promise updateMonitorSettingsAsync(array $args = [])
* @method \Aws\Result updateQueue(array $args = [])
* @method \GuzzleHttp\Promise\Promise updateQueueAsync(array $args = [])
* @method \Aws\Result updateQueueEnvironment(array $args = [])

View File

@@ -0,0 +1,97 @@
<?php
namespace Aws\DevOpsAgent;
use Aws\AwsClient;
/**
* This client is used to interact with the **AWS DevOps Agent Service** service.
* @method \Aws\Result associateService(array $args = [])
* @method \GuzzleHttp\Promise\Promise associateServiceAsync(array $args = [])
* @method \Aws\Result createAgentSpace(array $args = [])
* @method \GuzzleHttp\Promise\Promise createAgentSpaceAsync(array $args = [])
* @method \Aws\Result createBacklogTask(array $args = [])
* @method \GuzzleHttp\Promise\Promise createBacklogTaskAsync(array $args = [])
* @method \Aws\Result createChat(array $args = [])
* @method \GuzzleHttp\Promise\Promise createChatAsync(array $args = [])
* @method \Aws\Result createPrivateConnection(array $args = [])
* @method \GuzzleHttp\Promise\Promise createPrivateConnectionAsync(array $args = [])
* @method \Aws\Result deleteAgentSpace(array $args = [])
* @method \GuzzleHttp\Promise\Promise deleteAgentSpaceAsync(array $args = [])
* @method \Aws\Result deletePrivateConnection(array $args = [])
* @method \GuzzleHttp\Promise\Promise deletePrivateConnectionAsync(array $args = [])
* @method \Aws\Result deregisterService(array $args = [])
* @method \GuzzleHttp\Promise\Promise deregisterServiceAsync(array $args = [])
* @method \Aws\Result describePrivateConnection(array $args = [])
* @method \GuzzleHttp\Promise\Promise describePrivateConnectionAsync(array $args = [])
* @method \Aws\Result disableOperatorApp(array $args = [])
* @method \GuzzleHttp\Promise\Promise disableOperatorAppAsync(array $args = [])
* @method \Aws\Result disassociateService(array $args = [])
* @method \GuzzleHttp\Promise\Promise disassociateServiceAsync(array $args = [])
* @method \Aws\Result enableOperatorApp(array $args = [])
* @method \GuzzleHttp\Promise\Promise enableOperatorAppAsync(array $args = [])
* @method \Aws\Result getAccountUsage(array $args = [])
* @method \GuzzleHttp\Promise\Promise getAccountUsageAsync(array $args = [])
* @method \Aws\Result getAgentSpace(array $args = [])
* @method \GuzzleHttp\Promise\Promise getAgentSpaceAsync(array $args = [])
* @method \Aws\Result getAssociation(array $args = [])
* @method \GuzzleHttp\Promise\Promise getAssociationAsync(array $args = [])
* @method \Aws\Result getBacklogTask(array $args = [])
* @method \GuzzleHttp\Promise\Promise getBacklogTaskAsync(array $args = [])
* @method \Aws\Result getOperatorApp(array $args = [])
* @method \GuzzleHttp\Promise\Promise getOperatorAppAsync(array $args = [])
* @method \Aws\Result getRecommendation(array $args = [])
* @method \GuzzleHttp\Promise\Promise getRecommendationAsync(array $args = [])
* @method \Aws\Result getService(array $args = [])
* @method \GuzzleHttp\Promise\Promise getServiceAsync(array $args = [])
* @method \Aws\Result listAgentSpaces(array $args = [])
* @method \GuzzleHttp\Promise\Promise listAgentSpacesAsync(array $args = [])
* @method \Aws\Result listAssociations(array $args = [])
* @method \GuzzleHttp\Promise\Promise listAssociationsAsync(array $args = [])
* @method \Aws\Result listBacklogTasks(array $args = [])
* @method \GuzzleHttp\Promise\Promise listBacklogTasksAsync(array $args = [])
* @method \Aws\Result listChats(array $args = [])
* @method \GuzzleHttp\Promise\Promise listChatsAsync(array $args = [])
* @method \Aws\Result listExecutions(array $args = [])
* @method \GuzzleHttp\Promise\Promise listExecutionsAsync(array $args = [])
* @method \Aws\Result listGoals(array $args = [])
* @method \GuzzleHttp\Promise\Promise listGoalsAsync(array $args = [])
* @method \Aws\Result listJournalRecords(array $args = [])
* @method \GuzzleHttp\Promise\Promise listJournalRecordsAsync(array $args = [])
* @method \Aws\Result listPendingMessages(array $args = [])
* @method \GuzzleHttp\Promise\Promise listPendingMessagesAsync(array $args = [])
* @method \Aws\Result listPrivateConnections(array $args = [])
* @method \GuzzleHttp\Promise\Promise listPrivateConnectionsAsync(array $args = [])
* @method \Aws\Result listRecommendations(array $args = [])
* @method \GuzzleHttp\Promise\Promise listRecommendationsAsync(array $args = [])
* @method \Aws\Result listServices(array $args = [])
* @method \GuzzleHttp\Promise\Promise listServicesAsync(array $args = [])
* @method \Aws\Result listTagsForResource(array $args = [])
* @method \GuzzleHttp\Promise\Promise listTagsForResourceAsync(array $args = [])
* @method \Aws\Result listWebhooks(array $args = [])
* @method \GuzzleHttp\Promise\Promise listWebhooksAsync(array $args = [])
* @method \Aws\Result registerService(array $args = [])
* @method \GuzzleHttp\Promise\Promise registerServiceAsync(array $args = [])
* @method \Aws\Result sendMessage(array $args = [])
* @method \GuzzleHttp\Promise\Promise sendMessageAsync(array $args = [])
* @method \Aws\Result tagResource(array $args = [])
* @method \GuzzleHttp\Promise\Promise tagResourceAsync(array $args = [])
* @method \Aws\Result untagResource(array $args = [])
* @method \GuzzleHttp\Promise\Promise untagResourceAsync(array $args = [])
* @method \Aws\Result updateAgentSpace(array $args = [])
* @method \GuzzleHttp\Promise\Promise updateAgentSpaceAsync(array $args = [])
* @method \Aws\Result updateAssociation(array $args = [])
* @method \GuzzleHttp\Promise\Promise updateAssociationAsync(array $args = [])
* @method \Aws\Result updateBacklogTask(array $args = [])
* @method \GuzzleHttp\Promise\Promise updateBacklogTaskAsync(array $args = [])
* @method \Aws\Result updateGoal(array $args = [])
* @method \GuzzleHttp\Promise\Promise updateGoalAsync(array $args = [])
* @method \Aws\Result updateOperatorAppIdpConfig(array $args = [])
* @method \GuzzleHttp\Promise\Promise updateOperatorAppIdpConfigAsync(array $args = [])
* @method \Aws\Result updatePrivateConnectionCertificate(array $args = [])
* @method \GuzzleHttp\Promise\Promise updatePrivateConnectionCertificateAsync(array $args = [])
* @method \Aws\Result updateRecommendation(array $args = [])
* @method \GuzzleHttp\Promise\Promise updateRecommendationAsync(array $args = [])
* @method \Aws\Result validateAwsAssociations(array $args = [])
* @method \GuzzleHttp\Promise\Promise validateAwsAssociationsAsync(array $args = [])
*/
class DevOpsAgentClient extends AwsClient {}

View File

@@ -0,0 +1,9 @@
<?php
namespace Aws\DevOpsAgent\Exception;
use Aws\Exception\AwsException;
/**
* Represents an error interacting with the **AWS DevOps Agent Service** service.
*/
class DevOpsAgentException extends AwsException {}

View File

@@ -596,6 +596,10 @@
* @method \GuzzleHttp\Promise\Promise createRouteServerEndpointAsync(array $args = []) (supported in versions 2016-11-15)
* @method \Aws\Result createRouteServerPeer(array $args = []) (supported in versions 2016-11-15)
* @method \GuzzleHttp\Promise\Promise createRouteServerPeerAsync(array $args = []) (supported in versions 2016-11-15)
* @method \Aws\Result createSecondaryNetwork(array $args = []) (supported in versions 2016-11-15)
* @method \GuzzleHttp\Promise\Promise createSecondaryNetworkAsync(array $args = []) (supported in versions 2016-11-15)
* @method \Aws\Result createSecondarySubnet(array $args = []) (supported in versions 2016-11-15)
* @method \GuzzleHttp\Promise\Promise createSecondarySubnetAsync(array $args = []) (supported in versions 2016-11-15)
* @method \Aws\Result createSnapshots(array $args = []) (supported in versions 2016-11-15)
* @method \GuzzleHttp\Promise\Promise createSnapshotsAsync(array $args = []) (supported in versions 2016-11-15)
* @method \Aws\Result createStoreImageTask(array $args = []) (supported in versions 2016-11-15)
@@ -732,6 +736,10 @@
* @method \GuzzleHttp\Promise\Promise deleteRouteServerEndpointAsync(array $args = []) (supported in versions 2016-11-15)
* @method \Aws\Result deleteRouteServerPeer(array $args = []) (supported in versions 2016-11-15)
* @method \GuzzleHttp\Promise\Promise deleteRouteServerPeerAsync(array $args = []) (supported in versions 2016-11-15)
* @method \Aws\Result deleteSecondaryNetwork(array $args = []) (supported in versions 2016-11-15)
* @method \GuzzleHttp\Promise\Promise deleteSecondaryNetworkAsync(array $args = []) (supported in versions 2016-11-15)
* @method \Aws\Result deleteSecondarySubnet(array $args = []) (supported in versions 2016-11-15)
* @method \GuzzleHttp\Promise\Promise deleteSecondarySubnetAsync(array $args = []) (supported in versions 2016-11-15)
* @method \Aws\Result deleteSubnetCidrReservation(array $args = []) (supported in versions 2016-11-15)
* @method \GuzzleHttp\Promise\Promise deleteSubnetCidrReservationAsync(array $args = []) (supported in versions 2016-11-15)
* @method \Aws\Result deleteTrafficMirrorFilter(array $args = []) (supported in versions 2016-11-15)
@@ -964,6 +972,12 @@
* @method \GuzzleHttp\Promise\Promise describeRouteServerPeersAsync(array $args = []) (supported in versions 2016-11-15)
* @method \Aws\Result describeRouteServers(array $args = []) (supported in versions 2016-11-15)
* @method \GuzzleHttp\Promise\Promise describeRouteServersAsync(array $args = []) (supported in versions 2016-11-15)
* @method \Aws\Result describeSecondaryInterfaces(array $args = []) (supported in versions 2016-11-15)
* @method \GuzzleHttp\Promise\Promise describeSecondaryInterfacesAsync(array $args = []) (supported in versions 2016-11-15)
* @method \Aws\Result describeSecondaryNetworks(array $args = []) (supported in versions 2016-11-15)
* @method \GuzzleHttp\Promise\Promise describeSecondaryNetworksAsync(array $args = []) (supported in versions 2016-11-15)
* @method \Aws\Result describeSecondarySubnets(array $args = []) (supported in versions 2016-11-15)
* @method \GuzzleHttp\Promise\Promise describeSecondarySubnetsAsync(array $args = []) (supported in versions 2016-11-15)
* @method \Aws\Result describeSecurityGroupRules(array $args = []) (supported in versions 2016-11-15)
* @method \GuzzleHttp\Promise\Promise describeSecurityGroupRulesAsync(array $args = []) (supported in versions 2016-11-15)
* @method \Aws\Result describeSecurityGroupVpcAssociations(array $args = []) (supported in versions 2016-11-15)
@@ -1170,6 +1184,8 @@
* @method \GuzzleHttp\Promise\Promise getCapacityManagerMetricDataAsync(array $args = []) (supported in versions 2016-11-15)
* @method \Aws\Result getCapacityManagerMetricDimensions(array $args = []) (supported in versions 2016-11-15)
* @method \GuzzleHttp\Promise\Promise getCapacityManagerMetricDimensionsAsync(array $args = []) (supported in versions 2016-11-15)
* @method \Aws\Result getCapacityManagerMonitoredTagKeys(array $args = []) (supported in versions 2016-11-15)
* @method \GuzzleHttp\Promise\Promise getCapacityManagerMonitoredTagKeysAsync(array $args = []) (supported in versions 2016-11-15)
* @method \Aws\Result getCapacityReservationUsage(array $args = []) (supported in versions 2016-11-15)
* @method \GuzzleHttp\Promise\Promise getCapacityReservationUsageAsync(array $args = []) (supported in versions 2016-11-15)
* @method \Aws\Result getCoipPoolUsage(array $args = []) (supported in versions 2016-11-15)
@@ -1498,6 +1514,8 @@
* @method \GuzzleHttp\Promise\Promise unassignPrivateNatGatewayAddressAsync(array $args = []) (supported in versions 2016-11-15)
* @method \Aws\Result unlockSnapshot(array $args = []) (supported in versions 2016-11-15)
* @method \GuzzleHttp\Promise\Promise unlockSnapshotAsync(array $args = []) (supported in versions 2016-11-15)
* @method \Aws\Result updateCapacityManagerMonitoredTagKeys(array $args = []) (supported in versions 2016-11-15)
* @method \GuzzleHttp\Promise\Promise updateCapacityManagerMonitoredTagKeysAsync(array $args = []) (supported in versions 2016-11-15)
* @method \Aws\Result updateCapacityManagerOrganizationsAccess(array $args = []) (supported in versions 2016-11-15)
* @method \GuzzleHttp\Promise\Promise updateCapacityManagerOrganizationsAccessAsync(array $args = []) (supported in versions 2016-11-15)
* @method \Aws\Result updateInterruptibleCapacityReservationAllocation(array $args = []) (supported in versions 2016-11-15)

View File

@@ -10,6 +10,8 @@
* @method \GuzzleHttp\Promise\Promise createCapacityProviderAsync(array $args = [])
* @method \Aws\Result createCluster(array $args = [])
* @method \GuzzleHttp\Promise\Promise createClusterAsync(array $args = [])
* @method \Aws\Result createDaemon(array $args = [])
* @method \GuzzleHttp\Promise\Promise createDaemonAsync(array $args = [])
* @method \Aws\Result createExpressGatewayService(array $args = [])
* @method \GuzzleHttp\Promise\Promise createExpressGatewayServiceAsync(array $args = [])
* @method \Aws\Result createService(array $args = [])
@@ -24,6 +26,10 @@
* @method \GuzzleHttp\Promise\Promise deleteCapacityProviderAsync(array $args = [])
* @method \Aws\Result deleteCluster(array $args = [])
* @method \GuzzleHttp\Promise\Promise deleteClusterAsync(array $args = [])
* @method \Aws\Result deleteDaemon(array $args = [])
* @method \GuzzleHttp\Promise\Promise deleteDaemonAsync(array $args = [])
* @method \Aws\Result deleteDaemonTaskDefinition(array $args = [])
* @method \GuzzleHttp\Promise\Promise deleteDaemonTaskDefinitionAsync(array $args = [])
* @method \Aws\Result deleteExpressGatewayService(array $args = [])
* @method \GuzzleHttp\Promise\Promise deleteExpressGatewayServiceAsync(array $args = [])
* @method \Aws\Result deleteService(array $args = [])
@@ -42,6 +48,14 @@
* @method \GuzzleHttp\Promise\Promise describeClustersAsync(array $args = [])
* @method \Aws\Result describeContainerInstances(array $args = [])
* @method \GuzzleHttp\Promise\Promise describeContainerInstancesAsync(array $args = [])
* @method \Aws\Result describeDaemon(array $args = [])
* @method \GuzzleHttp\Promise\Promise describeDaemonAsync(array $args = [])
* @method \Aws\Result describeDaemonDeployments(array $args = [])
* @method \GuzzleHttp\Promise\Promise describeDaemonDeploymentsAsync(array $args = [])
* @method \Aws\Result describeDaemonRevisions(array $args = [])
* @method \GuzzleHttp\Promise\Promise describeDaemonRevisionsAsync(array $args = [])
* @method \Aws\Result describeDaemonTaskDefinition(array $args = [])
* @method \GuzzleHttp\Promise\Promise describeDaemonTaskDefinitionAsync(array $args = [])
* @method \Aws\Result describeExpressGatewayService(array $args = [])
* @method \GuzzleHttp\Promise\Promise describeExpressGatewayServiceAsync(array $args = [])
* @method \Aws\Result describeServiceDeployments(array $args = [])
@@ -70,6 +84,12 @@
* @method \GuzzleHttp\Promise\Promise listClustersAsync(array $args = [])
* @method \Aws\Result listContainerInstances(array $args = [])
* @method \GuzzleHttp\Promise\Promise listContainerInstancesAsync(array $args = [])
* @method \Aws\Result listDaemonDeployments(array $args = [])
* @method \GuzzleHttp\Promise\Promise listDaemonDeploymentsAsync(array $args = [])
* @method \Aws\Result listDaemonTaskDefinitions(array $args = [])
* @method \GuzzleHttp\Promise\Promise listDaemonTaskDefinitionsAsync(array $args = [])
* @method \Aws\Result listDaemons(array $args = [])
* @method \GuzzleHttp\Promise\Promise listDaemonsAsync(array $args = [])
* @method \Aws\Result listServiceDeployments(array $args = [])
* @method \GuzzleHttp\Promise\Promise listServiceDeploymentsAsync(array $args = [])
* @method \Aws\Result listServices(array $args = [])
@@ -94,6 +114,8 @@
* @method \GuzzleHttp\Promise\Promise putClusterCapacityProvidersAsync(array $args = [])
* @method \Aws\Result registerContainerInstance(array $args = [])
* @method \GuzzleHttp\Promise\Promise registerContainerInstanceAsync(array $args = [])
* @method \Aws\Result registerDaemonTaskDefinition(array $args = [])
* @method \GuzzleHttp\Promise\Promise registerDaemonTaskDefinitionAsync(array $args = [])
* @method \Aws\Result registerTaskDefinition(array $args = [])
* @method \GuzzleHttp\Promise\Promise registerTaskDefinitionAsync(array $args = [])
* @method \Aws\Result runTask(array $args = [])
@@ -124,6 +146,8 @@
* @method \GuzzleHttp\Promise\Promise updateContainerAgentAsync(array $args = [])
* @method \Aws\Result updateContainerInstancesState(array $args = [])
* @method \GuzzleHttp\Promise\Promise updateContainerInstancesStateAsync(array $args = [])
* @method \Aws\Result updateDaemon(array $args = [])
* @method \GuzzleHttp\Promise\Promise updateDaemonAsync(array $args = [])
* @method \Aws\Result updateExpressGatewayService(array $args = [])
* @method \GuzzleHttp\Promise\Promise updateExpressGatewayServiceAsync(array $args = [])
* @method \Aws\Result updateService(array $args = [])

View File

@@ -0,0 +1,29 @@
<?php
namespace Aws\ElementalInference;
use Aws\AwsClient;
/**
* This client is used to interact with the **AWS Elemental Inference** service.
* @method \Aws\Result associateFeed(array $args = [])
* @method \GuzzleHttp\Promise\Promise associateFeedAsync(array $args = [])
* @method \Aws\Result createFeed(array $args = [])
* @method \GuzzleHttp\Promise\Promise createFeedAsync(array $args = [])
* @method \Aws\Result deleteFeed(array $args = [])
* @method \GuzzleHttp\Promise\Promise deleteFeedAsync(array $args = [])
* @method \Aws\Result disassociateFeed(array $args = [])
* @method \GuzzleHttp\Promise\Promise disassociateFeedAsync(array $args = [])
* @method \Aws\Result getFeed(array $args = [])
* @method \GuzzleHttp\Promise\Promise getFeedAsync(array $args = [])
* @method \Aws\Result listFeeds(array $args = [])
* @method \GuzzleHttp\Promise\Promise listFeedsAsync(array $args = [])
* @method \Aws\Result listTagsForResource(array $args = [])
* @method \GuzzleHttp\Promise\Promise listTagsForResourceAsync(array $args = [])
* @method \Aws\Result tagResource(array $args = [])
* @method \GuzzleHttp\Promise\Promise tagResourceAsync(array $args = [])
* @method \Aws\Result untagResource(array $args = [])
* @method \GuzzleHttp\Promise\Promise untagResourceAsync(array $args = [])
* @method \Aws\Result updateFeed(array $args = [])
* @method \GuzzleHttp\Promise\Promise updateFeedAsync(array $args = [])
*/
class ElementalInferenceClient extends AwsClient {}

View File

@@ -0,0 +1,9 @@
<?php
namespace Aws\ElementalInference\Exception;
use Aws\Exception\AwsException;
/**
* Represents an error interacting with the **AWS Elemental Inference** service.
*/
class ElementalInferenceException extends AwsException {}

View File

@@ -19,6 +19,8 @@
* @method \GuzzleHttp\Promise\Promise disassociateEipFromVlanAsync(array $args = [])
* @method \Aws\Result getEnvironment(array $args = [])
* @method \GuzzleHttp\Promise\Promise getEnvironmentAsync(array $args = [])
* @method \Aws\Result getVersions(array $args = [])
* @method \GuzzleHttp\Promise\Promise getVersionsAsync(array $args = [])
* @method \Aws\Result listEnvironmentHosts(array $args = [])
* @method \GuzzleHttp\Promise\Promise listEnvironmentHostsAsync(array $args = [])
* @method \Aws\Result listEnvironmentVlans(array $args = [])

View File

@@ -150,6 +150,8 @@
* @method \GuzzleHttp\Promise\Promise getGameSessionLogUrlAsync(array $args = [])
* @method \Aws\Result getInstanceAccess(array $args = [])
* @method \GuzzleHttp\Promise\Promise getInstanceAccessAsync(array $args = [])
* @method \Aws\Result getPlayerConnectionDetails(array $args = [])
* @method \GuzzleHttp\Promise\Promise getPlayerConnectionDetailsAsync(array $args = [])
* @method \Aws\Result listAliases(array $args = [])
* @method \GuzzleHttp\Promise\Promise listAliasesAsync(array $args = [])
* @method \Aws\Result listBuilds(array $args = [])

View File

@@ -123,6 +123,8 @@
* @method \GuzzleHttp\Promise\Promise deleteColumnStatisticsTaskSettingsAsync(array $args = [])
* @method \Aws\Result deleteConnection(array $args = [])
* @method \GuzzleHttp\Promise\Promise deleteConnectionAsync(array $args = [])
* @method \Aws\Result deleteConnectionType(array $args = [])
* @method \GuzzleHttp\Promise\Promise deleteConnectionTypeAsync(array $args = [])
* @method \Aws\Result deleteCrawler(array $args = [])
* @method \GuzzleHttp\Promise\Promise deleteCrawlerAsync(array $args = [])
* @method \Aws\Result deleteCustomEntityType(array $args = [])
@@ -411,6 +413,8 @@
* @method \GuzzleHttp\Promise\Promise putWorkflowRunPropertiesAsync(array $args = [])
* @method \Aws\Result querySchemaVersionMetadata(array $args = [])
* @method \GuzzleHttp\Promise\Promise querySchemaVersionMetadataAsync(array $args = [])
* @method \Aws\Result registerConnectionType(array $args = [])
* @method \GuzzleHttp\Promise\Promise registerConnectionTypeAsync(array $args = [])
* @method \Aws\Result registerSchemaVersion(array $args = [])
* @method \GuzzleHttp\Promise\Promise registerSchemaVersionAsync(array $args = [])
* @method \Aws\Result removeSchemaVersionMetadata(array $args = [])

View File

@@ -27,6 +27,8 @@
* @method \GuzzleHttp\Promise\Promise deleteMissionProfileAsync(array $args = [])
* @method \Aws\Result describeContact(array $args = [])
* @method \GuzzleHttp\Promise\Promise describeContactAsync(array $args = [])
* @method \Aws\Result describeContactVersion(array $args = [])
* @method \GuzzleHttp\Promise\Promise describeContactVersionAsync(array $args = [])
* @method \Aws\Result describeEphemeris(array $args = [])
* @method \GuzzleHttp\Promise\Promise describeEphemerisAsync(array $args = [])
* @method \Aws\Result getAgentConfiguration(array $args = [])
@@ -43,14 +45,20 @@
* @method \GuzzleHttp\Promise\Promise getMissionProfileAsync(array $args = [])
* @method \Aws\Result getSatellite(array $args = [])
* @method \GuzzleHttp\Promise\Promise getSatelliteAsync(array $args = [])
* @method \Aws\Result listAntennas(array $args = [])
* @method \GuzzleHttp\Promise\Promise listAntennasAsync(array $args = [])
* @method \Aws\Result listConfigs(array $args = [])
* @method \GuzzleHttp\Promise\Promise listConfigsAsync(array $args = [])
* @method \Aws\Result listContactVersions(array $args = [])
* @method \GuzzleHttp\Promise\Promise listContactVersionsAsync(array $args = [])
* @method \Aws\Result listContacts(array $args = [])
* @method \GuzzleHttp\Promise\Promise listContactsAsync(array $args = [])
* @method \Aws\Result listDataflowEndpointGroups(array $args = [])
* @method \GuzzleHttp\Promise\Promise listDataflowEndpointGroupsAsync(array $args = [])
* @method \Aws\Result listEphemerides(array $args = [])
* @method \GuzzleHttp\Promise\Promise listEphemeridesAsync(array $args = [])
* @method \Aws\Result listGroundStationReservations(array $args = [])
* @method \GuzzleHttp\Promise\Promise listGroundStationReservationsAsync(array $args = [])
* @method \Aws\Result listGroundStations(array $args = [])
* @method \GuzzleHttp\Promise\Promise listGroundStationsAsync(array $args = [])
* @method \Aws\Result listMissionProfiles(array $args = [])
@@ -71,6 +79,8 @@
* @method \GuzzleHttp\Promise\Promise updateAgentStatusAsync(array $args = [])
* @method \Aws\Result updateConfig(array $args = [])
* @method \GuzzleHttp\Promise\Promise updateConfigAsync(array $args = [])
* @method \Aws\Result updateContact(array $args = [])
* @method \GuzzleHttp\Promise\Promise updateContactAsync(array $args = [])
* @method \Aws\Result updateEphemeris(array $args = [])
* @method \GuzzleHttp\Promise\Promise updateEphemerisAsync(array $args = [])
* @method \Aws\Result updateMissionProfile(array $args = [])

View File

@@ -0,0 +1,9 @@
<?php
namespace Aws\Interconnect\Exception;
use Aws\Exception\AwsException;
/**
* Represents an error interacting with the **Interconnect** service.
*/
class InterconnectException extends AwsException {}

View File

@@ -0,0 +1,35 @@
<?php
namespace Aws\Interconnect;
use Aws\AwsClient;
/**
* This client is used to interact with the **Interconnect** service.
* @method \Aws\Result acceptConnectionProposal(array $args = [])
* @method \GuzzleHttp\Promise\Promise acceptConnectionProposalAsync(array $args = [])
* @method \Aws\Result createConnection(array $args = [])
* @method \GuzzleHttp\Promise\Promise createConnectionAsync(array $args = [])
* @method \Aws\Result deleteConnection(array $args = [])
* @method \GuzzleHttp\Promise\Promise deleteConnectionAsync(array $args = [])
* @method \Aws\Result describeConnectionProposal(array $args = [])
* @method \GuzzleHttp\Promise\Promise describeConnectionProposalAsync(array $args = [])
* @method \Aws\Result getConnection(array $args = [])
* @method \GuzzleHttp\Promise\Promise getConnectionAsync(array $args = [])
* @method \Aws\Result getEnvironment(array $args = [])
* @method \GuzzleHttp\Promise\Promise getEnvironmentAsync(array $args = [])
* @method \Aws\Result listAttachPoints(array $args = [])
* @method \GuzzleHttp\Promise\Promise listAttachPointsAsync(array $args = [])
* @method \Aws\Result listConnections(array $args = [])
* @method \GuzzleHttp\Promise\Promise listConnectionsAsync(array $args = [])
* @method \Aws\Result listEnvironments(array $args = [])
* @method \GuzzleHttp\Promise\Promise listEnvironmentsAsync(array $args = [])
* @method \Aws\Result listTagsForResource(array $args = [])
* @method \GuzzleHttp\Promise\Promise listTagsForResourceAsync(array $args = [])
* @method \Aws\Result tagResource(array $args = [])
* @method \GuzzleHttp\Promise\Promise tagResourceAsync(array $args = [])
* @method \Aws\Result untagResource(array $args = [])
* @method \GuzzleHttp\Promise\Promise untagResourceAsync(array $args = [])
* @method \Aws\Result updateConnection(array $args = [])
* @method \GuzzleHttp\Promise\Promise updateConnectionAsync(array $args = [])
*/
class InterconnectClient extends AwsClient {}

View File

@@ -1,9 +0,0 @@
<?php
namespace Aws\IoTAnalytics\Exception;
use Aws\Exception\AwsException;
/**
* Represents an error interacting with the **AWS IoT Analytics** service.
*/
class IoTAnalyticsException extends AwsException {}

View File

@@ -1,77 +0,0 @@
<?php
namespace Aws\IoTAnalytics;
use Aws\AwsClient;
/**
* This client is used to interact with the **AWS IoT Analytics** service.
* @method \Aws\Result batchPutMessage(array $args = [])
* @method \GuzzleHttp\Promise\Promise batchPutMessageAsync(array $args = [])
* @method \Aws\Result cancelPipelineReprocessing(array $args = [])
* @method \GuzzleHttp\Promise\Promise cancelPipelineReprocessingAsync(array $args = [])
* @method \Aws\Result createChannel(array $args = [])
* @method \GuzzleHttp\Promise\Promise createChannelAsync(array $args = [])
* @method \Aws\Result createDataset(array $args = [])
* @method \GuzzleHttp\Promise\Promise createDatasetAsync(array $args = [])
* @method \Aws\Result createDatasetContent(array $args = [])
* @method \GuzzleHttp\Promise\Promise createDatasetContentAsync(array $args = [])
* @method \Aws\Result createDatastore(array $args = [])
* @method \GuzzleHttp\Promise\Promise createDatastoreAsync(array $args = [])
* @method \Aws\Result createPipeline(array $args = [])
* @method \GuzzleHttp\Promise\Promise createPipelineAsync(array $args = [])
* @method \Aws\Result deleteChannel(array $args = [])
* @method \GuzzleHttp\Promise\Promise deleteChannelAsync(array $args = [])
* @method \Aws\Result deleteDataset(array $args = [])
* @method \GuzzleHttp\Promise\Promise deleteDatasetAsync(array $args = [])
* @method \Aws\Result deleteDatasetContent(array $args = [])
* @method \GuzzleHttp\Promise\Promise deleteDatasetContentAsync(array $args = [])
* @method \Aws\Result deleteDatastore(array $args = [])
* @method \GuzzleHttp\Promise\Promise deleteDatastoreAsync(array $args = [])
* @method \Aws\Result deletePipeline(array $args = [])
* @method \GuzzleHttp\Promise\Promise deletePipelineAsync(array $args = [])
* @method \Aws\Result describeChannel(array $args = [])
* @method \GuzzleHttp\Promise\Promise describeChannelAsync(array $args = [])
* @method \Aws\Result describeDataset(array $args = [])
* @method \GuzzleHttp\Promise\Promise describeDatasetAsync(array $args = [])
* @method \Aws\Result describeDatastore(array $args = [])
* @method \GuzzleHttp\Promise\Promise describeDatastoreAsync(array $args = [])
* @method \Aws\Result describeLoggingOptions(array $args = [])
* @method \GuzzleHttp\Promise\Promise describeLoggingOptionsAsync(array $args = [])
* @method \Aws\Result describePipeline(array $args = [])
* @method \GuzzleHttp\Promise\Promise describePipelineAsync(array $args = [])
* @method \Aws\Result getDatasetContent(array $args = [])
* @method \GuzzleHttp\Promise\Promise getDatasetContentAsync(array $args = [])
* @method \Aws\Result listChannels(array $args = [])
* @method \GuzzleHttp\Promise\Promise listChannelsAsync(array $args = [])
* @method \Aws\Result listDatasetContents(array $args = [])
* @method \GuzzleHttp\Promise\Promise listDatasetContentsAsync(array $args = [])
* @method \Aws\Result listDatasets(array $args = [])
* @method \GuzzleHttp\Promise\Promise listDatasetsAsync(array $args = [])
* @method \Aws\Result listDatastores(array $args = [])
* @method \GuzzleHttp\Promise\Promise listDatastoresAsync(array $args = [])
* @method \Aws\Result listPipelines(array $args = [])
* @method \GuzzleHttp\Promise\Promise listPipelinesAsync(array $args = [])
* @method \Aws\Result listTagsForResource(array $args = [])
* @method \GuzzleHttp\Promise\Promise listTagsForResourceAsync(array $args = [])
* @method \Aws\Result putLoggingOptions(array $args = [])
* @method \GuzzleHttp\Promise\Promise putLoggingOptionsAsync(array $args = [])
* @method \Aws\Result runPipelineActivity(array $args = [])
* @method \GuzzleHttp\Promise\Promise runPipelineActivityAsync(array $args = [])
* @method \Aws\Result sampleChannelData(array $args = [])
* @method \GuzzleHttp\Promise\Promise sampleChannelDataAsync(array $args = [])
* @method \Aws\Result startPipelineReprocessing(array $args = [])
* @method \GuzzleHttp\Promise\Promise startPipelineReprocessingAsync(array $args = [])
* @method \Aws\Result tagResource(array $args = [])
* @method \GuzzleHttp\Promise\Promise tagResourceAsync(array $args = [])
* @method \Aws\Result untagResource(array $args = [])
* @method \GuzzleHttp\Promise\Promise untagResourceAsync(array $args = [])
* @method \Aws\Result updateChannel(array $args = [])
* @method \GuzzleHttp\Promise\Promise updateChannelAsync(array $args = [])
* @method \Aws\Result updateDataset(array $args = [])
* @method \GuzzleHttp\Promise\Promise updateDatasetAsync(array $args = [])
* @method \Aws\Result updateDatastore(array $args = [])
* @method \GuzzleHttp\Promise\Promise updateDatastoreAsync(array $args = [])
* @method \Aws\Result updatePipeline(array $args = [])
* @method \GuzzleHttp\Promise\Promise updatePipelineAsync(array $args = [])
*/
class IoTAnalyticsClient extends AwsClient {}

View File

@@ -15,6 +15,8 @@
* @method \GuzzleHttp\Promise\Promise createConfigurationAsync(array $args = [])
* @method \Aws\Result createReplicator(array $args = [])
* @method \GuzzleHttp\Promise\Promise createReplicatorAsync(array $args = [])
* @method \Aws\Result createTopic(array $args = [])
* @method \GuzzleHttp\Promise\Promise createTopicAsync(array $args = [])
* @method \Aws\Result createVpcConnection(array $args = [])
* @method \GuzzleHttp\Promise\Promise createVpcConnectionAsync(array $args = [])
* @method \Aws\Result deleteCluster(array $args = [])
@@ -23,6 +25,8 @@
* @method \GuzzleHttp\Promise\Promise deleteConfigurationAsync(array $args = [])
* @method \Aws\Result deleteReplicator(array $args = [])
* @method \GuzzleHttp\Promise\Promise deleteReplicatorAsync(array $args = [])
* @method \Aws\Result deleteTopic(array $args = [])
* @method \GuzzleHttp\Promise\Promise deleteTopicAsync(array $args = [])
* @method \Aws\Result deleteVpcConnection(array $args = [])
* @method \GuzzleHttp\Promise\Promise deleteVpcConnectionAsync(array $args = [])
* @method \Aws\Result describeCluster(array $args = [])
@@ -117,5 +121,7 @@
* @method \GuzzleHttp\Promise\Promise updateSecurityAsync(array $args = [])
* @method \Aws\Result updateStorage(array $args = [])
* @method \GuzzleHttp\Promise\Promise updateStorageAsync(array $args = [])
* @method \Aws\Result updateTopic(array $args = [])
* @method \GuzzleHttp\Promise\Promise updateTopicAsync(array $args = [])
*/
class KafkaClient extends AwsClient {}

View File

@@ -69,6 +69,8 @@
* @method \GuzzleHttp\Promise\Promise getResourceLFTagsAsync(array $args = [])
* @method \Aws\Result getTableObjects(array $args = [])
* @method \GuzzleHttp\Promise\Promise getTableObjectsAsync(array $args = [])
* @method \Aws\Result getTemporaryDataLocationCredentials(array $args = [])
* @method \GuzzleHttp\Promise\Promise getTemporaryDataLocationCredentialsAsync(array $args = [])
* @method \Aws\Result getTemporaryGluePartitionCredentials(array $args = [])
* @method \GuzzleHttp\Promise\Promise getTemporaryGluePartitionCredentialsAsync(array $args = [])
* @method \Aws\Result getTemporaryGlueTableCredentials(array $args = [])

View File

@@ -11,12 +11,16 @@
* @method \GuzzleHttp\Promise\Promise deleteDeploymentAsync(array $args = [])
* @method \Aws\Result getDeployment(array $args = [])
* @method \GuzzleHttp\Promise\Promise getDeploymentAsync(array $args = [])
* @method \Aws\Result getDeploymentPatternVersion(array $args = [])
* @method \GuzzleHttp\Promise\Promise getDeploymentPatternVersionAsync(array $args = [])
* @method \Aws\Result getWorkload(array $args = [])
* @method \GuzzleHttp\Promise\Promise getWorkloadAsync(array $args = [])
* @method \Aws\Result getWorkloadDeploymentPattern(array $args = [])
* @method \GuzzleHttp\Promise\Promise getWorkloadDeploymentPatternAsync(array $args = [])
* @method \Aws\Result listDeploymentEvents(array $args = [])
* @method \GuzzleHttp\Promise\Promise listDeploymentEventsAsync(array $args = [])
* @method \Aws\Result listDeploymentPatternVersions(array $args = [])
* @method \GuzzleHttp\Promise\Promise listDeploymentPatternVersionsAsync(array $args = [])
* @method \Aws\Result listDeployments(array $args = [])
* @method \GuzzleHttp\Promise\Promise listDeploymentsAsync(array $args = [])
* @method \Aws\Result listTagsForResource(array $args = [])
@@ -29,5 +33,7 @@
* @method \GuzzleHttp\Promise\Promise tagResourceAsync(array $args = [])
* @method \Aws\Result untagResource(array $args = [])
* @method \GuzzleHttp\Promise\Promise untagResourceAsync(array $args = [])
* @method \Aws\Result updateDeployment(array $args = [])
* @method \GuzzleHttp\Promise\Promise updateDeploymentAsync(array $args = [])
*/
class LaunchWizardClient extends AwsClient {}

View File

@@ -45,6 +45,8 @@
* @method \GuzzleHttp\Promise\Promise deleteBotAsync(array $args = [])
* @method \Aws\Result deleteBotAlias(array $args = [])
* @method \GuzzleHttp\Promise\Promise deleteBotAliasAsync(array $args = [])
* @method \Aws\Result deleteBotAnalyzerRecommendation(array $args = [])
* @method \GuzzleHttp\Promise\Promise deleteBotAnalyzerRecommendationAsync(array $args = [])
* @method \Aws\Result deleteBotLocale(array $args = [])
* @method \GuzzleHttp\Promise\Promise deleteBotLocaleAsync(array $args = [])
* @method \Aws\Result deleteBotReplica(array $args = [])
@@ -75,6 +77,8 @@
* @method \GuzzleHttp\Promise\Promise describeBotAsync(array $args = [])
* @method \Aws\Result describeBotAlias(array $args = [])
* @method \GuzzleHttp\Promise\Promise describeBotAliasAsync(array $args = [])
* @method \Aws\Result describeBotAnalyzerRecommendation(array $args = [])
* @method \GuzzleHttp\Promise\Promise describeBotAnalyzerRecommendationAsync(array $args = [])
* @method \Aws\Result describeBotLocale(array $args = [])
* @method \GuzzleHttp\Promise\Promise describeBotLocaleAsync(array $args = [])
* @method \Aws\Result describeBotRecommendation(array $args = [])
@@ -117,6 +121,8 @@
* @method \GuzzleHttp\Promise\Promise listBotAliasReplicasAsync(array $args = [])
* @method \Aws\Result listBotAliases(array $args = [])
* @method \GuzzleHttp\Promise\Promise listBotAliasesAsync(array $args = [])
* @method \Aws\Result listBotAnalyzerHistory(array $args = [])
* @method \GuzzleHttp\Promise\Promise listBotAnalyzerHistoryAsync(array $args = [])
* @method \Aws\Result listBotLocales(array $args = [])
* @method \GuzzleHttp\Promise\Promise listBotLocalesAsync(array $args = [])
* @method \Aws\Result listBotRecommendations(array $args = [])
@@ -175,6 +181,8 @@
* @method \GuzzleHttp\Promise\Promise listUtteranceMetricsAsync(array $args = [])
* @method \Aws\Result searchAssociatedTranscripts(array $args = [])
* @method \GuzzleHttp\Promise\Promise searchAssociatedTranscriptsAsync(array $args = [])
* @method \Aws\Result startBotAnalyzer(array $args = [])
* @method \GuzzleHttp\Promise\Promise startBotAnalyzerAsync(array $args = [])
* @method \Aws\Result startBotRecommendation(array $args = [])
* @method \GuzzleHttp\Promise\Promise startBotRecommendationAsync(array $args = [])
* @method \Aws\Result startBotResourceGeneration(array $args = [])
@@ -185,6 +193,8 @@
* @method \GuzzleHttp\Promise\Promise startTestExecutionAsync(array $args = [])
* @method \Aws\Result startTestSetGeneration(array $args = [])
* @method \GuzzleHttp\Promise\Promise startTestSetGenerationAsync(array $args = [])
* @method \Aws\Result stopBotAnalyzer(array $args = [])
* @method \GuzzleHttp\Promise\Promise stopBotAnalyzerAsync(array $args = [])
* @method \Aws\Result stopBotRecommendation(array $args = [])
* @method \GuzzleHttp\Promise\Promise stopBotRecommendationAsync(array $args = [])
* @method \Aws\Result tagResource(array $args = [])

View File

@@ -41,6 +41,8 @@
* @method \GuzzleHttp\Promise\Promise listTagsForResourceAsync(array $args = [])
* @method \Aws\Result startActiveApprovalTeamDeletion(array $args = [])
* @method \GuzzleHttp\Promise\Promise startActiveApprovalTeamDeletionAsync(array $args = [])
* @method \Aws\Result startApprovalTeamBaseline(array $args = [])
* @method \GuzzleHttp\Promise\Promise startApprovalTeamBaselineAsync(array $args = [])
* @method \Aws\Result tagResource(array $args = [])
* @method \GuzzleHttp\Promise\Promise tagResourceAsync(array $args = [])
* @method \Aws\Result untagResource(array $args = [])

View File

@@ -5,11 +5,35 @@
/**
* This client is used to interact with the **AWS Marketplace Agreement Service** service.
* @method \Aws\Result batchCreateBillingAdjustmentRequest(array $args = [])
* @method \GuzzleHttp\Promise\Promise batchCreateBillingAdjustmentRequestAsync(array $args = [])
* @method \Aws\Result cancelAgreementCancellationRequest(array $args = [])
* @method \GuzzleHttp\Promise\Promise cancelAgreementCancellationRequestAsync(array $args = [])
* @method \Aws\Result cancelAgreementPaymentRequest(array $args = [])
* @method \GuzzleHttp\Promise\Promise cancelAgreementPaymentRequestAsync(array $args = [])
* @method \Aws\Result describeAgreement(array $args = [])
* @method \GuzzleHttp\Promise\Promise describeAgreementAsync(array $args = [])
* @method \Aws\Result getAgreementCancellationRequest(array $args = [])
* @method \GuzzleHttp\Promise\Promise getAgreementCancellationRequestAsync(array $args = [])
* @method \Aws\Result getAgreementPaymentRequest(array $args = [])
* @method \GuzzleHttp\Promise\Promise getAgreementPaymentRequestAsync(array $args = [])
* @method \Aws\Result getAgreementTerms(array $args = [])
* @method \GuzzleHttp\Promise\Promise getAgreementTermsAsync(array $args = [])
* @method \Aws\Result getBillingAdjustmentRequest(array $args = [])
* @method \GuzzleHttp\Promise\Promise getBillingAdjustmentRequestAsync(array $args = [])
* @method \Aws\Result listAgreementCancellationRequests(array $args = [])
* @method \GuzzleHttp\Promise\Promise listAgreementCancellationRequestsAsync(array $args = [])
* @method \Aws\Result listAgreementInvoiceLineItems(array $args = [])
* @method \GuzzleHttp\Promise\Promise listAgreementInvoiceLineItemsAsync(array $args = [])
* @method \Aws\Result listAgreementPaymentRequests(array $args = [])
* @method \GuzzleHttp\Promise\Promise listAgreementPaymentRequestsAsync(array $args = [])
* @method \Aws\Result listBillingAdjustmentRequests(array $args = [])
* @method \GuzzleHttp\Promise\Promise listBillingAdjustmentRequestsAsync(array $args = [])
* @method \Aws\Result searchAgreements(array $args = [])
* @method \GuzzleHttp\Promise\Promise searchAgreementsAsync(array $args = [])
* @method \Aws\Result sendAgreementCancellationRequest(array $args = [])
* @method \GuzzleHttp\Promise\Promise sendAgreementCancellationRequestAsync(array $args = [])
* @method \Aws\Result sendAgreementPaymentRequest(array $args = [])
* @method \GuzzleHttp\Promise\Promise sendAgreementPaymentRequestAsync(array $args = [])
*/
class MarketplaceAgreementClient extends AwsClient {}

View File

@@ -0,0 +1,9 @@
<?php
namespace Aws\MarketplaceDiscovery\Exception;
use Aws\Exception\AwsException;
/**
* Represents an error interacting with the **AWS Marketplace Discovery** service.
*/
class MarketplaceDiscoveryException extends AwsException {}

View File

@@ -0,0 +1,27 @@
<?php
namespace Aws\MarketplaceDiscovery;
use Aws\AwsClient;
/**
* This client is used to interact with the **AWS Marketplace Discovery** service.
* @method \Aws\Result getListing(array $args = [])
* @method \GuzzleHttp\Promise\Promise getListingAsync(array $args = [])
* @method \Aws\Result getOffer(array $args = [])
* @method \GuzzleHttp\Promise\Promise getOfferAsync(array $args = [])
* @method \Aws\Result getOfferSet(array $args = [])
* @method \GuzzleHttp\Promise\Promise getOfferSetAsync(array $args = [])
* @method \Aws\Result getOfferTerms(array $args = [])
* @method \GuzzleHttp\Promise\Promise getOfferTermsAsync(array $args = [])
* @method \Aws\Result getProduct(array $args = [])
* @method \GuzzleHttp\Promise\Promise getProductAsync(array $args = [])
* @method \Aws\Result listFulfillmentOptions(array $args = [])
* @method \GuzzleHttp\Promise\Promise listFulfillmentOptionsAsync(array $args = [])
* @method \Aws\Result listPurchaseOptions(array $args = [])
* @method \GuzzleHttp\Promise\Promise listPurchaseOptionsAsync(array $args = [])
* @method \Aws\Result searchFacets(array $args = [])
* @method \GuzzleHttp\Promise\Promise searchFacetsAsync(array $args = [])
* @method \Aws\Result searchListings(array $args = [])
* @method \GuzzleHttp\Promise\Promise searchListingsAsync(array $args = [])
*/
class MarketplaceDiscoveryClient extends AwsClient {}

View File

@@ -240,7 +240,7 @@ private function determineState(): UploadState
$id = [$required['upload_id'] => null];
unset($required['upload_id']);
foreach ($required as $key => $param) {
if (!$this->config[$key]) {
if (!isset($this->config[$key]) || $this->config[$key] === '') {
throw new IAE('You must provide a value for "' . $key . '" in '
. 'your config for the MultipartUploader for '
. $this->client->getApi()->getServiceFullName() . '.');

View File

@@ -15,6 +15,8 @@
* @method \GuzzleHttp\Promise\Promise cancelAnnotationImportJobAsync(array $args = [])
* @method \Aws\Result cancelRun(array $args = [])
* @method \GuzzleHttp\Promise\Promise cancelRunAsync(array $args = [])
* @method \Aws\Result cancelRunBatch(array $args = [])
* @method \GuzzleHttp\Promise\Promise cancelRunBatchAsync(array $args = [])
* @method \Aws\Result cancelVariantImportJob(array $args = [])
* @method \GuzzleHttp\Promise\Promise cancelVariantImportJobAsync(array $args = [])
* @method \Aws\Result completeMultipartReadSetUpload(array $args = [])
@@ -23,6 +25,8 @@
* @method \GuzzleHttp\Promise\Promise createAnnotationStoreAsync(array $args = [])
* @method \Aws\Result createAnnotationStoreVersion(array $args = [])
* @method \GuzzleHttp\Promise\Promise createAnnotationStoreVersionAsync(array $args = [])
* @method \Aws\Result createConfiguration(array $args = [])
* @method \GuzzleHttp\Promise\Promise createConfigurationAsync(array $args = [])
* @method \Aws\Result createMultipartReadSetUpload(array $args = [])
* @method \GuzzleHttp\Promise\Promise createMultipartReadSetUploadAsync(array $args = [])
* @method \Aws\Result createReferenceStore(array $args = [])
@@ -45,12 +49,18 @@
* @method \GuzzleHttp\Promise\Promise deleteAnnotationStoreAsync(array $args = [])
* @method \Aws\Result deleteAnnotationStoreVersions(array $args = [])
* @method \GuzzleHttp\Promise\Promise deleteAnnotationStoreVersionsAsync(array $args = [])
* @method \Aws\Result deleteBatch(array $args = [])
* @method \GuzzleHttp\Promise\Promise deleteBatchAsync(array $args = [])
* @method \Aws\Result deleteConfiguration(array $args = [])
* @method \GuzzleHttp\Promise\Promise deleteConfigurationAsync(array $args = [])
* @method \Aws\Result deleteReference(array $args = [])
* @method \GuzzleHttp\Promise\Promise deleteReferenceAsync(array $args = [])
* @method \Aws\Result deleteReferenceStore(array $args = [])
* @method \GuzzleHttp\Promise\Promise deleteReferenceStoreAsync(array $args = [])
* @method \Aws\Result deleteRun(array $args = [])
* @method \GuzzleHttp\Promise\Promise deleteRunAsync(array $args = [])
* @method \Aws\Result deleteRunBatch(array $args = [])
* @method \GuzzleHttp\Promise\Promise deleteRunBatchAsync(array $args = [])
* @method \Aws\Result deleteRunCache(array $args = [])
* @method \GuzzleHttp\Promise\Promise deleteRunCacheAsync(array $args = [])
* @method \Aws\Result deleteRunGroup(array $args = [])
@@ -73,6 +83,10 @@
* @method \GuzzleHttp\Promise\Promise getAnnotationStoreAsync(array $args = [])
* @method \Aws\Result getAnnotationStoreVersion(array $args = [])
* @method \GuzzleHttp\Promise\Promise getAnnotationStoreVersionAsync(array $args = [])
* @method \Aws\Result getBatch(array $args = [])
* @method \GuzzleHttp\Promise\Promise getBatchAsync(array $args = [])
* @method \Aws\Result getConfiguration(array $args = [])
* @method \GuzzleHttp\Promise\Promise getConfigurationAsync(array $args = [])
* @method \Aws\Result getReadSet(array $args = [])
* @method \GuzzleHttp\Promise\Promise getReadSetAsync(array $args = [])
* @method \Aws\Result getReadSetActivationJob(array $args = [])
@@ -119,6 +133,10 @@
* @method \GuzzleHttp\Promise\Promise listAnnotationStoreVersionsAsync(array $args = [])
* @method \Aws\Result listAnnotationStores(array $args = [])
* @method \GuzzleHttp\Promise\Promise listAnnotationStoresAsync(array $args = [])
* @method \Aws\Result listBatch(array $args = [])
* @method \GuzzleHttp\Promise\Promise listBatchAsync(array $args = [])
* @method \Aws\Result listConfigurations(array $args = [])
* @method \GuzzleHttp\Promise\Promise listConfigurationsAsync(array $args = [])
* @method \Aws\Result listMultipartReadSetUploads(array $args = [])
* @method \GuzzleHttp\Promise\Promise listMultipartReadSetUploadsAsync(array $args = [])
* @method \Aws\Result listReadSetActivationJobs(array $args = [])
@@ -145,6 +163,8 @@
* @method \GuzzleHttp\Promise\Promise listRunTasksAsync(array $args = [])
* @method \Aws\Result listRuns(array $args = [])
* @method \GuzzleHttp\Promise\Promise listRunsAsync(array $args = [])
* @method \Aws\Result listRunsInBatch(array $args = [])
* @method \GuzzleHttp\Promise\Promise listRunsInBatchAsync(array $args = [])
* @method \Aws\Result listSequenceStores(array $args = [])
* @method \GuzzleHttp\Promise\Promise listSequenceStoresAsync(array $args = [])
* @method \Aws\Result listShares(array $args = [])
@@ -173,6 +193,8 @@
* @method \GuzzleHttp\Promise\Promise startReferenceImportJobAsync(array $args = [])
* @method \Aws\Result startRun(array $args = [])
* @method \GuzzleHttp\Promise\Promise startRunAsync(array $args = [])
* @method \Aws\Result startRunBatch(array $args = [])
* @method \GuzzleHttp\Promise\Promise startRunBatchAsync(array $args = [])
* @method \Aws\Result startVariantImportJob(array $args = [])
* @method \GuzzleHttp\Promise\Promise startVariantImportJobAsync(array $args = [])
* @method \Aws\Result tagResource(array $args = [])

View File

@@ -7,6 +7,8 @@
* This client is used to interact with the **OpenSearch Service Serverless** service.
* @method \Aws\Result batchGetCollection(array $args = [])
* @method \GuzzleHttp\Promise\Promise batchGetCollectionAsync(array $args = [])
* @method \Aws\Result batchGetCollectionGroup(array $args = [])
* @method \GuzzleHttp\Promise\Promise batchGetCollectionGroupAsync(array $args = [])
* @method \Aws\Result batchGetEffectiveLifecyclePolicy(array $args = [])
* @method \GuzzleHttp\Promise\Promise batchGetEffectiveLifecyclePolicyAsync(array $args = [])
* @method \Aws\Result batchGetLifecyclePolicy(array $args = [])
@@ -17,6 +19,8 @@
* @method \GuzzleHttp\Promise\Promise createAccessPolicyAsync(array $args = [])
* @method \Aws\Result createCollection(array $args = [])
* @method \GuzzleHttp\Promise\Promise createCollectionAsync(array $args = [])
* @method \Aws\Result createCollectionGroup(array $args = [])
* @method \GuzzleHttp\Promise\Promise createCollectionGroupAsync(array $args = [])
* @method \Aws\Result createIndex(array $args = [])
* @method \GuzzleHttp\Promise\Promise createIndexAsync(array $args = [])
* @method \Aws\Result createLifecyclePolicy(array $args = [])
@@ -31,6 +35,8 @@
* @method \GuzzleHttp\Promise\Promise deleteAccessPolicyAsync(array $args = [])
* @method \Aws\Result deleteCollection(array $args = [])
* @method \GuzzleHttp\Promise\Promise deleteCollectionAsync(array $args = [])
* @method \Aws\Result deleteCollectionGroup(array $args = [])
* @method \GuzzleHttp\Promise\Promise deleteCollectionGroupAsync(array $args = [])
* @method \Aws\Result deleteIndex(array $args = [])
* @method \GuzzleHttp\Promise\Promise deleteIndexAsync(array $args = [])
* @method \Aws\Result deleteLifecyclePolicy(array $args = [])
@@ -55,6 +61,8 @@
* @method \GuzzleHttp\Promise\Promise getSecurityPolicyAsync(array $args = [])
* @method \Aws\Result listAccessPolicies(array $args = [])
* @method \GuzzleHttp\Promise\Promise listAccessPoliciesAsync(array $args = [])
* @method \Aws\Result listCollectionGroups(array $args = [])
* @method \GuzzleHttp\Promise\Promise listCollectionGroupsAsync(array $args = [])
* @method \Aws\Result listCollections(array $args = [])
* @method \GuzzleHttp\Promise\Promise listCollectionsAsync(array $args = [])
* @method \Aws\Result listLifecyclePolicies(array $args = [])
@@ -77,6 +85,8 @@
* @method \GuzzleHttp\Promise\Promise updateAccountSettingsAsync(array $args = [])
* @method \Aws\Result updateCollection(array $args = [])
* @method \GuzzleHttp\Promise\Promise updateCollectionAsync(array $args = [])
* @method \Aws\Result updateCollectionGroup(array $args = [])
* @method \GuzzleHttp\Promise\Promise updateCollectionGroupAsync(array $args = [])
* @method \Aws\Result updateIndex(array $args = [])
* @method \GuzzleHttp\Promise\Promise updateIndexAsync(array $args = [])
* @method \Aws\Result updateLifecyclePolicy(array $args = [])

View File

@@ -53,6 +53,8 @@
* @method \GuzzleHttp\Promise\Promise deletePackageAsync(array $args = [])
* @method \Aws\Result deleteVpcEndpoint(array $args = [])
* @method \GuzzleHttp\Promise\Promise deleteVpcEndpointAsync(array $args = [])
* @method \Aws\Result deregisterCapability(array $args = [])
* @method \GuzzleHttp\Promise\Promise deregisterCapabilityAsync(array $args = [])
* @method \Aws\Result describeDomain(array $args = [])
* @method \GuzzleHttp\Promise\Promise describeDomainAsync(array $args = [])
* @method \Aws\Result describeDomainAutoTunes(array $args = [])
@@ -71,6 +73,8 @@
* @method \GuzzleHttp\Promise\Promise describeDryRunProgressAsync(array $args = [])
* @method \Aws\Result describeInboundConnections(array $args = [])
* @method \GuzzleHttp\Promise\Promise describeInboundConnectionsAsync(array $args = [])
* @method \Aws\Result describeInsightDetails(array $args = [])
* @method \GuzzleHttp\Promise\Promise describeInsightDetailsAsync(array $args = [])
* @method \Aws\Result describeInstanceTypeLimits(array $args = [])
* @method \GuzzleHttp\Promise\Promise describeInstanceTypeLimitsAsync(array $args = [])
* @method \Aws\Result describeOutboundConnections(array $args = [])
@@ -89,6 +93,8 @@
* @method \GuzzleHttp\Promise\Promise dissociatePackagesAsync(array $args = [])
* @method \Aws\Result getApplication(array $args = [])
* @method \GuzzleHttp\Promise\Promise getApplicationAsync(array $args = [])
* @method \Aws\Result getCapability(array $args = [])
* @method \GuzzleHttp\Promise\Promise getCapabilityAsync(array $args = [])
* @method \Aws\Result getCompatibleVersions(array $args = [])
* @method \GuzzleHttp\Promise\Promise getCompatibleVersionsAsync(array $args = [])
* @method \Aws\Result getDataSource(array $args = [])
@@ -119,6 +125,8 @@
* @method \GuzzleHttp\Promise\Promise listDomainNamesAsync(array $args = [])
* @method \Aws\Result listDomainsForPackage(array $args = [])
* @method \GuzzleHttp\Promise\Promise listDomainsForPackageAsync(array $args = [])
* @method \Aws\Result listInsights(array $args = [])
* @method \GuzzleHttp\Promise\Promise listInsightsAsync(array $args = [])
* @method \Aws\Result listInstanceTypeDetails(array $args = [])
* @method \GuzzleHttp\Promise\Promise listInstanceTypeDetailsAsync(array $args = [])
* @method \Aws\Result listPackagesForDomain(array $args = [])
@@ -139,6 +147,8 @@
* @method \GuzzleHttp\Promise\Promise purchaseReservedInstanceOfferingAsync(array $args = [])
* @method \Aws\Result putDefaultApplicationSetting(array $args = [])
* @method \GuzzleHttp\Promise\Promise putDefaultApplicationSettingAsync(array $args = [])
* @method \Aws\Result registerCapability(array $args = [])
* @method \GuzzleHttp\Promise\Promise registerCapabilityAsync(array $args = [])
* @method \Aws\Result rejectInboundConnection(array $args = [])
* @method \GuzzleHttp\Promise\Promise rejectInboundConnectionAsync(array $args = [])
* @method \Aws\Result removeTags(array $args = [])

View File

@@ -13,6 +13,8 @@
* @method \GuzzleHttp\Promise\Promise createOrderAsync(array $args = [])
* @method \Aws\Result createOutpost(array $args = [])
* @method \GuzzleHttp\Promise\Promise createOutpostAsync(array $args = [])
* @method \Aws\Result createRenewal(array $args = [])
* @method \GuzzleHttp\Promise\Promise createRenewalAsync(array $args = [])
* @method \Aws\Result createSite(array $args = [])
* @method \GuzzleHttp\Promise\Promise createSiteAsync(array $args = [])
* @method \Aws\Result deleteOutpost(array $args = [])
@@ -35,6 +37,8 @@
* @method \GuzzleHttp\Promise\Promise getOutpostInstanceTypesAsync(array $args = [])
* @method \Aws\Result getOutpostSupportedInstanceTypes(array $args = [])
* @method \GuzzleHttp\Promise\Promise getOutpostSupportedInstanceTypesAsync(array $args = [])
* @method \Aws\Result getRenewalPricing(array $args = [])
* @method \GuzzleHttp\Promise\Promise getRenewalPricingAsync(array $args = [])
* @method \Aws\Result getSite(array $args = [])
* @method \GuzzleHttp\Promise\Promise getSiteAsync(array $args = [])
* @method \Aws\Result getSiteAddress(array $args = [])

View File

@@ -15,12 +15,16 @@
* @method \GuzzleHttp\Promise\Promise createConfigurationSetAsync(array $args = [])
* @method \Aws\Result createEventDestination(array $args = [])
* @method \GuzzleHttp\Promise\Promise createEventDestinationAsync(array $args = [])
* @method \Aws\Result createNotifyConfiguration(array $args = [])
* @method \GuzzleHttp\Promise\Promise createNotifyConfigurationAsync(array $args = [])
* @method \Aws\Result createOptOutList(array $args = [])
* @method \GuzzleHttp\Promise\Promise createOptOutListAsync(array $args = [])
* @method \Aws\Result createPool(array $args = [])
* @method \GuzzleHttp\Promise\Promise createPoolAsync(array $args = [])
* @method \Aws\Result createProtectConfiguration(array $args = [])
* @method \GuzzleHttp\Promise\Promise createProtectConfigurationAsync(array $args = [])
* @method \Aws\Result createRcsAgent(array $args = [])
* @method \GuzzleHttp\Promise\Promise createRcsAgentAsync(array $args = [])
* @method \Aws\Result createRegistration(array $args = [])
* @method \GuzzleHttp\Promise\Promise createRegistrationAsync(array $args = [])
* @method \Aws\Result createRegistrationAssociation(array $args = [])
@@ -45,6 +49,10 @@
* @method \GuzzleHttp\Promise\Promise deleteKeywordAsync(array $args = [])
* @method \Aws\Result deleteMediaMessageSpendLimitOverride(array $args = [])
* @method \GuzzleHttp\Promise\Promise deleteMediaMessageSpendLimitOverrideAsync(array $args = [])
* @method \Aws\Result deleteNotifyConfiguration(array $args = [])
* @method \GuzzleHttp\Promise\Promise deleteNotifyConfigurationAsync(array $args = [])
* @method \Aws\Result deleteNotifyMessageSpendLimitOverride(array $args = [])
* @method \GuzzleHttp\Promise\Promise deleteNotifyMessageSpendLimitOverrideAsync(array $args = [])
* @method \Aws\Result deleteOptOutList(array $args = [])
* @method \GuzzleHttp\Promise\Promise deleteOptOutListAsync(array $args = [])
* @method \Aws\Result deleteOptedOutNumber(array $args = [])
@@ -55,6 +63,8 @@
* @method \GuzzleHttp\Promise\Promise deleteProtectConfigurationAsync(array $args = [])
* @method \Aws\Result deleteProtectConfigurationRuleSetNumberOverride(array $args = [])
* @method \GuzzleHttp\Promise\Promise deleteProtectConfigurationRuleSetNumberOverrideAsync(array $args = [])
* @method \Aws\Result deleteRcsAgent(array $args = [])
* @method \GuzzleHttp\Promise\Promise deleteRcsAgentAsync(array $args = [])
* @method \Aws\Result deleteRegistration(array $args = [])
* @method \GuzzleHttp\Promise\Promise deleteRegistrationAsync(array $args = [])
* @method \Aws\Result deleteRegistrationAttachment(array $args = [])
@@ -77,6 +87,10 @@
* @method \GuzzleHttp\Promise\Promise describeConfigurationSetsAsync(array $args = [])
* @method \Aws\Result describeKeywords(array $args = [])
* @method \GuzzleHttp\Promise\Promise describeKeywordsAsync(array $args = [])
* @method \Aws\Result describeNotifyConfigurations(array $args = [])
* @method \GuzzleHttp\Promise\Promise describeNotifyConfigurationsAsync(array $args = [])
* @method \Aws\Result describeNotifyTemplates(array $args = [])
* @method \GuzzleHttp\Promise\Promise describeNotifyTemplatesAsync(array $args = [])
* @method \Aws\Result describeOptOutLists(array $args = [])
* @method \GuzzleHttp\Promise\Promise describeOptOutListsAsync(array $args = [])
* @method \Aws\Result describeOptedOutNumbers(array $args = [])
@@ -87,6 +101,10 @@
* @method \GuzzleHttp\Promise\Promise describePoolsAsync(array $args = [])
* @method \Aws\Result describeProtectConfigurations(array $args = [])
* @method \GuzzleHttp\Promise\Promise describeProtectConfigurationsAsync(array $args = [])
* @method \Aws\Result describeRcsAgentCountryLaunchStatus(array $args = [])
* @method \GuzzleHttp\Promise\Promise describeRcsAgentCountryLaunchStatusAsync(array $args = [])
* @method \Aws\Result describeRcsAgents(array $args = [])
* @method \GuzzleHttp\Promise\Promise describeRcsAgentsAsync(array $args = [])
* @method \Aws\Result describeRegistrationAttachments(array $args = [])
* @method \GuzzleHttp\Promise\Promise describeRegistrationAttachmentsAsync(array $args = [])
* @method \Aws\Result describeRegistrationFieldDefinitions(array $args = [])
@@ -117,6 +135,8 @@
* @method \GuzzleHttp\Promise\Promise getProtectConfigurationCountryRuleSetAsync(array $args = [])
* @method \Aws\Result getResourcePolicy(array $args = [])
* @method \GuzzleHttp\Promise\Promise getResourcePolicyAsync(array $args = [])
* @method \Aws\Result listNotifyCountries(array $args = [])
* @method \GuzzleHttp\Promise\Promise listNotifyCountriesAsync(array $args = [])
* @method \Aws\Result listPoolOriginationIdentities(array $args = [])
* @method \GuzzleHttp\Promise\Promise listPoolOriginationIdentitiesAsync(array $args = [])
* @method \Aws\Result listProtectConfigurationRuleSetNumberOverrides(array $args = [])
@@ -149,6 +169,10 @@
* @method \GuzzleHttp\Promise\Promise sendDestinationNumberVerificationCodeAsync(array $args = [])
* @method \Aws\Result sendMediaMessage(array $args = [])
* @method \GuzzleHttp\Promise\Promise sendMediaMessageAsync(array $args = [])
* @method \Aws\Result sendNotifyTextMessage(array $args = [])
* @method \GuzzleHttp\Promise\Promise sendNotifyTextMessageAsync(array $args = [])
* @method \Aws\Result sendNotifyVoiceMessage(array $args = [])
* @method \GuzzleHttp\Promise\Promise sendNotifyVoiceMessageAsync(array $args = [])
* @method \Aws\Result sendTextMessage(array $args = [])
* @method \GuzzleHttp\Promise\Promise sendTextMessageAsync(array $args = [])
* @method \Aws\Result sendVoiceMessage(array $args = [])
@@ -163,6 +187,8 @@
* @method \GuzzleHttp\Promise\Promise setDefaultSenderIdAsync(array $args = [])
* @method \Aws\Result setMediaMessageSpendLimitOverride(array $args = [])
* @method \GuzzleHttp\Promise\Promise setMediaMessageSpendLimitOverrideAsync(array $args = [])
* @method \Aws\Result setNotifyMessageSpendLimitOverride(array $args = [])
* @method \GuzzleHttp\Promise\Promise setNotifyMessageSpendLimitOverrideAsync(array $args = [])
* @method \Aws\Result setTextMessageSpendLimitOverride(array $args = [])
* @method \GuzzleHttp\Promise\Promise setTextMessageSpendLimitOverrideAsync(array $args = [])
* @method \Aws\Result setVoiceMessageSpendLimitOverride(array $args = [])
@@ -175,6 +201,8 @@
* @method \GuzzleHttp\Promise\Promise untagResourceAsync(array $args = [])
* @method \Aws\Result updateEventDestination(array $args = [])
* @method \GuzzleHttp\Promise\Promise updateEventDestinationAsync(array $args = [])
* @method \Aws\Result updateNotifyConfiguration(array $args = [])
* @method \GuzzleHttp\Promise\Promise updateNotifyConfigurationAsync(array $args = [])
* @method \Aws\Result updatePhoneNumber(array $args = [])
* @method \GuzzleHttp\Promise\Promise updatePhoneNumberAsync(array $args = [])
* @method \Aws\Result updatePool(array $args = [])
@@ -183,6 +211,8 @@
* @method \GuzzleHttp\Promise\Promise updateProtectConfigurationAsync(array $args = [])
* @method \Aws\Result updateProtectConfigurationCountryRuleSet(array $args = [])
* @method \GuzzleHttp\Promise\Promise updateProtectConfigurationCountryRuleSetAsync(array $args = [])
* @method \Aws\Result updateRcsAgent(array $args = [])
* @method \GuzzleHttp\Promise\Promise updateRcsAgentAsync(array $args = [])
* @method \Aws\Result updateSenderId(array $args = [])
* @method \GuzzleHttp\Promise\Promise updateSenderIdAsync(array $args = [])
* @method \Aws\Result verifyDestinationNumber(array $args = [])

View File

@@ -149,6 +149,8 @@
* @method \GuzzleHttp\Promise\Promise describeAssetBundleExportJobAsync(array $args = [])
* @method \Aws\Result describeAssetBundleImportJob(array $args = [])
* @method \GuzzleHttp\Promise\Promise describeAssetBundleImportJobAsync(array $args = [])
* @method \Aws\Result describeAutomationJob(array $args = [])
* @method \GuzzleHttp\Promise\Promise describeAutomationJobAsync(array $args = [])
* @method \Aws\Result describeBrand(array $args = [])
* @method \GuzzleHttp\Promise\Promise describeBrandAsync(array $args = [])
* @method \Aws\Result describeBrandAssignment(array $args = [])
@@ -357,6 +359,8 @@
* @method \GuzzleHttp\Promise\Promise startAssetBundleExportJobAsync(array $args = [])
* @method \Aws\Result startAssetBundleImportJob(array $args = [])
* @method \GuzzleHttp\Promise\Promise startAssetBundleImportJobAsync(array $args = [])
* @method \Aws\Result startAutomationJob(array $args = [])
* @method \GuzzleHttp\Promise\Promise startAutomationJobAsync(array $args = [])
* @method \Aws\Result startDashboardSnapshotJob(array $args = [])
* @method \GuzzleHttp\Promise\Promise startDashboardSnapshotJobAsync(array $args = [])
* @method \Aws\Result startDashboardSnapshotJobSchedule(array $args = [])

View File

@@ -57,6 +57,8 @@
* @method \GuzzleHttp\Promise\Promise listResourceTypesAsync(array $args = [])
* @method \Aws\Result listResources(array $args = [])
* @method \GuzzleHttp\Promise\Promise listResourcesAsync(array $args = [])
* @method \Aws\Result listSourceAssociations(array $args = [])
* @method \GuzzleHttp\Promise\Promise listSourceAssociationsAsync(array $args = [])
* @method \Aws\Result promotePermissionCreatedFromPolicy(array $args = [])
* @method \GuzzleHttp\Promise\Promise promotePermissionCreatedFromPolicyAsync(array $args = [])
* @method \Aws\Result promoteResourceShareCreatedFromPolicy(array $args = [])

View File

@@ -238,6 +238,8 @@
* @method \GuzzleHttp\Promise\Promise describeIntegrationsAsync(array $args = []) (supported in versions 2014-10-31)
* @method \Aws\Result describePendingMaintenanceActions(array $args = []) (supported in versions 2014-10-31)
* @method \GuzzleHttp\Promise\Promise describePendingMaintenanceActionsAsync(array $args = []) (supported in versions 2014-10-31)
* @method \Aws\Result describeServerlessV2PlatformVersions(array $args = []) (supported in versions 2014-10-31)
* @method \GuzzleHttp\Promise\Promise describeServerlessV2PlatformVersionsAsync(array $args = []) (supported in versions 2014-10-31)
* @method \Aws\Result describeSourceRegions(array $args = []) (supported in versions 2014-10-31)
* @method \GuzzleHttp\Promise\Promise describeSourceRegionsAsync(array $args = []) (supported in versions 2014-10-31)
* @method \Aws\Result describeTenantDatabases(array $args = []) (supported in versions 2014-10-31)

View File

@@ -8,7 +8,7 @@
trait CalculatesChecksumTrait
{
private static $supportedAlgorithms = [
public static array $supportedAlgorithms = [
'crc32c' => true,
'crc32' => true,
'sha256' => true,
@@ -47,7 +47,13 @@ public static function getEncodedValue($requestedAlgorithm, $value) {
if ($requestedAlgorithm === "crc32") {
$requestedAlgorithm = "crc32b";
}
return base64_encode(Psr7\Utils::hash($value, $requestedAlgorithm, true));
return base64_encode(
Psr7\Utils::hash(Psr7\Utils::streamFor($value),
$requestedAlgorithm,
true
)
);
}
$validAlgorithms = implode(', ', array_keys(self::$supportedAlgorithms));
@@ -56,4 +62,23 @@ public static function getEncodedValue($requestedAlgorithm, $value) {
. " Valid algorithms supported by the runtime are {$validAlgorithms}."
);
}
/**
* Returns the first checksum available, if available.
*
* @param array $parameters
*
* @return string|null
*/
public static function filterChecksum(array $parameters): ?string
{
foreach (self::$supportedAlgorithms as $algorithm => $_) {
$checksumAlgorithm = "Checksum" . strtoupper($algorithm);
if (isset($parameters[$checksumAlgorithm])) {
return $checksumAlgorithm;
}
}
return null;
}
}

View File

@@ -247,6 +247,8 @@
* @method \GuzzleHttp\Promise\Promise updateBucketMetadataInventoryTableConfigurationAsync(array $args = [])
* @method \Aws\Result updateBucketMetadataJournalTableConfiguration(array $args = [])
* @method \GuzzleHttp\Promise\Promise updateBucketMetadataJournalTableConfigurationAsync(array $args = [])
* @method \Aws\Result updateObjectEncryption(array $args = [])
* @method \GuzzleHttp\Promise\Promise updateObjectEncryptionAsync(array $args = [])
* @method \Aws\Result uploadPart(array $args = [])
* @method \GuzzleHttp\Promise\Promise uploadPartAsync(array $args = [])
* @method \Aws\Result uploadPartCopy(array $args = [])
@@ -1140,7 +1142,7 @@ public static function applyDocFilters(array $api, array $docs)
// Add a note on the CopyObject docs
$s3ExceptionRetryMessage = "<p>Additional info on response behavior: if there is"
. " an internal error in S3 after the request was successfully recieved,"
. " an internal error in S3 after the request was successfully received,"
. " a 200 response will be returned with an <code>S3Exception</code> embedded"
. " in it; this will still be caught and retried by"
. " <code>RetryMiddleware.</code></p>";

View File

@@ -225,6 +225,8 @@
* @method \GuzzleHttp\Promise\Promise updateBucketMetadataInventoryTableConfigurationAsync(array $args = [])
* @method \Aws\Result updateBucketMetadataJournalTableConfiguration(array $args = [])
* @method \GuzzleHttp\Promise\Promise updateBucketMetadataJournalTableConfigurationAsync(array $args = [])
* @method \Aws\Result updateObjectEncryption(array $args = [])
* @method \GuzzleHttp\Promise\Promise updateObjectEncryptionAsync(array $args = [])
* @method \Aws\Result uploadPart(array $args = [])
* @method \GuzzleHttp\Promise\Promise uploadPartAsync(array $args = [])
* @method \Aws\Result uploadPartCopy(array $args = [])

View File

@@ -226,6 +226,8 @@
* @method \GuzzleHttp\Promise\Promise updateBucketMetadataInventoryTableConfigurationAsync(array $args = [])
* @method \Aws\Result updateBucketMetadataJournalTableConfiguration(array $args = [])
* @method \GuzzleHttp\Promise\Promise updateBucketMetadataJournalTableConfigurationAsync(array $args = [])
* @method \Aws\Result updateObjectEncryption(array $args = [])
* @method \GuzzleHttp\Promise\Promise updateObjectEncryptionAsync(array $args = [])
* @method \Aws\Result uploadPart(array $args = [])
* @method \GuzzleHttp\Promise\Promise uploadPartAsync(array $args = [])
* @method \Aws\Result uploadPartCopy(array $args = [])

View File

@@ -6,16 +6,20 @@
use Aws\S3\S3ClientInterface;
use Aws\S3\S3Transfer\Exception\S3TransferException;
use Aws\S3\S3Transfer\Models\DownloadResult;
use Aws\S3\S3Transfer\Models\ResumableDownload;
use Aws\S3\S3Transfer\Models\S3TransferManagerConfig;
use Aws\S3\S3Transfer\Progress\AbstractTransferListener;
use Aws\S3\S3Transfer\Progress\TransferListenerNotifier;
use Aws\S3\S3Transfer\Progress\TransferProgressSnapshot;
use Aws\S3\S3Transfer\Utils\ResumableDownloadHandlerInterface;
use Aws\S3\S3Transfer\Utils\AbstractDownloadHandler;
use Aws\S3\S3Transfer\Utils\StreamDownloadHandler;
use GuzzleHttp\Promise\Coroutine;
use GuzzleHttp\Promise\Create;
use GuzzleHttp\Promise\Each;
use GuzzleHttp\Promise\PromiseInterface;
use GuzzleHttp\Promise\PromisorInterface;
use Throwable;
abstract class AbstractMultipartDownloader implements PromisorInterface
{
@@ -23,6 +27,7 @@ abstract class AbstractMultipartDownloader implements PromisorInterface
public const PART_GET_MULTIPART_DOWNLOADER = "part";
public const RANGED_GET_MULTIPART_DOWNLOADER = "ranged";
private const OBJECT_SIZE_REGEX = "/\/(\d+)$/";
private const RANGE_TO_REGEX = "/(\d+)\//";
/** @var array */
protected readonly array $downloadRequestArgs;
@@ -51,30 +56,68 @@ abstract class AbstractMultipartDownloader implements PromisorInterface
/** Tracking Members */
private ?TransferProgressSnapshot $currentSnapshot;
/** @var array */
private array $partsCompleted;
/** @var ResumableDownload|null */
private ?ResumableDownload $resumableDownload;
/** @var bool Whether this is a resumed download */
private readonly bool $isResuming;
/** @var array|null Initial request response for resume state */
private ?array $initialRequestResult = null;
/**
* @param S3ClientInterface $s3Client
* @param array $downloadRequestArgs
* @param array $config
* @param ?AbstractDownloadHandler $downloadHandler
* @param int $currentPartNo
* @param array $partsCompleted
* @param int $objectPartsCount
* @param int $objectSizeInBytes
* @param string|null $eTag
* @param TransferProgressSnapshot|null $currentSnapshot
* @param TransferListenerNotifier|null $listenerNotifier
* @param ResumableDownload|null $resumableDownload
*/
public function __construct(
protected readonly S3ClientInterface $s3Client,
array $downloadRequestArgs,
array $config = [],
?AbstractDownloadHandler $downloadHandler = null,
int $currentPartNo = 0,
array $partsCompleted = [],
int $objectPartsCount = 0,
int $objectSizeInBytes = 0,
?string $eTag = null,
?TransferProgressSnapshot $currentSnapshot = null,
?TransferListenerNotifier $listenerNotifier = null
?TransferListenerNotifier $listenerNotifier = null,
?ResumableDownload $resumableDownload = null
) {
$this->resumableDownload = $resumableDownload;
$this->isResuming = $resumableDownload !== null;
// Initialize from resume state if available
if ($this->isResuming) {
$this->objectPartsCount = $resumableDownload->getTotalNumberOfParts();
$this->objectSizeInBytes = $resumableDownload->getObjectSizeInBytes();
$this->eTag = $resumableDownload->getETag();
$this->partsCompleted = $resumableDownload->getPartsCompleted();
$this->initialRequestResult = $this->resumableDownload->getInitialRequestResult();
// Restore current snapshot
$snapshotData = $resumableDownload->getCurrentSnapshot();
if (!empty($snapshotData)) {
$this->currentSnapshot = TransferProgressSnapshot::fromArray(
$snapshotData
);
}
} else {
$this->partsCompleted = $partsCompleted;
$this->objectPartsCount = $objectPartsCount;
$this->objectSizeInBytes = $objectSizeInBytes;
$this->eTag = $eTag;
$this->currentSnapshot = $currentSnapshot;
}
$this->downloadRequestArgs = $downloadRequestArgs;
$this->validateConfig($config);
$this->config = $config;
@@ -82,25 +125,17 @@ public function __construct(
$downloadHandler = new StreamDownloadHandler();
}
$this->downloadHandler = $downloadHandler;
$this->currentPartNo = $currentPartNo;
$this->objectPartsCount = $objectPartsCount;
$this->objectSizeInBytes = $objectSizeInBytes;
$this->eTag = $eTag;
$this->currentSnapshot = $currentSnapshot;
if ($listenerNotifier === null) {
$listenerNotifier = new TransferListenerNotifier();
}
// Add download handler to the listener notifier
$listenerNotifier->addListener($downloadHandler);
$this->listenerNotifier = $listenerNotifier;
// Always starts in 1
$this->currentPartNo = 1;
}
/**
* Returns the next command for fetching the next object part.
* Returns the next command args for fetching the next object part.
*
* @return CommandInterface
* @return array
*/
abstract protected function nextCommand(): CommandInterface;
abstract protected function getFetchCommandArgs(): array;
/**
* Compute the object dimensions, such as size and parts count.
@@ -117,9 +152,17 @@ private function validateConfig(array &$config): void
$config['target_part_size_bytes'] = S3TransferManagerConfig::DEFAULT_TARGET_PART_SIZE_BYTES;
}
if (!isset($config['concurrency'])) {
$config['concurrency'] = S3TransferManagerConfig::DEFAULT_CONCURRENCY;
}
if (!isset($config['response_checksum_validation'])) {
$config['response_checksum_validation'] = S3TransferManagerConfig::DEFAULT_RESPONSE_CHECKSUM_VALIDATION;
}
if (!isset($config['resume_enabled'])) {
$config['resume_enabled'] = false;
}
}
/**
@@ -179,57 +222,37 @@ public function download(): DownloadResult
public function promise(): PromiseInterface
{
return Coroutine::of(function () {
try {
$initialRequestResult = yield $this->initialRequest();
$prevPartNo = $this->currentPartNo - 1;
while ($this->currentPartNo < $this->objectPartsCount) {
// To prevent infinite loops
if ($prevPartNo !== $this->currentPartNo - 1) {
throw new S3TransferException(
"Current part `$this->currentPartNo` MUST increment."
);
}
// Skip initial request if resuming (we already have object dimensions)
if ($this->isResuming) {
$this->downloadInitiated($this->downloadRequestArgs);
} else {
yield $this->initialRequest();
}
$prevPartNo = $this->currentPartNo;
$partsDownloadPromises = $this->partDownloadRequests();
$command = $this->nextCommand();
yield $this->s3Client->executeAsync($command)
->then(function ($result) use ($command) {
$this->partDownloadCompleted(
$result,
$command->toArray()
);
return $result;
})->otherwise(function ($reason) {
$this->partDownloadFailed($reason);
throw $reason;
});
}
if ($this->currentPartNo !== $this->objectPartsCount) {
throw new S3TransferException(
"Expected number of parts `$this->objectPartsCount`"
. " to have been transferred but got `$this->currentPartNo`."
);
}
// When concurrency is not supported by the download handler
// Then the number of concurrency will be just one.
$concurrency = $this->downloadHandler->isConcurrencySupported()
? $this->config['concurrency']
: 1;
yield Each::ofLimitAll(
$partsDownloadPromises,
$concurrency,
)->then(function () {
// Transfer completed
$this->downloadComplete();
// Return response
$result = $initialRequestResult->toArray();
unset($result['Body']);
yield Create::promiseFor(new DownloadResult(
return Create::promiseFor(new DownloadResult(
$this->downloadHandler->getHandlerResult(),
$result,
$this->initialRequestResult,
));
} catch (\Throwable $e) {
})->otherwise(function (Throwable $e) {
$this->downloadFailed($e);
yield Create::rejectionFor($e);
}
throw $e;
});
});
}
@@ -240,7 +263,7 @@ public function promise(): PromiseInterface
*/
protected function initialRequest(): PromiseInterface
{
$command = $this->nextCommand();
$command = $this->getNextGetObjectCommand();
// Notify download initiated
$this->downloadInitiated($command->toArray());
@@ -254,16 +277,28 @@ protected function initialRequest(): PromiseInterface
$this->eTag = $result['ETag'];
}
// Notify listeners
$initialRequestResult = $result->toArray();
// Set full object size
$initialRequestResult['ContentLength'] = $this->objectSizeInBytes;
// Set full object content range
$initialRequestResult['ContentRange'] = "0-"
. ($this->objectSizeInBytes - 1)
. "/"
. $this->objectSizeInBytes;
// Remove unnecessary fields
unset($initialRequestResult['Body']);
unset($initialRequestResult['@metadata']);
// Store initial response for resume state
$this->initialRequestResult = $initialRequestResult;
// Notify listeners but we pass the actual request result
$this->partDownloadCompleted(
$result,
1,
$result->toArray(),
$command->toArray()
);
// Assign custom fields in the result
$result['ContentLength'] = $this->objectSizeInBytes;
return $result;
})->otherwise(function ($reason) {
$this->partDownloadFailed($reason);
@@ -272,26 +307,60 @@ protected function initialRequest(): PromiseInterface
}
/**
* Calculates the object size from content range.
*
* @param string $contentRange
* @return int
* @return \Generator
*/
protected function computeObjectSizeFromContentRange(
string $contentRange
): int
private function partDownloadRequests(): \Generator
{
if (empty($contentRange)) {
return 0;
while ($this->currentPartNo < $this->objectPartsCount) {
$this->currentPartNo++;
if ($this->partsCompleted[$this->currentPartNo] ?? false) {
continue;
}
$partNumber = $this->currentPartNo;
$command = $this->getNextGetObjectCommand();
yield $this->s3Client->executeAsync($command)
->then(function (ResultInterface $result)
use ($command, $partNumber) {
$requestArgs = $command->toArray();
// Remove metadata
unset($result['@metadata']);
$this->partDownloadCompleted(
$partNumber,
$result->toArray(),
$requestArgs
);
});
}
// For extracting the object size from the ContentRange header value.
if (preg_match(self::OBJECT_SIZE_REGEX, $contentRange, $matches)) {
return $matches[1];
if ($this->currentPartNo !== $this->objectPartsCount) {
throw new S3TransferException(
"Expected number of parts `$this->objectPartsCount`"
. " to have been transferred but got `$this->currentPartNo`."
);
}
}
/**
* @return CommandInterface
*/
private function getNextGetObjectCommand(): CommandInterface
{
$nextCommandArgs = $this->getFetchCommandArgs();
if ($this->config['response_checksum_validation'] === 'when_supported') {
$nextCommandArgs['ChecksumMode'] = 'ENABLED';
}
throw new S3TransferException(
"Invalid content range \"$contentRange\""
if (!empty($this->eTag)) {
$nextCommandArgs['IfMatch'] = $this->eTag;
}
return $this->s3Client->getCommand(
self::GET_OBJECT_COMMAND,
$nextCommandArgs
);
}
@@ -307,25 +376,32 @@ protected function computeObjectSizeFromContentRange(
*/
private function downloadInitiated(array $commandArgs): void
{
if ($this->currentSnapshot === null) {
$this->currentSnapshot = new TransferProgressSnapshot(
$commandArgs['Key'],
0,
$this->objectSizeInBytes
);
} else {
$this->currentSnapshot = new TransferProgressSnapshot(
$this->currentSnapshot->getIdentifier(),
$this->currentSnapshot->getTransferredBytes(),
$this->currentSnapshot->getTotalBytes(),
$this->currentSnapshot->getResponse()
);
}
if ($this->currentSnapshot === null) {
$this->currentSnapshot = new TransferProgressSnapshot(
$commandArgs['Key'],
0,
$this->objectSizeInBytes
);
} else {
$this->currentSnapshot = new TransferProgressSnapshot(
$this->currentSnapshot->getIdentifier(),
$this->currentSnapshot->getTransferredBytes(),
$this->currentSnapshot->getTotalBytes(),
$this->currentSnapshot->getResponse()
);
}
$this->listenerNotifier?->transferInitiated([
// Prepare context
$context = [
AbstractTransferListener::REQUEST_ARGS_KEY => $commandArgs,
AbstractTransferListener::PROGRESS_SNAPSHOT_KEY => $this->currentSnapshot,
]);
];
// Notify download handler
$this->downloadHandler->transferInitiated($context);
// Notify listeners
$this->listenerNotifier?->transferInitiated($context);
}
/**
@@ -350,40 +426,74 @@ private function downloadFailed(\Throwable $reason): void
$reason
);
$this->listenerNotifier?->transferFail([
// Prepare context
$context = [
AbstractTransferListener::REQUEST_ARGS_KEY => $this->downloadRequestArgs,
AbstractTransferListener::PROGRESS_SNAPSHOT_KEY => $this->currentSnapshot,
'reason' => $reason,
]);
AbstractTransferListener::REASON_KEY => $reason,
];
// Notify download handler
$this->downloadHandler->transferFail($context);
// Notify listeners
$this->listenerNotifier?->transferFail($context);
}
/**
* Propagates part-download-completed to listeners.
* It also does some computation in order to maintain internal states.
*
* @param ResultInterface $result
* @param int $partNumber
* @param array $result
* @param array $requestArgs
*
* @return void
*/
private function partDownloadCompleted(
ResultInterface $result,
int $partNumber,
array $result,
array $requestArgs
): void
{
$partDownloadBytes = $result['ContentLength'];
if (isset($result['ETag'])) {
$this->eTag = $result['ETag'];
}
$partTransferredBytes = $result['ContentLength'] ?? 0;
// Snapshot and context for listeners
$newSnapshot = new TransferProgressSnapshot(
$this->currentSnapshot->getIdentifier(),
$this->currentSnapshot->getTransferredBytes() + $partDownloadBytes,
$this->currentSnapshot->getTransferredBytes() + $partTransferredBytes,
$this->objectSizeInBytes,
$result->toArray()
$this->initialRequestResult
);
$this->currentSnapshot = $newSnapshot;
$this->listenerNotifier?->bytesTransferred([
// Notify download handler and evaluate if part was written
$downloadHandlerSnapshot = $this->currentSnapshot->withResponse(
$result
);
$wasPartWritten = $this->downloadHandler->bytesTransferred([
AbstractTransferListener::REQUEST_ARGS_KEY => $requestArgs,
AbstractTransferListener::PROGRESS_SNAPSHOT_KEY => $downloadHandlerSnapshot,
]);
// If part was written to destination then we mark it as completed
if ($wasPartWritten) {
$this->partsCompleted[$partNumber] = true;
// Persist resume state just if resume is enabled
if ($this->config['resume_enabled'] ?? false) {
// Update the resume state holder
$this->resumableDownload?->updateCurrentSnapshot(
$this->currentSnapshot->toArray()
);
$this->resumableDownload?->markPartCompleted($partNumber);
// Persist the resume state
$this->persistResumeState();
}
}
// Notify listeners
$this->listenerNotifier?->bytesTransferred([
AbstractTransferListener::REQUEST_ARGS_KEY => $this->downloadRequestArgs,
AbstractTransferListener::PROGRESS_SNAPSHOT_KEY => $this->currentSnapshot,
]);
}
@@ -416,10 +526,108 @@ private function downloadComplete(): void
$this->currentSnapshot->getResponse()
);
$this->currentSnapshot = $newSnapshot;
$this->listenerNotifier?->transferComplete([
// Prepare context
$context = [
AbstractTransferListener::REQUEST_ARGS_KEY => $this->downloadRequestArgs,
AbstractTransferListener::PROGRESS_SNAPSHOT_KEY => $this->currentSnapshot,
]);
];
// Notify download handler
$this->downloadHandler->transferComplete($context);
// Notify listeners
$this->listenerNotifier?->transferComplete($context);
// Delete resume file on successful completion
if ($this->config['resume_enabled'] ?? false) {
$this->resumableDownload?->deleteResumeFile();
}
}
/**
* Persist the current download state to the resume file.
* This method is called after each part is downloaded.
*
* @return void
*/
private function persistResumeState(): void
{
// Only persist if we have a download handler that supports resume
if (!($this->downloadHandler instanceof ResumableDownloadHandlerInterface)) {
return;
}
// Create ResumableDownload object
if ($this->resumableDownload === null) {
// Resume file destination
$resumeFilePath = $this->config['resume_file_path'] ??
$this->downloadHandler->getResumeFilePath();
// Create snapshot data
$snapshotData = $this->currentSnapshot->toArray();
// Determine multipart download type
$config = $this->config;
$this->resumableDownload = new ResumableDownload(
$resumeFilePath,
$this->downloadRequestArgs,
$config,
$snapshotData,
$this->initialRequestResult,
$this->partsCompleted,
$this->objectPartsCount,
$this->downloadHandler->getTemporaryFilePath(),
$this->eTag ?? '',
$this->objectSizeInBytes,
$this->downloadHandler->getFixedPartSize(),
$this->downloadHandler->getDestination()
);
}
try {
$this->resumableDownload->toFile();
} catch (\Exception $e) {
throw new S3TransferException(
"Unable to persist resumable download state due to: " . $e->getMessage(),
);
}
}
/**
* Calculates the object size from content range.
*
* @param string $contentRange
* @return int
*/
public static function computeObjectSizeFromContentRange(
string $contentRange
): int
{
if (empty($contentRange)) {
return 0;
}
// For extracting the object size from the ContentRange header value.
if (preg_match(self::OBJECT_SIZE_REGEX, $contentRange, $matches)) {
return (int) $matches[1];
}
throw new S3TransferException(
"Invalid content range \"$contentRange\""
);
}
/**
* @param string $range
*
* @return int
*/
public static function getRangeTo(string $range): int
{
preg_match(self::RANGE_TO_REGEX, $range, $match);
if (empty($match)) {
return 0;
}
return (int) $match[1];
}
/**

View File

@@ -6,13 +6,11 @@
use Aws\CommandPool;
use Aws\ResultInterface;
use Aws\S3\S3ClientInterface;
use Aws\S3\S3Transfer\Exception\S3TransferException;
use Aws\S3\S3Transfer\Models\S3TransferManagerConfig;
use Aws\S3\S3Transfer\Progress\AbstractTransferListener;
use Aws\S3\S3Transfer\Progress\TransferListenerNotifier;
use Aws\S3\S3Transfer\Progress\TransferProgressSnapshot;
use GuzzleHttp\Promise\Coroutine;
use GuzzleHttp\Promise\Create;
use GuzzleHttp\Promise\PromiseInterface;
use GuzzleHttp\Promise\PromisorInterface;
use Throwable;
@@ -39,7 +37,7 @@ abstract class AbstractMultipartUploader implements PromisorInterface
protected string|null $uploadId;
/** @var array */
protected array $parts;
protected array $partsCompleted;
/** @var array */
protected array $onCompletionCallbacks = [];
@@ -58,7 +56,7 @@ abstract class AbstractMultipartUploader implements PromisorInterface
* - target_part_size_bytes: (int, optional)
* - concurrency: (int, optional)
* @param string|null $uploadId
* @param array $parts
* @param array $partsCompleted
* @param TransferProgressSnapshot|null $currentSnapshot
* @param TransferListenerNotifier|null $listenerNotifier
*/
@@ -67,7 +65,7 @@ public function __construct(
array $requestArgs,
array $config = [],
?string $uploadId = null,
array $parts = [],
array $partsCompleted = [],
?TransferProgressSnapshot $currentSnapshot = null,
?TransferListenerNotifier $listenerNotifier = null,
) {
@@ -76,7 +74,7 @@ public function __construct(
$this->validateConfig($config);
$this->config = $config;
$this->uploadId = $uploadId;
$this->parts = $parts;
$this->partsCompleted = $partsCompleted;
$this->currentSnapshot = $currentSnapshot;
$this->listenerNotifier = $listenerNotifier;
}
@@ -96,6 +94,24 @@ abstract protected function completeMultipartOperation(): PromiseInterface;
*/
abstract protected function processMultipartOperation(): PromiseInterface;
/**
* @param int $partSize
* @param array $requestArgs
* @param array $partData
*
* @return void
*/
abstract protected function partCompleted(
int $partSize,
array $requestArgs,
array $partData
): void;
/**
* @return PromiseInterface
*/
abstract protected function abortMultipartOperation(): PromiseInterface;
/**
* @return int
*/
@@ -144,9 +160,9 @@ public function getUploadId(): ?string
/**
* @return array
*/
public function getParts(): array
public function getPartsCompleted(): array
{
return $this->parts;
return $this->partsCompleted;
}
/**
@@ -180,40 +196,27 @@ public function promise(): PromiseInterface
});
}
/**
* @return PromiseInterface
*/
protected function abortMultipartOperation(): PromiseInterface
{
$abortMultipartUploadArgs = $this->requestArgs;
$abortMultipartUploadArgs['UploadId'] = $this->uploadId;
$command = $this->s3Client->getCommand(
'AbortMultipartUpload',
$abortMultipartUploadArgs
);
return $this->s3Client->executeAsync($command);
}
/**
* @return void
*/
protected function sortParts(): void
{
usort($this->parts, function ($partOne, $partTwo) {
return $partOne['PartNumber'] <=> $partTwo['PartNumber'];
usort($this->partsCompleted, function ($partOne, $partTwo) {
return $partOne['PartNumber']
<=> $partTwo['PartNumber'];
});
}
/**
* @param ResultInterface $result
* @param CommandInterface $command
* @return void
*
* @return array
*/
protected function collectPart(
ResultInterface $result,
CommandInterface $command
): void
): array
{
$checksumResult = match($command->getName()) {
'UploadPart' => $result,
@@ -221,8 +224,9 @@ protected function collectPart(
default => $result[$command->getName() . 'Result']
};
$partNumber = $command['PartNumber'];
$partData = [
'PartNumber' => $command['PartNumber'],
'PartNumber' => $partNumber,
'ETag' => $checksumResult['ETag'],
];
@@ -231,7 +235,9 @@ protected function collectPart(
$partData[$checksumMemberName] = $checksumResult[$checksumMemberName] ?? null;
}
$this->parts[] = $partData;
$this->partsCompleted[$partNumber] = $partData;
return $partData;
}
/**
@@ -343,32 +349,6 @@ protected function operationFailed(Throwable $reason): void
]);
}
/**
* @param int $partSize
* @param array $requestArgs
* @return void
*/
protected function partCompleted(
int $partSize,
array $requestArgs
): void
{
$newSnapshot = new TransferProgressSnapshot(
$this->currentSnapshot->getIdentifier(),
$this->currentSnapshot->getTransferredBytes() + $partSize,
$this->currentSnapshot->getTotalBytes(),
$this->currentSnapshot->getResponse(),
$this->currentSnapshot->getReason(),
);
$this->currentSnapshot = $newSnapshot;
$this->listenerNotifier?->bytesTransferred([
AbstractTransferListener::REQUEST_ARGS_KEY => $requestArgs,
AbstractTransferListener::PROGRESS_SNAPSHOT_KEY => $this->currentSnapshot
]);
}
/**
* @return void
*/

View File

@@ -0,0 +1,369 @@
<?php
namespace Aws\S3\S3Transfer;
use Aws\MetricsBuilder;
use Aws\S3\S3ClientInterface;
use Aws\S3\S3Transfer\Exception\S3TransferException;
use Aws\S3\S3Transfer\Models\DownloadDirectoryRequest;
use Aws\S3\S3Transfer\Models\DownloadDirectoryResult;
use Aws\S3\S3Transfer\Models\DownloadFileRequest;
use Aws\S3\S3Transfer\Models\DownloadRequest;
use Aws\S3\S3Transfer\Progress\DirectoryProgressTracker;
use Aws\S3\S3Transfer\Progress\DirectoryTransferProgressAggregator;
use Closure;
use GuzzleHttp\Promise\Each;
use GuzzleHttp\Promise\PromiseInterface;
use GuzzleHttp\Promise\PromisorInterface;
use Throwable;
use function Aws\filter;
use function Aws\map;
final class DirectoryDownloader implements PromisorInterface
{
/** @var S3ClientInterface */
private S3ClientInterface $s3Client;
/** @var array */
private array $config;
/** @var Closure */
private Closure $downloadFile;
/** @var int */
private int $objectsDownloaded = 0;
/** @var int */
private int $objectsFailed = 0;
/** @var DownloadDirectoryRequest */
private DownloadDirectoryRequest $downloadDirectoryRequest;
/**
* @param S3ClientInterface $s3Client
* @param array $config
* @param Closure $downloadFile A closure that receives (S3ClientInterface, DownloadFileRequest) and returns PromiseInterface
* @param DownloadDirectoryRequest $downloadDirectoryRequest
*/
public function __construct(
S3ClientInterface $s3Client,
array $config,
Closure $downloadFile,
DownloadDirectoryRequest $downloadDirectoryRequest
) {
$this->s3Client = $s3Client;
$this->config = $config;
$this->downloadFile = $downloadFile;
$this->downloadDirectoryRequest = $downloadDirectoryRequest;
// Validations
$this->downloadDirectoryRequest->updateConfigWithDefaults(
$this->config
);
$this->downloadDirectoryRequest->validateConfig();
$this->downloadDirectoryRequest->validateDestinationDirectory();
MetricsBuilder::appendMetricsCaptureMiddleware(
$this->s3Client->getHandlerList(),
MetricsBuilder::S3_TRANSFER_DOWNLOAD_DIRECTORY
);
}
/**
* @return PromiseInterface
*
* @throws Throwable
*/
public function promise(): PromiseInterface
{
$this->objectsDownloaded = 0;
$this->objectsFailed = 0;
$destinationDirectory = $this->downloadDirectoryRequest->getDestinationDirectory();
$sourceBucket = $this->downloadDirectoryRequest->getSourceBucket();
$progressTracker = $this->downloadDirectoryRequest->getProgressTracker();
$config = $this->downloadDirectoryRequest->getConfig();
if ($progressTracker === null && $config['track_progress']) {
$progressTracker = new DirectoryProgressTracker();
}
$listArgs = [
'Bucket' => $sourceBucket,
] + ($config['list_objects_v2_args'] ?? []);
$s3Prefix = $config['s3_prefix'] ?? null;
if (empty($listArgs['Prefix']) && $s3Prefix !== null) {
$listArgs['Prefix'] = $s3Prefix;
}
// MUST BE NULL
$listArgs['Delimiter'] = null;
$objects = $this->s3Client
->getPaginator('ListObjectsV2', $listArgs)
->search('Contents[]');
$filter = $config['filter'] ?? null;
$objects = filter($objects, function (array $object) use ($filter) {
$key = $object['Key'] ?? '';
if ($filter !== null) {
return call_user_func($filter, $key) && !str_ends_with($key, "/");
}
return !str_ends_with($key, "/");
});
$objects = map($objects, function (array $object) use ($sourceBucket) {
return [
'uri' => self::formatAsS3URI($sourceBucket, $object['Key']),
'size' => $object['Size'] ?? 0,
];
});
$downloadObjectRequestModifier = $config['download_object_request_modifier']
?? null;
$failurePolicyCallback = $config['failure_policy'] ?? null;
$directoryListeners = $this->downloadDirectoryRequest->getListeners();
$singleObjectListeners = $this->downloadDirectoryRequest->getSingleObjectListeners();
$aggregator = new DirectoryTransferProgressAggregator(
identifier: $this->buildDirectoryIdentifier(
$sourceBucket,
$destinationDirectory,
$s3Prefix
),
totalBytes: 0,
totalFiles: 0,
directoryListeners: $directoryListeners,
directoryProgressTracker: $progressTracker
);
$maxConcurrency = $config['max_concurrency']
?? DownloadDirectoryRequest::DEFAULT_MAX_CONCURRENCY;
$aggregator->notifyDirectoryInitiated([
'bucket' => $sourceBucket,
'destination_directory' => $destinationDirectory,
's3_prefix' => $s3Prefix,
]);
return Each::ofLimitAll(
$this->createDownloadPromises(
$objects,
$config,
$destinationDirectory,
$sourceBucket,
$s3Prefix,
$downloadObjectRequestModifier,
$failurePolicyCallback,
$aggregator,
$singleObjectListeners
),
$maxConcurrency
)->then(function () use ($aggregator) {
$aggregator->notifyDirectoryComplete([
'objects_downloaded' => $this->objectsDownloaded,
'objects_failed' => $this->objectsFailed,
]);
return new DownloadDirectoryResult(
$this->objectsDownloaded,
$this->objectsFailed
);
})->otherwise(function (Throwable $reason) use ($aggregator) {
$aggregator->notifyDirectoryFail($reason);
return new DownloadDirectoryResult(
$this->objectsDownloaded,
$this->objectsFailed,
$reason
);
});
}
/**
* @param iterable $objects
* @param array $config
* @param string $destinationDirectory
* @param string $sourceBucket
* @param string|null $s3Prefix
* @param callable|null $downloadObjectRequestModifier
* @param callable|null $failurePolicyCallback
* @param DirectoryTransferProgressAggregator $aggregator
* @param array $singleObjectListeners
*
* @return \Generator
* @throws Throwable
*/
private function createDownloadPromises(
iterable $objects,
array $config,
string $destinationDirectory,
string $sourceBucket,
?string $s3Prefix,
?callable $downloadObjectRequestModifier,
?callable $failurePolicyCallback,
DirectoryTransferProgressAggregator $aggregator,
array $singleObjectListeners
): \Generator
{
$s3Delimiter = '/';
foreach ($objects as $object) {
$aggregator->incrementTotals($object['size'] ?? 0);
$bucketAndKeyArray = S3TransferManager::s3UriAsBucketAndKey($object['uri']);
$objectKey = $bucketAndKeyArray['Key'];
if ($s3Prefix !== null && str_contains($objectKey, $s3Delimiter)) {
$prefixToStrip = str_ends_with($s3Prefix, $s3Delimiter)
? $s3Prefix
: $s3Prefix . $s3Delimiter;
$objectKey = substr($objectKey, strlen($prefixToStrip));
}
// CONVERT THE KEY DIR SEPARATOR TO OS BASED DIR SEPARATOR
if (DIRECTORY_SEPARATOR !== $s3Delimiter) {
$objectKey = str_replace(
$s3Delimiter,
DIRECTORY_SEPARATOR,
$objectKey
);
}
$destinationFile = $destinationDirectory . DIRECTORY_SEPARATOR . $objectKey;
if ($this->resolvesOutsideTargetDirectory($destinationFile, $objectKey)) {
throw new S3TransferException(
"Cannot download key $objectKey "
."its relative path resolves outside the parent directory."
);
}
$requestArgs = $this->downloadDirectoryRequest->getDownloadRequestArgs();
foreach ($bucketAndKeyArray as $key => $value) {
$requestArgs[$key] = $value;
}
if ($downloadObjectRequestModifier !== null) {
call_user_func($downloadObjectRequestModifier, $requestArgs);
}
$downloadFile = $this->downloadFile;
$downloadConfig = $config;
$downloadConfig['track_progress'] = false;
yield $downloadFile(
$this->s3Client,
new DownloadFileRequest(
destination: $destinationFile,
failsWhenDestinationExists: $config['fails_when_destination_exists'] ?? false,
downloadRequest: new DownloadRequest(
source: null, // Source has been provided in the request args
downloadRequestArgs: $requestArgs,
config: array_merge(
$downloadConfig,
[
'target_part_size_bytes' => $config['target_part_size_bytes'] ?? 0,
]
),
downloadHandler: null,
listeners: array_merge(
[$aggregator],
array_map(
fn($listener) => clone $listener,
$singleObjectListeners
)
),
progressTracker: null
)
),
)->then(function () {
$this->objectsDownloaded++;
})->otherwise(function (Throwable $reason) use (
$sourceBucket,
$destinationDirectory,
$failurePolicyCallback,
$requestArgs
) {
$this->objectsFailed++;
if ($failurePolicyCallback !== null) {
call_user_func(
$failurePolicyCallback,
$requestArgs,
[
"destination_directory" => $destinationDirectory,
"bucket" => $sourceBucket,
],
$reason,
new DownloadDirectoryResult(
$this->objectsDownloaded,
$this->objectsFailed
)
);
return;
}
throw $reason;
});
}
}
/**
* @param string $bucket
* @param string $key
*
* @return string
*/
private static function formatAsS3URI(string $bucket, string $key): string
{
return "s3://$bucket/$key";
}
/**
* @param string $sink
* @param string $objectKey
*
* @return bool
*/
private function resolvesOutsideTargetDirectory(
string $sink,
string $objectKey
): bool
{
$resolved = [];
$sections = explode(DIRECTORY_SEPARATOR, $sink);
$targetSectionsLength = count(explode(DIRECTORY_SEPARATOR, $objectKey));
$targetSections = array_slice($sections, -($targetSectionsLength + 1));
$targetDirectory = $targetSections[0];
foreach ($targetSections as $section) {
if ($section === '.' || $section === '') {
continue;
}
if ($section === '..') {
array_pop($resolved);
if (empty($resolved) || $resolved[0] !== $targetDirectory) {
return true;
}
} else {
$resolved []= $section;
}
}
return false;
}
/**
* @param string $bucket
* @param string $destinationDirectory
* @param string|null $s3Prefix
*
* @return string
*/
private function buildDirectoryIdentifier(
string $bucket,
string $destinationDirectory,
?string $s3Prefix
): string {
return sprintf(
'download:%s/%s->%s',
$bucket,
$s3Prefix ?? '',
rtrim($destinationDirectory, DIRECTORY_SEPARATOR)
);
}
}

View File

@@ -0,0 +1,364 @@
<?php
namespace Aws\S3\S3Transfer;
use Aws\MetricsBuilder;
use Aws\S3\S3Transfer\Exception\S3TransferException;
use Aws\S3\S3Transfer\Models\UploadDirectoryRequest;
use Aws\S3\S3Transfer\Models\UploadDirectoryResult;
use Aws\S3\S3Transfer\Models\UploadRequest;
use Aws\S3\S3Transfer\Models\UploadResult;
use Aws\S3\S3Transfer\Progress\DirectoryProgressTracker;
use Aws\S3\S3Transfer\Progress\DirectoryTransferProgressAggregator;
use Aws\S3\S3ClientInterface;
use Closure;
use FilesystemIterator;
use GuzzleHttp\Promise\Each;
use GuzzleHttp\Promise\PromiseInterface;
use GuzzleHttp\Promise\PromisorInterface;
use RecursiveDirectoryIterator;
use RecursiveIteratorIterator;
use Throwable;
use function Aws\filter;
final class DirectoryUploader implements PromisorInterface
{
/** @var array */
private array $config;
/** @var S3ClientInterface */
private S3ClientInterface $s3Client;
/** @var Closure */
private Closure $uploadObject;
/** @var int */
private int $objectsUploaded = 0;
/** @var int */
private int $objectsFailed = 0;
/** @var UploadDirectoryRequest */
private UploadDirectoryRequest $uploadDirectoryRequest;
/**
* @param S3ClientInterface $s3Client
* @param array $config
* @param Closure $uploadObject A closure that receives
* (S3ClientInterface, UploadRequest) and returns PromiseInterface
* @param UploadDirectoryRequest $uploadDirectoryRequest
*/
public function __construct(
S3ClientInterface $s3Client,
array $config,
Closure $uploadObject,
UploadDirectoryRequest $uploadDirectoryRequest
) {
$this->s3Client = $s3Client;
$this->config = $config;
$this->uploadObject = $uploadObject;
$this->uploadDirectoryRequest = $uploadDirectoryRequest;
// Validations
$this->uploadDirectoryRequest->updateConfigWithDefaults(
$this->config
);
$this->uploadDirectoryRequest->validateSourceDirectory();
$this->uploadDirectoryRequest->validateConfig();
MetricsBuilder::appendMetricsCaptureMiddleware(
$this->s3Client->getHandlerList(),
MetricsBuilder::S3_TRANSFER_UPLOAD_DIRECTORY
);
}
/**
* @return PromiseInterface
*
* @throws Throwable
*/
public function promise(): PromiseInterface
{
$this->objectsUploaded = 0;
$this->objectsFailed = 0;
$config = $this->uploadDirectoryRequest->getConfig();
$filter = $config['filter'] ?? null;
$uploadObjectRequestModifier = $config['upload_object_request_modifier']
?? null;
$failurePolicyCallback = $config['failure_policy'] ?? null;
$sourceDirectory = $this->uploadDirectoryRequest->getSourceDirectory();
$files = $this->iterateSourceFiles(
$sourceDirectory,
$config,
$filter
);
$baseDir = rtrim($sourceDirectory, '/') . DIRECTORY_SEPARATOR;
$delimiter = $config['s3_delimiter'] ?? '/';
$s3Prefix = $config['s3_prefix'] ?? '';
if ($s3Prefix !== '' && !str_ends_with($s3Prefix, '/')) {
$s3Prefix .= '/';
}
$targetBucket = $this->uploadDirectoryRequest->getTargetBucket();
$directoryProgressTracker = $this->uploadDirectoryRequest->getProgressTracker();
if ($directoryProgressTracker === null
&& ($config['track_progress']
?? ($this->config['track_progress'] ?? false))) {
$directoryProgressTracker = new DirectoryProgressTracker();
}
$directoryListeners = $this->uploadDirectoryRequest->getListeners();
$singleObjectListeners = $this->uploadDirectoryRequest->getSingleObjectListeners();
$aggregator = new DirectoryTransferProgressAggregator(
identifier: $this->buildDirectoryIdentifier(
$sourceDirectory,
$targetBucket,
$s3Prefix
),
totalBytes: 0,
totalFiles: 0,
directoryListeners: $directoryListeners,
directoryProgressTracker: $directoryProgressTracker,
);
$maxConcurrency = $config['max_concurrency']
?? UploadDirectoryRequest::DEFAULT_MAX_CONCURRENCY;
$aggregator->notifyDirectoryInitiated([
'source_directory' => $sourceDirectory,
'bucket' => $targetBucket,
's3_prefix' => $s3Prefix,
]);
return Each::ofLimitAll(
$this->createUploadPromises(
$files,
$config,
$uploadObjectRequestModifier,
$failurePolicyCallback,
$sourceDirectory,
$targetBucket,
$baseDir,
$delimiter,
$s3Prefix,
$aggregator,
$singleObjectListeners
),
$maxConcurrency
)->then(function () use ($aggregator) {
$aggregator->notifyDirectoryComplete([
'objects_uploaded' => $this->objectsUploaded,
'objects_failed' => $this->objectsFailed,
]);
return new UploadDirectoryResult(
$this->objectsUploaded,
$this->objectsFailed
);
})->otherwise(function (Throwable $reason) use ($aggregator) {
$aggregator->notifyDirectoryFail($reason);
return new UploadDirectoryResult(
$this->objectsUploaded,
$this->objectsFailed,
$reason
);
});
}
/**
* @param iterable $files
* @param array $config
* @param callable|null $uploadObjectRequestModifier
* @param callable|null $failurePolicyCallback
* @param string $sourceDirectory
* @param string $targetBucket
* @param string $baseDir
* @param string $delimiter
* @param string $s3Prefix
* @param DirectoryTransferProgressAggregator $aggregator
* @param array $singleObjectListeners
*
* @return \Generator
* @throws Throwable
*/
private function createUploadPromises(
iterable $files,
array $config,
?callable $uploadObjectRequestModifier,
?callable $failurePolicyCallback,
string $sourceDirectory,
string $targetBucket,
string $baseDir,
string $delimiter,
string $s3Prefix,
DirectoryTransferProgressAggregator $aggregator,
array $singleObjectListeners
): \Generator
{
foreach ($files as $file) {
$fileSize = filesize($file);
$aggregator->incrementTotals(
$fileSize !== false ? $fileSize : 0
);
$relativePath = substr($file, strlen($baseDir));
if (str_contains($relativePath, $delimiter) && $delimiter !== '/') {
throw new S3TransferException(
"The filename `$relativePath` must not contain the provided delimiter `$delimiter`"
);
}
$objectKey = $s3Prefix.$relativePath;
$objectKey = str_replace(
DIRECTORY_SEPARATOR,
$delimiter,
$objectKey
);
$uploadRequestArgs = $this->uploadDirectoryRequest->getUploadRequestArgs();
$uploadRequestArgs['Bucket'] = $targetBucket;
$uploadRequestArgs['Key'] = $objectKey;
if ($uploadObjectRequestModifier !== null) {
$uploadObjectRequestModifier($uploadRequestArgs);
}
$uploadObject = $this->uploadObject;
$uploadConfig = $config;
$uploadConfig['track_progress'] = false;
yield $uploadObject(
$this->s3Client,
new UploadRequest(
$file,
$uploadRequestArgs,
$uploadConfig,
listeners: array_merge(
[$aggregator],
array_map(
fn($listener) => clone $listener,
$singleObjectListeners
)
),
progressTracker: null
)
)->then(function (UploadResult $response) {
$this->objectsUploaded++;
return $response;
})->otherwise(function (Throwable $reason) use (
$targetBucket,
$sourceDirectory,
$failurePolicyCallback,
$uploadRequestArgs
) {
$this->objectsFailed++;
if($failurePolicyCallback !== null) {
call_user_func(
$failurePolicyCallback,
$uploadRequestArgs,
[
"source_directory" => $sourceDirectory,
"bucket_to" => $targetBucket,
],
$reason,
new UploadDirectoryResult(
$this->objectsUploaded,
$this->objectsFailed
)
);
return;
}
throw $reason;
});
}
}
/**
* Iterate source files applying traversal config and filter.
*
* @param string $sourceDirectory
* @param array $config
* @param callable|null $filter
*
* @return \Generator
*/
private function iterateSourceFiles(
string $sourceDirectory,
array $config,
?callable $filter
): \Generator {
$dirIterator = new RecursiveDirectoryIterator($sourceDirectory);
$flags = FilesystemIterator::SKIP_DOTS;
if ($config['follow_symbolic_links'] ?? false) {
$flags |= FilesystemIterator::FOLLOW_SYMLINKS;
}
$dirIterator->setFlags($flags);
if ($config['recursive'] ?? false) {
$dirIterator = new RecursiveIteratorIterator(
$dirIterator,
RecursiveIteratorIterator::SELF_FIRST
);
if (isset($config['max_depth'])) {
$dirIterator->setMaxDepth($config['max_depth']);
}
}
$dirVisited = [];
$files = filter(
$dirIterator,
function ($file) use ($filter, &$dirVisited) {
if (is_dir($file)) {
// To avoid circular symbolic links traversal
$dirRealPath = realpath($file);
if ($dirRealPath !== false) {
if ($dirVisited[$dirRealPath] ?? false) {
throw new S3TransferException(
"A circular symbolic link traversal has been detected at $file -> $dirRealPath"
);
}
$dirVisited[$dirRealPath] = true;
}
}
if ($filter !== null) {
return !is_dir($file) && $filter($file);
}
return !is_dir($file);
}
);
foreach ($files as $file) {
yield $file;
}
}
/**
* @param string $sourceDirectory
* @param string $bucket
* @param string $s3Prefix
*
* @return string
*/
private function buildDirectoryIdentifier(
string $sourceDirectory,
string $bucket,
string $s3Prefix
): string {
return sprintf(
'upload:%s->%s/%s',
rtrim($sourceDirectory, DIRECTORY_SEPARATOR),
$bucket,
$s3Prefix
);
}
}

View File

@@ -0,0 +1,214 @@
<?php
namespace Aws\S3\S3Transfer\Models;
use Aws\S3\S3Transfer\Exception\S3TransferException;
abstract class AbstractResumableTransfer
{
protected const VERSION = '1.0';
protected const SIGNATURE_CHECKSUM_ALGORITHM = 'sha256';
/** @var string */
protected string $resumeFilePath;
/** @var array */
protected array $requestArgs;
/** @var array */
protected array $config;
/** @var array */
protected array $currentSnapshot;
/**
* @param string $resumeFilePath
* @param array $requestArgs The request arguments used for the transfer
* @param array $config The config used in the request
* @param array $currentSnapshot The current progress snapshot
*/
public function __construct(
string $resumeFilePath,
array $requestArgs,
array $config,
array $currentSnapshot,
) {
// Resume files must end in .resume
if (!str_ends_with($resumeFilePath, '.resume')) {
$resumeFilePath .= '.resume';
}
$this->resumeFilePath = $resumeFilePath;
$this->requestArgs = $requestArgs;
$this->config = $config;
$this->currentSnapshot = $currentSnapshot;
}
/**
* Serialize the resumable state to JSON format.
*
* @return string JSON-encoded state
*/
public abstract function toJson(): string;
/**
* Deserialize a resumable state from JSON format.
*
* @param string $json JSON-encoded state
* @return self
* @throws S3TransferException If the JSON is invalid or missing required fields
*/
public static abstract function fromJson(string $json): self;
/**
* Load a resumable state from a file.
*
* @param string $filePath Path to the resume file
* @return self
* @throws S3TransferException If the file cannot be read or is invalid
*/
public static abstract function fromFile(string $filePath): self;
/**
* Save the resumable state to a file.
* When a file path is not provided by default it will use
* the `resumeFilePath` property.
*
* @param string|null $filePath Path where the resume file should be saved
*/
public function toFile(?string $filePath = null): void
{
$saveFileToPath = $filePath ?? $this->resumeFilePath;
// Ensure directory exists
$resumeDir = dirname($saveFileToPath);
if (!is_dir($resumeDir)
&& !mkdir($resumeDir, 0755, true)) {
throw new S3TransferException(
"Failed to create resume directory: $resumeDir"
);
}
$json = $this->toJson();
$signature = hash(self::SIGNATURE_CHECKSUM_ALGORITHM, $json);
$dataWithSignature = json_encode([
'signature' => $signature,
'data' => json_decode($json, true)
], JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES);
$result = file_put_contents($saveFileToPath, $dataWithSignature, LOCK_EX);
if ($result === false) {
throw new S3TransferException(
"Failed to write resume file: $saveFileToPath"
);
}
}
/**
* @param string|null $filePath
*
* @return void
*/
public function deleteResumeFile(?string $filePath = null): void
{
$resumeFilePath = $filePath ?? $this->resumeFilePath;
if (file_exists($resumeFilePath)) {
unlink($resumeFilePath);
}
}
/**
* @return string
*/
public function getResumeFilePath(): string
{
return $this->resumeFilePath;
}
/**
* @return array
*/
public function getRequestArgs(): array
{
return $this->requestArgs;
}
/**
* @return array
*/
public function getConfig(): array
{
return $this->config;
}
/**
* @return string
*/
public function getBucket(): string
{
return $this->requestArgs['Bucket'];
}
/**
* @return string
*/
public function getKey(): string
{
return $this->requestArgs['Key'];
}
/**
* @return array
*/
public function getCurrentSnapshot(): array
{
return $this->currentSnapshot;
}
/**
* Update the current snapshot.
*
* @param array $snapshot The new snapshot data
*/
public function updateCurrentSnapshot(array $snapshot): void
{
$this->currentSnapshot = $snapshot;
}
/**
* Check if a file path is a valid resume file.
*
* @param string $filePath
* @return bool
*/
public static function isResumeFile(string $filePath): bool
{
// Check file extension
if (!str_ends_with($filePath, '.resume')) {
return false;
}
// Check if file exists and is readable
if (!file_exists($filePath) || !is_readable($filePath)) {
return false;
}
// Validate file content by attempting to parse it
try {
$json = file_get_contents($filePath);
if ($json === false) {
return false;
}
$data = json_decode($json, true);
if (json_last_error() !== JSON_ERROR_NONE) {
return false;
}
// Check for required version field
return isset($data['data']) && isset($data['signature']);
} catch (\Exception $e) {
return false;
}
}
}

View File

@@ -2,7 +2,6 @@
namespace Aws\S3\S3Transfer\Models;
use Aws\S3\S3ClientInterface;
use Aws\S3\S3Transfer\Progress\AbstractTransferListener;
use InvalidArgumentException;
@@ -19,27 +18,26 @@ abstract class AbstractTransferRequest
protected ?AbstractTransferListener $progressTracker;
/** @var array */
protected array $config;
protected array $singleObjectListeners;
/** @var S3ClientInterface|null */
private ?S3ClientInterface $s3Client;
/** @var array */
protected array $config;
/**
* @param array $listeners
* @param AbstractTransferListener|null $progressTracker
* @param array $config
* @param S3ClientInterface|null $s3Client
*/
public function __construct(
array $listeners,
?AbstractTransferListener $progressTracker,
array $config,
?S3ClientInterface $s3Client = null,
array $singleObjectListeners = []
) {
$this->listeners = $listeners;
$this->progressTracker = $progressTracker;
$this->singleObjectListeners = $singleObjectListeners;
$this->config = $config;
$this->s3Client = $s3Client;
}
/**
@@ -62,6 +60,16 @@ public function getProgressTracker(): ?AbstractTransferListener
return $this->progressTracker;
}
/**
* Get listeners that should receive single-object events.
*
* @return array
*/
public function getSingleObjectListeners(): array
{
return $this->singleObjectListeners;
}
/**
* @return array
*/
@@ -70,14 +78,6 @@ public function getConfig(): array
return $this->config;
}
/**
* @return S3ClientInterface|null
*/
public function getS3Client(): ?S3ClientInterface
{
return $this->s3Client;
}
/**
* @param array $defaultConfig
*

View File

@@ -68,11 +68,9 @@ final class DownloadDirectoryRequest extends AbstractTransferRequest
* - MaxKeys: (int) Sets the maximum number of keys returned in the response.
* - Prefix: (string) To limit the response to keys that begin with the
* specified prefix.
* @param AbstractTransferListener[] $listeners The listeners for watching
* transfer events. Each listener will be cloned per file upload.
* @param AbstractTransferListener|null $progressTracker Ideally the progress
* tracker implementation provided here should be able to track multiple
* transfers at once. Please see MultiProgressTracker implementation.
* @param AbstractTransferListener[] $listeners Directory-level listeners that receive directory snapshots.
* @param AbstractTransferListener|null $progressTracker Directory-level progress tracker.
* @param array $singleObjectListeners Per-object listeners that receive single-object snapshots.
*/
public function __construct(
string $sourceBucket,
@@ -80,9 +78,15 @@ public function __construct(
array $downloadRequestArgs = [],
array $config = [],
array $listeners = [],
?AbstractTransferListener $progressTracker = null
?AbstractTransferListener $progressTracker = null,
array $singleObjectListeners = []
) {
parent::__construct($listeners, $progressTracker, $config);
parent::__construct(
$listeners,
$progressTracker,
$config,
$singleObjectListeners
);
if (ArnParser::isArn($sourceBucket)) {
$sourceBucket = ArnParser::parse($sourceBucket)->getResource();
}

Some files were not shown because too many files have changed in this diff Show More