├── .coveralls.yml ├── .gitignore ├── .travis.yml ├── README.md ├── composer.json ├── phpunit.xml ├── src └── AliyunFC │ ├── Auth.php │ ├── Client.php │ └── util.php └── test ├── bootstrap.php ├── client_test.php ├── counter.zip ├── index.zip ├── index_http.zip ├── new_index.zip └── versioning_test.php /.coveralls.yml: -------------------------------------------------------------------------------- 1 | coverage_clover: coverage.xml 2 | json_path: coverage.json 3 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | vendor 2 | composer.lock 3 | coverage.xml 4 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: php 2 | php: 3 | - 7.2 4 | - 7.1 5 | - 7.0 6 | - 5.6 7 | install: 8 | - composer self-update 9 | - composer install --no-interaction 10 | script: 11 | - php vendor/bin/phpunit -c phpunit.xml 12 | after_success: 13 | - php vendor/bin/coveralls -v 14 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | Aliyun FunctionCompute Php SDK 2 | ================================= 3 | 4 | [![Latest Stable Version](https://img.shields.io/packagist/v/aliyunfc/fc-php-sdk.svg)](https://packagist.org/packages/aliyunfc/fc-php-sdk) 5 | [![Build Status](https://travis-ci.org/aliyun/fc-php-sdk.svg?branch=master)](https://travis-ci.org/aliyun/fc-php-sdk) 6 | [![Coverage Status](https://coveralls.io/repos/github/aliyun/fc-php-sdk/badge.svg?branch=master)](https://coveralls.io/github/aliyun/fc-php-sdk?branch=master) 7 | 8 | 9 | Overview 10 | -------- 11 | 12 | The SDK of this version is dependent on the third-party HTTP library [guzzlehttp/guzzle](https://github.com/guzzle/guzzle). 13 | 14 | 15 | Running environment 16 | ------------------- 17 | 18 | - PHP 5.6+. 19 | - cURL extension. 20 | 21 | 22 | Installation 23 | ------------------- 24 | 25 | The recommended way to install fc-php-sdk is through Composer. 26 | 27 | - install composer: https://getcomposer.org/doc/00-intro.md 28 | - install fc-php-sdk 29 | 30 | ```bash 31 | $ composer require aliyunfc/fc-php-sdk 32 | ``` 33 | 34 | You can also declare the dependency on Alibaba Cloud FC SDK for PHP in the composer.json file. 35 | 36 | ```json 37 | "require": { 38 | "aliyunfc/fc-php-sdk": "~1.2" 39 | } 40 | ``` 41 | 42 | Then run `composer install --no-dev` to install the dependency. After the Composer Dependency Manager is installed, import the dependency in your PHP code: 43 | 44 | ```php 45 | require_once __DIR__ . '/vendor/autoload.php'; 46 | ``` 47 | 48 | Getting started 49 | ------------------- 50 | 51 | ```php 52 | '', 61 | "accessKeyID" =>'', 62 | "accessKeySecret" =>'' 63 | ]); 64 | 65 | // Create service. 66 | $fcClient->createService('service_name'); 67 | 68 | /* 69 | Create function. 70 | the current directory has a main.zip file (main.php which has a function of my_handler) 71 | set environment variables {'testKey': 'testValue'} 72 | */ 73 | $fcClient->createFunction( 74 | 'service_name', 75 | array( 76 | 'functionName' => $functionName, 77 | 'handler' => 'index.handler', 78 | 'runtime' => 'php7.2', 79 | 'memorySize' => 128, 80 | 'code' => array( 81 | 'zipFile' => base64_encode(file_get_contents(__DIR__ . '/main.zip')), 82 | ), 83 | 'description' => "test function", 84 | 'environmentVariables' => ['testKey' => 'testValue'], 85 | ) 86 | ); 87 | 88 | //Invoke function synchronously. 89 | $fcClient->invokeFunction('service_name', 'function_name'); 90 | 91 | /* 92 | Create function with initializer. 93 | the current directory has a main.zip file (main.php which hava functions of my_handler and my_initializer) 94 | set environment variables {'testKey': 'testValue'} 95 | */ 96 | $fcClient->createFunction( 97 | 'service_name_with_initializer', 98 | array( 99 | 'functionName' => $functionName, 100 | 'handler' => 'index.handler', 101 | 'initializer' => 'index.initializer', 102 | 'runtime' => 'php7.2', 103 | 'memorySize' => 128, 104 | 'code' => array( 105 | 'zipFile' => base64_encode(file_get_contents(__DIR__ . '/main.zip')), 106 | ), 107 | 'description' => "test function with initializer", 108 | 'environmentVariables' => ['testKey' => 'testValue'], 109 | ) 110 | ); 111 | 112 | //Invoke function synchronously. 113 | $fcClient->invokeFunction('service_name_with_initializer', 'function_name'); 114 | 115 | //Create trigger, for example: oss trigger 116 | $prefix = 'pre'; 117 | $suffix = 'suf'; 118 | $triggerConfig = [ 119 | 'events' => ['oss:ObjectCreated:*'], 120 | 'filter' => [ 121 | 'key' => [ 122 | 'prefix' => $prefix, 123 | 'suffix' => $suffix, 124 | ], 125 | ], 126 | ]; 127 | $sourceArn = 'acs:oss:cn-shanghai:12345678:bucketName'; 128 | $invocationRole = 'acs:ram::12345678:role/aliyunosseventnotificationrole'; 129 | $ret = $fcClient->createTrigger( 130 | 'service_name', 131 | 'function_name', 132 | [ 133 | 'triggerName' => 'trigger_name', 134 | 'triggerType' => 'oss', 135 | 'invocationRole' => $invocationRole, 136 | 'sourceArn' => $sourceArn, 137 | 'triggerConfig' => $triggerConfig, 138 | ] 139 | ); 140 | 141 | 142 | //Invoke a function with a input parameter. 143 | $fcClient->invokeFunction('service_name', 'function_name', $payload='hello_world'); 144 | 145 | 146 | // Invoke function asynchronously. 147 | $fcClient->invokeFunction('service_name', 'function_name', 'hello world', ['x-fc-invocation-type' => 'Async']); 148 | 149 | // List services. 150 | $fcClient->listServices(); 151 | 152 | //List functions with prefix and limit. 153 | $fcClient->listFunctions('service_name', ['prefix' => 'hello', "limit" => 2]); 154 | 155 | //List triggers 156 | $fcClient->listTriggers('service_name', 'function_name'); 157 | 158 | //Delete trigger 159 | $fcClient->deleteTrigger('service_name', 'function_name', 'trigger_name'); 160 | 161 | //Delete function 162 | $fcClient->deleteFunction('service_name', 'function_name'); 163 | 164 | //Delete service. 165 | $fcClient->deleteService('service_name'); 166 | 167 | ``` 168 | 169 | Testing 170 | ------- 171 | 172 | To run the tests, please set the access key id/secret, endpoint as environment variables. 173 | Take the Linux system for example: 174 | 175 | ```bash 176 | $ export ENDPOINT= 177 | $ export ACCESS_KEY_ID= 178 | $ export ACCESS_KEY_SECRET= 179 | $ export ACCOUNT_ID= 180 | ... 181 | ``` 182 | For details, refer to `client_test.php` 183 | 184 | Run the test in the following method: 185 | 186 | ```bash 187 | $ phpunit 188 | ``` 189 | 190 | More resources 191 | -------------- 192 | - [Aliyun FunctionCompute docs](https://help.aliyun.com/product/50980.html) 193 | 194 | Contacting us 195 | ------------- 196 | - [Links](https://help.aliyun.com/document_detail/53087.html) 197 | 198 | License 199 | ------- 200 | - [MIT](https://github.com/aliyun/fc-python-sdk/blob/master/LICENSE) 201 | 202 | -------------------------------------------------------------------------------- /composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "aliyunfc/fc-php-sdk", 3 | "description": "Aliyun FC SDK for PHP", 4 | "keywords": ["php", "fc", "fcunction compute", "aliyun"], 5 | "homepage": "http://www.aliyun.com/product/fc/", 6 | "type": "library", 7 | "license": "MIT", 8 | "authors": [ 9 | { 10 | "name": "aliyunfc", 11 | "email": "ls_huster@163.com" 12 | } 13 | ], 14 | "require": { 15 | "php":">=5.5", 16 | "guzzlehttp/guzzle": "~6.0" 17 | }, 18 | "require-dev" : { 19 | "phpunit/phpunit": "^4.8.35 || ^5.7 || ^6.4 || ^7.0", 20 | "satooshi/php-coveralls": "~1.0" 21 | }, 22 | "autoload": { 23 | "psr-4": {"AliyunFC\\": "src/AliyunFC"} 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /phpunit.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 14 | 15 | 16 | ./src/AliyunFC 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | ./test 26 | 27 | 28 | ./test 29 | 30 | 31 | 32 | -------------------------------------------------------------------------------- /src/AliyunFC/Auth.php: -------------------------------------------------------------------------------- 1 | access_key_id = trim($ak_id); 11 | $this->access_key_secret = trim($ak_secret); 12 | $this->security_token = trim($ak_secret_token); 13 | } 14 | 15 | public function getSecurityToken() { 16 | return $this->security_token; 17 | } 18 | 19 | private function base64UrlEncode($str) { 20 | $find = array('+', '/'); 21 | $replace = array('-', '_'); 22 | return str_replace($find, $replace, base64_encode($str)); 23 | } 24 | 25 | public function signRequest($method, $unescaped_path, $headers, $unescaped_queries = null) { 26 | /* 27 | Sign the request. See the spec for reference. 28 | https://help.aliyun.com/document_detail/52877.html 29 | @param $method: method of the http request. 30 | @param $headers: headers of the http request. 31 | @param $unescaped_path: unescaped path without queries of the http request. 32 | @return: the signature string. 33 | */ 34 | $content_md5 = isset($headers['content-md5']) ? $headers['content-md5'] : ''; 35 | $content_type = isset($headers['content-type']) ? $headers['content-type'] : ''; 36 | $date = isset($headers['date']) ? $headers['date'] : ''; 37 | $canonical_headers = $this->buildCanonicalHeaders($headers); 38 | $canonical_resource = $unescaped_path; 39 | 40 | if (is_array($unescaped_queries)) { 41 | $canonical_resource = $this->getSignResource($unescaped_path, $unescaped_queries); 42 | } 43 | 44 | $string_to_sign = implode("\n", 45 | [strtoupper($method), $content_md5, $content_type, $date, $canonical_headers . $canonical_resource]); 46 | 47 | //echo 'string to sign: ' . $string_to_sign . PHP_EOL; 48 | 49 | $h = hash_hmac('sha256', $string_to_sign, $this->access_key_secret, true); 50 | 51 | $signature = "FC " . $this->access_key_id . ":" . base64_encode($h); 52 | 53 | return $signature; 54 | } 55 | 56 | private function buildCanonicalHeaders($headers) { 57 | /* 58 | @param $headers: array 59 | @return: $Canonicalized header string. 60 | @return: String 61 | */ 62 | $canonical_headers = []; 63 | foreach ($headers as $k => $v) { 64 | $lower_key = trim(strtolower($k)); 65 | if (substr($lower_key, 0, 5) === 'x-fc-') { 66 | $canonical_headers[$lower_key] = $v; 67 | } 68 | } 69 | ksort($canonical_headers); 70 | $canonical = ''; 71 | foreach ($canonical_headers as $k => $v) { 72 | $canonical = $canonical . $k . ':' . $v . "\n"; 73 | } 74 | return $canonical; 75 | } 76 | 77 | private function getSignResource($unescaped_path, $unescaped_queries) { 78 | if (!is_array($unescaped_queries)) { 79 | throw new \Exception("`array` type required for queries"); 80 | } 81 | 82 | $params = []; 83 | foreach ($unescaped_queries as $key => $values) { 84 | if (is_string($values)) { 85 | $params[] = sprintf('%s=%s', $key, $values); 86 | continue; 87 | } 88 | if (count($values) > 0) { 89 | foreach ($values as $value) { 90 | $params[] = sprintf('%s=%s', $key, $value); 91 | } 92 | } else { 93 | $params[] = strval($key); 94 | } 95 | } 96 | ksort($params); 97 | 98 | $resource = $unescaped_path . "\n" . implode("\n", $params); 99 | 100 | return $resource; 101 | } 102 | } 103 | -------------------------------------------------------------------------------- /src/AliyunFC/Client.php: -------------------------------------------------------------------------------- 1 | endpoint = $this->normalizeEndpoint($options['endpoint']); 22 | $this->apiVersion = '2016-08-15'; 23 | $this->userAgent = sprintf('aliyun-fc-sdk-v%s.php-%s.%s-%s-%s', $this->version, phpversion(), 24 | php_uname("s"), php_uname("r"), php_uname("m")); 25 | 26 | $security_token = isset($options['securityToken']) ? $options['securityToken'] : ''; 27 | $this->auth = new Auth($options['accessKeyID'], $options['accessKeySecret'], $security_token); 28 | $this->timeout = isset($options['timeout']) ? $options['timeout'] : 60; 29 | $this->host = $this->getHost(); 30 | } 31 | 32 | private function normalizeEndpoint($url) { 33 | if (!((substr($url, 0, 7) === 'http://') || (substr($url, 0, 8) === 'https://'))) { 34 | return 'https://' . $url; 35 | } 36 | return trim($url); 37 | } 38 | 39 | private function getHost() { 40 | if (substr($this->endpoint, 0, 7) === 'http://') { 41 | return substr($this->endpoint, 7); 42 | } 43 | if (substr($this->endpoint, 0, 8) === 'https://') { 44 | return substr($this->endpoint, 8); 45 | } 46 | return trim($this->endpoint); 47 | } 48 | 49 | private function buildCommonHeaders($method, $path, $customHeaders = [], $unescapedQueries = null) { 50 | $headers = array( 51 | 'host' => $this->host, 52 | 'date' => gmdate('D, d M Y H:i:s T'), 53 | 'content-type' => 'application/json', 54 | 'content-length' => '0', 55 | 'user-agent' => $this->userAgent, 56 | ); 57 | if ($this->auth->getSecurityToken() != '') { 58 | $headers['x-fc-security-token'] = $this->auth->getSecurityToken(); 59 | } 60 | 61 | if (count($customHeaders) > 0) { 62 | $headers = array_merge($headers, $customHeaders); 63 | } 64 | 65 | //Sign the request and set the signature to headers. 66 | $headers['authorization'] = $this->auth->signRequest($method, $path, $headers, $unescapedQueries); 67 | 68 | return $headers; 69 | } 70 | 71 | private function doRequest($method, $path, $headers, $data = null, $query = []) { 72 | /* 73 | @param string $method 74 | @param string $path 75 | @param array $headers Extra headers to send with the request 76 | @param string in the body for POST requests 77 | @param array $query $data Data to send either as a query string for GET/HEAD requests 78 | @return array 79 | */ 80 | $url = $this->endpoint . $path; 81 | $client = new \GuzzleHttp\Client(["timeout" => $this->timeout]); 82 | 83 | $options = []; 84 | if ($headers) { 85 | $options['headers'] = $headers; 86 | } 87 | 88 | if ($data) { 89 | $options['body'] = $data; 90 | } 91 | 92 | if ($query) { 93 | $options['query'] = $query; 94 | } 95 | $res = $client->request($method, $url, $options); 96 | 97 | $respStatusCode = $res->getStatusCode(); 98 | $respBody = $res->getBody()->getContents(); 99 | $rid = $res->getHeaderLine('X-Fc-Request-Id'); 100 | 101 | if ($respStatusCode < 400) { 102 | $body = json_decode($respBody, $assoc = true); 103 | if (is_null($body)) { 104 | $body = $respBody; 105 | } 106 | return array( 107 | "headers" => $res->getHeaders(), 108 | "data" => $body, 109 | ); 110 | } elseif ($respStatusCode >= 400 && $respStatusCode < 500) { 111 | throw new \Exception( 112 | sprintf('Client error, status_code = %s, requestId = %s, detail = %s', $respStatusCode, $rid, $respBody), 113 | $respStatusCode); 114 | 115 | } elseif ($respStatusCode >= 500 && $respStatusCode < 600) { 116 | throw new \Exception( 117 | sprintf('Server error, status_code = %s, requestId = %s, detail = %s', $respStatusCode, $rid, $respBody), 118 | $respStatusCode); 119 | 120 | } else { 121 | throw new \Exception( 122 | sprintf('Unknown error, status_code = %s, requestId = %s, detail = %s', $respStatusCode, $rid, $respBody), 123 | $respStatusCode); 124 | } 125 | } 126 | 127 | public function doHttpRequest($method, $serviceName, $functionName, $path, $headers = [], $unescapedQueries = [], $data = null) { 128 | /* 129 | use for http trigger, http invoke 130 | @param string $method 131 | @param string $path 132 | @param array $headers Extra headers to send with the request 133 | @param string in the body for POST requests 134 | @param array|null $query $data Data to send either as a query string for GET/HEAD requests 135 | @return array 136 | */ 137 | if ($unescapedQueries) { 138 | assert(is_array($unescapedQueries)); 139 | } 140 | $path = $path ?: "/"; 141 | $path = sprintf('/%s/proxy/%s/%s%s', $this->apiVersion, $serviceName, $functionName, $path); 142 | $url = $this->endpoint . $path; 143 | $headers = $this->buildCommonHeaders($method, unescape($path), $headers, $unescapedQueries); 144 | 145 | $client = new \GuzzleHttp\Client(["timeout" => $this->timeout]); 146 | $options = []; 147 | if ($headers) { 148 | $options['headers'] = $headers; 149 | } 150 | 151 | if ($data) { 152 | $options['body'] = $data; 153 | } 154 | 155 | $options['query'] = $unescapedQueries; 156 | 157 | $res = $client->request($method, $url, $options); 158 | return $res; 159 | } 160 | 161 | public function createService($serviceName, $description = "", $options = [], $headers = []) { 162 | /* 163 | Create a service. see: https://help.aliyun.com/document_detail/52877.html#createservice 164 | @param serviceName: name of the service. 165 | @param description: (optional, string), detail description of the service. 166 | @param options: (optional, array) see: https://help.aliyun.com/document_detail/52877.html#service 167 | @param headers: (optional, array) 'x-fc-trace-id': string (a uuid to do the request tracing), etc 168 | @return: array 169 | */ 170 | $method = 'POST'; 171 | $path = sprintf('/%s/services', $this->apiVersion); 172 | $headers = $this->buildCommonHeaders($method, $path, $headers); 173 | 174 | $payload = array( 175 | 'serviceName' => $serviceName, 176 | 'description' => $description, 177 | ); 178 | 179 | if (count($options) > 0) { 180 | $payload = array_merge($payload, $options); 181 | } 182 | 183 | $content = json_encode($payload); 184 | $headers['content-length'] = strlen($content); 185 | return $this->doRequest($method, $path, $headers, $data = $content); 186 | } 187 | 188 | public function deleteService($serviceName, $headers = []) { 189 | /* 190 | Delete the specified service. see: https://help.aliyun.com/document_detail/52877.html#deleteservice 191 | @param service_name: name of the service. 192 | @param headers, optional 193 | 1, 'x-fc-trace-id': string (a uuid to do the request tracing) 194 | 2, 'if-match': string (delete the service only when matched the given etag.) 195 | 3, user define key value 196 | @return: array 197 | */ 198 | $method = 'DELETE'; 199 | $path = sprintf('/%s/services/%s', $this->apiVersion, $serviceName); 200 | $headers = $this->buildCommonHeaders($method, $path, $headers); 201 | return $this->doRequest($method, $path, $headers); 202 | } 203 | 204 | public function updateService($serviceName, $description = "", $options = [], $headers = []) { 205 | /* 206 | Update a service. see: https://help.aliyun.com/document_detail/52877.html#updateservice 207 | @param serviceName: name of the service. 208 | @param description: (optional, string), detail description of the service. 209 | @param options: (optional, array) see:https://help.aliyun.com/document_detail/52877.html#serviceupdatefields 210 | @param headers: (optional, array) 'x-fc-trace-id': string (a uuid to do the request tracing), etc 211 | @return: array 212 | */ 213 | $method = 'PUT'; 214 | $path = sprintf('/%s/services/%s', $this->apiVersion, $serviceName); 215 | $headers = $this->buildCommonHeaders($method, $path, $headers); 216 | $payload = array( 217 | 'description' => $description, 218 | ); 219 | if (count($options) > 0) { 220 | $payload = array_merge($payload, $options); 221 | } 222 | $content = json_encode($payload); 223 | $headers['content-length'] = strlen($content); 224 | return $this->doRequest($method, $path, $headers, $data = $content); 225 | } 226 | 227 | public function getService($serviceName, $headers = [], $qualifier = null) { 228 | /* 229 | get the specified service. see: https://help.aliyun.com/document_detail/52877.html#getservice 230 | @param service_name: name of the service. 231 | @param headers, optional 232 | @param qualifier: (optional, string) qualifier of service. 233 | 1, 'x-fc-trace-id': string (a uuid to do the request tracing) 234 | 2, 'if-match': string 235 | 3, user define key value 236 | @return: array 237 | */ 238 | $method = 'GET'; 239 | if ($qualifier != null && $qualifier != "") { 240 | $serviceName = sprintf("%s.%s", $serviceName, $qualifier); 241 | } 242 | $path = sprintf('/%s/services/%s', $this->apiVersion, $serviceName); 243 | $headers = $this->buildCommonHeaders($method, $path, $headers); 244 | return $this->doRequest($method, $path, $headers); 245 | } 246 | 247 | public function listServices($options = [], $headers = []) { 248 | /* 249 | list services. see: https://help.aliyun.com/document_detail/52877.html#listservices 250 | @param options: optional 251 | @param headers, optional 252 | 1, 'x-fc-trace-id': string (a uuid to do the request tracing) 253 | 2, 'if-match': string 254 | 3, user define key value 255 | @return: array 256 | */ 257 | $method = 'GET'; 258 | $path = sprintf('/%s/services', $this->apiVersion); 259 | $headers = $this->buildCommonHeaders($method, $path, $headers); 260 | 261 | if(array_key_exists("tags", $options)){ 262 | $tags = $options["tags"]; 263 | unset($options["tags"]); 264 | foreach ($tags as $key => $value) { 265 | $options["tag_".$key] = $value; 266 | } 267 | } 268 | 269 | return $this->doRequest($method, $path, $headers, $data = null, $query = $options); 270 | } 271 | 272 | private function normalizeParams(&$opts) { 273 | $opts['functionName'] = strval($opts['functionName']); 274 | $opts['runtime'] = strval($opts['runtime']); 275 | $opts['handler'] = strval($opts['handler']); 276 | $opts['initializer'] = isset($opts['initializer']) ? strval($opts['initializer']) : null; 277 | $opts['memorySize'] = isset($opts['memorySize']) ? intval($opts['memorySize']) : 256; 278 | $opts['timeout'] = isset($opts['timeout']) ? intval($opts['timeout']) : 60; 279 | $opts['initializationTimeout'] = isset($opts['initializationTimeout']) ? intval($opts['initializationTimeout']) : 30; 280 | } 281 | 282 | public function createFunction($serviceName, $functionPayload, $headers = []) { 283 | /* 284 | createFunction. see: https://help.aliyun.com/document_detail/52877.html#createfunction 285 | @param serviceName : require 286 | @param functionPayload: function ,see: https://help.aliyun.com/document_detail/52877.html#function 287 | @param headers, optional 288 | 1, 'x-fc-trace-id': string (a uuid to do the request tracing) 289 | 2, 'if-match': string 290 | 3, user define key value 291 | @return: array 292 | */ 293 | $opts = $functionPayload; 294 | if (!(isset($opts['functionName']) && isset($opts['runtime']) && isset($opts['handler']) && isset($opts['code']))) { 295 | throw new \Exception('functionName|handler|runtime|code parameters must be specified'); 296 | } 297 | $this->normalizeParams($functionPayload); 298 | $method = 'POST'; 299 | $path = sprintf('/%s/services/%s/functions', $this->apiVersion, $serviceName); 300 | $headers = $this->buildCommonHeaders($method, $path, $headers); 301 | $content = json_encode($functionPayload); 302 | $headers['content-length'] = strlen($content); 303 | 304 | return $this->doRequest($method, $path, $headers, $data = $content); 305 | } 306 | 307 | public function updateFunction($serviceName, $functionName, $options = [], $headers = []) { 308 | /* 309 | updateFunction. see: https://help.aliyun.com/document_detail/52877.html#updatefunction 310 | @param serviceName : require 311 | @param functionName: require 312 | @param options: require 313 | @param headers, optional, see: https://help.aliyun.com/document_detail/52877.html#functionupdatefields 314 | 1, 'x-fc-trace-id': string (a uuid to do the request tracing) 315 | 2, 'if-match': string 316 | 3, user define key value 317 | @return: array 318 | 319 | */ 320 | 321 | $method = 'PUT'; 322 | $path = sprintf('/%s/services/%s/functions/%s', $this->apiVersion, $serviceName, $functionName); 323 | $headers = $this->buildCommonHeaders($method, $path, $headers); 324 | $options['functionName'] = $functionName; 325 | 326 | 327 | $this->normalizeParams($options); 328 | unset($options['functionName']); 329 | $content = json_encode($options); 330 | $headers['content-length'] = strlen($content); 331 | 332 | return $this->doRequest($method, $path, $headers, $data = $content); 333 | } 334 | 335 | public function deleteFunction($serviceName, $functionName, $headers = []) { 336 | /* 337 | createFunction. see: https://help.aliyun.com/document_detail/52877.html#deletefunction 338 | @param serviceName : require 339 | @param functionName: require 340 | @param headers, optional 341 | 1, 'x-fc-trace-id': string (a uuid to do the request tracing) 342 | 2, 'if-match': string 343 | 3, user define key value 344 | @return: array 345 | */ 346 | $method = 'DELETE'; 347 | $path = sprintf('/%s/services/%s/functions/%s', $this->apiVersion, $serviceName, $functionName); 348 | $headers = $this->buildCommonHeaders($method, $path, $headers); 349 | 350 | return $this->doRequest($method, $path, $headers); 351 | } 352 | 353 | public function getFunction($serviceName, $functionName, $headers = [], $qualifier = null) { 354 | /* 355 | getFunction. see: https://help.aliyun.com/document_detail/52877.html#getfunction 356 | @param serviceName : require 357 | @param functionName: require 358 | @param headers, optional 359 | @param qualifier: (optional, string) qualifier of service. 360 | 1, 'x-fc-trace-id': string (a uuid to do the request tracing) 361 | 2, 'if-match': string 362 | 3, user define key value 363 | @return: array 364 | */ 365 | $method = 'GET'; 366 | if ($qualifier != null && $qualifier != "") { 367 | $serviceName = sprintf("%s.%s", $serviceName, $qualifier); 368 | } 369 | $path = sprintf('/%s/services/%s/functions/%s', $this->apiVersion, $serviceName, $functionName); 370 | $headers = $this->buildCommonHeaders($method, $path, $headers); 371 | return $this->doRequest($method, $path, $headers); 372 | } 373 | 374 | public function getFunctionCode($serviceName, $functionName, $headers = [], $qualifier = null) { 375 | /* 376 | getFunctionCode. see: https://help.aliyun.com/document_detail/52877.html#getfunctioncode 377 | @param serviceName : require 378 | @param functionName: require 379 | @param headers, optional 380 | @param qualifier: (optional, string) qualifier of service. 381 | 1, 'x-fc-trace-id': string (a uuid to do the request tracing) 382 | 2, 'if-match': string 383 | 3, user define key value 384 | @return: array 385 | */ 386 | $method = 'GET'; 387 | if ($qualifier != null && $qualifier != "") { 388 | $serviceName = sprintf("%s.%s", $serviceName, $qualifier); 389 | } 390 | $path = sprintf('/%s/services/%s/functions/%s/code', $this->apiVersion, $serviceName, $functionName); 391 | $headers = $this->buildCommonHeaders($method, $path, $headers); 392 | return $this->doRequest($method, $path, $headers); 393 | } 394 | 395 | public function listFunctions($serviceName, $options = [], $headers = []) { 396 | /* 397 | listFunctions. see: https://help.aliyun.com/document_detail/52877.html#listfunctions 398 | @param serviceName : require 399 | @param options, optional 400 | @param headers, optional 401 | 1, 'x-fc-trace-id': string (a uuid to do the request tracing) 402 | 2, 'if-match': string 403 | 3, user define key value 404 | @return: array 405 | */ 406 | $method = 'GET'; 407 | if (isset($options['qualifier'])) { 408 | $qualifier = $options['qualifier']; 409 | $serviceName = sprintf("%s.%s", $serviceName, $qualifier); 410 | } 411 | $path = sprintf('/%s/services/%s/functions', $this->apiVersion, $serviceName); 412 | $headers = $this->buildCommonHeaders($method, $path, $headers); 413 | return $this->doRequest($method, $path, $headers, $data = null, $query = $options); 414 | } 415 | 416 | public function invokeFunction($serviceName, $functionName, $payload = '', $headers = [], $qualifier = null) { 417 | /* 418 | invokeFunction. see: https://help.aliyun.com/document_detail/52877.html#invokefunction 419 | @param serviceName : require 420 | @param functionName: require 421 | @param payload: (optional, bytes or seekable file-like object): the input of the function. 422 | @param headers: (optional, array) user-defined request header. 423 | @param qualifier: (optional, string) qualifier of service. 424 | 'x-fc-invocation-type' : require, 'Sync'/'Async' ,only two choice 425 | 'x-fc-trace-id' : option (a uuid to do the request tracing) 426 | other can add user define header 427 | @return: array 428 | */ 429 | $method = 'POST'; 430 | if ($qualifier != null && $qualifier != "") { 431 | $serviceName = sprintf("%s.%s", $serviceName, $qualifier); 432 | } 433 | $path = sprintf('/%s/services/%s/functions/%s/invocations', $this->apiVersion, $serviceName, $functionName); 434 | $headers = $this->buildCommonHeaders($method, $path, $headers); 435 | return $this->doRequest($method, $path, $headers, $data = $payload); 436 | } 437 | 438 | public function createTrigger($serviceName, $functionName, $trigger = [], $headers = []) { 439 | /* 440 | createTrigger. see: https://help.aliyun.com/document_detail/52877.html#createtrigger 441 | @param serviceName : require 442 | @param functionName: require 443 | @param trigger: required, see: https://help.aliyun.com/document_detail/52877.html#trigger 444 | @param headers: (optional, array) user-defined request header. 445 | 'x-fc-trace-id' : option, (a uuid to do the request tracing) 446 | @return: array 447 | */ 448 | $method = 'POST'; 449 | $path = sprintf('/%s/services/%s/functions/%s/triggers', $this->apiVersion, $serviceName, $functionName); 450 | $headers = $this->buildCommonHeaders($method, $path, $headers); 451 | $content = json_encode($trigger); 452 | $headers['content-length'] = strlen($content); 453 | return $this->doRequest($method, $path, $headers, $data = $content); 454 | } 455 | 456 | public function deleteTrigger($serviceName, $functionName, $triggerName, $headers = []) { 457 | /* 458 | deleteTrigger. see: https://help.aliyun.com/document_detail/52877.html#deletetrigger 459 | @param serviceName : require 460 | @param functionName: require 461 | @param triggerName: required 462 | @param headers: (optional, array) user-defined request header. 463 | 'x-fc-trace-id' : option, (a uuid to do the request tracing) 464 | 'if-match': string 465 | @return: array 466 | */ 467 | $method = 'DELETE'; 468 | $path = sprintf('/%s/services/%s/functions/%s/triggers/%s', $this->apiVersion, $serviceName, $functionName, $triggerName); 469 | $headers = $this->buildCommonHeaders($method, $path, $headers); 470 | return $this->doRequest($method, $path, $headers); 471 | } 472 | 473 | public function updateTrigger($serviceName, $functionName, $triggerName, $triggerUpdateFields, $headers = []) { 474 | /* 475 | updateTrigger. see: https://help.aliyun.com/document_detail/52877.html#updatetrigger 476 | @param serviceName : require 477 | @param functionName: require 478 | @param triggerName: require 479 | @param triggerUpdateFields: required, see: https://help.aliyun.com/document_detail/52877.html#triggerupdatefields 480 | @param headers: (optional, array) user-defined request header. 481 | 'x-fc-trace-id' : option, (a uuid to do the request tracing) 482 | 'if-match': string 483 | @return: array 484 | */ 485 | $method = 'PUT'; 486 | $path = sprintf('/%s/services/%s/functions/%s/triggers/%s', $this->apiVersion, $serviceName, $functionName, $triggerName); 487 | $headers = $this->buildCommonHeaders($method, $path, $headers); 488 | 489 | $content = json_encode($triggerUpdateFields); 490 | $headers['content-length'] = strlen($content); 491 | 492 | return $this->doRequest($method, $path, $headers, $data = $content); 493 | } 494 | 495 | public function getTrigger($serviceName, $functionName, $triggerName, $headers = []) { 496 | /* 497 | getTrigger. see: https://help.aliyun.com/document_detail/52877.html#gettrigger 498 | @param serviceName : require 499 | @param functionName: require 500 | @param triggerName: required 501 | @param headers: (optional, array) user-defined request header. 502 | 'x-fc-trace-id' : option, (a uuid to do the request tracing) 503 | 'if-match': string 504 | @return: array 505 | */ 506 | $method = 'GET'; 507 | $path = sprintf('/%s/services/%s/functions/%s/triggers/%s', $this->apiVersion, $serviceName, $functionName, $triggerName); 508 | $headers = $this->buildCommonHeaders($method, $path, $headers); 509 | return $this->doRequest($method, $path, $headers); 510 | } 511 | 512 | public function listTriggers($serviceName, $functionName, $options = [], $headers = []) { 513 | /* 514 | listTriggers. see: https://help.aliyun.com/document_detail/52877.html#listtriggers 515 | @param serviceName : require 516 | @param functionName: require 517 | @param triggerName: required 518 | @param options, optional 519 | @param headers: (optional, array) user-defined request header. 520 | 'x-fc-trace-id' : option, (a uuid to do the request tracing) 521 | 'if-match': string 522 | @return: array 523 | */ 524 | $method = 'GET'; 525 | $path = sprintf('/%s/services/%s/functions/%s/triggers', $this->apiVersion, $serviceName, $functionName); 526 | $headers = $this->buildCommonHeaders($method, $path, $headers); 527 | return $this->doRequest($method, $path, $headers, $data = null, $query = $options); 528 | } 529 | 530 | public function publishVersion($serviceName, $description = "", $headers = []) { 531 | /* 532 | Publish a version. 533 | @param serviceName: (required, string), name of the service. 534 | @param description: (optional, string) the readable description of the version. 535 | @param headers, optional 536 | 1, 'x-fc-trace-id': string (a uuid to do the request tracing) 537 | 2, 'if-match': string (publish the version only when matched the given etag.) 538 | 3, user define key value 539 | @return: array 540 | [ 541 | headers => array(), 542 | //array of the version attributes. 543 | data => 544 | [ 545 | 'versionId' => 'string', 546 | 'description' => 'string', 547 | 'createdTime' => 'string', 548 | 'lastModifiedTime' => 'string', 549 | ] 550 | ] 551 | */ 552 | 553 | $method = 'POST'; 554 | $path = sprintf('/%s/services/%s/versions', $this->apiVersion, $serviceName); 555 | $headers = $this->buildCommonHeaders($method, $path, $headers); 556 | 557 | $payload = array( 558 | 'description' => $description, 559 | ); 560 | 561 | $content = json_encode($payload); 562 | $headers['content-length'] = strlen($content); 563 | return $this->doRequest($method, $path, $headers, $data = $content); 564 | } 565 | 566 | public function listVersions($serviceName, $options = [], $headers = []) { 567 | /* 568 | List the versions of the current service. 569 | @param serviceName: (required, string), name of the service. 570 | @param options, optional 571 | @param headers, optional 572 | 1, 'x-fc-trace-id': string (a uuid to do the request tracing) 573 | 2, user define key value 574 | @return: arrray 575 | [ 576 | headers => array(), 577 | // array, including all function information. 578 | data => 579 | [ 580 | 'versions' => 581 | [ 582 | [ 583 | 'versionId' => 'string', 584 | 'description' => 'string', 585 | 'createdTime' => 'string', 586 | 'lastModifiedTime' => 'string', 587 | ], 588 | ... 589 | ], 590 | 'nextToken' => 'string' 591 | ] 592 | ] 593 | */ 594 | $method = 'GET'; 595 | $path = sprintf('/%s/services/%s/versions', $this->apiVersion, $serviceName); 596 | $headers = $this->buildCommonHeaders($method, $path, $headers); 597 | return $this->doRequest($method, $path, $headers, $data = null, $query = $options); 598 | } 599 | 600 | public function deleteVersion($serviceName, $versionId, $headers = []) { 601 | /* 602 | Delete a version. 603 | @param serviceName: (required, string), name of the service. 604 | @param versionId: (required, string), Id of the version. 605 | @param headers, optional 606 | 1, 'x-fc-trace-id': string (a uuid to do the request tracing) 607 | 2, user define key value 608 | :return: array 609 | */ 610 | $method = 'DELETE'; 611 | $path = sprintf('/%s/services/%s/versions/%s', $this->apiVersion, $serviceName, $versionId); 612 | $headers = $this->buildCommonHeaders($method, $path, $headers); 613 | 614 | return $this->doRequest($method, $path, $headers); 615 | } 616 | 617 | public function createAlias($serviceName, $payload = [], $headers = []) { 618 | /* 619 | Create an alias. 620 | @param serviceName: (required, string), name of the service. 621 | @param payload ['aliasName' => aliasName, 'versionId'=> versionId, ...] 622 | @param headers, optional 623 | 1, 'x-fc-trace-id': string (a uuid to do the request tracing) 624 | 2, user define key value 625 | @return: array 626 | [ 627 | 'headers' => array(), 628 | //array of the version attributes. 629 | 'data' => 630 | [ 631 | 'aliasName' => 'string' 632 | 'versionId' => 'string', 633 | 'description' => 'string', 634 | 'additionalVersionWeight' => 'array', 635 | 'createdTime' => 'string', 636 | 'lastModifiedTime' => 'string', 637 | ] 638 | ] 639 | */ 640 | $method = 'POST'; 641 | $path = sprintf('/%s/services/%s/aliases', $this->apiVersion, $serviceName); 642 | $headers = $this->buildCommonHeaders($method, $path, $headers); 643 | $content = json_encode($payload); 644 | $headers['content-length'] = strlen($content); 645 | return $this->doRequest($method, $path, $headers, $data = $content); 646 | } 647 | 648 | public function getAlias($serviceName, $aliasName, $headers = []) { 649 | /* 650 | Get the alias. 651 | @param serviceName: (required, string) name of the service. 652 | @param aliasName: (required, string) name of the alias. 653 | @param headers, optional 654 | 1, 'x-fc-trace-id': string (a uuid to do the request tracing) 655 | 2, user define key value 656 | @return: array 657 | [ 658 | 'headers' => array(), 659 | //array alias attributes. 660 | 'data' => 661 | [ 662 | 'aliasName' => 'string' 663 | 'versionId' => 'string', 664 | 'description' => 'string', 665 | 'additionalVersionWeight' => 'array', 666 | 'createdTime' => 'string', 667 | 'lastModifiedTime' => 'string', 668 | ] 669 | ] 670 | */ 671 | $method = 'GET'; 672 | $path = sprintf('/%s/services/%s/aliases/%s', $this->apiVersion, $serviceName, $aliasName); 673 | $headers = $this->buildCommonHeaders($method, $path, $headers); 674 | 675 | return $this->doRequest($method, $path, $headers); 676 | } 677 | 678 | public function updateAlias($serviceName, $aliasName, $payload = [], $headers = []) { 679 | /* 680 | Update an alias. 681 | @param serviceName: (required, string), name of the service. 682 | @param aliasName: (required, string) name of the alias. 683 | @payload ['versionId'=> versionId, 'additionalVersionWeight' => additionalVersionWeight ...] 684 | @param headers, optional 685 | 1, 'x-fc-trace-id': string (a uuid to do the request tracing) 686 | 2, 'if-match': string (update the alias only when matched the given etag.) 687 | 3, user define key value 688 | @return: array 689 | headers: dict 690 | data: dict of the version attributes. 691 | { 692 | 'aliasName': 'string' 693 | 'versionId': 'string', 694 | 'description': 'string', 695 | 'additionalVersionWeight': 'dict', 696 | 'createdTime': 'string', 697 | 'lastModifiedTime': 'string', 698 | } 699 | */ 700 | $method = 'PUT'; 701 | $path = sprintf('/%s/services/%s/aliases/%s', $this->apiVersion, $serviceName, $aliasName); 702 | $headers = $this->buildCommonHeaders($method, $path, $headers); 703 | 704 | $content = json_encode($payload); 705 | $headers['content-length'] = strlen($content); 706 | 707 | return $this->doRequest($method, $path, $headers, $data = $content); 708 | } 709 | 710 | public function listAliases($serviceName, $options = [], $headers = []) { 711 | /* 712 | List the aliases in the current service. 713 | @param serviceName: (required, string), name of the service. 714 | @param options: (optional, array) 715 | [ 716 | "limit" => "int", 717 | "nextToken" => "string", 718 | "prefix" => "string", 719 | "startKey" => "string", 720 | ] 721 | @param headers, optional 722 | 1, 'x-fc-trace-id': string (a uuid to do the request tracing) 723 | 2, user define key value 724 | @return: array 725 | [ 726 | headers => array(), 727 | //array, including all aliase information. 728 | data => 729 | [ 730 | 'aliases'=> 731 | [ 732 | [ 733 | 'aliasName'=> 'string' 734 | 'versionId'=> 'string', 735 | 'description'=> 'string', 736 | 'additionalVersionWeight'=> 'array', 737 | 'createdTime'=> 'string', 738 | 'lastModifiedTime'=> 'string', 739 | ], 740 | ... 741 | ], 742 | 'nextToken'=> 'string' 743 | ] 744 | ] 745 | */ 746 | 747 | $method = 'GET'; 748 | $path = sprintf('/%s/services/%s/aliases', $this->apiVersion, $serviceName); 749 | $headers = $this->buildCommonHeaders($method, $path, $headers); 750 | return $this->doRequest($method, $path, $headers, $data = null, $query = $options); 751 | } 752 | 753 | public function deleteAlias($serviceName, $aliasName, $headers = []) { 754 | /* 755 | Delete an aliase. 756 | @param serviceName: (required, string), name of the service. 757 | @param aliasName: (required, string), name of the alias. 758 | @param headers, optional 759 | 1, 'x-fc-trace-id': string (a uuid to do the request tracing) 760 | 2, 'if-match': string (delete the alias only when matched the given etag.) 761 | 3, user define key value 762 | :return: array 763 | */ 764 | $method = 'DELETE'; 765 | $path = sprintf('/%s/services/%s/aliases/%s', $this->apiVersion, $serviceName, $aliasName); 766 | $headers = $this->buildCommonHeaders($method, $path, $headers); 767 | 768 | return $this->doRequest($method, $path, $headers); 769 | } 770 | 771 | public function tagResource($payload, $headers=[]){ 772 | /* 773 | Tag on a resource, Currently only services are supported 774 | :param payload 775 | resourceArn: (required string), Resource ARN. Either full ARN or partial ARN 776 | tags:(required array), A list of tag keys. At least 1 tag is required. At most 20. Tag key is required, but tag value is optional 777 | :param headers, optional 778 | 1, 'x-fc-trace-id': string (a uuid to do the request tracing) 779 | 2, user define key value 780 | return: array 781 | */ 782 | 783 | $method = 'POST'; 784 | $path = sprintf('/%s/tag', $this->apiVersion); 785 | $headers = $this->buildCommonHeaders($method, $path, $headers); 786 | $content = json_encode($payload); 787 | $headers['content-length'] = strlen($content); 788 | return $this->doRequest($method, $path, $headers, $data = $content); 789 | } 790 | 791 | public function untagResource($payload, $headers=[]) { 792 | /* 793 | unTag on a resource, Currently only services are supported 794 | :param payload 795 | resourceArn: (required string), Resource ARN. Either full ARN or partial ARN 796 | tagKeys:(optinal array), A list of tag keys. 797 | deletaAll: (optinal bool), when tagKeys is empty and deleteAll be True can take effect. 798 | :param headers, optional 799 | 1, 'x-fc-trace-id': string (a uuid to do the request tracing) 800 | 2, user define key value 801 | :return: array 802 | */ 803 | $method = 'DELETE'; 804 | $path = sprintf('/%s/tag', $this->apiVersion); 805 | $headers = $this->buildCommonHeaders($method, $path, $headers); 806 | $content = json_encode($payload); 807 | $headers['content-length'] = strlen($content); 808 | return $this->doRequest($method, $path, $headers, $data = $content); 809 | } 810 | 811 | public function getResourceTags($options, $headers=[]){ 812 | /* 813 | get a resource's tags, Currently only services are supported 814 | :param $options 815 | resourceArn: (required string), Resource ARN. Either full ARN or partial ARN 816 | :param headers, optional 817 | 1, 'x-fc-trace-id': string (a uuid to do the request tracing) 818 | 2, user define key value 819 | :return: array 820 | */ 821 | $method = 'GET'; 822 | $path = sprintf('/%s/tag', $this->apiVersion); 823 | $headers = $this->buildCommonHeaders($method, $path, $headers); 824 | return $this->doRequest($method, $path, $headers, $data = null, $query = $options); 825 | } 826 | 827 | public function listReservedCapacities($options = [], $headers = []) { 828 | /* 829 | @param options: optional 830 | @param headers, optional 831 | 1, 'x-fc-trace-id': string (a uuid to do the request tracing) 832 | 2, 'if-match': string 833 | 3, user define key value 834 | @return: array 835 | */ 836 | $method = 'GET'; 837 | $path = sprintf('/%s/reservedCapacities', $this->apiVersion); 838 | $headers = $this->buildCommonHeaders($method, $path, $headers); 839 | 840 | return $this->doRequest($method, $path, $headers, $data = null, $query = $options); 841 | } 842 | 843 | public function putProvisionConfig($serviceName, $qualifier, $functionName, $payload, $headers=[]){ 844 | /* 845 | put provision config 846 | @param service_name: name of the service. 847 | @param qualifier: name of the service's alias. 848 | @param functionName: name of the funtion. 849 | @param payload: body of provision request 850 | @param headers, optional 851 | 1, 'x-fc-trace-id': string (a uuid to do the request tracing) 852 | 2, 'if-match': string (delete the service only when matched the given etag.) 853 | 3, user define key value 854 | :return array 855 | */ 856 | $method = 'PUT'; 857 | $path = sprintf('/%s/services/%s.%s/functions/%s/provision-config', 858 | $this->apiVersion, $serviceName, $qualifier, $functionName); 859 | $headers = $this->buildCommonHeaders($method, $path, $headers); 860 | $content = json_encode($payload); 861 | $headers['content-length'] = strlen($content); 862 | return $this->doRequest($method, $path, $headers, $data = $content); 863 | } 864 | 865 | public function getProvisionConfig($serviceName, $qualifier, $functionName, $headers=[]){ 866 | /* 867 | put provision config 868 | @param service_name: name of the service. 869 | @param qualifier: name of the service's alias. 870 | @param functionName: name of the funtion. 871 | @param target: number of provision 872 | @param headers, optional 873 | 1, 'x-fc-trace-id': string (a uuid to do the request tracing) 874 | 2, user define key value 875 | :return array 876 | */ 877 | $method = 'GET'; 878 | $path = sprintf('/%s/services/%s.%s/functions/%s/provision-config', 879 | $this->apiVersion, $serviceName, $qualifier, $functionName); 880 | $headers = $this->buildCommonHeaders($method, $path, $headers); 881 | 882 | return $this->doRequest($method, $path, $headers, $data = null, $query = null); 883 | } 884 | 885 | public function listProvisionConfigs($serviceName, $qualifier, $options=[], $headers=[]){ 886 | /* 887 | List the provision configin the current service. 888 | @param serviceName: (optional, string), name of the service. 889 | @param qualifier: (optional, string) name of the service's alias. 890 | @param limit: (optional, integer) the total number of the returned aliases. 891 | @param nextToken: (optional, string) continue listing the aliase from the previous point. 892 | @param headers, optional 893 | 1, 'x-fc-trace-id': string (a uuid to do the request tracing) 894 | 2, user define key value 895 | :return: array 896 | */ 897 | if (!empty($qualifier) && empty($serviceName)){ 898 | throw new \Exception("serviceName is required when qualifier is not empty"); 899 | } 900 | $method = 'GET'; 901 | $path = sprintf('/%s/provision-configs', $this->apiVersion); 902 | $headers = $this->buildCommonHeaders($method, $path, $headers); 903 | $options['serviceName']= $serviceName; 904 | $options['qualifier']= $qualifier; 905 | return $this->doRequest($method, $path, $headers, $data = null, $query = $options); 906 | } 907 | 908 | public function putFunctionAsyncConfig($serviceName, $qualifier, $functionName, $payload, $headers=[]){ 909 | /* 910 | put async config 911 | @param service_name: name of the service. 912 | @param qualifier: name of the service's alias. 913 | @param functionName: name of the funtion. 914 | @param payload: body of async config request 915 | @param headers, optional 916 | 1, 'x-fc-trace-id': string (a uuid to do the request tracing) 917 | 2, user define key value 918 | :return array 919 | */ 920 | $method = 'PUT'; 921 | $path = sprintf('/%s/services/%s.%s/functions/%s/async-invoke-config', 922 | $this->apiVersion, $serviceName, $qualifier, $functionName); 923 | $headers = $this->buildCommonHeaders($method, $path, $headers); 924 | $content = json_encode($payload); 925 | $headers['content-length'] = strlen($content); 926 | return $this->doRequest($method, $path, $headers, $data = $content); 927 | } 928 | 929 | public function getFunctionAsyncConfig($serviceName, $qualifier, $functionName, $headers=[]){ 930 | /* 931 | get async config 932 | @param service_name: name of the service. 933 | @param qualifier: name of the service's alias. 934 | @param functionName: name of the funtion. 935 | @param headers, optional 936 | 1, 'x-fc-trace-id': string (a uuid to do the request tracing) 937 | 2, user define key value 938 | :return array 939 | */ 940 | $method = 'GET'; 941 | $path = sprintf('/%s/services/%s.%s/functions/%s/async-invoke-config', 942 | $this->apiVersion, $serviceName, $qualifier, $functionName); 943 | $headers = $this->buildCommonHeaders($method, $path, $headers); 944 | 945 | return $this->doRequest($method, $path, $headers, $data = null, $query = null); 946 | } 947 | 948 | public function listFunctionAsyncConfigs($serviceName, $functionName, $options=[], $headers=[]){ 949 | /* 950 | List the async config in the current function. 951 | @param serviceName: name of the service. 952 | @param functionName: name of the function. 953 | @param limit: (optional, integer) the total number of the returned aliases. 954 | @param nextToken: (optional, string) continue listing the configs from the previous point. 955 | @param headers, optional 956 | 1, 'x-fc-trace-id': string (a uuid to do the request tracing) 957 | 2, user define key value 958 | :return: array 959 | */ 960 | if (!empty($qualifier) && empty($serviceName)){ 961 | throw new \Exception("serviceName is required when qualifier is not empty"); 962 | } 963 | $method = 'GET'; 964 | $path = sprintf('/%s/services/%s/functions/%s/async-invoke-configs', 965 | $this->apiVersion, $serviceName, $functionName); 966 | $headers = $this->buildCommonHeaders($method, $path, $headers); 967 | return $this->doRequest($method, $path, $headers, $data = null, $query = $options); 968 | } 969 | 970 | public function deleteFunctionAsyncConfig($serviceName, $qualifier, $functionName, $headers=[]){ 971 | /* 972 | delete async config 973 | @param service_name: name of the service. 974 | @param qualifier: name of the service's alias. 975 | @param functionName: name of the function. 976 | @param headers, optional 977 | 1, 'x-fc-trace-id': string (a uuid to do the request tracing) 978 | 2, user define key value 979 | :return array 980 | */ 981 | $method = 'DELETE'; 982 | $path = sprintf('/%s/services/%s.%s/functions/%s/async-invoke-config', 983 | $this->apiVersion, $serviceName, $qualifier, $functionName); 984 | $headers = $this->buildCommonHeaders($method, $path, $headers); 985 | 986 | return $this->doRequest($method, $path, $headers, $data = null, $query = null); 987 | } 988 | } 989 | -------------------------------------------------------------------------------- /src/AliyunFC/util.php: -------------------------------------------------------------------------------- 1 | > 6)) . 15 | chr(0x80 | ($val & 0x3f)); 16 | } else { 17 | $ret .= chr(0xe0 | ($val >> 12)) . 18 | chr(0x80 | (($val >> 6) & 0x3f)) . 19 | chr(0x80 | ($val & 0x3f)); 20 | } 21 | 22 | $i += 5; 23 | } else 24 | if ($str[$i] == '%') { 25 | $ret .= urldecode(substr($str, $i, 3)); 26 | $i += 2; 27 | } else { 28 | $ret .= $str[$i]; 29 | } 30 | 31 | } 32 | return $ret; 33 | } 34 | -------------------------------------------------------------------------------- /test/bootstrap.php: -------------------------------------------------------------------------------- 1 | serviceName = "Test-Php-SDK" . createUuid(); 31 | $this->fcClient = new Client([ 32 | 'accessKeyID' => getenv('ACCESS_KEY_ID'), 33 | 'accessKeySecret' => getenv('ACCESS_KEY_SECRET'), 34 | 'endpoint' => getenv('ENDPOINT'), 35 | ]); 36 | $this->clearAllTestRes(); 37 | $this->initOpts(); 38 | $this->codeBucket = getenv('CODE_BUCKET'); 39 | $this->accountId = getenv('ACCOUNT_ID'); 40 | $this->region = getenv('REGION'); 41 | $this->invocationRoleOss = getenv('INVOCATION_ROLE_OSS'); 42 | $this->invocationRoleSls = getenv('INVOCATION_ROLE_SLS'); 43 | $this->logProject = getenv('LOG_PROJECT'); 44 | $this->logStore = getenv('LOG_STORE'); 45 | } 46 | 47 | private function initOpts() { 48 | $role = getenv('SERVICE_ROLE'); 49 | $logProject = getenv('LOG_PROJECT'); 50 | $logStore = getenv('LOG_STORE'); 51 | $vpcId = getenv('VPC_ID'); 52 | $vSwitchIds = getenv('VSWITCH_IDS'); 53 | $securityGroupId = getenv('SECURITY_GROUP_ID'); 54 | $vpcRole = getenv('VPC_ROLE'); 55 | $userId = getenv('USER_ID'); 56 | $groupId = getenv('GROUP_ID'); 57 | $nasServerAddr = getenv('NAS_SERVER_ADDR'); 58 | $nasMountDir = getenv('NAS_MOUNT_DIR'); 59 | 60 | $nasConfig = array( 61 | "userId" => intval($userId), 62 | "groupId" => intval($groupId), 63 | "mountPoints" => array( 64 | [ 65 | "serverAddr" => $nasServerAddr, 66 | "mountDir" => $nasMountDir, 67 | ], 68 | ), 69 | ); 70 | 71 | $vpcConfig = array( 72 | 'vpcId' => $vpcId, 73 | 'vSwitchIds' => array($vSwitchIds), 74 | 'securityGroupId' => $securityGroupId, 75 | 'role' => "", 76 | ); 77 | 78 | $this->opts = array( 79 | "logConfig" => array( 80 | "project" => $logProject, 81 | "logstore" => $logStore, 82 | "enableRequestMetrics" => false, 83 | "enableInstanceMetrics" => false, 84 | ), 85 | "role" => $role, 86 | "vpcConfig" => $vpcConfig, 87 | "nasConfig" => $nasConfig, 88 | 'internetAccess' => true, 89 | ); 90 | } 91 | 92 | public function tearDown() { 93 | $this->clearAllTestRes(); 94 | } 95 | 96 | private function clearAllTestRes() { 97 | try { 98 | $serviceName = $this->serviceName; 99 | $r = $this->fcClient->listFunctions($serviceName); 100 | $functions = $r['data']['functions']; 101 | foreach ($functions as $func) { 102 | $functionName = $func['functionName']; 103 | $tr = $this->fcClient->listTriggers($serviceName, $functionName); 104 | $triggers = $tr['data']['triggers']; 105 | foreach ($triggers as $t) { 106 | $triggerName = $t['triggerName']; 107 | $this->fcClient->deleteTrigger($serviceName, $functionName, $triggerName); 108 | } 109 | $this->fcClient->deleteFunction($serviceName, $functionName); 110 | } 111 | $this->fcClient->deleteService($serviceName); 112 | } catch (Exception $e) { 113 | } 114 | 115 | try { 116 | $this->fcClient->deleteService($this->serviceName . "abc"); 117 | } catch (Exception $e) { 118 | } 119 | 120 | try { 121 | $this->fcClient->deleteService($this->serviceName . "abd"); 122 | } catch (Exception $e) { 123 | } 124 | 125 | try { 126 | $this->fcClient->deleteService($this->serviceName . "ade"); 127 | } catch (Exception $e) { 128 | } 129 | 130 | try { 131 | $this->fcClient->deleteService($this->serviceName . "bcd"); 132 | } catch (Exception $e) { 133 | } 134 | 135 | try { 136 | $this->fcClient->deleteService($this->serviceName . "bde"); 137 | } catch (Exception $e) { 138 | } 139 | 140 | try { 141 | $this->fcClient->deleteService("Test-Php-SDK-zzz"); 142 | } catch (Exception $e) { 143 | } 144 | } 145 | 146 | public function testServiceCRUD() { 147 | $serviceName = $this->serviceName; 148 | $serviceDesc = "测试的service, php sdk 创建"; 149 | $ret = $this->fcClient->createService( 150 | $serviceName, 151 | $serviceDesc, 152 | $options = $this->opts 153 | ); 154 | 155 | $service = $ret['data']; 156 | $etag = $ret['headers']['Etag'][0]; 157 | 158 | $this->assertEquals($service['serviceName'], $serviceName); 159 | $this->assertEquals($service['description'], $serviceDesc); 160 | $this->assertTrue(isset($service['lastModifiedTime'])); 161 | $this->assertTrue(isset($service['serviceId'])); 162 | $this->assertEquals($service['logConfig'], $this->opts['logConfig']); 163 | $this->assertEquals($service['role'], $this->opts['role']); 164 | $this->assertEquals($service['vpcConfig'], $this->opts['vpcConfig']); 165 | $this->assertEquals($service['nasConfig'], $this->opts['nasConfig']); 166 | $this->assertEquals($service['internetAccess'], true); 167 | $this->assertTrue($etag != ''); 168 | 169 | $ret = $this->fcClient->getService($serviceName, $headers = ['x-fc-trace-id' => createUuid()]); 170 | $service = $ret['data']; 171 | $this->assertEquals($service['serviceName'], $serviceName); 172 | $this->assertEquals($service['description'], $serviceDesc); 173 | 174 | $serviceDesc = "测试的service"; 175 | $opts["nasConfig"]["userId"] = -1; 176 | $ret = $this->fcClient->updateService($serviceName, $serviceDesc, $opts); 177 | $service = $ret['data']; 178 | $this->assertEquals($service['description'], $serviceDesc); 179 | $this->assertEquals($service['nasConfig']["userId"], -1); 180 | $etag = $ret['headers']['Etag'][0]; 181 | 182 | $ret = $this->fcClient->getService($serviceName); 183 | $service = $ret['data']; 184 | $this->assertEquals($service['description'], $serviceDesc); 185 | $this->assertEquals($service['nasConfig']["userId"], -1); 186 | 187 | $err = ''; 188 | try { 189 | $this->fcClient->deleteService($serviceName, $headers = ['if-match' => 'invalid etag']); 190 | } catch (Exception $e) { 191 | $err = $e->getMessage(); 192 | } 193 | $this->assertContains('"ErrorMessage":"the resource being modified has been changed"', $err); 194 | 195 | $this->fcClient->deleteService($serviceName, $headers = ['if-match' => $etag]); 196 | 197 | $this->subTestListServices(); 198 | $this->clearAllTestRes(); 199 | } 200 | 201 | private function subTestListServices() { 202 | $prefix = $this->serviceName; 203 | $this->fcClient->createService($prefix . "abc"); 204 | $this->fcClient->createService($prefix . "abd"); 205 | $this->fcClient->createService($prefix . "ade"); 206 | $this->fcClient->createService($prefix . "bcd"); 207 | $this->fcClient->createService($prefix . "bde"); 208 | $this->fcClient->createService($prefix . "zzz"); 209 | 210 | $r = $this->fcClient->listServices(['startKey' => $prefix . 'b', "limit" => 2]); 211 | $r = $r['data']; 212 | $services = $r['services']; 213 | $nextToken = $r['nextToken']; 214 | $this->assertEquals(count($services), 2); 215 | $this->assertTrue(in_array($services[0]['serviceName'], [$prefix . 'bcd', $prefix . 'bde'])); 216 | $this->assertTrue(in_array($services[1]['serviceName'], [$prefix . 'bcd', $prefix . 'bde'])); 217 | 218 | $r = $this->fcClient->listServices(['startKey' => $prefix . 'b', "limit" => 1, 'nextToken' => $nextToken]); 219 | $r = $r['data']; 220 | $services = $r['services']; 221 | $this->assertEquals(count($services), 1); 222 | $this->assertEquals($services[0]['serviceName'], $prefix . 'zzz'); 223 | 224 | // It's ok to omit the startKey and only provide continuationToken. 225 | // As long as the continuationToken is provided, the startKey is not considered. 226 | $r = $this->fcClient->listServices(["limit" => 1, 'nextToken' => $nextToken]); 227 | $r = $r['data']; 228 | $services = $r['services']; 229 | $this->assertEquals(count($services), 1); 230 | $this->assertEquals($services[0]['serviceName'], $prefix . 'zzz'); 231 | 232 | $r = $this->fcClient->listServices(['prefix' => $prefix . 'x', "limit" => 2]); 233 | $r = $r['data']; 234 | $services = $r['services']; 235 | $this->assertEquals(count($services), 0); 236 | 237 | $r = $this->fcClient->listServices(['prefix' => $prefix . 'a', "limit" => 2]); 238 | $r = $r['data']; 239 | $services = $r['services']; 240 | $this->assertEquals(count($services), 2); 241 | $this->assertEquals($services[0]['serviceName'], $prefix . 'abc'); 242 | $this->assertEquals($services[1]['serviceName'], $prefix . 'abd'); 243 | 244 | $r = $this->fcClient->listServices(['prefix' => $prefix . 'ab', "limit" => 2, 'startKey' => $prefix . 'abd']); 245 | $r = $r['data']; 246 | $services = $r['services']; 247 | $this->assertEquals(count($services), 1); 248 | $this->assertEquals($services[0]['serviceName'], $prefix . 'abd'); 249 | } 250 | 251 | private function checkFunction($function, $functionName, $desc, $runtime = 'php7.2', 252 | $handler = 'index.handler', $envs = ['TestKey' => 'TestValue'], $initializer = null) { 253 | $etag = $function['headers']['Etag'][0]; 254 | $this->assertTrue($etag != ''); 255 | $function = $function['data']; 256 | $this->assertEquals($function['functionName'], $functionName); 257 | $this->assertEquals($function['runtime'], $runtime); 258 | $this->assertEquals($function['handler'], $handler); 259 | $this->assertEquals($function['initializer'], $initializer); 260 | $this->assertEquals($function['description'], $desc); 261 | $this->assertEquals($function['environmentVariables'], $envs); 262 | $this->assertTrue(isset($function['codeChecksum'])); 263 | $this->assertTrue(isset($function['codeSize'])); 264 | $this->assertTrue(isset($function['createdTime'])); 265 | $this->assertTrue(isset($function['lastModifiedTime'])); 266 | $this->assertTrue(isset($function['functionId'])); 267 | $this->assertTrue(isset($function['memorySize'])); 268 | $this->assertTrue(isset($function['timeout'])); 269 | $this->assertTrue(isset($function['initializationTimeout'])); 270 | 271 | $serviceName = $this->serviceName; 272 | $checksum = $function['codeChecksum']; 273 | $function = $this->fcClient->getFunction($serviceName, $functionName, $headers = ['x-fc-trace-id' => createUuid()]); 274 | $function = $function['data']; 275 | $this->assertEquals($function['functionName'], $functionName); 276 | $this->assertEquals($function['runtime'], $runtime); 277 | $this->assertEquals($function['handler'], $handler); 278 | $this->assertEquals($function['initializer'], $initializer); 279 | $this->assertEquals($function['description'], $desc); 280 | 281 | $code = $this->fcClient->getFunctionCode($serviceName, $functionName); 282 | $code = $code['data']; 283 | $this->assertEquals($code['checksum'], $checksum); 284 | $this->assertTrue($code['url'] != ''); 285 | 286 | $err = ''; 287 | try { 288 | $this->fcClient->deleteFunction($serviceName, $functionName, $headers = ['if-match' => 'invalid etag']); 289 | } catch (Exception $e) { 290 | $err = $e->getMessage(); 291 | } 292 | $this->assertContains('"ErrorMessage":"the resource being modified has been changed"', $err); 293 | } 294 | 295 | public function testFunctionCRUDInitialize() { 296 | $serviceName = $this->serviceName; 297 | $serviceDesc = "测试的service, php sdk 创建"; 298 | $this->fcClient->createService($serviceName, $serviceDesc); 299 | $functionName = "test_initialize"; 300 | 301 | $ret = $this->fcClient->createFunction( 302 | $serviceName, 303 | array( 304 | 'functionName' => $functionName, 305 | 'handler' => 'counter.handler', 306 | 'initializer' => 'counter.initializer', 307 | 'runtime' => 'php7.2', 308 | 'memorySize' => 128, 309 | 'code' => array( 310 | 'zipFile' => base64_encode(file_get_contents(__DIR__ . '/counter.zip')), 311 | ), 312 | 'description' => "test function", 313 | 'environmentVariables' => ['TestKey' => 'TestValue'], 314 | ) 315 | ); 316 | $this->checkFunction($ret, $functionName, 'test function', $runtime = 'php7.2', $handler = 'counter.handler', $envs = ['TestKey' => 'TestValue'], $initializer = 'counter.initializer'); 317 | 318 | $invkRet = $this->fcClient->invokeFunction($serviceName, $functionName); 319 | $this->assertEquals($invkRet['data'], '2'); 320 | 321 | $invkRet = $this->fcClient->invokeFunction($serviceName, $functionName, '', ['x-fc-invocation-type' => 'Async']); 322 | $this->assertEquals($invkRet['data'], ''); 323 | $this->assertTrue(isset($invkRet['headers']['X-Fc-Request-Id'])); 324 | 325 | $ret = $this->fcClient->updateFunction( 326 | $serviceName, 327 | $functionName, 328 | array( 329 | 'handler' => 'counter.handler', 330 | 'initializer' => 'counter.initializer', 331 | 'runtime' => 'php7.2', 332 | 'memorySize' => 128, 333 | 'code' => array( 334 | 'zipFile' => base64_encode(file_get_contents(__DIR__ . '/counter.zip')), 335 | ), 336 | 'description' => "test update function", 337 | 'environmentVariables' => ['newTestKey' => 'newTestValue'], 338 | ) 339 | ); 340 | $this->checkFunction($ret, $functionName, 'test update function', $runtime = 'php7.2', $handler = 'counter.handler', $envs = ['newTestKey' => 'newTestValue'], $initializer = 'counter.initializer'); 341 | $etag = $ret['headers']['Etag'][0]; 342 | # now success with valid etag. 343 | $this->fcClient->deleteFunction($serviceName, $functionName, $headers = ['if-match' => $etag]); 344 | 345 | $err = ''; 346 | try { 347 | $this->fcClient->getFunction($serviceName, $functionName); 348 | } catch (Exception $e) { 349 | $err = $e->getMessage(); 350 | } 351 | $this->assertTrue($err != ''); 352 | 353 | $this->subTestListFunctions($serviceName); 354 | 355 | $this->clearAllTestRes(); 356 | } 357 | 358 | public function testFunctionCRUDInvoke() { 359 | $serviceName = $this->serviceName; 360 | $serviceDesc = "测试的service, php sdk 创建"; 361 | $this->fcClient->createService($serviceName, $serviceDesc); 362 | $functionName = "test_invoke"; 363 | 364 | $ret = $this->fcClient->createFunction( 365 | $serviceName, 366 | array( 367 | 'functionName' => $functionName, 368 | 'handler' => 'index.handler', 369 | 'runtime' => 'php7.2', 370 | 'memorySize' => 128, 371 | 'code' => array( 372 | 'zipFile' => base64_encode(file_get_contents(__DIR__ . '/index.zip')), 373 | ), 374 | 'description' => "test function", 375 | 'environmentVariables' => ['TestKey' => 'TestValue'], 376 | ) 377 | ); 378 | $this->checkFunction($ret, $functionName, 'test function', $runtime = 'php7.2'); 379 | 380 | $invkRet = $this->fcClient->invokeFunction($serviceName, $functionName, $payload = "hello world"); 381 | $this->assertEquals($invkRet['data'], 'hello world'); 382 | 383 | $invkRet = $this->fcClient->invokeFunction($serviceName, $functionName, '', ['x-fc-invocation-type' => 'Async']); 384 | $this->assertEquals($invkRet['data'], ''); 385 | $this->assertTrue(isset($invkRet['headers']['X-Fc-Request-Id'])); 386 | 387 | $ret = $this->fcClient->updateFunction( 388 | $serviceName, 389 | $functionName, 390 | array( 391 | 'handler' => 'hello_world.handler', 392 | 'runtime' => 'nodejs6', 393 | 'memorySize' => 256, 394 | 'code' => array( 395 | 'ossBucketName' => $this->codeBucket, 396 | 'ossObjectName' => "hello_world_nodejs.zip", 397 | ), 398 | 'description' => "test update function", 399 | 'environmentVariables' => ['newTestKey' => 'newTestValue'], 400 | ) 401 | ); 402 | $this->checkFunction($ret, $functionName, 'test update function', 'nodejs6', 'hello_world.handler', ['newTestKey' => 'newTestValue']); 403 | $etag = $ret['headers']['Etag'][0]; 404 | # now success with valid etag. 405 | $this->fcClient->deleteFunction($serviceName, $functionName, $headers = ['if-match' => $etag]); 406 | 407 | $err = ''; 408 | try { 409 | $this->fcClient->getFunction($serviceName, $functionName); 410 | } catch (Exception $e) { 411 | $err = $e->getMessage(); 412 | } 413 | $this->assertTrue($err != ''); 414 | 415 | $this->subTestListFunctions($serviceName); 416 | 417 | $this->clearAllTestRes(); 418 | } 419 | 420 | private function subTestListFunctions($serviceName) { 421 | $prefix = 'test_list_'; 422 | 423 | $f = function ($serviceName, $functionName) { 424 | $this->fcClient->createFunction( 425 | $serviceName, 426 | array( 427 | 'functionName' => $functionName, 428 | 'handler' => 'index.handler', 429 | 'runtime' => 'php7.2', 430 | 'code' => array( 431 | 'zipFile' => base64_encode(file_get_contents(__DIR__ . '/index.zip')), 432 | ), 433 | ) 434 | ); 435 | }; 436 | 437 | $f($serviceName, $prefix . "abc"); 438 | $f($serviceName, $prefix . "abd"); 439 | $f($serviceName, $prefix . "ade"); 440 | $f($serviceName, $prefix . "bcd"); 441 | $f($serviceName, $prefix . "bde"); 442 | $f($serviceName, $prefix . "zzz"); 443 | 444 | $r = $this->fcClient->listFunctions($serviceName, ['startKey' => $prefix . 'b', "limit" => 2]); 445 | $r = $r['data']; 446 | $functions = $r['functions']; 447 | $nextToken = $r['nextToken']; 448 | $this->assertEquals(count($functions), 2); 449 | $this->assertEquals($functions[0]['functionName'], $prefix . 'bcd'); 450 | $this->assertEquals($functions[1]['functionName'], $prefix . 'bde'); 451 | 452 | $r = $this->fcClient->listFunctions($serviceName, ['startKey' => $prefix . 'b', "limit" => 2, 'nextToken' => $nextToken]); 453 | $r = $r['data']; 454 | $functions = $r['functions']; 455 | $this->assertEquals(count($functions), 1); 456 | $this->assertEquals($functions[0]['functionName'], $prefix . 'zzz'); 457 | 458 | $r = $this->fcClient->listFunctions($serviceName, ["limit" => 1, 'nextToken' => $nextToken]); 459 | $r = $r['data']; 460 | $functions = $r['functions']; 461 | $this->assertEquals(count($functions), 1); 462 | $this->assertEquals($functions[0]['functionName'], $prefix . 'zzz'); 463 | 464 | $r = $this->fcClient->listFunctions($serviceName, ['prefix' => $prefix . 'x', "limit" => 2, 'nextToken' => $nextToken]); 465 | $r = $r['data']; 466 | $functions = $r['functions']; 467 | $this->assertEquals(count($functions), 0); 468 | 469 | $r = $this->fcClient->listFunctions($serviceName, ['prefix' => $prefix . 'a', "limit" => 2]); 470 | $r = $r['data']; 471 | $functions = $r['functions']; 472 | $this->assertEquals(count($functions), 2); 473 | $this->assertEquals($functions[0]['functionName'], $prefix . 'abc'); 474 | $this->assertEquals($functions[1]['functionName'], $prefix . 'abd'); 475 | 476 | $r = $this->fcClient->listFunctions($serviceName, ['prefix' => $prefix . 'ab', "limit" => 2, 'startKey' => $prefix . 'abd']); 477 | $r = $r['data']; 478 | $functions = $r['functions']; 479 | $this->assertEquals(count($functions), 1); 480 | $this->assertEquals($functions[0]['functionName'], $prefix . 'abd'); 481 | } 482 | 483 | public function testTriggerCRUD() { 484 | $serviceName = $this->serviceName; 485 | $serviceDesc = "测试的service, php sdk 创建"; 486 | $this->fcClient->createService($serviceName, $serviceDesc); 487 | $functionName = $this->serviceName . "test"; 488 | $this->fcClient->createFunction( 489 | $serviceName, 490 | array( 491 | 'functionName' => $functionName, 492 | 'handler' => 'index.handler', 493 | 'runtime' => 'php7.2', 494 | 'memorySize' => 128, 495 | 'code' => array( 496 | 'zipFile' => base64_encode(file_get_contents(__DIR__ . '/index.zip')), 497 | ), 498 | 'description' => "test function", 499 | ) 500 | ); 501 | $httpFunctionName = $this->serviceName . "test-http" ; 502 | $this->fcClient->createFunction( 503 | $serviceName, 504 | array( 505 | 'functionName' => $httpFunctionName, 506 | 'handler' => 'index_http.handler', 507 | 'runtime' => 'php7.2', 508 | 'memorySize' => 128, 509 | 'code' => array( 510 | 'zipFile' => base64_encode(file_get_contents(__DIR__ . '/index_http.zip')), 511 | ), 512 | 'description' => "test http function", 513 | ) 514 | ); 515 | $this->subTestOssTrigger($serviceName, $functionName); 516 | $this->subTestLogTrigger($serviceName, $functionName); 517 | $this->subTestHttpTrigger($serviceName, $httpFunctionName); 518 | } 519 | 520 | private function checkTriggerResponse($resp, $triggerName, $description, $triggerType, $triggerConfig, $sourceArn, $invocationRole) { 521 | $this->assertEquals($resp['triggerName'], $triggerName); 522 | $this->assertEquals($resp['description'], $description); 523 | $this->assertEquals($resp['triggerType'], $triggerType); 524 | $this->assertEquals($resp['sourceArn'], $sourceArn); 525 | $this->assertEquals($resp['invocationRole'], $invocationRole); 526 | $this->assertTrue(isset($resp['createdTime'])); 527 | $this->assertTrue(isset($resp['lastModifiedTime'])); 528 | $this->assertEquals($resp['triggerConfig'], $triggerConfig); 529 | } 530 | 531 | private function subTestOssTrigger($serviceName, $functionName) { 532 | $triggerType = 'oss'; 533 | $triggerName = 'test-trigger-oss'; 534 | $createTriggerDesc = 'create oss trigger'; 535 | $sourceArn = sprintf("acs:oss:%s:%s:%s", $this->region, $this->accountId, $this->codeBucket); 536 | $prefix = 'pre' . createUuid(); 537 | $suffix = 'suf' . createUuid(); 538 | $triggerConfig = [ 539 | 'events' => ['oss:ObjectCreated:*'], 540 | 'filter' => [ 541 | 'key' => [ 542 | 'prefix' => $prefix, 543 | 'suffix' => $suffix, 544 | ], 545 | ], 546 | ]; 547 | $ret = $this->fcClient->createTrigger( 548 | $serviceName, 549 | $functionName, 550 | array( 551 | 'triggerName' => $triggerName, 552 | 'description' => $createTriggerDesc, 553 | 'triggerType' => $triggerType, 554 | 'invocationRole' => $this->invocationRoleOss, 555 | 'sourceArn' => $sourceArn, 556 | 'triggerConfig' => $triggerConfig, 557 | ) 558 | ); 559 | 560 | $triggerData = $ret['data']; 561 | $this->checkTriggerResponse($triggerData, $triggerName, $createTriggerDesc, $triggerType, $triggerConfig, $sourceArn, $this->invocationRoleOss); 562 | 563 | $err = ''; 564 | try { 565 | $this->fcClient->createTrigger( 566 | $serviceName, 567 | $functionName, 568 | array( 569 | 'triggerName' => $triggerName, 570 | 'triggerType' => $triggerType, 571 | 'invocationRole' => $this->invocationRoleOss, 572 | 'sourceArn' => $sourceArn, 573 | 'triggerConfig' => $triggerConfig, 574 | ) 575 | ); 576 | } catch (Exception $e) { 577 | $err = $e->getMessage(); 578 | } 579 | $this->assertTrue($err != ''); 580 | 581 | $getTriggerData = $this->fcClient->getTrigger($serviceName, $functionName, $triggerName)['data']; 582 | $this->checkTriggerResponse($getTriggerData, $triggerName, $createTriggerDesc, $triggerType, $triggerConfig, $sourceArn, $this->invocationRoleOss); 583 | 584 | $prefixUpdate = $prefix . 'update'; 585 | $suffixUpdate = $suffix . 'update'; 586 | $updateTriggerDesc = 'update oss trigger'; 587 | $triggerConfigUpdate = [ 588 | 'events' => ['oss:ObjectCreated:*'], 589 | 'filter' => [ 590 | 'key' => [ 591 | 'prefix' => $prefixUpdate, 592 | 'suffix' => $suffixUpdate, 593 | ], 594 | ], 595 | ]; 596 | 597 | $ret = $this->fcClient->updateTrigger( 598 | $serviceName, 599 | $functionName, 600 | $triggerName, 601 | array( 602 | 'invocationRole' => $this->invocationRoleOss, 603 | 'triggerConfig' => $triggerConfigUpdate, 604 | 'description' => $updateTriggerDesc, 605 | ) 606 | ); 607 | 608 | $updateTriggerData = $ret['data']; 609 | $this->checkTriggerResponse($updateTriggerData, $triggerName, $updateTriggerDesc, $triggerType, $triggerConfigUpdate, $sourceArn, $this->invocationRoleOss); 610 | $this->fcClient->deleteTrigger($serviceName, $functionName, $triggerName); 611 | 612 | for ($i = 1; $i < 6; $i++) { 613 | $triggerConfig = [ 614 | 'events' => ['oss:ObjectCreated:*'], 615 | 'filter' => [ 616 | 'key' => [ 617 | 'prefix' => $prefixUpdate . strval($i), 618 | 'suffix' => $suffixUpdate . strval($i), 619 | ], 620 | ], 621 | ]; 622 | $this->fcClient->createTrigger( 623 | $serviceName, 624 | $functionName, 625 | array( 626 | 'triggerName' => $triggerName . strval($i), 627 | 'triggerType' => $triggerType, 628 | 'invocationRole' => $this->invocationRoleOss, 629 | 'sourceArn' => $sourceArn, 630 | 'triggerConfig' => $triggerConfig, 631 | ) 632 | ); 633 | } 634 | $listTriggerResp = $this->fcClient->listTriggers($serviceName, $functionName)['data']; 635 | $this->assertEquals(count($listTriggerResp['triggers']), 5); 636 | $listTriggerResp = $this->fcClient->listTriggers($serviceName, $functionName, ["limit" => 2])['data']; 637 | $numCalled = 1; 638 | while (isset($listTriggerResp['nextToken'])) { 639 | $listTriggerResp = $this->fcClient->listTriggers($serviceName, $functionName, 640 | ["limit" => 2, "nextToken" => $listTriggerResp['nextToken']])['data']; 641 | $numCalled += 1; 642 | } 643 | $this->assertEquals($numCalled, 3); 644 | 645 | for ($i = 1; $i < 6; $i++) { 646 | $this->fcClient->deleteTrigger($serviceName, $functionName, $triggerName . strval($i)); 647 | } 648 | } 649 | 650 | private function subTestLogTrigger($serviceName, $functionName) { 651 | $triggerType = 'log'; 652 | $triggerName = 'test-trigger-sls'; 653 | $createTriggerDesc = 'create log trigger'; 654 | $sourceArn = sprintf('acs:log:%s:%s:project/%s', $this->region, $this->accountId, $this->logProject); 655 | 656 | $triggerConfig = [ 657 | 'sourceConfig' => [ 658 | 'logstore' => $this->logStore . '_source', 659 | ], 660 | 'jobConfig' => [ 661 | 'triggerInterval' => 60, 662 | 'maxRetryTime' => 10, 663 | ], 664 | 'functionParameter' => ["a" => "b"], 665 | 'logConfig' => [ 666 | 'project' => $this->logProject, 667 | 'logstore' => $this->logStore, 668 | ], 669 | 'enable' => false, 670 | ]; 671 | 672 | $ret = $this->fcClient->createTrigger( 673 | $serviceName, 674 | $functionName, 675 | array( 676 | 'triggerName' => $triggerName, 677 | 'description' => $createTriggerDesc, 678 | 'triggerType' => $triggerType, 679 | 'invocationRole' => $this->invocationRoleSls, 680 | 'sourceArn' => $sourceArn, 681 | 'triggerConfig' => $triggerConfig, 682 | ) 683 | ); 684 | 685 | $triggerData = $ret['data']; 686 | $this->checkTriggerResponse($triggerData, $triggerName, $createTriggerDesc, $triggerType, $triggerConfig, $sourceArn, $this->invocationRoleSls); 687 | 688 | $err = ''; 689 | try { 690 | $this->fcClient->createTrigger( 691 | $serviceName, 692 | $functionName, 693 | array( 694 | 'triggerName' => $triggerName, 695 | 'triggerType' => $triggerType, 696 | 'invocationRole' => $this->invocationRoleSls, 697 | 'sourceArn' => $sourceArn, 698 | 'triggerConfig' => $triggerConfig, 699 | ) 700 | ); 701 | } catch (Exception $e) { 702 | $err = $e->getMessage(); 703 | } 704 | $this->assertTrue($err != ''); 705 | 706 | $getTriggerData = $this->fcClient->getTrigger($serviceName, $functionName, $triggerName)['data']; 707 | $this->checkTriggerResponse($getTriggerData, $triggerName, $createTriggerDesc, $triggerType, $triggerConfig, $sourceArn, $this->invocationRoleSls); 708 | 709 | $updateTriggerDesc = 'update log trigger'; 710 | $triggerConfigUpdate = [ 711 | 'sourceConfig' => [ 712 | 'logstore' => $this->logStore . '_source', 713 | ], 714 | 'jobConfig' => [ 715 | 'triggerInterval' => 5, 716 | 'maxRetryTime' => 80, 717 | ], 718 | 'functionParameter' => ["a" => "b"], 719 | 'logConfig' => [ 720 | 'project' => $this->logProject, 721 | 'logstore' => $this->logStore, 722 | ], 723 | 'enable' => false, 724 | ]; 725 | 726 | $ret = $this->fcClient->updateTrigger( 727 | $serviceName, 728 | $functionName, 729 | $triggerName, 730 | array( 731 | 'description' => $updateTriggerDesc, 732 | 'invocationRole' => $this->invocationRoleSls, 733 | 'triggerConfig' => $triggerConfigUpdate, 734 | ) 735 | ); 736 | 737 | $updateTriggerData = $ret['data']; 738 | $this->checkTriggerResponse($updateTriggerData, $triggerName, $updateTriggerDesc, $triggerType, $triggerConfigUpdate, $sourceArn, $this->invocationRoleSls); 739 | $this->assertEquals($updateTriggerData['triggerConfig']['jobConfig']['triggerInterval'], 5); 740 | $this->assertEquals($updateTriggerData['triggerConfig']['jobConfig']['maxRetryTime'], 80); 741 | $this->fcClient->deleteTrigger($serviceName, $functionName, $triggerName); 742 | } 743 | 744 | private function subTestHttpTrigger($serviceName, $functionName) { 745 | $triggerType = 'http'; 746 | $triggerName = 'test-trigger-http'; 747 | $sourceArn = 'dummy_arn'; 748 | $description = 'create http trigger'; 749 | $invocationRole = ''; 750 | 751 | $triggerConfig = [ 752 | 'authType' => 'anonymous', 753 | 'methods' => ['GET', 'POST', 'PUT'], 754 | ]; 755 | 756 | $ret = $this->fcClient->createTrigger( 757 | $serviceName, 758 | $functionName, 759 | array( 760 | 'triggerName' => $triggerName, 761 | 'description' => $description, 762 | 'triggerType' => $triggerType, 763 | 'invocationRole' => $invocationRole, 764 | 'sourceArn' => $sourceArn, 765 | 'triggerConfig' => $triggerConfig, 766 | ) 767 | ); 768 | $triggerData = $ret['data']; 769 | $this->checkTriggerResponse($triggerData, $triggerName, $description, $triggerType, $triggerConfig, null, $invocationRole); 770 | 771 | $getTriggerData = $this->fcClient->getTrigger($serviceName, $functionName, $triggerName)['data']; 772 | $this->checkTriggerResponse($getTriggerData, $triggerName, $description, $triggerType, $triggerConfig, null, $invocationRole); 773 | 774 | $triggerConfigUpdate = [ 775 | 'authType' => 'function', 776 | 'methods' => ['GET', 'POST'], 777 | ]; 778 | 779 | $updateTriggerDesc = 'update http trigger'; 780 | $ret = $this->fcClient->updateTrigger( 781 | $serviceName, 782 | $functionName, 783 | $triggerName, 784 | array( 785 | 'description' => $updateTriggerDesc, 786 | 'invocationRole' => $invocationRole, 787 | 'triggerConfig' => $triggerConfigUpdate, 788 | ) 789 | ); 790 | 791 | $updateTriggerData = $ret['data']; 792 | $this->checkTriggerResponse($updateTriggerData, $triggerName, $updateTriggerDesc, $triggerType, $triggerConfigUpdate, null, $invocationRole); 793 | $this->assertEquals($updateTriggerData['triggerConfig']['authType'], 'function'); 794 | 795 | $headers = [ 796 | 'Foo' => 'Bar', 797 | ]; 798 | $query = [ 799 | 'key with space' => 'value with space', 800 | 'key' => 'value', 801 | ]; 802 | $res = $this->fcClient->doHttpRequest('POST', $serviceName, $functionName, '/action%20with%20space', $headers, $query, 'hello world'); 803 | $this->assertEquals($res->getStatusCode(), 202); 804 | $this->assertEquals($res->getBody()->getContents(), 'hello world'); 805 | 806 | $res = $this->fcClient->doHttpRequest('POST', $serviceName, $functionName, '/'); 807 | $this->assertEquals($res->getStatusCode(), 202); 808 | $this->assertEquals($res->getBody()->getContents(), ''); 809 | 810 | $err = ''; 811 | try { 812 | $this->fcClient->doHttpRequest('POST', $serviceName, $functionName, '/action%20with%20space', [], 123, 'hello world'); 813 | } catch (Exception $e) { 814 | $err = $e->getMessage(); 815 | } 816 | $this->assertTrue($err != ''); 817 | 818 | $err = ''; 819 | try { 820 | $this->fcClient->updateTrigger( 821 | $serviceName . 'invalid', 822 | $functionName, 823 | $triggerName, 824 | array( 825 | 'invocationRole' => $invocationRole, 826 | 'triggerConfig' => $triggerConfigUpdate, 827 | ) 828 | ); 829 | } catch (Exception $e) { 830 | $err = $e->getMessage(); 831 | } 832 | $this->assertTrue($err != ''); 833 | 834 | $listTriggerResp = $this->fcClient->listTriggers($serviceName, $functionName)['data']; 835 | $this->assertEquals(count($listTriggerResp['triggers']), 1); 836 | $this->fcClient->deleteTrigger($serviceName, $functionName, $triggerName); 837 | } 838 | 839 | public function testListReservedCapacities() { 840 | $r = $this->fcClient->listReservedCapacities(["limit" => 5]); 841 | $r = $r['data']; 842 | $rcs = $r['reservedCapacities']; 843 | $this->assertLessThanOrEqual(5, count($rcs)); 844 | 845 | for ($i=0; $iassertEquals(strlen($rcs[i]['instanceId']), 22); 847 | $this->assertGreaterThan(0, $rcs[i]['cu']); 848 | $this->assertGreaterThan($rcs[i]['createdTime'], $rcs[i]['deadline']); 849 | $this->assertNotNull($rcs[i]['lastModifiedTime']); 850 | $this->assertNotNull($rcs[i]['isRefunded']); 851 | } 852 | } 853 | 854 | public function testException() { 855 | $err = ''; 856 | try { 857 | $fcClient = new Client([ 858 | 'accessKeyID' => 'ACCESS_KEY_ID', 859 | 'accessKeySecret' => 'ACCESS_KEY_SECRET', 860 | ]); 861 | } catch (Exception $e) { 862 | $err = $e->getMessage(); 863 | } 864 | $this->assertTrue($err != ''); 865 | } 866 | 867 | public function testTag() { 868 | $prefix = $this->serviceName . "test_php_tag_"; 869 | try { 870 | for ($i = 0; $i <= 3; $i++) { 871 | $this->fcClient->createService($prefix . $i); 872 | $resourceArn = sprintf("acs:fc:%s:%s:services/%s", $this->region, $this->accountId, $prefix . $i); 873 | $this->fcClient->tagResource([ 874 | "resourceArn" => $resourceArn, 875 | "tags" => ["k3" => "v3"], 876 | ]); 877 | if ($i % 2 == 0) { 878 | $this->fcClient->tagResource([ 879 | "resourceArn" => $resourceArn, 880 | "tags" => ["k1" => "v1"], 881 | ]); 882 | } else { 883 | $this->fcClient->tagResource([ 884 | "resourceArn" => $resourceArn, 885 | "tags" => ["k2" => "v2"], 886 | ]); 887 | } 888 | } 889 | 890 | $services = $this->fcClient->listServices(['prefix' => $prefix])['data']['services']; 891 | $this->assertEquals(count($services), 4); 892 | $services = $this->fcClient->listServices(['prefix' => $prefix, 'tags' => ["k1" => "v1"]])['data']['services']; 893 | $this->assertEquals(count($services), 2); 894 | $services = $this->fcClient->listServices(['prefix' => $prefix, 'tags' => ["k2" => "v2"]])['data']['services']; 895 | $this->assertEquals(count($services), 2); 896 | $services = $this->fcClient->listServices(['prefix' => $prefix, 'tags' => ["k3" => "v3"]])['data']['services']; 897 | $this->assertEquals(count($services), 4); 898 | $services = $this->fcClient->listServices(['prefix' => $prefix, 'tags' => ["k1" => "v1", "k2" => "v2"]])['data']['services']; 899 | $this->assertEquals(count($services), 0); 900 | 901 | for ($i = 0; $i <= 3; $i++) { 902 | $resourceArn = sprintf("acs:fc:%s:%s:services/%s", $this->region, $this->accountId, $prefix . $i); 903 | $resp = $this->fcClient->getResourceTags(["resourceArn" => $resourceArn])['data']; 904 | // var_export($resp); 905 | $this->assertEquals($resourceArn, $resp['resourceArn']); 906 | if ($i % 2 == 0) { 907 | $this->assertEquals(0, count(array_diff($resp['tags'], ["k1" => "v1", "k3" => "v3"]))); 908 | } else { 909 | $this->assertEquals(0, count(array_diff($resp['tags'], ["k2" => "v2", "k3" => "v3"]))); 910 | } 911 | $this->fcClient->untagResource([ 912 | "resourceArn" => $resourceArn, 913 | "tagKeys" => ["k3"], 914 | "all" => false, 915 | ] 916 | ); 917 | $resp = $this->fcClient->getResourceTags(["resourceArn" => $resourceArn])['data']; 918 | $this->assertEquals($resourceArn, $resp['resourceArn']); 919 | if ($i % 2 == 0) { 920 | $this->assertEquals(0, count(array_diff($resp['tags'], ["k1" => "v1"]))); 921 | } else { 922 | $this->assertEquals(0, count(array_diff($resp['tags'], ["k2" => "v2"]))); 923 | } 924 | $this->fcClient->untagResource(["resourceArn" => $resourceArn, "tagKeys" => [], "all" => true]); 925 | $resp = $this->fcClient->getResourceTags(["resourceArn" => $resourceArn])['data']; 926 | $this->assertEquals($resourceArn, $resp['resourceArn']); 927 | $this->assertEquals(0, count($resp['tags'])); 928 | } 929 | } catch (Exception $e) { 930 | 931 | } finally { 932 | for ($x = 0; $x <= 3; $x++) { 933 | try { 934 | $resourceArn = sprintf("acs:fc:%s:%s:services/%s", $this->region, $this->accountId, $prefix . $i); 935 | $this->fcClient->untagResource(["resourceArn" => $resourceArn, "tagKeys" => [], "all" => true]); 936 | $this->fcClient->deleteService($prefix . $x); 937 | } catch (Exception $e) {} 938 | } 939 | } 940 | } 941 | } 942 | -------------------------------------------------------------------------------- /test/counter.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aliyun/fc-php-sdk/4a1db20a73d5689ef98867d47f91ee66270f5e02/test/counter.zip -------------------------------------------------------------------------------- /test/index.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aliyun/fc-php-sdk/4a1db20a73d5689ef98867d47f91ee66270f5e02/test/index.zip -------------------------------------------------------------------------------- /test/index_http.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aliyun/fc-php-sdk/4a1db20a73d5689ef98867d47f91ee66270f5e02/test/index_http.zip -------------------------------------------------------------------------------- /test/new_index.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aliyun/fc-php-sdk/4a1db20a73d5689ef98867d47f91ee66270f5e02/test/new_index.zip -------------------------------------------------------------------------------- /test/versioning_test.php: -------------------------------------------------------------------------------- 1 | serviceName = "Test-Php-SDK" . createUuid(); 21 | $this->fcClient = new Client([ 22 | 'accessKeyID' => getenv('ACCESS_KEY_ID'), 23 | 'accessKeySecret' => getenv('ACCESS_KEY_SECRET'), 24 | 'endpoint' => getenv('ENDPOINT'), 25 | ]); 26 | $this->clearAllTestRes(); 27 | $this->initOpts(); 28 | $this->codeBucket = getenv('CODE_BUCKET'); 29 | $this->accountId = getenv('ACCOUNT_ID'); 30 | $this->region = getenv('REGION'); 31 | $this->invocationRoleOss = getenv('INVOCATION_ROLE_OSS'); 32 | $this->invocationRoleSls = getenv('INVOCATION_ROLE_SLS'); 33 | $this->logProject = getenv('LOG_PROJECT'); 34 | $this->logStore = getenv('LOG_STORE'); 35 | } 36 | 37 | private function initOpts() { 38 | $role = getenv('SERVICE_ROLE'); 39 | $logProject = getenv('LOG_PROJECT'); 40 | $logStore = getenv('LOG_STORE'); 41 | $vpcId = getenv('VPC_ID'); 42 | $vSwitchIds = getenv('VSWITCH_IDS'); 43 | $securityGroupId = getenv('SECURITY_GROUP_ID'); 44 | $vpcRole = getenv('VPC_ROLE'); 45 | $userId = getenv('USER_ID'); 46 | $groupId = getenv('GROUP_ID'); 47 | $nasServerAddr = getenv('NAS_SERVER_ADDR'); 48 | $nasMountDir = getenv('NAS_MOUNT_DIR'); 49 | 50 | $nasConfig = array( 51 | "userId" => intval($userId), 52 | "groupId" => intval($groupId), 53 | "mountPoints" => array( 54 | [ 55 | "serverAddr" => $nasServerAddr, 56 | "mountDir" => $nasMountDir, 57 | ], 58 | ), 59 | ); 60 | 61 | $vpcConfig = array( 62 | 'vpcId' => $vpcId, 63 | 'vSwitchIds' => array($vSwitchIds), 64 | 'securityGroupId' => $securityGroupId, 65 | ); 66 | 67 | $this->opts = array( 68 | "logConfig" => array( 69 | "project" => $logProject, 70 | "logstore" => $logStore, 71 | "enableRequestMetrics" => false, 72 | "enableInstanceMetrics" => false, 73 | ), 74 | "role" => $role, 75 | "vpcConfig" => $vpcConfig, 76 | //"nasConfig" => $nasConfig, 77 | 'internetAccess' => true, 78 | ); 79 | } 80 | 81 | public function tearDown() { 82 | $this->clearAllTestRes(); 83 | } 84 | 85 | private function clearAllTestRes() { 86 | try { 87 | $serviceName = $this->serviceName; 88 | $r = $this->fcClient->listFunctions($serviceName); 89 | $functions = $r['data']['functions']; 90 | foreach ($functions as $func) { 91 | $functionName = $func['functionName']; 92 | $tr = $this->fcClient->listTriggers($serviceName, $functionName); 93 | $triggers = $tr['data']['triggers']; 94 | foreach ($triggers as $t) { 95 | $triggerName = $t['triggerName']; 96 | $this->fcClient->deleteTrigger($serviceName, $functionName, $triggerName); 97 | } 98 | $this->fcClient->deleteFunction($serviceName, $functionName); 99 | } 100 | 101 | // clear all versions and alias 102 | $data = $this->fcClient->listVersions($serviceName)['data']; 103 | $versions = $data['versions']; 104 | $nextToken = isset($data['nextToken']) ? $data['nextToken'] : null; 105 | while ($nextToken != null || $nextToken != "") { 106 | $data = $this->fcClient->listVersions($serviceName, ["nextToken" => nextToken])['data']; 107 | $versions = array_merge($data['versions'], $versions); 108 | $nextToken = isset($data['nextToken']) ? $data['nextToken'] : null; 109 | 110 | } 111 | 112 | foreach ($versions as $v) { 113 | $this->fcClient->deleteVersion($serviceName, $v['versionId']); 114 | } 115 | 116 | $data = $this->fcClient->listAliases($serviceName)['data']; 117 | $aliases = $data['aliases']; 118 | $nextToken = isset($data['nextToken']) ? $data['nextToken'] : null; 119 | while ($nextToken != null || $nextToken != "") { 120 | $data = $this->fcClient->listAliases($serviceName, ["nextToken" => nextToken])['data']; 121 | $aliases = array_merge($data['aliases'], $aliases); 122 | $nextToken = isset($data['nextToken']) ? $data['nextToken'] : null; 123 | 124 | } 125 | 126 | foreach ($aliases as $a) { 127 | $this->fcClient->deleteAlias($serviceName, $a['aliasName']); 128 | } 129 | 130 | $this->fcClient->deleteService($serviceName); 131 | 132 | $data = $this->fcClient->listFunctionAsyncConfigs($serviceName, $functionName, ["limit"=>2])['data']; 133 | foreach ($data['configs'] as $c) { 134 | $this->fcClient->deleteFunctionAsyncConfig($c['service'], $c['qualifier'], $c['function']); 135 | 136 | } 137 | } catch (Exception $e) { 138 | } 139 | } 140 | 141 | public function testVersion() { 142 | $serviceName = $this->serviceName; 143 | $serviceDesc = "测试的service, php sdk 创建"; 144 | $this->fcClient->createService( 145 | $serviceName, 146 | $serviceDesc, 147 | $options = $this->opts 148 | ); 149 | 150 | $data = $this->fcClient->publishVersion($serviceName, "test service v1")['data']; 151 | $this->assertTrue(isset($data['versionId'])); 152 | $this->assertEquals($data['description'], 'test service v1'); 153 | $this->assertTrue(isset($data['createdTime'])); 154 | $this->assertTrue(isset($data['lastModifiedTime'])); 155 | $v1 = $data['versionId']; 156 | 157 | $err = ''; 158 | try { 159 | $this->fcClient->publishVersion($serviceName, "test service v2"); 160 | } catch (Exception $e) { 161 | $err = $e->getMessage(); 162 | } 163 | 164 | $this->assertTrue($err != ""); 165 | 166 | $err = ''; 167 | try { 168 | $this->fcClient->deleteService($serviceName); 169 | } catch (Exception $e) { 170 | $err = $e->getMessage(); 171 | } 172 | $this->assertTrue($err != ""); 173 | 174 | $this->fcClient->deleteVersion($serviceName, $v1); 175 | 176 | $data = $this->fcClient->listVersions($serviceName, ['limit' => 2])['data']; 177 | $versions = $data['versions']; 178 | $this->assertEquals(count($versions), 0); 179 | 180 | $num = 6; 181 | for ($i = 0; $i < $num; $i++) { 182 | $desc = 'service description' . strval($i); 183 | $service = $this->fcClient->updateService($serviceName, $desc); 184 | $this->assertEquals($service['data']['description'], $desc); 185 | $version = strVAL($i + 2); 186 | $r = $this->fcClient->publishVersion($serviceName, "test service v" . $version); 187 | $data = $r['data']; 188 | 189 | $this->assertTrue(isset($data['versionId'])); 190 | $this->assertEquals($data['description'], "test service v" . $version); 191 | $this->assertTrue(isset($data['createdTime'])); 192 | $this->assertTrue(isset($data['lastModifiedTime'])); 193 | } 194 | 195 | $data = $this->fcClient->listVersions($serviceName, ['limit' => 2])['data']; 196 | $versions = $data['versions']; 197 | $nextToken = $data['nextToken']; 198 | $this->assertEquals(count($versions), 2); 199 | for ($i = 0; $i < 2; $i++) { 200 | $data = $versions[$i]; 201 | $this->assertTrue(isset($data['versionId'])); 202 | $this->assertTrue(isset($data['description'])); 203 | $this->assertTrue(isset($data['createdTime'])); 204 | $this->assertTrue(isset($data['lastModifiedTime'])); 205 | } 206 | 207 | $this->assertTrue($nextToken != null); 208 | $versions_len = 2; 209 | while ($nextToken != null || $nextToken != "") { 210 | $data = $this->fcClient->listVersions($serviceName, ["nextToken" => $nextToken])["data"]; 211 | $versions = $data['versions']; 212 | $nextToken = isset($data['nextToken']) ? $data['nextToken'] : null; 213 | $versions_len += count($versions); 214 | } 215 | 216 | $this->assertEquals($versions_len, 6); 217 | 218 | } 219 | 220 | public function testAlias() { 221 | $serviceName = $this->serviceName; 222 | $serviceDesc = "测试的service, php sdk 创建"; 223 | $this->fcClient->createService( 224 | $serviceName, 225 | $serviceDesc, 226 | $options = $this->opts 227 | ); 228 | 229 | $data = $this->fcClient->publishVersion($serviceName, "test service v1")['data']; 230 | $this->assertTrue(isset($data['versionId'])); 231 | $this->assertEquals($data['description'], 'test service v1'); 232 | $this->assertTrue(isset($data['createdTime'])); 233 | $this->assertTrue(isset($data['lastModifiedTime'])); 234 | $v1 = $data['versionId']; 235 | 236 | $r_data = $this->fcClient->createAlias($serviceName, 237 | ['aliasName' => 'test', 238 | 'versionId' => $v1, 239 | 'description' => 'test alias', 240 | 'additionalVersionWeight' => ["1" => 0.9], 241 | ])['data']; 242 | 243 | $this->assertEquals($r_data['aliasName'], "test"); 244 | $this->assertEquals($r_data['versionId'], $v1); 245 | $this->assertEquals($r_data['description'], "test alias"); 246 | $this->assertEquals($r_data['additionalVersionWeight'], ["1" => 0.9]); 247 | $this->assertTrue(isset($r_data['createdTime'])); 248 | $this->assertTrue(isset($r_data['lastModifiedTime'])); 249 | 250 | $r_data = $this->fcClient->getAlias($serviceName, "test")['data']; 251 | $this->assertEquals($r_data['aliasName'], "test"); 252 | $this->assertEquals($r_data['versionId'], $v1); 253 | $this->assertEquals($r_data['description'], "test alias"); 254 | $this->assertEquals($r_data['additionalVersionWeight'], ["1" => 0.9]); 255 | $this->assertTrue(isset($r_data['createdTime'])); 256 | $this->assertTrue(isset($r_data['lastModifiedTime'])); 257 | 258 | $r_data = $this->fcClient->updateAlias($serviceName, "test", 259 | ['versionId' => $v1, 260 | 'description' => "test alias_update", 261 | 'additionalVersionWeight' => ["1" => 0.8], 262 | ])['data']; 263 | $this->assertEquals($r_data['aliasName'], "test"); 264 | $this->assertEquals($r_data['versionId'], $v1); 265 | $this->assertEquals($r_data['description'], "test alias_update"); 266 | $this->assertEquals($r_data['additionalVersionWeight'], ["1" => 0.8]); 267 | $this->assertTrue(isset($r_data['createdTime'])); 268 | $this->assertTrue(isset($r_data['lastModifiedTime'])); 269 | 270 | $this->fcClient->deleteAlias($serviceName, "test"); 271 | 272 | $err = ''; 273 | try { 274 | $this->fcClient->getAlias($serviceName, "test")['data']; 275 | } catch (Exception $e) { 276 | $err = $e->getMessage(); 277 | } 278 | $this->assertTrue($err != ""); 279 | 280 | $num = 6; 281 | for ($i = 0; $i < $num; $i++) { 282 | $desc = 'service description' . strval($i); 283 | $service = $this->fcClient->updateService($serviceName, $desc); 284 | $this->assertEquals($service['data']['description'], $desc); 285 | $version = strval($i + 2); 286 | $this->fcClient->publishVersion($serviceName, "test service v" . $version); 287 | 288 | $this->fcClient->createAlias($serviceName, 289 | ['aliasName' => "test" . strval($version), 290 | 'versionId' => $v1, 291 | 'description' => "test alias" . strval($version), 292 | 'additionalVersionWeight' => ["1" => 0.9], 293 | ]); 294 | } 295 | 296 | $data = $this->fcClient->listAliases($serviceName, ['limit' => 2])['data']; 297 | $aliases = $data['aliases']; 298 | $nextToken = $data['nextToken']; 299 | $this->assertEquals(count($aliases), 2); 300 | for ($i = 0; $i < 2; $i++) { 301 | $data = $aliases[$i]; 302 | $this->assertTrue(isset($data['aliasName'])); 303 | $this->assertTrue(isset($data['versionId'])); 304 | $this->assertTrue(isset($data['description'])); 305 | $this->assertTrue(isset($data['createdTime'])); 306 | $this->assertTrue(isset($data['lastModifiedTime'])); 307 | } 308 | 309 | $this->assertTrue($nextToken != null); 310 | 311 | $versions_len = 2; 312 | while ($nextToken != null || $nextToken != "") { 313 | $data = $this->fcClient->listAliases($serviceName, ["nextToken" => $nextToken])["data"]; 314 | $aliases = $data['aliases']; 315 | $nextToken = isset($data['nextToken']) ? $data['nextToken'] : null; 316 | $versions_len += count($aliases); 317 | } 318 | 319 | $this->assertEquals($versions_len, 6); 320 | } 321 | 322 | public function testGetService() { 323 | $serviceName = $this->serviceName; 324 | $serviceDesc = "测试的service, php sdk 创建"; 325 | $this->fcClient->createService( 326 | $serviceName, 327 | $serviceDesc, 328 | $options = $this->opts 329 | ); 330 | 331 | $data = $this->fcClient->publishVersion($serviceName, "test service v1 desc")['data']; 332 | $this->assertTrue(isset($data['versionId'])); 333 | $this->assertEquals($data['description'], 'test service v1 desc'); 334 | $this->assertTrue(isset($data['createdTime'])); 335 | $this->assertTrue(isset($data['lastModifiedTime'])); 336 | $v1 = $data['versionId']; 337 | 338 | $service = $this->fcClient->getService($serviceName, [], $v1)['data']; 339 | $this->assertEquals($service['serviceName'], $serviceName); 340 | $this->assertEquals($service['description'], "test service v1 desc"); 341 | 342 | $service = $this->fcClient->getService($serviceName)['data']; 343 | $this->assertEquals($service['serviceName'], $serviceName); 344 | $this->assertEquals($service['description'], $serviceDesc); 345 | 346 | $service = $this->fcClient->updateService($serviceName, "update test service v2 desc"); 347 | $data = $this->fcClient->publishVersion($serviceName, "test service v2 desc")['data']; 348 | $v2 = $data['versionId']; 349 | 350 | $service = $this->fcClient->getService($serviceName, [], $v2)['data']; 351 | $this->assertEquals($service['serviceName'], $serviceName); 352 | $this->assertEquals($service['description'], "test service v2 desc"); 353 | 354 | $service = $this->fcClient->getService($serviceName)['data']; 355 | $this->assertEquals($service['serviceName'], $serviceName); 356 | $this->assertEquals($service['description'], "update test service v2 desc"); 357 | 358 | $this->fcClient->createAlias($serviceName, 359 | ['aliasName' => 'test', 360 | 'versionId' => $v1, 361 | 'description' => 'test alias', 362 | 'additionalVersionWeight' => ["1" => 0.9], 363 | ]); 364 | 365 | $service = $this->fcClient->getService($serviceName, [], "test")['data']; 366 | $this->assertEquals($service['serviceName'], $serviceName); 367 | $this->assertEquals($service['description'], "test service v1 desc"); 368 | } 369 | 370 | public function testGetFunction() { 371 | $serviceName = $this->serviceName; 372 | $serviceDesc = "测试的service, php sdk 创建"; 373 | $this->fcClient->createService( 374 | $serviceName, 375 | $serviceDesc, 376 | $options = $this->opts 377 | ); 378 | 379 | $functionName = 'test_function'; 380 | $desc = '这是测试function'; 381 | 382 | $function = $this->fcClient->createFunction( 383 | $serviceName, 384 | array( 385 | 'functionName' => $functionName, 386 | 'handler' => 'index.handler', 387 | 'runtime' => 'php7.2', 388 | 'memorySize' => 128, 389 | 'code' => array( 390 | 'zipFile' => base64_encode(file_get_contents(__DIR__ . '/index.zip')), 391 | ), 392 | 'description' => $desc, 393 | ) 394 | ); 395 | 396 | $function = $function['data']; 397 | $checksum = $function['codeChecksum']; 398 | $this->checkFunction($functionName, $desc, $checksum, 'php7.2', 'index.handler'); 399 | 400 | $data = $this->fcClient->publishVersion($serviceName, "test service v1 desc")['data']; 401 | $v1 = $data['versionId']; 402 | $this->fcClient->createAlias($serviceName, 403 | ['aliasName' => 'test', 404 | 'versionId' => $v1, 405 | 'description' => 'test alias', 406 | 'additionalVersionWeight' => ["1" => 0.9], 407 | ]); 408 | 409 | $this->checkFunction($functionName, $desc, $checksum, 'php7.2', 'index.handler', $v1); 410 | $this->checkFunction($functionName, $desc, $checksum, 'php7.2', 'index.handler', "test"); 411 | 412 | $data = $this->fcClient->putProvisionConfig($serviceName, "test", $functionName, ["target"=>10])['data']; 413 | $this->assertEquals(10, $data['target']); 414 | $this->assertEquals($this->accountId."#". $serviceName . "#test#". $functionName, $data['resource']); 415 | 416 | $data = $this->fcClient->getProvisionConfig($serviceName, "test", $functionName)['data']; 417 | $this->assertEquals(10, $data['target']); 418 | $this->assertEquals($this->accountId."#". $serviceName . "#test#". $functionName, $data['resource']); 419 | $this->assertTrue($data['current']>=0); 420 | 421 | $data = $this->fcClient->listProvisionConfigs($serviceName, "test")['data']; 422 | $this->assertEquals(1, count($data['provisionConfigs'])); 423 | $data = $data['provisionConfigs'][0]; 424 | $this->assertEquals(10, $data['target']); 425 | $this->assertEquals($this->accountId."#". $serviceName . "#test#". $functionName, $data['resource']); 426 | $this->assertTrue($data['current']>=0); 427 | 428 | $err = ''; 429 | try { 430 | $this->fcClient->listProvisionConfigs($serviceName, "test", ["limit"=>0])['data']; 431 | } catch (Exception $e) { 432 | $err = $e->getMessage(); 433 | } 434 | $this->assertTrue($err != ""); 435 | 436 | $this->fcClient->putProvisionConfig($serviceName, "test", $functionName, ["target"=>0])['data']; 437 | 438 | $ret = $this->fcClient->updateFunction( 439 | $serviceName, 440 | $functionName, 441 | array( 442 | 'handler' => 'hello_world.handler', 443 | 'runtime' => 'nodejs6', 444 | 'memorySize' => 256, 445 | 'code' => array( 446 | 'ossBucketName' => $this->codeBucket, 447 | 'ossObjectName' => "hello_world_nodejs.zip", 448 | ), 449 | 'description' => "update function desc", 450 | 'environmentVariables' => ['newTestKey' => 'newTestValue'], 451 | ) 452 | ); 453 | $function = $ret['data']; 454 | $checksum2 = $function['codeChecksum']; 455 | $this->assertTrue($checksum != $checksum2); 456 | $this->checkFunction($functionName, "update function desc", $checksum2, 'nodejs6', 'hello_world.handler'); 457 | $data = $this->fcClient->publishVersion($serviceName, "test service v2 desc")['data']; 458 | $v2 = $data['versionId']; 459 | $this->fcClient->createAlias($serviceName, 460 | ['aliasName' => 'prod', 461 | 'versionId' => $v2, 462 | 'description' => 'test alias', 463 | 'additionalVersionWeight' => ["1" => 0.8], 464 | ]); 465 | $this->checkFunction($functionName, "update function desc", $checksum2, 'nodejs6', 'hello_world.handler', $v2); 466 | $this->checkFunction($functionName, "update function desc", $checksum2, 'nodejs6', 'hello_world.handler', "prod"); 467 | 468 | } 469 | 470 | private function checkFunction($functionName, $desc, $checksum, $runtime = 'python2.7', $handler = 'index.handler', $qualifier = null) { 471 | $serviceName = $this->serviceName; 472 | $function = $this->fcClient->getFunction($serviceName, $functionName, [], $qualifier)['data']; 473 | $this->assertEquals($function['functionName'], $functionName); 474 | $this->assertEquals($function['runtime'], $runtime); 475 | $this->assertEquals($function['handler'], $handler); 476 | $this->assertEquals($function['description'], $desc); 477 | 478 | $code = $this->fcClient->getFunctionCode($serviceName, $functionName, [], $qualifier)['data']; 479 | $this->assertEquals($code['checksum'], $checksum); 480 | $this->assertTrue($code['url'] != ''); 481 | } 482 | 483 | public function testListFunctions() { 484 | $serviceName = $this->serviceName; 485 | $serviceDesc = "测试的service, php sdk 创建"; 486 | $this->fcClient->createService( 487 | $serviceName, 488 | $serviceDesc, 489 | $options = $this->opts 490 | ); 491 | $prefix = 'test_list_'; 492 | 493 | $f = function ($serviceName, $functionName) { 494 | $this->fcClient->createFunction( 495 | $serviceName, 496 | array( 497 | 'functionName' => $functionName, 498 | 'handler' => 'index.handler', 499 | 'runtime' => 'php7.2', 500 | 'code' => array( 501 | 'zipFile' => base64_encode(file_get_contents(__DIR__ . '/index.zip')), 502 | ), 503 | ) 504 | ); 505 | }; 506 | 507 | $f($serviceName, $prefix . "abc"); 508 | $f($serviceName, $prefix . "abd"); 509 | $f($serviceName, $prefix . "ade"); 510 | 511 | $data = $this->fcClient->publishVersion($serviceName, "test service v1 desc")['data']; 512 | $v1 = $data['versionId']; 513 | $this->fcClient->createAlias($serviceName, 514 | ['aliasName' => 'test', 515 | 'versionId' => $v1, 516 | 'description' => 'test alias', 517 | 'additionalVersionWeight' => ["1" => 0.9], 518 | ]); 519 | 520 | $f($serviceName, $prefix . "bcd"); 521 | $f($serviceName, $prefix . "bde"); 522 | $f($serviceName, $prefix . "zzz"); 523 | 524 | $data = $this->fcClient->publishVersion($serviceName, "test service v2 desc")['data']; 525 | $v2 = $data['versionId']; 526 | $this->fcClient->createAlias($serviceName, 527 | ['aliasName' => 'prod', 528 | 'versionId' => $v2, 529 | 'description' => 'test alias', 530 | 'additionalVersionWeight' => ["1" => 0.8], 531 | ]); 532 | 533 | $r = $this->fcClient->listFunctions($serviceName)['data']; 534 | $functions = $r['functions']; 535 | $this->assertEquals(count($functions), 6); 536 | 537 | $r1 = $this->fcClient->listFunctions($serviceName, ["qualifier" => $v1])['data']; 538 | $r2 = $this->fcClient->listFunctions($serviceName, ["qualifier" => "test"])['data']; 539 | $this->assertEquals($r1, $r2); 540 | $functions = $r1['functions']; 541 | $this->assertEquals(count($functions), 3); 542 | 543 | $r3 = $this->fcClient->listFunctions($serviceName, ["qualifier" => $v2])['data']; 544 | $r4 = $this->fcClient->listFunctions($serviceName, ["qualifier" => "prod"])['data']; 545 | $this->assertEquals($r3, $r4); 546 | $functions = $r3['functions']; 547 | $this->assertEquals(count($functions), 6); 548 | } 549 | 550 | public function testAsyncConfig() { 551 | $serviceName = $this->serviceName; 552 | $serviceDesc = "测试的service, php sdk 创建"; 553 | $this->fcClient->createService( 554 | $serviceName, 555 | $serviceDesc, 556 | $options = $this->opts 557 | ); 558 | 559 | $functionName = 'test_function'; 560 | $desc = '这是测试function'; 561 | 562 | $function = $this->fcClient->createFunction( 563 | $serviceName, 564 | array( 565 | 'functionName' => $functionName, 566 | 'handler' => 'index.handler', 567 | 'runtime' => 'php7.2', 568 | 'memorySize' => 128, 569 | 'code' => array( 570 | 'zipFile' => base64_encode(file_get_contents(__DIR__ . '/index.zip')), 571 | ), 572 | 'description' => $desc, 573 | ) 574 | ); 575 | 576 | $function = $function['data']; 577 | $checksum = $function['codeChecksum']; 578 | $this->checkFunction($functionName, $desc, $checksum, 'php7.2', 'index.handler'); 579 | 580 | $data = $this->fcClient->publishVersion($serviceName, "test service v1 desc")['data']; 581 | $v1 = $data['versionId']; 582 | $this->fcClient->createAlias($serviceName, 583 | ['aliasName' => 'test', 584 | 'versionId' => $v1, 585 | 'description' => 'test alias', 586 | 'additionalVersionWeight' => ["1" => 0.9], 587 | ]); 588 | 589 | $this->checkFunction($functionName, $desc, $checksum, 'php7.2', 'index.handler', $v1); 590 | $this->checkFunction($functionName, $desc, $checksum, 'php7.2', 'index.handler', "test"); 591 | 592 | $destination = sprintf('acs:fc:%s:%s:services/%s/functions/fc2', $this->region, $this->accoutId, $serviceName); 593 | $asyncConfig = [ 594 | 'destinationConfig' => [ 595 | 'onSuccess' => ['destination'=>$destination], 596 | ], 597 | 'maxAsyncEventAgeInSeconds' => 100, 598 | 'maxAsyncRetryAttempts' => 1, 599 | ]; 600 | $data = $this->fcClient->putFunctionAsyncConfig($serviceName, "test", $functionName, $asyncConfig)['data']; 601 | 602 | $this->assertEquals($serviceName, $data['service']); 603 | $this->assertEquals("test", $data['qualifier']); 604 | $this->assertEquals($functionName, $data['function']); 605 | $this->assertEquals($destination, $data['destinationConfig']['onSuccess']['destination']); 606 | $this->assertNotEmpty($data['lastModifiedTime']); 607 | $this->assertNotEmpty($data['createdTime']); 608 | $this->assertEquals(100, $data['maxAsyncEventAgeInSeconds']); 609 | $this->assertEquals(1, $data['maxAsyncRetryAttempts']); 610 | 611 | $data = $this->fcClient->getFunctionAsyncConfig($serviceName, "test", $functionName)['data']; 612 | $this->assertEquals($serviceName, $data['service']); 613 | $this->assertEquals("test", $data['qualifier']); 614 | $this->assertEquals($functionName, $data['function']); 615 | 616 | $data = $this->fcClient->listFunctionAsyncConfigs($serviceName, $functionName, ["limit"=>2])['data']; 617 | $this->assertEquals(1, count($data['configs'])); 618 | 619 | $this->fcClient->deleteFunctionAsyncConfig($serviceName, "test", $functionName); 620 | 621 | $data2 = $this->fcClient->putFunctionAsyncConfig($serviceName, "LATEST", $functionName, $asyncConfig)['data']; 622 | $this->assertEquals("LATEST", $data2['qualifier']); 623 | 624 | $this->fcClient->deleteFunctionAsyncConfig($serviceName, "LATEST", $functionName); 625 | } 626 | 627 | public function testInvokeFunciton() { 628 | $serviceName = $this->serviceName; 629 | $serviceDesc = "测试的service, php sdk 创建"; 630 | $this->fcClient->createService( 631 | $serviceName, 632 | $serviceDesc, 633 | $options = $this->opts 634 | ); 635 | $functionName = 'test_function'; 636 | $desc = '这是测试function'; 637 | 638 | $function = $this->fcClient->createFunction( 639 | $serviceName, 640 | array( 641 | 'functionName' => $functionName, 642 | 'handler' => 'index.handler', 643 | 'runtime' => 'php7.2', 644 | 'memorySize' => 128, 645 | 'code' => array( 646 | 'zipFile' => base64_encode(file_get_contents(__DIR__ . '/index.zip')), 647 | ), 648 | 'description' => $desc, 649 | ) 650 | ); 651 | $data = $this->fcClient->publishVersion($serviceName, "test service v1 desc")['data']; 652 | $v1 = $data['versionId']; 653 | $this->fcClient->createAlias($serviceName, 654 | ['aliasName' => 'test', 655 | 'versionId' => $v1, 656 | 'description' => 'test alias', 657 | 'additionalVersionWeight' => [$v1 => 1], 658 | ]); 659 | 660 | $ret = $this->fcClient->updateFunction( 661 | $serviceName, 662 | $functionName, 663 | array( 664 | 'handler' => 'index.handler', 665 | 'runtime' => 'php7.2', 666 | 'memorySize' => 128, 667 | 'code' => array( 668 | 'zipFile' => base64_encode(file_get_contents(__DIR__ . '/new_index.zip')), 669 | ), 670 | 'description' => "update function desc", 671 | ) 672 | ); 673 | 674 | $data = $this->fcClient->publishVersion($serviceName, "test service v2 desc")['data']; 675 | $v2 = $data['versionId']; 676 | $this->fcClient->createAlias($serviceName, 677 | ['aliasName' => 'prod', 678 | 'versionId' => $v2, 679 | 'description' => 'test alias', 680 | 'additionalVersionWeight' => [$v2 => 1], 681 | ]); 682 | 683 | $invkRet = $this->fcClient->invokeFunction($serviceName, $functionName); 684 | $this->assertEquals($invkRet['data'], 'new hello world'); 685 | 686 | $invkRet = $this->fcClient->invokeFunction($serviceName, $functionName, '', [], $v1); 687 | $this->assertEquals($invkRet['data'], 'hello world'); 688 | 689 | $invkRet = $this->fcClient->invokeFunction($serviceName, $functionName, '', [], "test"); 690 | $this->assertEquals($invkRet['data'], 'hello world'); 691 | 692 | $invkRet = $this->fcClient->invokeFunction($serviceName, $functionName, '', [], $v2); 693 | $this->assertEquals($invkRet['data'], 'new hello world'); 694 | 695 | $invkRet = $this->fcClient->invokeFunction($serviceName, $functionName, '', [], "prod"); 696 | $this->assertEquals($invkRet['data'], 'new hello world'); 697 | 698 | } 699 | 700 | public function disTrigger() { 701 | $serviceName = $this->serviceName; 702 | $serviceDesc = "测试的service, php sdk 创建"; 703 | $this->fcClient->createService( 704 | $serviceName, 705 | $serviceDesc, 706 | $options = $this->opts 707 | ); 708 | $functionName = 'test_function'; 709 | $desc = '这是测试function'; 710 | 711 | $function = $this->fcClient->createFunction( 712 | $serviceName, 713 | array( 714 | 'functionName' => $functionName, 715 | 'handler' => 'index.handler', 716 | 'runtime' => 'php7.2', 717 | 'memorySize' => 128, 718 | 'code' => array( 719 | 'zipFile' => base64_encode(file_get_contents(__DIR__ . '/index.zip')), 720 | ), 721 | 'description' => $desc, 722 | ) 723 | ); 724 | 725 | $data = $this->fcClient->publishVersion($serviceName, "test service v1 desc")['data']; 726 | $v1 = $data['versionId']; 727 | $this->fcClient->createAlias($serviceName, 728 | ['aliasName' => 'test', 729 | 'versionId' => $v1, 730 | 'description' => 'test alias', 731 | 'additionalVersionWeight' => ["1" => 0.9], 732 | ]); 733 | 734 | $triggerType = 'oss'; 735 | $triggerName = 'test-trigger-oss'; 736 | $sourceArn = sprintf("acs:oss:%s:%s:%s", $this->region, $this->accountId, $this->codeBucket); 737 | $prefix = 'pre' . createUuid(); 738 | $suffix = 'suf' . createUuid(); 739 | $triggerConfig = [ 740 | 'events' => ['oss:ObjectCreated:*'], 741 | 'filter' => [ 742 | 'key' => [ 743 | 'prefix' => $prefix, 744 | 'suffix' => $suffix, 745 | ], 746 | ], 747 | ]; 748 | $ret = $this->fcClient->createTrigger( 749 | $serviceName, 750 | $functionName, 751 | array( 752 | 'triggerName' => $triggerName, 753 | 'triggerType' => $triggerType, 754 | 'invocationRole' => $this->invocationRoleOss, 755 | 'sourceArn' => $sourceArn, 756 | 'triggerConfig' => $triggerConfig, 757 | 'qualifier' => $v1, 758 | ) 759 | ); 760 | $triggerData = $ret['data']; 761 | $this->checkTriggerResponse($triggerData, $triggerName, $triggerType, $triggerConfig, $sourceArn, $this->invocationRoleOss, $v1); 762 | 763 | $prefixUpdate = $prefix . 'update'; 764 | $suffixUpdate = $suffix . 'update'; 765 | $triggerConfigUpdate = [ 766 | 'events' => ['oss:ObjectCreated:*'], 767 | 'filter' => [ 768 | 'key' => [ 769 | 'prefix' => $prefixUpdate, 770 | 'suffix' => $suffixUpdate, 771 | ], 772 | ], 773 | ]; 774 | 775 | $ret = $this->fcClient->updateTrigger( 776 | $serviceName, 777 | $functionName, 778 | $triggerName, 779 | array( 780 | 'invocationRole' => $this->invocationRoleOss, 781 | 'triggerConfig' => $triggerConfigUpdate, 782 | 'qualifier' => $v1, 783 | ) 784 | ); 785 | 786 | $updateTriggerData = $ret['data']; 787 | $this->checkTriggerResponse($updateTriggerData, $triggerName, $triggerType, $triggerConfigUpdate, $sourceArn, $this->invocationRoleOss, $v1); 788 | 789 | $ret = $this->fcClient->updateTrigger( 790 | $serviceName, 791 | $functionName, 792 | $triggerName, 793 | array( 794 | 'invocationRole' => $this->invocationRoleOss, 795 | 'triggerConfig' => $triggerConfigUpdate, 796 | 'qualifier' => "test", 797 | ) 798 | ); 799 | 800 | $updateTriggerData = $ret['data']; 801 | $this->checkTriggerResponse($updateTriggerData, $triggerName, $triggerType, $triggerConfigUpdate, $sourceArn, $this->invocationRoleOss, "test"); 802 | 803 | } 804 | 805 | private function checkTriggerResponse($resp, $triggerName, $triggerType, $triggerConfig, $sourceArn, $invocationRole, $qualifier) { 806 | $this->assertEquals($resp['triggerName'], $triggerName); 807 | $this->assertEquals($resp['triggerType'], $triggerType); 808 | $this->assertEquals($resp['sourceArn'], $sourceArn); 809 | $this->assertEquals($resp['invocationRole'], $invocationRole); 810 | $this->assertTrue(isset($resp['createdTime'])); 811 | $this->assertTrue(isset($resp['lastModifiedTime'])); 812 | $this->assertEquals($resp['triggerConfig'], $triggerConfig); 813 | $this->assertEquals($resp['qualifier'], $qualifier); 814 | } 815 | 816 | } --------------------------------------------------------------------------------