From 09d2a997c1cd3a3db99fcf948d8a7658d777cce3 Mon Sep 17 00:00:00 2001 From: "shuai.chang" Date: Wed, 10 May 2017 21:10:23 +0800 Subject: [PATCH] Releasing Function Compute Java SDK --- .gitignore | 3 + .travis.yml | 8 + LICENSE | 222 +--- README.md | 85 +- pom.xml | 123 +++ src/main/.DS_Store | Bin 0 -> 6148 bytes src/main/java/.DS_Store | Bin 0 -> 6148 bytes src/main/java/META-INF/MANIFEST.MF | 4 + .../com/aliyuncs/fc/auth/AcsURLEncoder.java | 39 + .../aliyuncs/fc/auth/FcSignatureComposer.java | 122 +++ .../aliyuncs/fc/client/DefaultFcClient.java | 193 ++++ .../fc/client/FunctionComputeClient.java | 235 +++++ .../java/com/aliyuncs/fc/config/Config.java | 147 +++ .../java/com/aliyuncs/fc/constants/Const.java | 18 + .../com/aliyuncs/fc/constants/HeaderKeys.java | 10 + .../fc/exceptions/ClientException.java | 115 +++ .../aliyuncs/fc/exceptions/ErrorCodes.java | 9 + .../fc/exceptions/ServerException.java | 81 ++ .../java/com/aliyuncs/fc/http/FormatType.java | 48 + .../com/aliyuncs/fc/http/HttpRequest.java | 74 ++ .../com/aliyuncs/fc/http/HttpResponse.java | 162 +++ src/main/java/com/aliyuncs/fc/model/Code.java | 64 ++ .../aliyuncs/fc/model/FunctionMetadata.java | 103 ++ .../fc/model/ListRequestUrlHelper.java | 32 + .../java/com/aliyuncs/fc/model/LogConfig.java | 33 + .../aliyuncs/fc/model/OSSTriggerConfig.java | 28 + .../aliyuncs/fc/model/OSSTriggerFilter.java | 24 + .../com/aliyuncs/fc/model/OSSTriggerKey.java | 29 + .../com/aliyuncs/fc/model/PrepareUrl.java | 25 + .../aliyuncs/fc/model/ServiceMetadata.java | 55 + .../aliyuncs/fc/model/TriggerMetadata.java | 70 ++ .../fc/request/CreateFunctionRequest.java | 161 +++ .../fc/request/CreateServiceRequest.java | 117 +++ .../fc/request/CreateTriggerRequest.java | 143 +++ .../fc/request/DeleteFunctionRequest.java | 96 ++ .../fc/request/DeleteServiceRequest.java | 85 ++ .../fc/request/DeleteTriggerRequest.java | 108 ++ .../fc/request/GetFunctionRequest.java | 81 ++ .../fc/request/GetServiceRequest.java | 71 ++ .../fc/request/GetTriggerRequest.java | 86 ++ .../fc/request/InvokeFunctionRequest.java | 109 ++ .../fc/request/ListFunctionsRequest.java | 111 ++ .../fc/request/ListServicesRequest.java | 98 ++ .../fc/request/ListTriggersRequest.java | 119 +++ .../fc/request/UpdateFunctionRequest.java | 171 ++++ .../fc/request/UpdateServiceRequest.java | 124 +++ .../fc/request/UpdateTriggerRequest.java | 131 +++ .../fc/response/CreateFunctionResponse.java | 114 +++ .../fc/response/CreateServiceResponse.java | 92 ++ .../fc/response/CreateTriggerResponse.java | 87 ++ .../fc/response/DeleteFunctionResponse.java | 48 + .../fc/response/DeleteServiceResponse.java | 48 + .../fc/response/DeleteTriggerResponse.java | 49 + .../fc/response/GetFunctionResponse.java | 115 +++ .../fc/response/GetServiceResponse.java | 93 ++ .../fc/response/GetTriggerResponse.java | 93 ++ .../fc/response/InvokeFunctionResponse.java | 60 ++ .../fc/response/ListFunctionsResponse.java | 73 ++ .../fc/response/ListServicesResponse.java | 70 ++ .../fc/response/ListTriggersResponse.java | 75 ++ .../fc/response/UpdateFunctionResponse.java | 116 +++ .../fc/response/UpdateServiceResponse.java | 93 ++ .../fc/response/UpdateTriggerResponse.java | 92 ++ .../com/aliyuncs/fc/utils/Base64Helper.java | 120 +++ .../aliyuncs/fc/utils/ParameterHelper.java | 110 ++ .../java/com/aliyuncs/fc/utils/XmlUtils.java | 161 +++ .../java/com/aliyuncs/fc/utils/ZipUtils.java | 59 ++ .../fc/FunctionComputeClientTest.java | 949 ++++++++++++++++++ 68 files changed, 6486 insertions(+), 203 deletions(-) create mode 100644 .gitignore create mode 100644 .travis.yml create mode 100755 pom.xml create mode 100644 src/main/.DS_Store create mode 100644 src/main/java/.DS_Store create mode 100644 src/main/java/META-INF/MANIFEST.MF create mode 100644 src/main/java/com/aliyuncs/fc/auth/AcsURLEncoder.java create mode 100644 src/main/java/com/aliyuncs/fc/auth/FcSignatureComposer.java create mode 100644 src/main/java/com/aliyuncs/fc/client/DefaultFcClient.java create mode 100644 src/main/java/com/aliyuncs/fc/client/FunctionComputeClient.java create mode 100644 src/main/java/com/aliyuncs/fc/config/Config.java create mode 100644 src/main/java/com/aliyuncs/fc/constants/Const.java create mode 100644 src/main/java/com/aliyuncs/fc/constants/HeaderKeys.java create mode 100644 src/main/java/com/aliyuncs/fc/exceptions/ClientException.java create mode 100644 src/main/java/com/aliyuncs/fc/exceptions/ErrorCodes.java create mode 100644 src/main/java/com/aliyuncs/fc/exceptions/ServerException.java create mode 100644 src/main/java/com/aliyuncs/fc/http/FormatType.java create mode 100644 src/main/java/com/aliyuncs/fc/http/HttpRequest.java create mode 100644 src/main/java/com/aliyuncs/fc/http/HttpResponse.java create mode 100644 src/main/java/com/aliyuncs/fc/model/Code.java create mode 100644 src/main/java/com/aliyuncs/fc/model/FunctionMetadata.java create mode 100644 src/main/java/com/aliyuncs/fc/model/ListRequestUrlHelper.java create mode 100644 src/main/java/com/aliyuncs/fc/model/LogConfig.java create mode 100644 src/main/java/com/aliyuncs/fc/model/OSSTriggerConfig.java create mode 100644 src/main/java/com/aliyuncs/fc/model/OSSTriggerFilter.java create mode 100644 src/main/java/com/aliyuncs/fc/model/OSSTriggerKey.java create mode 100644 src/main/java/com/aliyuncs/fc/model/PrepareUrl.java create mode 100644 src/main/java/com/aliyuncs/fc/model/ServiceMetadata.java create mode 100644 src/main/java/com/aliyuncs/fc/model/TriggerMetadata.java create mode 100755 src/main/java/com/aliyuncs/fc/request/CreateFunctionRequest.java create mode 100755 src/main/java/com/aliyuncs/fc/request/CreateServiceRequest.java create mode 100755 src/main/java/com/aliyuncs/fc/request/CreateTriggerRequest.java create mode 100755 src/main/java/com/aliyuncs/fc/request/DeleteFunctionRequest.java create mode 100755 src/main/java/com/aliyuncs/fc/request/DeleteServiceRequest.java create mode 100755 src/main/java/com/aliyuncs/fc/request/DeleteTriggerRequest.java create mode 100755 src/main/java/com/aliyuncs/fc/request/GetFunctionRequest.java create mode 100755 src/main/java/com/aliyuncs/fc/request/GetServiceRequest.java create mode 100755 src/main/java/com/aliyuncs/fc/request/GetTriggerRequest.java create mode 100755 src/main/java/com/aliyuncs/fc/request/InvokeFunctionRequest.java create mode 100755 src/main/java/com/aliyuncs/fc/request/ListFunctionsRequest.java create mode 100755 src/main/java/com/aliyuncs/fc/request/ListServicesRequest.java create mode 100755 src/main/java/com/aliyuncs/fc/request/ListTriggersRequest.java create mode 100755 src/main/java/com/aliyuncs/fc/request/UpdateFunctionRequest.java create mode 100755 src/main/java/com/aliyuncs/fc/request/UpdateServiceRequest.java create mode 100755 src/main/java/com/aliyuncs/fc/request/UpdateTriggerRequest.java create mode 100755 src/main/java/com/aliyuncs/fc/response/CreateFunctionResponse.java create mode 100755 src/main/java/com/aliyuncs/fc/response/CreateServiceResponse.java create mode 100755 src/main/java/com/aliyuncs/fc/response/CreateTriggerResponse.java create mode 100755 src/main/java/com/aliyuncs/fc/response/DeleteFunctionResponse.java create mode 100755 src/main/java/com/aliyuncs/fc/response/DeleteServiceResponse.java create mode 100755 src/main/java/com/aliyuncs/fc/response/DeleteTriggerResponse.java create mode 100755 src/main/java/com/aliyuncs/fc/response/GetFunctionResponse.java create mode 100755 src/main/java/com/aliyuncs/fc/response/GetServiceResponse.java create mode 100755 src/main/java/com/aliyuncs/fc/response/GetTriggerResponse.java create mode 100755 src/main/java/com/aliyuncs/fc/response/InvokeFunctionResponse.java create mode 100755 src/main/java/com/aliyuncs/fc/response/ListFunctionsResponse.java create mode 100755 src/main/java/com/aliyuncs/fc/response/ListServicesResponse.java create mode 100755 src/main/java/com/aliyuncs/fc/response/ListTriggersResponse.java create mode 100755 src/main/java/com/aliyuncs/fc/response/UpdateFunctionResponse.java create mode 100755 src/main/java/com/aliyuncs/fc/response/UpdateServiceResponse.java create mode 100755 src/main/java/com/aliyuncs/fc/response/UpdateTriggerResponse.java create mode 100644 src/main/java/com/aliyuncs/fc/utils/Base64Helper.java create mode 100644 src/main/java/com/aliyuncs/fc/utils/ParameterHelper.java create mode 100644 src/main/java/com/aliyuncs/fc/utils/XmlUtils.java create mode 100644 src/main/java/com/aliyuncs/fc/utils/ZipUtils.java create mode 100644 src/test/java/com/aliyuncs/fc/FunctionComputeClientTest.java diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..ea6cc40 --- /dev/null +++ b/.gitignore @@ -0,0 +1,3 @@ +*.iml +.idea/ +target/ diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 0000000..518cb6d --- /dev/null +++ b/.travis.yml @@ -0,0 +1,8 @@ +language: java +jdk: +- oraclejdk8 +script: +- mvn test +env: + global: + - secure: diff --git a/LICENSE b/LICENSE index 8dada3e..3db721f 100644 --- a/LICENSE +++ b/LICENSE @@ -1,201 +1,21 @@ - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "{}" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright {yyyy} {name of copyright owner} - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. +The MIT License (MIT) + +Copyright (c) ali-sdk and other contributors. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. \ No newline at end of file diff --git a/README.md b/README.md index b213b06..128c20d 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,83 @@ -# fc-java-sdk -The Java SDK of FunctionCompute. +# fc-java-sdk + +## Requirements +- `Java 1.8+` + +## License +[MIT](LICENSE) + +## Install +Add Maven dependencies into pom.xml +```xml + + com.aliyun + aliyun-fc-java-sdk + 1.0.0 + +``` + +## Example +Create the code directory and write hello world nodejs code +```bash +mkdir /tmp/fc_code +echo "'use strict'; module.exports.handler = function(event, context, callback) {console.log('hello world'); callback(null, 'hello world');};" > /tmp/fc_code/hello_world.js +``` + +Run below with your own ENDPOINT, ACCESS_KEY/SECRET_KEY and ACCOUNT_ID environment variables +```Java +public class FcSample { + private static final String CODE_DIR = "/tmp/fc_code"; + private static final String REGION = "cn-shanghai"; + private static final String SERVICE_NAME = "test_service"; + private static final String FUNCTION_NAME = "test_function"; + + public static void main(final String[] args) throws IOException { + String accessKey = System.getenv("ACCESS_KEY"); + String accessSecretKey = System.getenv("SECRET_KEY"); + String accountId = System.getenv("ACCOUNT_ID"); + String role = System.getenv("ROLE"); + + // Initialize FC client + FunctionComputeClient fcClient = new FunctionComputeClient(REGION, accountId, accessKey, accessSecretKey); + + // Create a service + CreateServiceRequest csReq = new CreateServiceRequest(); + csReq.setServiceName(SERVICE_NAME); + csReq.setDescription("FC test service"); + csReq.setRole(role); + CreateServiceResponse csResp = fcClient.createService(csReq); + System.out.println("Created service, request ID " + csResp.getRequestId()); + + // Create a function + CreateFunctionRequest cfReq = new CreateFunctionRequest(SERVICE_NAME); + cfReq.setFunctionName(FUNCTION_NAME); + cfReq.setDescription("Function for test"); + cfReq.setMemorySize(128); + cfReq.setHandler("hello_world.handler"); + cfReq.setRuntime("nodejs4.4"); + Code code = new Code().setDir(CODE_DIR); + cfReq.setCode(code); + cfReq.setTimeout(10); + CreateFunctionResponse cfResp = fcClient.createFunction(cfReq); + System.out.println("Created function, request ID " + cfResp.getRequestId()); + + // Invoke the function + InvokeFunctionRequest invkReq = new InvokeFunctionRequest(SERVICE_NAME, FUNCTION_NAME); + InvokeFunctionResponse invkResp = fcClient.invokeFunction(invkReq); + System.out.println(new String(invkResp.getContent())); + + // Delete the function + DeleteFunctionRequest dfReq = new DeleteFunctionRequest(SERVICE_NAME, FUNCTION_NAME); + DeleteFunctionResponse dfResp = fcClient.deleteFunction(dfReq); + System.out.println("Deleted function, request ID " + dfResp.getRequestId()); + + // Delete the service + DeleteServiceRequest dsReq = new DeleteServiceRequest(SERVICE_NAME); + DeleteServiceResponse dsResp = fcClient.deleteService(dsReq); + System.out.println("Deleted service, request ID " + dsResp.getRequestId()); + } +} +``` + +## API Spec +See: https://help.aliyun.com/document_detail/52877.html diff --git a/pom.xml b/pom.xml new file mode 100755 index 0000000..28408f0 --- /dev/null +++ b/pom.xml @@ -0,0 +1,123 @@ + + 4.0.0 + com.aliyun + aliyun-java-sdk-fc + jar + 1.0.0-SNAPSHOT + aliyun-java-sdk-fc + https://www.aliyun.com/product/fc + Aliyun Java SDK for FunctionCompute + + + + ossrh + https://oss.sonatype.org/content/repositories/snapshots + + + ossrh + https://oss.sonatype.org/service/local/staging/deploy/maven2/ + + + + + + junit + junit + 4.12 + test + + + com.google.code.gson + gson + 2.2.4 + + + org.json + org.json + chargebee-1.0 + + + com.google.guava + guava + 19.0 + + + + + MIT + + + + + + + aliyunproducts + Aliyun SDK + aliyunsdk@aliyun.com + + + + + + org.apache.maven.plugins + maven-compiler-plugin + 2.3.2 + + 1.6 + 1.6 + UTF-8 + + + + org.apache.maven.plugins + maven-jar-plugin + 2.3.2 + + + + + + + org.apache.maven.plugins + maven-javadoc-plugin + 2.8 + + UTF-8 + + + + org.apache.maven.plugins + maven-surefire-plugin + 2.10 + + -Dfile.encoding=UTF-8 + + + + org.apache.maven.plugins + maven-gpg-plugin + 1.5 + + + sign-artifacts + verify + + sign + + + + + + org.sonatype.plugins + nexus-staging-maven-plugin + 1.6.7 + true + + ossrh + https://oss.sonatype.org/ + true + + + + + diff --git a/src/main/.DS_Store b/src/main/.DS_Store new file mode 100644 index 0000000000000000000000000000000000000000..aaaccb85f15c0136b8881b388359ff2462714528 GIT binary patch literal 6148 zcmeHKPm9_>6rWMsje1FG7ldBsy5K>#ir3V-$AXZ>rR)})G@(ujiI}J?BILa1eu8%Y zeUH+9hy5sf>w7b!SZuFS%X{I?@8!*Vlgw|zOdey5cc(#l(ELHLA9YI# z##033IEFt@$9|OfaR0a!O^$z&0bIKh`^-ExW8UWa`Qu2YS)=j53&qltrw3NKQpL-D zR(bD^lDV6C*);8XlXG<^gU~m2-^)fT`!q?Swe9%>8P13Hi#JJ}c`^ts(G7ge? zH<`vkdg1Ev&Sa2{hW25963!sC@5SLjrqY*@%r31mUPHUKSTv7Yb@8fkysV2wr_-p5 zR=c@e+FvZ|?a`xhyh|?e;6>kmsQ=LSEe^528e+jF@XDn07Y~R<{H)30gWmF088Lj z0yfqXm?I2226K(j1HyGGpibqc#Nav|{KCXJ26K%%opDoqaPwqtDip4s4&w_I&bXtI zT4I10_?-c){XlFy|4;s2|EnNshyh~Y|73uddTy@^b2De_)-3U?6`&tLQ7|soxK05> i9mNofM{x~Q3HSvXfR4djBX~gQM?ld)4Kc7&27UplrD(_i literal 0 HcmV?d00001 diff --git a/src/main/java/.DS_Store b/src/main/java/.DS_Store new file mode 100644 index 0000000000000000000000000000000000000000..b2c165738469607887d25ec6888ecb94de06e6cc GIT binary patch literal 6148 zcmeHKF>V4u4739UQX0yX`-S{qg~$u|Kop=Ox&qQ)m3QT7nXxSdIz?B}L}ST2yI#+( zZi@5T%zX28cr{y_*$PgyZw^!AK7C?O6(Ks$*q=Uz;l${&wq}9ch3##y&%^naf3c&T z?Q$EOJxmEwKnh3!DIf);z^nqO*|gPjqDCno1*E`L0sbEvoY)J;#Q1e!h!y~NeeYu) zy#%l!mE2x9CL#j!qym%b)na(k5pR{(3&+Hyo5#&Kr*8J@P&{r&yhXZsPt+&{q` refreshSignParameters(Map parameters) { + if (parameters == null) { + parameters = new HashMap(); + } + parameters.put("Date", ParameterHelper.getRFC2616Date(null)); + return parameters; + } + + public static String composeStringToSign(String method, String path, + Map headers) { + StringBuilder sb = new StringBuilder(); + sb.append(method).append(HEADER_SEPARATOR); + if (headers.get("Content-MD5") != null) { + sb.append(headers.get("Content-MD5")); + } + sb.append(HEADER_SEPARATOR); + if (headers.get("Content-Type") != null) { + sb.append(headers.get("Content-Type")); + } + sb.append(HEADER_SEPARATOR); + if (headers.get("Date") != null) { + sb.append(headers.get("Date")); + } + sb.append(HEADER_SEPARATOR); + sb.append(buildCanonicalHeaders(headers, "x-fc")); + sb.append(path); + return sb.toString(); + } + + public static String buildCanonicalHeaders(Map headers, String headerBegin) { + Map sortMap = new TreeMap(); + for (Map.Entry e : headers.entrySet()) { + String key = e.getKey().toLowerCase(); + String val = e.getValue(); + if (key.startsWith(headerBegin)) { + sortMap.put(key, val); + } + } + StringBuilder headerBuilder = new StringBuilder(); + for (Map.Entry e : sortMap.entrySet()) { + headerBuilder.append(e.getKey()); + headerBuilder.append(':').append(e.getValue()); + headerBuilder.append(HEADER_SEPARATOR); + } + return headerBuilder.toString(); + } + + public static String signString(String source, String accessSecret) + throws InvalidKeyException, IllegalStateException { + try { + Mac mac = Mac.getInstance(AGLORITHM_NAME); + mac.init(new SecretKeySpec( + accessSecret.getBytes(AcsURLEncoder.URL_ENCODING), AGLORITHM_NAME)); + byte[] signData = mac.doFinal(source.getBytes(AcsURLEncoder.URL_ENCODING)); + return Base64Helper.encode(signData); + } catch (NoSuchAlgorithmException e) { + throw new RuntimeException("HMAC-SHA1 not supported."); + } catch (UnsupportedEncodingException e) { + throw new RuntimeException("UTF-8 not supported."); + } + + } + + public String getSignerName() { + return "HMAC-SHA256"; + } + + public String getSignerVersion() { + return "1.0"; + } + + public static FcSignatureComposer getComposer() { + if (null == composer) { + composer = new FcSignatureComposer(); + } + return composer; + } + +} diff --git a/src/main/java/com/aliyuncs/fc/client/DefaultFcClient.java b/src/main/java/com/aliyuncs/fc/client/DefaultFcClient.java new file mode 100644 index 0000000..b1f9803 --- /dev/null +++ b/src/main/java/com/aliyuncs/fc/client/DefaultFcClient.java @@ -0,0 +1,193 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +package com.aliyuncs.fc.client; + +import com.aliyuncs.fc.constants.HeaderKeys; +import com.google.common.base.Preconditions; +import com.google.common.base.Strings; +import java.io.IOException; +import java.io.UnsupportedEncodingException; +import java.net.SocketTimeoutException; +import java.security.InvalidKeyException; +import java.security.NoSuchAlgorithmException; +import java.util.HashMap; +import java.util.Map; + +import com.aliyuncs.fc.auth.FcSignatureComposer; +import com.aliyuncs.fc.config.Config; +import com.aliyuncs.fc.exceptions.ClientException; +import com.aliyuncs.fc.exceptions.ServerException; +import com.aliyuncs.fc.http.HttpRequest; +import com.aliyuncs.fc.http.HttpResponse; +import com.google.gson.Gson; +import com.aliyuncs.fc.auth.AcsURLEncoder; +import com.aliyuncs.fc.model.PrepareUrl; +import com.aliyuncs.fc.utils.ParameterHelper; + +public class DefaultFcClient { + public final static Boolean AUTO_RETRY = true; + public final static int MAX_RETRIES = 3; + private final Config config; + + public DefaultFcClient(Config config) { + this.config = config; + } + + public String composeUrl(String endpoint, Map queries) + throws UnsupportedEncodingException { + + Map mapQueries = queries; + StringBuilder urlBuilder = new StringBuilder(""); + urlBuilder.append(endpoint); + if (-1 == urlBuilder.indexOf("?")) { + urlBuilder.append("?"); + } else if (!urlBuilder.toString().endsWith("?")) { + urlBuilder.append("&"); + } + String url = urlBuilder.toString(); + if (queries != null && queries.size() > 0) { + String query = concatQueryString(mapQueries); + url = urlBuilder.append(query).toString(); + } + if (url.endsWith("?") || url.endsWith("&")) { + url = url.substring(0, url.length() - 1); + } + return url; + } + + /** + * concate query string parameters (e.g. &name=foo) + * @param parameters + * @return concatenated query string + * @throws UnsupportedEncodingException + */ + public String concatQueryString(Map parameters) + throws UnsupportedEncodingException { + if (null == parameters) { + return null; + } + + StringBuilder urlBuilder = new StringBuilder(""); + for (Map.Entry entry : parameters.entrySet()) { + String key = entry.getKey(); + String val = entry.getValue(); + urlBuilder.append(AcsURLEncoder.encode(key)); + if (val != null) { + urlBuilder.append("=").append(AcsURLEncoder.encode(val)); + } + urlBuilder.append("&"); + } + + int strIndex = urlBuilder.length(); + if (parameters.size() > 0) { + urlBuilder.deleteCharAt(strIndex - 1); + } + + return urlBuilder.toString(); + } + + public Map getHeader(Map header, byte[] Payload, String form) { + if (header == null) { + header = new HashMap(); + } + header.put("Host", config.getHost()); + header.put("User-Agent", config.getUserAgent()); + header.put("Accept", "application/json"); + header.put("Content-Type", form); + header.put("x-fc-account-id", config.getUid()); + if (Payload != null) { + header.put("Content-MD5", ParameterHelper.md5Sum(Payload)); + } + return header; + } + + public PrepareUrl signRequest(HttpRequest request, String form, String method) + throws InvalidKeyException, IllegalStateException, UnsupportedEncodingException, NoSuchAlgorithmException { + + Map imutableMap = null; + if (request.getHeader() != null) { + imutableMap = request.getHeader(); + } else { + imutableMap = new HashMap(); + } + String accessKeyId = config.getAccessKeyID(); + String accessSecret = config.getAccessKeySecret(); + + Preconditions.checkArgument(!Strings.isNullOrEmpty(accessKeyId), "Access key cannot be blank"); + Preconditions.checkArgument(!Strings.isNullOrEmpty(accessSecret), "Secret key cannot be blank"); + imutableMap = FcSignatureComposer.refreshSignParameters(imutableMap); + + // Get relevent path + String uri = request.getPath(); + + // Set all headers + imutableMap = getHeader(imutableMap, request.getPayload(), form); + + // Sign URL + String strToSign = FcSignatureComposer.composeStringToSign(method, uri, imutableMap); + String signature = FcSignatureComposer.signString(strToSign, accessSecret); + + // Set signature + imutableMap.put("Authorization", "FC " + accessKeyId + ":" + signature); + String allPath = composeUrl(config.getEndpoint() + request.getPath(), + request.getQueryParams()); + return new PrepareUrl(allPath, imutableMap); + } + + public HttpResponse doAction(HttpRequest request, String form, String method) + throws ClientException, ServerException { + request.validate(); + try { + PrepareUrl prepareUrl = signRequest(request, form, method); + int retryTimes = 1; + HttpResponse response = HttpResponse + .getResponse(prepareUrl.getUrl(), prepareUrl.getHeader(), request, method); + + while (500 <= response.getStatus() && AUTO_RETRY && retryTimes < MAX_RETRIES) { + prepareUrl = signRequest(request, form, method); + response = HttpResponse + .getResponse(prepareUrl.getUrl(), prepareUrl.getHeader(), request, method); + retryTimes++; + } + if (response.getStatus() >= 500) { + String stringContent = response.getContent() == null ? "" : new String(response.getContent()); + ServerException se = new Gson().fromJson(stringContent, ServerException.class); + se.setStatusCode(response.getStatus()); + se.setRequestId(response.getHeaderValue(HeaderKeys.REQUEST_ID)); + throw se; + } else if (response.getStatus() >= 300) { + String stringContent = response.getContent() == null ? "" : new String(response.getContent()); + ClientException ce = new Gson().fromJson(stringContent, ClientException.class); + ce.setStatusCode(response.getStatus()); + ce.setRequestId(response.getHeaderValue(HeaderKeys.REQUEST_ID)); + throw ce; + } + return response; + } catch (InvalidKeyException exp) { + throw new ClientException("SDK.InvalidAccessSecret", "Speicified access secret is not valid."); + } catch (SocketTimeoutException exp){ + throw new ClientException("SDK.ServerUnreachable", "SocketTimeoutException has occurred on a socket read or accept."); + } catch (IOException exp) { + throw new ClientException("SDK.ServerUnreachable", "Server unreachable: " + exp.toString()); + } catch (NoSuchAlgorithmException exp) { + throw new ClientException("SDK.InvalidMD5Algorithm", "MD5 hash is not supported by client side."); + } + } +} diff --git a/src/main/java/com/aliyuncs/fc/client/FunctionComputeClient.java b/src/main/java/com/aliyuncs/fc/client/FunctionComputeClient.java new file mode 100644 index 0000000..4c0bb1a --- /dev/null +++ b/src/main/java/com/aliyuncs/fc/client/FunctionComputeClient.java @@ -0,0 +1,235 @@ +package com.aliyuncs.fc.client; + +import com.aliyuncs.fc.request.*; +import com.aliyuncs.fc.config.Config; +import com.aliyuncs.fc.exceptions.ClientException; +import com.aliyuncs.fc.exceptions.ServerException; +import com.aliyuncs.fc.http.HttpResponse; +import com.aliyuncs.fc.model.FunctionMetadata; +import com.aliyuncs.fc.model.ServiceMetadata; +import com.aliyuncs.fc.model.TriggerMetadata; +import com.aliyuncs.fc.response.*; +import com.google.gson.Gson; + +/** + * TODO: add javadoc + */ +public class FunctionComputeClient { + + private final static String CONTENT_TYPE_APPLICATION_JSON = "application/json"; + private final static String CONTENT_TYPE_APPLICATION_STREAM = "application/octet-stream"; + + private final DefaultFcClient client; + private static final Gson GSON = new Gson(); + private final Config config; + + public FunctionComputeClient(String region, String uid, String accessKeyId, String accessKeySecret) { + this.config = new Config(region, uid, accessKeyId, accessKeySecret, null, false); + client = new DefaultFcClient(config); + } + + public FunctionComputeClient(Config config) { + this.config = config; + client = new DefaultFcClient(config); + } + + public Config getConfig() { + return config; + } + + /** + * Override the default endpoint for the region + * @param endpoint the endpoint that client sends requests to + */ + public void setEndpoint(String endpoint) { + config.setEndpoint(endpoint); + } + + public DeleteServiceResponse deleteService(DeleteServiceRequest request) + throws ClientException, ServerException { + + HttpResponse response = client.doAction(request, CONTENT_TYPE_APPLICATION_JSON, "DELETE"); + DeleteServiceResponse deleteServiceResponse = new DeleteServiceResponse(); + deleteServiceResponse.setHeaders(response.getHeaders()); + deleteServiceResponse.setStatus(response.getStatus()); + return deleteServiceResponse; + } + + public DeleteFunctionResponse deleteFunction(DeleteFunctionRequest request) + throws ClientException, ServerException { + HttpResponse response = client.doAction(request, CONTENT_TYPE_APPLICATION_JSON, "DELETE"); + DeleteFunctionResponse deleteFunctionResponse = new DeleteFunctionResponse(); + deleteFunctionResponse.setHeader(response.getHeaders()); + deleteFunctionResponse.setStatus(response.getStatus()); + return deleteFunctionResponse; + } + + public GetServiceResponse getService(GetServiceRequest request) + throws ClientException, ServerException { + HttpResponse response = client.doAction(request, CONTENT_TYPE_APPLICATION_JSON, "GET"); + ServiceMetadata serviceMetadata = GSON.fromJson( + new String(response.getContent()), ServiceMetadata.class); + GetServiceResponse getServiceResponse = new GetServiceResponse(); + getServiceResponse.setServiceMetadata(serviceMetadata); + getServiceResponse.setHeader(response.getHeaders()); + getServiceResponse.setContent(response.getContent()); + getServiceResponse.setStatus(response.getStatus()); + return getServiceResponse; + } + + public GetFunctionResponse getFunction(GetFunctionRequest request) + throws ClientException, ServerException { + HttpResponse response = client.doAction(request, CONTENT_TYPE_APPLICATION_JSON, "GET"); + FunctionMetadata functionMetadata = GSON.fromJson( + new String(response.getContent()), FunctionMetadata.class); + GetFunctionResponse getFunctionResponse = new GetFunctionResponse(); + getFunctionResponse.setFunctionMetadata(functionMetadata); + getFunctionResponse.setHeader(response.getHeaders()); + getFunctionResponse.setContent(response.getContent()); + getFunctionResponse.setStatus(response.getStatus()); + return getFunctionResponse; + } + + public CreateServiceResponse createService(CreateServiceRequest request) + throws ClientException, ServerException { + HttpResponse response = client.doAction(request, CONTENT_TYPE_APPLICATION_JSON, "POST"); + ServiceMetadata serviceMetadata = GSON.fromJson( + new String(response.getContent()), ServiceMetadata.class); + CreateServiceResponse createServiceResponse = new CreateServiceResponse(); + createServiceResponse.setServiceMetadata(serviceMetadata); + createServiceResponse.setHeaders(response.getHeaders()); + createServiceResponse.setContent(response.getContent()); + createServiceResponse.setStatus(response.getStatus()); + return createServiceResponse; + } + + public CreateFunctionResponse createFunction(CreateFunctionRequest request) + throws ClientException, ServerException { + HttpResponse response = client.doAction(request, CONTENT_TYPE_APPLICATION_JSON, "POST"); + FunctionMetadata functionMetadata = GSON.fromJson( + new String(response.getContent()), FunctionMetadata.class); + CreateFunctionResponse createFunctionResponse = new CreateFunctionResponse(); + createFunctionResponse.setFunctionMetadata(functionMetadata); + createFunctionResponse.setHeader(response.getHeaders()); + createFunctionResponse.setContent(response.getContent()); + createFunctionResponse.setStatus(response.getStatus()); + return createFunctionResponse; + } + + public UpdateServiceResponse updateService(UpdateServiceRequest request) + throws ClientException, ServerException { + HttpResponse response = client.doAction(request, CONTENT_TYPE_APPLICATION_JSON, "PUT"); + ServiceMetadata serviceMetadata = GSON.fromJson( + new String(response.getContent()), ServiceMetadata.class); + UpdateServiceResponse updateServiceResponse = new UpdateServiceResponse(); + updateServiceResponse.setServiceMetadata(serviceMetadata); + updateServiceResponse.setHeader(response.getHeaders()); + updateServiceResponse.setContent(response.getContent()); + updateServiceResponse.setStatus(response.getStatus()); + return updateServiceResponse; + } + + public UpdateFunctionResponse updateFunction(UpdateFunctionRequest request) + throws ClientException, ServerException { + HttpResponse response = client.doAction(request, CONTENT_TYPE_APPLICATION_JSON, "PUT"); + FunctionMetadata functionMetadata = GSON.fromJson( + new String(response.getContent()), FunctionMetadata.class); + UpdateFunctionResponse updateFunctionResponse = new UpdateFunctionResponse(); + updateFunctionResponse.setFunctionMetadata(functionMetadata); + updateFunctionResponse.setHeader(response.getHeaders()); + updateFunctionResponse.setContent(response.getContent()); + updateFunctionResponse.setStatus(response.getStatus()); + return updateFunctionResponse; + } + + public ListServicesResponse listServices(ListServicesRequest request) + throws ClientException, ServerException { + HttpResponse response = client.doAction(request, CONTENT_TYPE_APPLICATION_JSON, "GET"); + ListServicesResponse listServicesResponse = GSON.fromJson( + new String(response.getContent()), ListServicesResponse.class); + listServicesResponse.setHeader(response.getHeaders()); + listServicesResponse.setContent(response.getContent()); + listServicesResponse.setStatus(response.getStatus()); + return listServicesResponse; + } + + public ListFunctionsResponse listFunctions(ListFunctionsRequest request) + throws ClientException, ServerException { + HttpResponse response = client.doAction(request, CONTENT_TYPE_APPLICATION_JSON, "GET"); + ListFunctionsResponse listFunctionsResponse = GSON.fromJson( + new String(response.getContent()), ListFunctionsResponse.class); + listFunctionsResponse.setHeader(response.getHeaders()); + listFunctionsResponse.setContent(response.getContent()); + listFunctionsResponse.setStatus(response.getStatus()); + return listFunctionsResponse; + } + + public CreateTriggerResponse createTrigger(CreateTriggerRequest request) + throws ClientException, ServerException { + HttpResponse response = client.doAction(request, CONTENT_TYPE_APPLICATION_JSON, "POST"); + TriggerMetadata triggerMetadata = GSON.fromJson( + new String(response.getContent()), TriggerMetadata.class); + CreateTriggerResponse createTriggerResponse = new CreateTriggerResponse(); + createTriggerResponse.setTriggerMetadata(triggerMetadata); + createTriggerResponse.setHeader(response.getHeaders()); + createTriggerResponse.setContent(response.getContent()); + createTriggerResponse.setStatus(response.getStatus()); + return createTriggerResponse; + } + + public DeleteTriggerResponse deleteTrigger(DeleteTriggerRequest request) + throws ClientException, ServerException { + HttpResponse response = client.doAction(request, CONTENT_TYPE_APPLICATION_JSON, "DELETE"); + DeleteTriggerResponse deleteTriggerResponse = new DeleteTriggerResponse(); + deleteTriggerResponse.setHeader(response.getHeaders()); + deleteTriggerResponse.setStatus(response.getStatus()); + return deleteTriggerResponse; + } + + public UpdateTriggerResponse updateTrigger(UpdateTriggerRequest request) + throws ClientException, ServerException { + HttpResponse response = client.doAction(request, CONTENT_TYPE_APPLICATION_JSON, "PUT"); + TriggerMetadata triggerMetadata = GSON.fromJson( + new String(response.getContent()), TriggerMetadata.class); + UpdateTriggerResponse updateTriggerResponse = new UpdateTriggerResponse(); + updateTriggerResponse.setTriggerMetadata(triggerMetadata); + updateTriggerResponse.setHeader(response.getHeaders()); + updateTriggerResponse.setContent(response.getContent()); + updateTriggerResponse.setStatus(response.getStatus()); + return updateTriggerResponse; + } + + public GetTriggerResponse getTrigger(GetTriggerRequest request) + throws ClientException, ServerException { + HttpResponse response = client.doAction(request, CONTENT_TYPE_APPLICATION_JSON, "GET"); + TriggerMetadata triggerMetadata = GSON.fromJson( + new String(response.getContent()), TriggerMetadata.class); + GetTriggerResponse getTriggerResponse = new GetTriggerResponse(); + getTriggerResponse.setTriggerMetadata(triggerMetadata); + getTriggerResponse.setHeader(response.getHeaders()); + getTriggerResponse.setContent(response.getContent()); + getTriggerResponse.setStatus(response.getStatus()); + return getTriggerResponse; + } + + public ListTriggersResponse listTriggers(ListTriggersRequest request) + throws ClientException, ServerException { + HttpResponse response = client.doAction(request, CONTENT_TYPE_APPLICATION_JSON, "GET"); + ListTriggersResponse listTriggersResponse = GSON.fromJson( + new String(response.getContent()), ListTriggersResponse.class); + listTriggersResponse.setHeader(response.getHeaders()); + listTriggersResponse.setContent(response.getContent()); + listTriggersResponse.setStatus(response.getStatus()); + return listTriggersResponse; + } + + public InvokeFunctionResponse invokeFunction(InvokeFunctionRequest request) + throws ClientException, ServerException { + HttpResponse response = client.doAction(request, CONTENT_TYPE_APPLICATION_STREAM, "POST"); + InvokeFunctionResponse invokeFunctionResponse = new InvokeFunctionResponse(); + invokeFunctionResponse.setContent(response.getContent()); + invokeFunctionResponse.setHeader(response.getHeaders()); + invokeFunctionResponse.setStatus(response.getStatus()); + return invokeFunctionResponse; + } +} diff --git a/src/main/java/com/aliyuncs/fc/config/Config.java b/src/main/java/com/aliyuncs/fc/config/Config.java new file mode 100644 index 0000000..6885721 --- /dev/null +++ b/src/main/java/com/aliyuncs/fc/config/Config.java @@ -0,0 +1,147 @@ +package com.aliyuncs.fc.config; + +import com.google.common.base.Preconditions; +import com.google.common.base.Strings; +import com.google.gson.Gson; +import com.google.gson.stream.JsonReader; +import java.io.FileReader; +import java.io.IOException; +import java.util.Map; + +/** + * TODO: add javadoc + */ +public class Config { + + private static final String ENDPOINT_FMT = "%s.fc.%s.aliyuncs.com"; + private String endpoint; + private String apiVersion = "2016-08-15"; + private String accessKeyID; + private String accessKeySecret; + private String securityToken; + private String userAgent = "java-sdk-1.0.0"; + private Boolean isDebug = false; + private String accountId; + private String uid; + private int timeout = 60; + private String host; + + public Config(String region, String uid, String accessKeyID, String accessKeySecret, + String securityToken, boolean isHttps) { + Preconditions.checkArgument(!Strings.isNullOrEmpty(region),"Region cannot be blank"); + Preconditions.checkArgument(!Strings.isNullOrEmpty(uid),"Account ID cannot be blank"); + Preconditions.checkArgument(!Strings.isNullOrEmpty(accessKeyID),"Access key cannot be blank"); + Preconditions.checkArgument(!Strings.isNullOrEmpty(accessKeySecret),"Secret key cannot be blank"); + + this.endpoint = buildEndpoint(region, uid, isHttps); + this.accessKeyID = accessKeyID; + this.accessKeySecret = accessKeySecret; + this.uid = uid; + this.securityToken = securityToken; + } + + public String getUid() { + return uid; + } + + public Config setUid(String uid) { + this.uid = uid; + return this; + } + + public String getAccountId() { + return accountId; + } + + public Config setAccoutId(String accountId) { + this.accountId = accountId; + return this; + } + + public String getEndpoint() { + return endpoint; + } + + public Config setEndpoint(String endpoint) { + this.endpoint = endpoint; + return this; + } + + public String getApiVersion() { + return apiVersion; + } + + public Config setApiVersion(String apiVersion) { + this.apiVersion = apiVersion; + return this; + } + + public String getAccessKeyID() { + return accessKeyID; + } + + public Config setAccessKeyID(String accessKeyID) { + this.accessKeyID = accessKeyID; + return this; + } + + public String getAccessKeySecret() { + return accessKeySecret; + } + + public Config setAccessKeySecret(String accessKeySecret) { + this.accessKeySecret = accessKeySecret; + return this; + } + + public Boolean getDebug() { + return isDebug; + } + + public Config setDebug(Boolean debug) { + this.isDebug = debug; + return this; + } + + public int getTimeout() { + return timeout; + } + + public Config setTimeout(int timeout) { + this.timeout = timeout; + return this; + } + + public String getHost() { + return host; + } + + public Config setHost(String host) { + this.host = host; + return this; + } + + public String getUserAgent() { + return userAgent; + } + + public Config setUserAgent(String userAgent) { + this.userAgent = userAgent; + return this; + } + + public String getSecurityToken() { + return securityToken; + } + + public Config setSecurityToken(String securityToken) { + this.securityToken = securityToken; + return this; + } + + private String buildEndpoint(String region, String uid, boolean isHttps) { + String endpoint = String.format(ENDPOINT_FMT, uid, region); + String protocol = isHttps ? "https" : "http"; + return protocol + "://" + endpoint; + } +} diff --git a/src/main/java/com/aliyuncs/fc/constants/Const.java b/src/main/java/com/aliyuncs/fc/constants/Const.java new file mode 100644 index 0000000..bf7c8bf --- /dev/null +++ b/src/main/java/com/aliyuncs/fc/constants/Const.java @@ -0,0 +1,18 @@ +package com.aliyuncs.fc.constants; + +/** + * TODO: add javadoc + */ +public class Const { + + public final static String SERVICE_PATH = "/%s/services"; + public final static String SINGLE_SERVICE_PATH = "/%s/services/%s"; + public final static String FUNCTION_PATH = "/%s/services/%s/functions"; + public final static String SINGLE_FUNCTION_PATH = "/%s/services/%s/functions/%s"; + public final static String TRIGGER_PATH = "/%s/services/%s/functions/%s/triggers"; + public final static String SINGLE_TRIGGER_PATH = "/%s/services/%s/functions/%s/triggers/%s"; + public final static String INVOKE_FUNCTION_PATH = "/%s/services/%s/functions/%s/invocations"; + public final static int CONNECT_TIMEOUT = 1000; + public final static int READ_TIMEOUT = 100000; + public final static String API_VERSION = "2016-08-15"; +} diff --git a/src/main/java/com/aliyuncs/fc/constants/HeaderKeys.java b/src/main/java/com/aliyuncs/fc/constants/HeaderKeys.java new file mode 100644 index 0000000..56b565f --- /dev/null +++ b/src/main/java/com/aliyuncs/fc/constants/HeaderKeys.java @@ -0,0 +1,10 @@ +package com.aliyuncs.fc.constants; + + +/** + * Contains shared constant request header String keys + */ +public class HeaderKeys { + + public static final String REQUEST_ID = "X-Fc-Request-Id"; +} diff --git a/src/main/java/com/aliyuncs/fc/exceptions/ClientException.java b/src/main/java/com/aliyuncs/fc/exceptions/ClientException.java new file mode 100644 index 0000000..eeb2018 --- /dev/null +++ b/src/main/java/com/aliyuncs/fc/exceptions/ClientException.java @@ -0,0 +1,115 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package com.aliyuncs.fc.exceptions; + + +import com.google.gson.annotations.SerializedName; +import java.util.Map; + +/** + * TODO: add javadoc + */ +public class ClientException extends RuntimeException { + + private static final long serialVersionUID = 534996425110290578L; + + private Map headers; + + private int statusCode; + + @SerializedName("ErrorCode") + private String errorCode; + + @SerializedName("ErrorMessage") + private String errorMessage; + + private String requestId; + + public ClientException(String errCode, String errMsg, String requestId) { + this(errCode, errMsg); + this.requestId = requestId; + } + + public ClientException(String errCode, String errMsg) { + super(errCode + " : " + errMsg); + this.errorCode = errCode; + this.errorMessage = errMsg; + } + + public ClientException(String message) { + super(message); + } + + public ClientException(Throwable cause) { + super(cause); + } + + public int getStatusCode() { + return statusCode; + } + + public ClientException setStatusCode(int statusCode) { + this.statusCode = statusCode; + return this; + } + + public ClientException setHeaders(Map headers) { + this.headers = headers; + return this; + } + + public Map getHeaders() { + return headers; + } + + public String getRequestId() { + return requestId; + } + + public void setRequestId(String requestId) { + this.requestId = requestId; + } + + public String getErrorCode() { + return errorCode; + } + + public ClientException setErrCode(String errCode) { + this.errorCode = errCode; + return this; + } + + public String getErrorMessage() { + return errorMessage; + } + + public ClientException setErrMsg(String errMsg) { + this.errorMessage = errMsg; + return this; + } + + @Override + public String getMessage() { + if (requestId == null) { + return super.getMessage(); + } + return "RequestId: " + requestId + ", ErrorCode: " + + errorCode + ", ErrorMessage: " + errorMessage; + } +} diff --git a/src/main/java/com/aliyuncs/fc/exceptions/ErrorCodes.java b/src/main/java/com/aliyuncs/fc/exceptions/ErrorCodes.java new file mode 100644 index 0000000..d51c93d --- /dev/null +++ b/src/main/java/com/aliyuncs/fc/exceptions/ErrorCodes.java @@ -0,0 +1,9 @@ +package com.aliyuncs.fc.exceptions; + +/** + * Contains error code constants returned from FC + */ +public class ErrorCodes { + public static final String SERVICE_NOT_FOUND = "ServiceNotFound"; + public static final String INVALID_ARGUMENT = "InvalidArgument"; +} diff --git a/src/main/java/com/aliyuncs/fc/exceptions/ServerException.java b/src/main/java/com/aliyuncs/fc/exceptions/ServerException.java new file mode 100644 index 0000000..729f3f9 --- /dev/null +++ b/src/main/java/com/aliyuncs/fc/exceptions/ServerException.java @@ -0,0 +1,81 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package com.aliyuncs.fc.exceptions; + +import com.google.gson.annotations.SerializedName; + +/** + * TODO: add javadoc + */ +public class ServerException extends RuntimeException { + + private int statusCode; + + @SerializedName("ErrorCode") + private String errorCode; + + @SerializedName("ErrorMessage") + private String errorMessage; + + private String requestId; + + public ServerException(String errorCode, String errorMessage, String requestId) { + this.errorCode = errorCode; + this.errorMessage = errorMessage; + this.requestId = requestId; + } + + public void setStatusCode(int statusCode) { + this.statusCode = statusCode; + } + + public int getStatusCode() { + return statusCode; + } + + public String getErrorCode() { + return errorCode; + } + + public void setErrorCode(String errorCode) { + this.errorCode = errorCode; + } + + public void setErrorMessage(String errorMessage) { + this.errorMessage = errorMessage; + } + + public String getErrorMessage() { + return errorMessage; + } + + public void setRequestId (String requestId) { + this.requestId = requestId; + } + + public String getRequestId() { + return requestId; + } + + @Override + public String getMessage() { + return "RequestId: " + requestId + ", ErrorCode: " + + errorCode + ", ErrorMessage: " + errorMessage; + } +} diff --git a/src/main/java/com/aliyuncs/fc/http/FormatType.java b/src/main/java/com/aliyuncs/fc/http/FormatType.java new file mode 100644 index 0000000..7c463e1 --- /dev/null +++ b/src/main/java/com/aliyuncs/fc/http/FormatType.java @@ -0,0 +1,48 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package com.aliyuncs.fc.http; + +public enum FormatType { + XML, + JSON, + RAW; + + public static String mapFormatToAccept(FormatType format) { + if (FormatType.XML == format) { + return "application/xml"; + } + if (FormatType.JSON == format) { + return "application/json"; + } + + return "application/octet-stream"; + } + + public static FormatType mapAcceptToFormat(String accept) { + if (accept.toLowerCase().equals("application/xml") || + accept.toLowerCase().equals("text/xml")) { + return FormatType.XML; + } + if (accept.toLowerCase().equals("application/json")) { + return FormatType.JSON; + } + + return FormatType.RAW; + } +} diff --git a/src/main/java/com/aliyuncs/fc/http/HttpRequest.java b/src/main/java/com/aliyuncs/fc/http/HttpRequest.java new file mode 100644 index 0000000..f5c59e7 --- /dev/null +++ b/src/main/java/com/aliyuncs/fc/http/HttpRequest.java @@ -0,0 +1,74 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package com.aliyuncs.fc.http; + +import com.aliyuncs.fc.exceptions.ClientException; +import java.io.IOException; +import java.net.HttpURLConnection; +import java.net.URL; +import java.util.Map; + +import com.aliyuncs.fc.constants.Const; + +public abstract class HttpRequest { + + public abstract String getPath(); + + public abstract Map getQueryParams(); + + public abstract Map getHeader(); + + public abstract byte[] getPayload(); + + public abstract void validate() throws ClientException; + + public HttpURLConnection getHttpConnection(String urls, byte[] content, + Map headers, String method) throws IOException { + Map mappedHeaders = headers; + String strUrl = urls; + if (null == strUrl || null == method) { + return null; + } + URL url = null; + String[] urlArray = null; + if ("POST".equals(method) && null == content) { + urlArray = strUrl.split("\\?"); + url = new URL(urlArray[0]); + } else { + url = new URL(strUrl); + } + System.setProperty("sun.net.http.allowRestrictedHeaders", "true"); + HttpURLConnection httpConn = (HttpURLConnection) url.openConnection(); + httpConn.setRequestMethod(method); + httpConn.setDoOutput(true); + httpConn.setDoInput(true); + httpConn.setUseCaches(false); + httpConn.setConnectTimeout(Const.CONNECT_TIMEOUT); + httpConn.setReadTimeout(Const.READ_TIMEOUT); + + for (Map.Entry entry : headers.entrySet()) { + httpConn.setRequestProperty(entry.getKey(), entry.getValue()); + } + + if ("POST".equals(method) && null != urlArray && urlArray.length == 2) { + httpConn.getOutputStream().write(urlArray[1].getBytes()); + } + return httpConn; + } +} diff --git a/src/main/java/com/aliyuncs/fc/http/HttpResponse.java b/src/main/java/com/aliyuncs/fc/http/HttpResponse.java new file mode 100644 index 0000000..863eb3b --- /dev/null +++ b/src/main/java/com/aliyuncs/fc/http/HttpResponse.java @@ -0,0 +1,162 @@ +/* +Z * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package com.aliyuncs.fc.http; + +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.net.HttpURLConnection; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; + +public class HttpResponse { + + private int status; + + private byte[] content; + + private Map headers; + + public HttpResponse() { + } + + public void putHeaderParameter(String key, String value) { + if (headers == null) { + headers = new HashMap(); + } + headers.put(key, value); + } + + public void setContent(byte[] content) { + this.content = content; + } + + public byte[] getContent() { + return this.content; + } + + + public String getHeaderValue(String name) { + String value = this.headers.get(name); + if (null == value) { + value = this.headers.get(name.toLowerCase()); + } + return value; + } + + public Map getHeaders() { + return headers; + } + + private static byte[] readContent(InputStream content) + throws IOException { + + if (content == null) { + return null; + } + ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); + byte[] buff = new byte[1024]; + + while (true) { + final int read = content.read(buff); + if (read == -1) { + break; + } + outputStream.write(buff, 0, read); + } + + return outputStream.toByteArray(); + } + + private static void pasrseHttpConn(HttpResponse response, HttpURLConnection httpConn, + InputStream content) throws IOException { + byte[] buff = readContent(content); + response.setStatus(httpConn.getResponseCode()); + Map> headers = httpConn.getHeaderFields(); + for (Entry> entry : headers.entrySet()) { + String key = entry.getKey(); + if (null == key) { + continue; + } + List values = entry.getValue(); + StringBuilder builder = new StringBuilder(values.get(0)); + for (int i = 1; i < values.size(); i++) { + builder.append(","); + builder.append(values.get(i)); + } + //这里面定义自己的headers + response.putHeaderParameter(key, builder.toString()); + } + + response.setContent(buff); + } + + // 真的请求. + public static HttpResponse getResponse(String urls, Map header, + HttpRequest request, String method) throws IOException { + OutputStream out = null; + InputStream content = null; + HttpResponse response = null; + HttpURLConnection httpConn = request + .getHttpConnection(urls, request.getPayload(), header, method); + + try { + //这里面把context写进入request里面去, 在request里面自定getContent方法, 把getPayload改成 + httpConn.connect(); + if (null != request.getPayload() && request.getPayload().length > 0) { + out = httpConn.getOutputStream(); + out.write(request.getPayload()); + } + content = httpConn.getInputStream(); + response = new HttpResponse(); + pasrseHttpConn(response, httpConn, content); + return response; + } catch (IOException e) { + content = httpConn.getErrorStream(); + response = new HttpResponse(); + pasrseHttpConn(response, httpConn, content); + return response; + } finally { + if (content != null) { + content.close(); + } + httpConn.disconnect(); + } + } + + public int getStatus() { + return this.status; + } + + public void setStatus(int status) { + this.status = status; + } + + public boolean isSuccess() { + if (200 <= this.status && + 300 > this.status) { + return true; + } + return false; + } + +} diff --git a/src/main/java/com/aliyuncs/fc/model/Code.java b/src/main/java/com/aliyuncs/fc/model/Code.java new file mode 100644 index 0000000..0d5c26f --- /dev/null +++ b/src/main/java/com/aliyuncs/fc/model/Code.java @@ -0,0 +1,64 @@ +package com.aliyuncs.fc.model; + +import com.aliyuncs.fc.utils.ZipUtils; +import com.google.gson.annotations.SerializedName; +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; +import java.util.UUID; +import sun.misc.BASE64Encoder; + +/** + * TODO: add javadoc + */ +public class Code { + + @SerializedName("ossBucketName") + public String ossBucketName; + + @SerializedName("ossObjectName") + public String ossObjectName; + + @SerializedName("zipFile") + public String zipFile; + + public Code setOssBucketName(String ossBucketName) { + this.ossBucketName = ossBucketName; + return this; + } + + public String getOssBucketName() { + return ossBucketName; + } + + public Code setOssObjectName(String ossObjectName) { + this.ossObjectName = ossObjectName; + return this; + } + + public String getOssObjectName() { + return ossObjectName; + } + + public Code setZipFile(byte[] zipFile) { + this.zipFile = new BASE64Encoder().encode(zipFile); + return this; + } + + public String getZipFile() { + return zipFile; + } + + public Code setDir(String dir) throws IOException { + String tempZipPath = "/tmp/code" + UUID.randomUUID() + ".zip"; + ZipUtils.zipDir(new File(dir), tempZipPath); + File file = new File(tempZipPath); + byte[] buffer = new byte[file.length() > Integer.MAX_VALUE ? Integer.MAX_VALUE : (int)file.length()]; + FileInputStream fis = new FileInputStream(tempZipPath); + fis.read(buffer); + fis.close(); + this.zipFile = new BASE64Encoder().encode(buffer); + new File(tempZipPath).delete(); + return this; + } +} diff --git a/src/main/java/com/aliyuncs/fc/model/FunctionMetadata.java b/src/main/java/com/aliyuncs/fc/model/FunctionMetadata.java new file mode 100644 index 0000000..60dff38 --- /dev/null +++ b/src/main/java/com/aliyuncs/fc/model/FunctionMetadata.java @@ -0,0 +1,103 @@ +package com.aliyuncs.fc.model; + +import com.google.gson.annotations.SerializedName; + +/** + * TODO: add javadoc + */ +public class FunctionMetadata { + + @SerializedName("functionId") + private String functionId; + + @SerializedName("functionName") + private String functionName; + + @SerializedName("description") + private String description; + + @SerializedName("runtime") + private String runtime; + + @SerializedName("handler") + private String handler; + + @SerializedName("timeout") + private Integer timeout; + + @SerializedName("memorySize") + private Integer memorySize; + + @SerializedName("codeSize") + private Integer codeSize; + + @SerializedName("codeChecksum") + private String codeChecksum; + + @SerializedName("createdTime") + private String createdTime; + + @SerializedName("lastModifiedTime") + private String lastModifiedTime; + + public FunctionMetadata(String functionId, String functionName, String description, + String runtime, String handler, Integer timeout, Integer memorySize, + int codeSize, String codeChecksum, String createdTime, String lastModifiedTime) { + this.functionId = functionId; + this.functionName = functionName; + this.description = description; + this.runtime = runtime; + this.handler = handler; + this.timeout = timeout; + this.memorySize = memorySize; + this.codeSize = codeSize; + this.codeChecksum = codeChecksum; + this.createdTime = createdTime; + this.lastModifiedTime = lastModifiedTime; + + } + public String getFunctionName() { + return functionName; + } + + public String getFunctionId() { + return functionId; + } + + public String getDescription() { + return description; + } + + public String getRuntime() { + return runtime; + } + + public String getHandler() { + return handler; + } + + public Integer getTimeout() { + return timeout; + } + + public Integer getMemorySize() { + return memorySize; + } + + public String getCreatedTime() { + return createdTime; + } + + public String getLastModifiedTime() { + return lastModifiedTime; + } + + public Integer getCodeSize() { + return codeSize; + } + + public String getCodeChecksum() { + return codeChecksum; + } + +} diff --git a/src/main/java/com/aliyuncs/fc/model/ListRequestUrlHelper.java b/src/main/java/com/aliyuncs/fc/model/ListRequestUrlHelper.java new file mode 100644 index 0000000..896b83b --- /dev/null +++ b/src/main/java/com/aliyuncs/fc/model/ListRequestUrlHelper.java @@ -0,0 +1,32 @@ +package com.aliyuncs.fc.model; + +import java.util.HashMap; +import java.util.Map; + +/** + * Contains helper methods to build url query string parameters + */ +public class ListRequestUrlHelper { + + public static Map buildParams(String prefix, String startKey, + String nextToken, Integer limit) { + Map queryParams = new HashMap(); + if (prefix != null) { + queryParams.put("prefix", prefix); + } + + if (startKey != null) { + queryParams.put("startKey", startKey); + } + + if (nextToken != null) { + queryParams.put("nextToken", nextToken); + } + + if (limit != null) { + queryParams.put("limit", limit.toString()); + } + return queryParams; + } +} + diff --git a/src/main/java/com/aliyuncs/fc/model/LogConfig.java b/src/main/java/com/aliyuncs/fc/model/LogConfig.java new file mode 100644 index 0000000..6fa3950 --- /dev/null +++ b/src/main/java/com/aliyuncs/fc/model/LogConfig.java @@ -0,0 +1,33 @@ +package com.aliyuncs.fc.model; + +/** + * TODO: add javadoc + */ +public class LogConfig { + + private String project; + private String logstore; + + public LogConfig(String project, String logStore) { + this.project = project; + this.logstore = logStore; + } + + public LogConfig setProject(String project) { + this.project = project; + return this; + } + + public String getProject() { + return project; + } + + public LogConfig setLogStore(String logStore) { + this.logstore = logStore; + return this; + } + + public String getLogStore() { + return logstore; + } +} diff --git a/src/main/java/com/aliyuncs/fc/model/OSSTriggerConfig.java b/src/main/java/com/aliyuncs/fc/model/OSSTriggerConfig.java new file mode 100644 index 0000000..4b319b3 --- /dev/null +++ b/src/main/java/com/aliyuncs/fc/model/OSSTriggerConfig.java @@ -0,0 +1,28 @@ +package com.aliyuncs.fc.model; + +import com.google.gson.annotations.SerializedName; + +/** + * OSS Trigger config + */ +public class OSSTriggerConfig { + + @SerializedName("events") + private String[] events; + + @SerializedName("filter") + private OSSTriggerFilter filter; + + public OSSTriggerConfig(String[] events, String filterPrefix, String filterSuffix) { + this.events = events; + this.filter = new OSSTriggerFilter(filterPrefix, filterSuffix); + } + + public String[] getEvents() { + return events; + } + + public OSSTriggerFilter getFilter() { + return filter; + } +} diff --git a/src/main/java/com/aliyuncs/fc/model/OSSTriggerFilter.java b/src/main/java/com/aliyuncs/fc/model/OSSTriggerFilter.java new file mode 100644 index 0000000..a170851 --- /dev/null +++ b/src/main/java/com/aliyuncs/fc/model/OSSTriggerFilter.java @@ -0,0 +1,24 @@ +package com.aliyuncs.fc.model; + +import com.google.gson.annotations.SerializedName; + +/** + * OSS event notification filter + */ +public class OSSTriggerFilter { + + @SerializedName("key") + private OSSTriggerKey key; + + public OSSTriggerFilter(String filterPrefix, String filterSuffix) { + this.key = new OSSTriggerKey(filterPrefix, filterSuffix); + } + + public void setKey(OSSTriggerKey key) { + this.key = key; + } + + public OSSTriggerKey getKey() { + return key; + } +} diff --git a/src/main/java/com/aliyuncs/fc/model/OSSTriggerKey.java b/src/main/java/com/aliyuncs/fc/model/OSSTriggerKey.java new file mode 100644 index 0000000..b35f729 --- /dev/null +++ b/src/main/java/com/aliyuncs/fc/model/OSSTriggerKey.java @@ -0,0 +1,29 @@ +package com.aliyuncs.fc.model; + +import com.google.gson.annotations.SerializedName; + +/** + * Used to bind OSS Trigger Key + */ +public class OSSTriggerKey { + + @SerializedName("prefix") + private String prefix; + + @SerializedName("suffix") + private String suffix; + + public OSSTriggerKey(String prefix, String suffix) { + this.prefix = prefix; + this.suffix = suffix; + } + + public String getPrefix() { + return prefix; + } + + public String getSuffix() { + return suffix; + } +} + diff --git a/src/main/java/com/aliyuncs/fc/model/PrepareUrl.java b/src/main/java/com/aliyuncs/fc/model/PrepareUrl.java new file mode 100644 index 0000000..17b3025 --- /dev/null +++ b/src/main/java/com/aliyuncs/fc/model/PrepareUrl.java @@ -0,0 +1,25 @@ +package com.aliyuncs.fc.model; + +import java.util.Map; + +/** + * TODO: add javadoc + */ +public class PrepareUrl { + + private String url = null; + private Map header = null; + + public PrepareUrl(String url, Map header) { + this.url = url; + this.header = header; + } + + public String getUrl() { + return url; + } + + public Map getHeader() { + return header; + } +} diff --git a/src/main/java/com/aliyuncs/fc/model/ServiceMetadata.java b/src/main/java/com/aliyuncs/fc/model/ServiceMetadata.java new file mode 100644 index 0000000..1af3e91 --- /dev/null +++ b/src/main/java/com/aliyuncs/fc/model/ServiceMetadata.java @@ -0,0 +1,55 @@ +package com.aliyuncs.fc.model; + +/** + * TODO: add javadoc + */ +public class ServiceMetadata { + + private String serviceName; + private String description; + private String role; + private LogConfig logConfig; + private String serviceId; + private String createdTime; + private String lastModifiedTime; + + public ServiceMetadata(String serviceName, String description, String role, + LogConfig logConfig, String serviceId, String createdTime, String lastModifiedTime) { + this.serviceName = serviceName; + this.description = description; + this.role = role; + this.logConfig = logConfig; + this.serviceId = serviceId; + this.createdTime = createdTime; + this.lastModifiedTime = lastModifiedTime; + } + + public String getServiceName() { + return serviceName; + } + + public String getDescription() { + return description; + } + + public String getRole() { + return role; + } + + public LogConfig getLogConfig() { + return logConfig; + } + + public String getServiceId() { + return serviceId; + } + + public String getCreatedTime() { + return createdTime; + } + + public String getLastModifiedTime() { + return lastModifiedTime; + } + +} diff --git a/src/main/java/com/aliyuncs/fc/model/TriggerMetadata.java b/src/main/java/com/aliyuncs/fc/model/TriggerMetadata.java new file mode 100644 index 0000000..a1645de --- /dev/null +++ b/src/main/java/com/aliyuncs/fc/model/TriggerMetadata.java @@ -0,0 +1,70 @@ +package com.aliyuncs.fc.model; + +import com.google.gson.annotations.SerializedName; + +/** + * TODO: add javadoc + */ +public class TriggerMetadata { + + @SerializedName("triggerName") + private String triggerName; + + @SerializedName("sourceArn") + private String sourceArn; + + @SerializedName("triggerType") + private String triggerType; + + @SerializedName("invocationRole") + private String invocationRole; + + @SerializedName("createdTime") + private String createdTime; + + @SerializedName("lastModifiedTime") + private String lastModifiedTime; + + @SerializedName("triggerConfig") + private Object triggerConfig; + + public TriggerMetadata(String triggerName, String sourceArn, String triggerType, + String invocationRole, String createdTime, String lastModifiedTime, + Object triggerConfig) { + this.triggerName = triggerName; + this.sourceArn = sourceArn; + this.triggerType = triggerType; + this.invocationRole = invocationRole; + this.createdTime = createdTime; + this.lastModifiedTime = lastModifiedTime; + this.triggerConfig = triggerConfig; + } + + public String getTriggerName() { + return triggerName; + } + + public String getSourceArn() { + return sourceArn; + } + + public String getTriggerType() { + return triggerType; + } + + public String getInvocationRole() { + return invocationRole; + } + + public String getCreatedTime() { + return createdTime; + } + + public String getLastModifiedTime() { + return lastModifiedTime; + } + + public Object getTriggerConfig() { + return triggerConfig; + } +} diff --git a/src/main/java/com/aliyuncs/fc/request/CreateFunctionRequest.java b/src/main/java/com/aliyuncs/fc/request/CreateFunctionRequest.java new file mode 100755 index 0000000..2955177 --- /dev/null +++ b/src/main/java/com/aliyuncs/fc/request/CreateFunctionRequest.java @@ -0,0 +1,161 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package com.aliyuncs.fc.request; + +import com.aliyuncs.fc.constants.Const; +import com.aliyuncs.fc.exceptions.ClientException; +import com.aliyuncs.fc.http.FormatType; +import com.aliyuncs.fc.http.HttpRequest; +import com.aliyuncs.fc.model.Code; +import com.aliyuncs.fc.response.CreateFunctionResponse; +import com.aliyuncs.fc.utils.ParameterHelper; + +import com.google.common.base.Strings; +import com.google.gson.annotations.SerializedName; +import java.util.Map; + +/** + * TODO: add javadoc + */ +public class CreateFunctionRequest extends HttpRequest { + + private transient final String serviceName; + + @SerializedName("functionName") + private String functionName; + + @SerializedName("description") + private String description; + + @SerializedName("runtime") + private String runtime; + + @SerializedName("handler") + private String handler; + + @SerializedName("timeout") + private Integer timeout; + + @SerializedName("memorySize") + private Integer memorySize; + + @SerializedName("code") + private Code code; + + public CreateFunctionRequest(String serviceName) { + this.serviceName = serviceName; + } + + public String getServiceName() { + return serviceName; + } + + public CreateFunctionRequest setCode(Code code) { + this.code = code; + return this; + } + + public Code getCode() { + return code; + } + + public CreateFunctionRequest setFunctionName(String functionName) { + this.functionName = functionName; + return this; + } + + public String getFunctionName() { + return functionName; + } + + public CreateFunctionRequest setDescription(String description) { + this.description = description; + return this; + } + + public String getDescription() { + return description; + } + + public CreateFunctionRequest setRuntime(String runtime) { + this.runtime = runtime; + return this; + } + + public String getRuntime() { + return runtime; + } + + public CreateFunctionRequest setHandler(String handler) { + this.handler = handler; + return this; + } + + public String getHandler() { + return handler; + } + + public CreateFunctionRequest setTimeout(Integer timeout) { + this.timeout = timeout; + return this; + } + + public Integer getTimeout() { + return timeout; + } + + public CreateFunctionRequest setMemorySize(Integer memorySize) { + this.memorySize = memorySize; + return this; + } + + public Integer getMemorySize() { + return memorySize; + } + + public String getPath() { + return String.format(Const.FUNCTION_PATH, Const.API_VERSION, this.serviceName); + } + + public Map getQueryParams() { + return null; + } + + public Map getHeader() { + return null; + } + + public byte[] getPayload() { + return ParameterHelper.ObjectToJson(this).getBytes(); + } + + public FormatType getFormat() { + return FormatType.JSON; + } + + public void validate() throws ClientException { + if (Strings.isNullOrEmpty(serviceName)) { + throw new ClientException("Service name cannot be blank"); + } + } + + public Class getResponseClass() { + return CreateFunctionResponse.class; + } +} diff --git a/src/main/java/com/aliyuncs/fc/request/CreateServiceRequest.java b/src/main/java/com/aliyuncs/fc/request/CreateServiceRequest.java new file mode 100755 index 0000000..167669a --- /dev/null +++ b/src/main/java/com/aliyuncs/fc/request/CreateServiceRequest.java @@ -0,0 +1,117 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package com.aliyuncs.fc.request; + + +import com.aliyuncs.fc.constants.Const; +import com.aliyuncs.fc.exceptions.ClientException; +import com.aliyuncs.fc.http.HttpRequest; +import com.aliyuncs.fc.model.LogConfig; +import com.aliyuncs.fc.http.FormatType; +import com.aliyuncs.fc.response.CreateServiceResponse; +import com.aliyuncs.fc.utils.ParameterHelper; + +import com.google.common.base.Strings; +import com.google.gson.annotations.SerializedName; +import java.util.Map; + +/** + * TODO: add javadoc + */ +public class CreateServiceRequest extends HttpRequest { + + @SerializedName("serviceName") + private String serviceName; + + @SerializedName("description") + private String description; + + @SerializedName("role") + private String role; + + @SerializedName("logConfig") + private LogConfig logConfig; + + public CreateServiceRequest setServiceName(String serviceName) { + this.serviceName = serviceName; + return this; + } + + public String getServiceName() { + return serviceName; + } + + public CreateServiceRequest setDescription(String description) { + this.description = description; + return this; + } + + public String getDescription() { + return description; + } + + public CreateServiceRequest setRole(String role) { + this.role = role; + return this; + } + + public String getRole() { + return role; + } + + public LogConfig getLogConfig() { + return logConfig; + } + + public CreateServiceRequest setLogConfig(LogConfig logConfig) { + this.logConfig = logConfig; + return this; + } + + public String getPath() { + return String.format(Const.SERVICE_PATH, Const.API_VERSION); + } + + public Map getHeader() { + return null; + } + + public byte[] getPayload() { + if (ParameterHelper.ObjectToJson(this) != null) { + return ParameterHelper.ObjectToJson(this).getBytes(); + } + return null; + } + + public FormatType getForm() { + return FormatType.JSON; + } + + public void validate() throws ClientException { + return; + } + + public Map getQueryParams() { + return null; + } + + public Class getResponseClass() { + return CreateServiceResponse.class; + } +} diff --git a/src/main/java/com/aliyuncs/fc/request/CreateTriggerRequest.java b/src/main/java/com/aliyuncs/fc/request/CreateTriggerRequest.java new file mode 100755 index 0000000..b812958 --- /dev/null +++ b/src/main/java/com/aliyuncs/fc/request/CreateTriggerRequest.java @@ -0,0 +1,143 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package com.aliyuncs.fc.request; + + +import com.aliyuncs.fc.exceptions.ClientException; +import com.aliyuncs.fc.http.HttpRequest; +import com.aliyuncs.fc.constants.Const; +import com.aliyuncs.fc.response.CreateTriggerResponse; +import com.aliyuncs.fc.utils.ParameterHelper; + +import com.google.common.base.Strings; +import com.google.gson.annotations.SerializedName; +import java.util.Map; + +/** + * TODO: add javadoc + */ +public class CreateTriggerRequest extends HttpRequest { + + private transient final String serviceName; + private transient final String functionName; + + @SerializedName("triggerName") + private String triggerName; + + @SerializedName("sourceArn") + private String sourceArn; + + @SerializedName("triggerType") + private String triggerType; + + @SerializedName("invocationRole") + private String invocationRole; + + @SerializedName("triggerConfig") + private Object triggerConfig; + + public CreateTriggerRequest(String serviceName, String functionName) { + this.serviceName = serviceName; + this.functionName = functionName; + } + + public String getServiceName() { + return serviceName; + } + + public String getFunctionName() { + return functionName; + } + + public CreateTriggerRequest setTriggerName(String triggerName) { + this.triggerName = triggerName; + return this; + } + + public String getTriggerName() { + return triggerName; + } + + public CreateTriggerRequest setSourceArn(String sourceArn) { + this.sourceArn = sourceArn; + return this; + } + + public String getSourceArn() { + return sourceArn; + } + + public CreateTriggerRequest setTriggerType(String triggerType) { + this.triggerType = triggerType; + return this; + } + + public String getTriggerType() { + return triggerType; + } + + public CreateTriggerRequest setInvocationRole(String invocationRole) { + this.invocationRole = invocationRole; + return this; + } + + public String getInvocationRole() { + return invocationRole; + } + + public CreateTriggerRequest setTriggerConfig(Object triggerConfig) { + this.triggerConfig = triggerConfig; + return this; + } + + public Object getTriggerConfig() { + return triggerConfig; + } + + public String getPath() { + return String + .format(Const.TRIGGER_PATH, Const.API_VERSION, this.serviceName, this.functionName); + } + + public Map getQueryParams() { + return null; + } + + public Map getHeader() { + return null; + } + + public byte[] getPayload() { + return ParameterHelper.ObjectToJson(this).getBytes(); + } + + public void validate() throws ClientException { + if (Strings.isNullOrEmpty(serviceName)) { + throw new ClientException("Service name cannot be blank"); + } + if (Strings.isNullOrEmpty(functionName)) { + throw new ClientException("Function name cannot be blank"); + } + return; + } + + public Class getResponseClass() { + return CreateTriggerResponse.class; + } +} diff --git a/src/main/java/com/aliyuncs/fc/request/DeleteFunctionRequest.java b/src/main/java/com/aliyuncs/fc/request/DeleteFunctionRequest.java new file mode 100755 index 0000000..281d108 --- /dev/null +++ b/src/main/java/com/aliyuncs/fc/request/DeleteFunctionRequest.java @@ -0,0 +1,96 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package com.aliyuncs.fc.request; + + +import com.aliyuncs.fc.constants.Const; +import com.aliyuncs.fc.exceptions.ClientException; +import com.aliyuncs.fc.http.HttpRequest; +import com.aliyuncs.fc.response.DeleteFunctionResponse; + +import com.google.common.base.Strings; +import java.util.HashMap; +import java.util.Map; + +/** + * TODO: add javadoc + */ +public class DeleteFunctionRequest extends HttpRequest { + + private final String serviceName; + private final String functionName; + private transient String ifMatch; + + public DeleteFunctionRequest(String serviceName, String functionName) { + this.serviceName = serviceName; + this.functionName = functionName; + } + + public String getServiceName() { + return serviceName; + } + + public String getFunctionName() { + return functionName; + } + + public DeleteFunctionRequest setIfMatch(String IfMatch) { + this.ifMatch = IfMatch; + return this; + } + + public String getIfMatch() { + return ifMatch; + } + + public String getPath() { + return String.format(Const.SINGLE_FUNCTION_PATH, Const.API_VERSION, this.serviceName, + this.functionName); + } + + public Map getQueryParams() { + return null; + } + + public Map getHeader() { + Map header = new HashMap(); + if (!Strings.isNullOrEmpty(ifMatch)) { + header.put("If-Match", ifMatch); + } + return header; + } + + public byte[] getPayload() { + return null; + } + + public void validate() throws ClientException { + if (Strings.isNullOrEmpty(serviceName)) { + throw new ClientException("Service name cannot be blank"); + } + if (Strings.isNullOrEmpty(functionName)) { + throw new ClientException("Function name cannot be blank"); + } + } + + public Class getResponseClass() { + return DeleteFunctionResponse.class; + } + +} diff --git a/src/main/java/com/aliyuncs/fc/request/DeleteServiceRequest.java b/src/main/java/com/aliyuncs/fc/request/DeleteServiceRequest.java new file mode 100755 index 0000000..6504eab --- /dev/null +++ b/src/main/java/com/aliyuncs/fc/request/DeleteServiceRequest.java @@ -0,0 +1,85 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package com.aliyuncs.fc.request; + + +import com.aliyuncs.fc.constants.Const; +import com.aliyuncs.fc.exceptions.ClientException; +import com.aliyuncs.fc.http.HttpRequest; +import com.aliyuncs.fc.response.DeleteServiceResponse; + +import com.google.common.base.Strings; +import java.util.HashMap; +import java.util.Map; + +/** + * TODO: add javadoc + */ +public class DeleteServiceRequest extends HttpRequest { + + private final String serviceName; + private transient String ifMatch; + + public DeleteServiceRequest(String serviceName) { + this.serviceName = serviceName; + } + public String getServiceName() { + return serviceName; + } + + public DeleteServiceRequest setIfMath(String ifMatch) { + this.ifMatch = ifMatch; + return this; + } + + public String getIfMatch() { + return ifMatch; + } + + public String getPath() { + return String.format(Const.SINGLE_SERVICE_PATH, Const.API_VERSION, this.serviceName); + } + + public Map getQueryParams() { + return null; + } + + public Map getHeader() { + Map header = new HashMap(); + if (!Strings.isNullOrEmpty(ifMatch)) { + header.put("If-Match", ifMatch); + } + return header; + } + + public byte[] getPayload() { + return null; + } + + public void validate() throws ClientException { + if (Strings.isNullOrEmpty(serviceName)) { + throw new ClientException("Service name cannot be blank"); + } + } + + public Class getResponseClass() { + return DeleteServiceResponse.class; + } + +} diff --git a/src/main/java/com/aliyuncs/fc/request/DeleteTriggerRequest.java b/src/main/java/com/aliyuncs/fc/request/DeleteTriggerRequest.java new file mode 100755 index 0000000..f1ffa0f --- /dev/null +++ b/src/main/java/com/aliyuncs/fc/request/DeleteTriggerRequest.java @@ -0,0 +1,108 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package com.aliyuncs.fc.request; + + +import com.aliyuncs.fc.constants.Const; +import com.aliyuncs.fc.exceptions.ClientException; +import com.aliyuncs.fc.http.HttpRequest; +import com.aliyuncs.fc.response.DeleteTriggerResponse; + +import com.google.common.base.Strings; +import java.util.HashMap; +import java.util.Map; + +/** + * TODO: add javadoc + */ +public class DeleteTriggerRequest extends HttpRequest { + + private final String serviceName; + private final String functionName; + private final String triggerName; + private transient String ifMatch; + + public DeleteTriggerRequest(String serviceName, String functionName, String triggerName) { + this.serviceName = serviceName; + this.functionName = functionName; + this.triggerName = triggerName; + } + + public DeleteTriggerRequest setIfMatch(String ifMath) { + this.ifMatch = ifMath; + return this; + } + + public String getIfMatch() { + return ifMatch; + } + + public String getServiceName() { + return serviceName; + } + + public String getFunctionName() { + return functionName; + } + + public String getTriggerName() { + return triggerName; + } + + public String getPath() { + return String + .format(Const.SINGLE_TRIGGER_PATH, Const.API_VERSION, this.serviceName, this.functionName, + this.triggerName); + } + + public Map getQueryParams() { + return null; + } + + public Map getHeader() { + Map header = new HashMap(); + if (!Strings.isNullOrEmpty(ifMatch)) { + header.put("If-Match", this.ifMatch); + } + return header; + } + + public byte[] getPayload() { + return null; + } + + public void validate() throws ClientException { + if (Strings.isNullOrEmpty(serviceName)) { + throw new ClientException("Service name cannot be blank"); + } + + if (Strings.isNullOrEmpty(functionName)) { + throw new ClientException("Function name cannot be blank"); + } + + if (Strings.isNullOrEmpty(triggerName)) { + throw new ClientException("Trigger name cannot be blank"); + } + } + + public Class getResponseClass() { + return DeleteTriggerResponse.class; + } + +} diff --git a/src/main/java/com/aliyuncs/fc/request/GetFunctionRequest.java b/src/main/java/com/aliyuncs/fc/request/GetFunctionRequest.java new file mode 100755 index 0000000..418b624 --- /dev/null +++ b/src/main/java/com/aliyuncs/fc/request/GetFunctionRequest.java @@ -0,0 +1,81 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package com.aliyuncs.fc.request; + + +import com.aliyuncs.fc.constants.Const; +import com.aliyuncs.fc.exceptions.ClientException; +import com.aliyuncs.fc.http.HttpRequest; +import com.aliyuncs.fc.response.GetFunctionResponse; + +import com.google.common.base.Strings; +import java.util.Map; + +/** + * TODO: add javadoc + */ +public class GetFunctionRequest extends HttpRequest { + + private final String serviceName; + private final String functionName; + + public GetFunctionRequest(String serviceName, String functionName) { + this.serviceName = serviceName; + this.functionName = functionName; + } + + public String getServiceName() { + return serviceName; + } + + public String getFunctionName() { + return functionName; + } + + public String getPath() { + return String.format(Const.SINGLE_FUNCTION_PATH, Const.API_VERSION, this.serviceName, + this.functionName); + } + + public Map getQueryParams() { + return null; + } + + public Map getHeader() { + return null; + } + + public byte[] getPayload() { + return null; + } + + public void validate() throws ClientException { + if (Strings.isNullOrEmpty(serviceName)) { + throw new ClientException("Service name cannot be blank"); + } + if (Strings.isNullOrEmpty(functionName)) { + throw new ClientException("Function name cannot be blank"); + } + } + + public Class getResponseClass() { + return GetFunctionResponse.class; + } + +} diff --git a/src/main/java/com/aliyuncs/fc/request/GetServiceRequest.java b/src/main/java/com/aliyuncs/fc/request/GetServiceRequest.java new file mode 100755 index 0000000..a85c7c0 --- /dev/null +++ b/src/main/java/com/aliyuncs/fc/request/GetServiceRequest.java @@ -0,0 +1,71 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package com.aliyuncs.fc.request; + + +import com.aliyuncs.fc.exceptions.ClientException; +import com.aliyuncs.fc.http.HttpRequest; +import com.aliyuncs.fc.constants.Const; +import com.aliyuncs.fc.response.GetServiceResponse; + +import com.google.common.base.Strings; +import java.util.Map; + +/** + * TODO: add javadoc + */ +public class GetServiceRequest extends HttpRequest { + + private final String serviceName; + + public GetServiceRequest(String serviceName) { + this.serviceName = serviceName; + } + + public String getServiceName() { + return serviceName; + } + + public String getPath() { + return String.format(Const.SINGLE_SERVICE_PATH, Const.API_VERSION, serviceName); + } + + public Map getQueryParams() { + return null; + } + + public Map getHeader() { + return null; + } + + public byte[] getPayload() { + return null; + } + + public void validate() throws ClientException { + if (Strings.isNullOrEmpty(serviceName)) { + throw new ClientException("Service name cannot be blank"); + } + } + + public Class getResponseClass() { + return GetServiceResponse.class; + } + +} diff --git a/src/main/java/com/aliyuncs/fc/request/GetTriggerRequest.java b/src/main/java/com/aliyuncs/fc/request/GetTriggerRequest.java new file mode 100755 index 0000000..ec99d06 --- /dev/null +++ b/src/main/java/com/aliyuncs/fc/request/GetTriggerRequest.java @@ -0,0 +1,86 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package com.aliyuncs.fc.request; + +import com.aliyuncs.fc.constants.Const; +import com.aliyuncs.fc.exceptions.ClientException; +import com.aliyuncs.fc.http.HttpRequest; +import com.aliyuncs.fc.response.GetTriggerResponse; + +import com.google.common.base.Strings; +import java.util.Map; + +/** + * TODO: add javadoc + */ +public class GetTriggerRequest extends HttpRequest { + + private final String serviceName; + private final String functionName; + private final String triggerName; + + public GetTriggerRequest(String serviceName, String functionName, String triggerName) { + this.serviceName = serviceName; + this.functionName = functionName; + this.triggerName = triggerName; + } + + public String getServiceName() { + return serviceName; + } + + public String getTriggerName() { + return triggerName; + } + + public Map getQueryParams() { + return null; + } + + public Map getHeader() { + return null; + } + + public String getPath() { + return String + .format(Const.SINGLE_TRIGGER_PATH, Const.API_VERSION, this.serviceName, this.functionName, + this.triggerName); + } + + public byte[] getPayload() { + return null; + } + + public void validate() throws ClientException { + if (Strings.isNullOrEmpty(serviceName)) { + throw new ClientException("Service name cannot be blank"); + } + if (Strings.isNullOrEmpty(functionName)) { + throw new ClientException("Function name cannot be blank"); + } + if (Strings.isNullOrEmpty(triggerName)) { + throw new ClientException("Trigger name cannot be blank"); + } + } + + public Class getResponseClass() { + return GetTriggerResponse.class; + } + +} diff --git a/src/main/java/com/aliyuncs/fc/request/InvokeFunctionRequest.java b/src/main/java/com/aliyuncs/fc/request/InvokeFunctionRequest.java new file mode 100755 index 0000000..4603ef0 --- /dev/null +++ b/src/main/java/com/aliyuncs/fc/request/InvokeFunctionRequest.java @@ -0,0 +1,109 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package com.aliyuncs.fc.request; + +import com.aliyuncs.fc.exceptions.ClientException; +import com.aliyuncs.fc.http.HttpRequest; +import com.aliyuncs.fc.constants.Const; +import com.aliyuncs.fc.response.InvokeFunctionResponse; + +import com.google.common.base.Strings; +import java.util.HashMap; +import java.util.Map; + +/** + * TODO: add javadoc + */ +public class InvokeFunctionRequest extends HttpRequest { + + private final String serviceName; + private final String functionName; + private String invocationType; + private byte[] payload; + + public InvokeFunctionRequest(String serviceName, String functionName) { + this.serviceName = serviceName; + this.functionName = functionName; + } + + public String getServiceName() { + return serviceName; + } + + public String getFunctionName() { + return functionName; + } + + public InvokeFunctionRequest setInvocationType(String invocationType) { + this.invocationType = invocationType; + return this; + } + + public String getInvocationType() { + return invocationType; + } + + public InvokeFunctionRequest setPayload(byte[] payload) { + this.payload = payload; + return this; + } + + public Map getQueryParams() { + return null; + } + + public String getPath() { + return String.format(Const.INVOKE_FUNCTION_PATH, Const.API_VERSION, this.serviceName, + this.functionName); + } + + public Map getQueryParam() { + return null; + } + + public Map getHeader() { + Map headers = new HashMap(); + if (this.invocationType != null && this.invocationType.length() > 0) { + headers.put("X-Fc-Invocation-Type", this.invocationType); + } + return headers; + } + + public void validate() throws ClientException { + if (Strings.isNullOrEmpty(serviceName)) { + throw new ClientException("Service name cannot be blank"); + } + if (Strings.isNullOrEmpty(functionName)) { + throw new ClientException("Function name cannot be blank"); + } + } + + public byte[] getPayload() { + if (this.payload == null || this.payload.length <= 0) { + return null; + } + return payload; + } + + + public Class getResponseClass() { + return InvokeFunctionResponse.class; + } + +} diff --git a/src/main/java/com/aliyuncs/fc/request/ListFunctionsRequest.java b/src/main/java/com/aliyuncs/fc/request/ListFunctionsRequest.java new file mode 100755 index 0000000..56972b0 --- /dev/null +++ b/src/main/java/com/aliyuncs/fc/request/ListFunctionsRequest.java @@ -0,0 +1,111 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package com.aliyuncs.fc.request; + +import com.aliyuncs.fc.exceptions.ClientException; +import com.aliyuncs.fc.http.HttpRequest; +import com.aliyuncs.fc.constants.Const; +import com.aliyuncs.fc.model.ListRequestUrlHelper; +import com.aliyuncs.fc.response.ListFunctionsResponse; + +import com.google.common.base.Strings; +import java.util.Map; + +/** + * TODO: add javadoc + */ +public class ListFunctionsRequest extends HttpRequest { + + private final String serviceName; + private String prefix; + private String startKey; + private String nextToken; + private Integer limit; + + public ListFunctionsRequest(String serviceName) { + this.serviceName = serviceName; + } + + public ListFunctionsRequest setPrefix(String prefix) { + this.prefix = prefix; + return this; + } + + public String getPrefix() { + return prefix; + } + + public ListFunctionsRequest setStartKey(String startKey) { + this.startKey = startKey; + return this; + } + + public String getStartKey() { + return startKey; + } + + public ListFunctionsRequest setNextToken(String nextToken) { + this.nextToken = nextToken; + return this; + } + + public String getNextToken() { + return nextToken; + } + + public ListFunctionsRequest setLimit(Integer limit) { + this.limit = limit; + return this; + } + + public Integer getLimit() { + return limit; + } + + public String getPath() { + return String.format(Const.FUNCTION_PATH, Const.API_VERSION, this.serviceName); + } + + public Map getQueryParams() { + return ListRequestUrlHelper.buildParams(prefix, startKey, nextToken, limit); + } + + public Map getHeader() { + return null; + } + + public byte[] getPayload() { + return null; + } + + public String getServiceName() { + return serviceName; + } + + public void validate() throws ClientException { + if (Strings.isNullOrEmpty(serviceName)) { + throw new ClientException("Service name cannot be blank"); + } + } + + public Class getResponseClass() { + return ListFunctionsResponse.class; + } + +} diff --git a/src/main/java/com/aliyuncs/fc/request/ListServicesRequest.java b/src/main/java/com/aliyuncs/fc/request/ListServicesRequest.java new file mode 100755 index 0000000..6511e56 --- /dev/null +++ b/src/main/java/com/aliyuncs/fc/request/ListServicesRequest.java @@ -0,0 +1,98 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package com.aliyuncs.fc.request; + +import com.aliyuncs.fc.exceptions.ClientException; +import com.aliyuncs.fc.http.HttpRequest; +import com.aliyuncs.fc.constants.Const; +import com.aliyuncs.fc.model.ListRequestUrlHelper; +import com.aliyuncs.fc.response.ListServicesResponse; +import java.util.Map; + +/** + * TODO: add javadoc + */ +public class ListServicesRequest extends HttpRequest { + + private String prefix; + private String startKey; + private String nextToken; + private Integer limit; + + public ListServicesRequest setPrefix(String prefix) { + this.prefix = prefix; + return this; + } + + public String getPrefix() { + return prefix; + } + + public ListServicesRequest setStartKey(String startKey) { + this.startKey = startKey; + return this; + } + + public String getStartKey() { + return startKey; + } + + public ListServicesRequest setNextToken(String nextToken) { + this.nextToken = nextToken; + return this; + } + + public String getNextToken() { + return nextToken; + } + + public ListServicesRequest setLimit(int limit) { + this.limit = limit; + return this; + } + + public Integer getLimit() { + return limit; + } + + public String getPath() { + return String.format(Const.SERVICE_PATH, Const.API_VERSION); + } + + public Map getQueryParams() { + return ListRequestUrlHelper.buildParams(prefix, startKey, nextToken, limit); + } + + public Map getHeader() { + return null; + } + + public byte[] getPayload() { + return null; + } + + public void validate() throws ClientException { + return; + } + + public Class getResponseClass() { + return ListServicesResponse.class; + } + +} diff --git a/src/main/java/com/aliyuncs/fc/request/ListTriggersRequest.java b/src/main/java/com/aliyuncs/fc/request/ListTriggersRequest.java new file mode 100755 index 0000000..2f7e5d1 --- /dev/null +++ b/src/main/java/com/aliyuncs/fc/request/ListTriggersRequest.java @@ -0,0 +1,119 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package com.aliyuncs.fc.request; + +import com.aliyuncs.fc.constants.Const; +import com.aliyuncs.fc.exceptions.ClientException; +import com.aliyuncs.fc.http.HttpRequest; +import com.aliyuncs.fc.model.ListRequestUrlHelper; +import com.aliyuncs.fc.response.ListTriggersResponse; +import com.google.common.base.Strings; +import java.util.Map; + +/** + * TODO: add javadoc + */ +public class ListTriggersRequest extends HttpRequest { + private final String serviceName; + private final String functionName; + private String prefix; + private String startKey; + private String nextToken; + private Integer limit; + + public ListTriggersRequest(String serviceName, String functionName) { + this.serviceName = serviceName; + this.functionName = functionName; + } + + public String getServiceName() { + return serviceName; + } + + public String getFunctionName() { + return functionName; + } + + public ListTriggersRequest setPrefix(String prefix) { + this.prefix = prefix; + return this; + } + + public String getPrefix() { + return prefix; + } + + public ListTriggersRequest setStartKey(String startKey) { + this.startKey = startKey; + return this; + } + + public String getStartKey() { + return startKey; + } + + public ListTriggersRequest setNextToken(String nextToken) { + this.nextToken = nextToken; + return this; + } + + public String getNextToken() { + return nextToken; + } + + public ListTriggersRequest setLimit(Integer limit) { + this.limit = limit; + return this; + } + + public Integer getLimit() { + return limit; + } + + public Map getQueryParams() { + return ListRequestUrlHelper.buildParams(prefix, startKey, nextToken, limit); + } + + public byte[] getPayload() { + return null; + } + + public Map getHeader() { + return null; + } + + public void validate() throws ClientException { + if (Strings.isNullOrEmpty(this.serviceName)) { + throw new ClientException("Service name cannot be blank"); + } + if (Strings.isNullOrEmpty(this.functionName)) { + throw new ClientException("Function name cannot be blank"); + } + } + + public String getPath() { + return String + .format(Const.TRIGGER_PATH, Const.API_VERSION, this.serviceName, this.functionName); + } + + public Class getResponseClass() { + return ListTriggersResponse.class; + } + +} diff --git a/src/main/java/com/aliyuncs/fc/request/UpdateFunctionRequest.java b/src/main/java/com/aliyuncs/fc/request/UpdateFunctionRequest.java new file mode 100755 index 0000000..2418738 --- /dev/null +++ b/src/main/java/com/aliyuncs/fc/request/UpdateFunctionRequest.java @@ -0,0 +1,171 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package com.aliyuncs.fc.request; + +import com.aliyuncs.fc.constants.Const; +import com.aliyuncs.fc.exceptions.ClientException; +import com.aliyuncs.fc.http.HttpRequest; +import com.aliyuncs.fc.model.Code; +import com.aliyuncs.fc.response.UpdateFunctionResponse; +import com.aliyuncs.fc.utils.ParameterHelper; + +import com.google.common.base.Strings; +import com.google.gson.annotations.SerializedName; +import java.util.HashMap; +import java.util.Map; + +/** + * TODO: add javadoc + */ +public class UpdateFunctionRequest extends HttpRequest { + + private transient final String serviceName; + private transient final String functionName; + + @SerializedName("description") + private String description; + + @SerializedName("runtime") + private String runtime; + + @SerializedName("handler") + private String handler; + + @SerializedName("timeout") + private Integer timeout; + + @SerializedName("memorySize") + private Integer memorySize; + + @SerializedName("code") + private Code code; + + private transient String ifMatch; + + + public UpdateFunctionRequest(String serviceName, String functionName) { + this.serviceName = serviceName; + this.functionName = functionName; + } + + public String getServiceName() { + return serviceName; + } + + public String getFunctionName() { + return functionName; + } + + public UpdateFunctionRequest setDescription(String description) { + this.description = description; + return this; + } + + public String getDescription() { + return description; + } + + public UpdateFunctionRequest setRuntime(String runtime) { + this.runtime = runtime; + return this; + } + + public String getRuntime() { + return runtime; + } + + public UpdateFunctionRequest setHandler(String handler) { + this.handler = handler; + return this; + } + + public String getHandler() { + return handler; + } + + public UpdateFunctionRequest setTimeout(Integer timeout) { + this.timeout = timeout; + return this; + } + + public Integer getTimeout() { + return timeout; + } + + public UpdateFunctionRequest setMemorySize(Integer memorySize) { + this.memorySize = memorySize; + return this; + } + + public Integer getMemorySize() { + return memorySize; + } + + public UpdateFunctionRequest setCode(Code code) { + this.code = code; + return this; + } + + public Code getCode() { + return code; + } + + public UpdateFunctionRequest setIfMatch(String ifMatch) { + this.ifMatch = ifMatch; + return this; + } + + public String getIfMatch() { + return ifMatch; + } + + public String getPath() { + return String.format(Const.SINGLE_FUNCTION_PATH, Const.API_VERSION, this.serviceName, + this.functionName); + } + + public Map getHeader() { + Map headers = new HashMap(); + if (this.ifMatch != null && this.ifMatch.length() < 0) { + headers.put("If-Match", this.ifMatch); + } + return headers; + } + + public byte[] getPayload() { + return ParameterHelper.ObjectToJson(this).getBytes(); + } + + public Map getQueryParams() { + return null; + } + + public void validate() throws ClientException { + if (Strings.isNullOrEmpty(serviceName)) { + throw new ClientException("Service name cannot be blank"); + } + if (Strings.isNullOrEmpty(functionName)) { + throw new ClientException("Function name cannot be blank"); + } + } + + public Class getResponseClass() { + return UpdateFunctionResponse.class; + } +} diff --git a/src/main/java/com/aliyuncs/fc/request/UpdateServiceRequest.java b/src/main/java/com/aliyuncs/fc/request/UpdateServiceRequest.java new file mode 100755 index 0000000..654b4bd --- /dev/null +++ b/src/main/java/com/aliyuncs/fc/request/UpdateServiceRequest.java @@ -0,0 +1,124 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package com.aliyuncs.fc.request; + +import com.aliyuncs.fc.constants.Const; +import com.aliyuncs.fc.exceptions.ClientException; +import com.aliyuncs.fc.http.HttpRequest; +import com.aliyuncs.fc.model.LogConfig; +import com.aliyuncs.fc.response.UpdateServiceResponse; +import com.aliyuncs.fc.utils.ParameterHelper; + +import com.google.common.base.Strings; +import com.google.gson.annotations.SerializedName; +import java.util.HashMap; +import java.util.Map; + +/** + * TODO: add javadoc + */ +public class UpdateServiceRequest extends HttpRequest { + + private transient final String serviceName; + + @SerializedName("description") + private String description; + + @SerializedName("role") + private String role; + + @SerializedName("logConfig") + private LogConfig logConfig; + private transient String ifMatch; + + public UpdateServiceRequest(String serviceName) { + this.serviceName = serviceName; + } + + public UpdateServiceRequest setIfMatch(String ifMatch) { + this.ifMatch = ifMatch; + return this; + } + + public String getIfMatch() { + return serviceName; + } + + public String getServiceName() { + return serviceName; + } + + public UpdateServiceRequest setDescription(String description) { + this.description = description; + return this; + } + + public String getDescription() { + return description; + } + + public UpdateServiceRequest setRole(String role) { + this.role = role; + return this; + } + + public String getRole() { + return role; + } + + public UpdateServiceRequest setLogConfig(LogConfig logConfig) { + this.logConfig = logConfig; + return this; + } + + public LogConfig getLogConfig() { + return logConfig; + } + + public Map getQueryParams() { + return null; + } + + public String getPath() { + return String.format(Const.SINGLE_SERVICE_PATH, Const.API_VERSION, this.serviceName); + } + + public Map getHeader() { + Map headers = new HashMap(); + if (this.ifMatch != null && this.ifMatch.length() > 0) { + headers.put("If-Match", this.getIfMatch()); + } + return headers; + } + + public byte[] getPayload() { + return ParameterHelper.ObjectToJson(this).getBytes(); + } + + public void validate() throws ClientException { + if (Strings.isNullOrEmpty(serviceName)) { + throw new ClientException("Service name cannot be blank"); + } + } + + public Class getResponseClass() { + return UpdateServiceResponse.class; + } + +} diff --git a/src/main/java/com/aliyuncs/fc/request/UpdateTriggerRequest.java b/src/main/java/com/aliyuncs/fc/request/UpdateTriggerRequest.java new file mode 100755 index 0000000..70406ec --- /dev/null +++ b/src/main/java/com/aliyuncs/fc/request/UpdateTriggerRequest.java @@ -0,0 +1,131 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package com.aliyuncs.fc.request; + +import com.aliyuncs.fc.exceptions.ClientException; +import com.aliyuncs.fc.http.HttpRequest; +import com.aliyuncs.fc.constants.Const; +import com.aliyuncs.fc.response.UpdateTriggerResponse; +import com.aliyuncs.fc.utils.ParameterHelper; + +import com.google.common.base.Strings; +import com.google.gson.annotations.SerializedName; +import java.util.HashMap; +import java.util.Map; + +/** + * TODO: add javadoc + */ +public class UpdateTriggerRequest extends HttpRequest { + + private transient final String serviceName; + private transient final String functionName; + private transient final String triggerName; + + @SerializedName("invocationRole") + private String invocationRole; + + @SerializedName("triggerConfig") + private Object triggerConfig; + private transient String ifMatch; + + public UpdateTriggerRequest(String serviveName, String functionName, String triggerName) { + this.serviceName = serviveName; + this.functionName = functionName; + this.triggerName = triggerName; + } + + public String getIfMatch() { + return ifMatch; + } + + public UpdateTriggerRequest setIfMatch(String ifMatch) { + this.ifMatch = ifMatch; + return this; + } + + public String getServiceName() { + return serviceName; + } + + public String getFunctionName() { + return functionName; + } + + public String getTriggerName() { + return triggerName; + } + + public UpdateTriggerRequest setTriggerConfig(Object triggerConfig) { + this.triggerConfig = triggerConfig; + return this; + } + + public Object getTriggerConfig() { + return triggerConfig; + } + + public UpdateTriggerRequest setInvocationRole(String invocationRole) { + this.invocationRole = invocationRole; + return this; + } + + public String getInvocationRole() { + return invocationRole; + } + + public String getPath() { + return String.format(Const.SINGLE_TRIGGER_PATH, Const.API_VERSION, + serviceName, functionName, triggerName); + } + + public Map getHeader() { + Map header = new HashMap(); + if (!Strings.isNullOrEmpty(ifMatch)) { + header.put("If-Match", ifMatch); + } + return header; + } + + public byte[] getPayload() { + return ParameterHelper.ObjectToJson(this).getBytes(); + } + + public Map getQueryParams() { + return null; + } + + public void validate() throws ClientException { + if (Strings.isNullOrEmpty(serviceName)) { + throw new ClientException("Service name cannot be blank"); + } + + if (Strings.isNullOrEmpty(functionName)) { + throw new ClientException("Function name cannot be blank"); + } + + if (Strings.isNullOrEmpty(triggerName)) { + throw new ClientException("Trigger name cannot be blank"); + } + } + + public Class getResponseClass() { + return UpdateTriggerResponse.class; + } +} diff --git a/src/main/java/com/aliyuncs/fc/response/CreateFunctionResponse.java b/src/main/java/com/aliyuncs/fc/response/CreateFunctionResponse.java new file mode 100755 index 0000000..8e57745 --- /dev/null +++ b/src/main/java/com/aliyuncs/fc/response/CreateFunctionResponse.java @@ -0,0 +1,114 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package com.aliyuncs.fc.response; + +import com.aliyuncs.fc.model.FunctionMetadata; +import com.aliyuncs.fc.http.HttpResponse; + +import com.google.common.base.Preconditions; +import java.util.Map; + +/** + * TODO: add javadoc + */ +public class CreateFunctionResponse extends HttpResponse { + + private Map header; + private FunctionMetadata functionMetadata; + + public CreateFunctionResponse setFunctionMetadata(FunctionMetadata functionMetadata) { + this.functionMetadata = functionMetadata; + return this; + } + + public String getFunctionName() { + Preconditions.checkArgument(functionMetadata != null); + return functionMetadata.getFunctionName(); + } + + public String getFunctionId() { + Preconditions.checkArgument(functionMetadata != null); + return functionMetadata.getFunctionId(); + } + + public String getDescription() { + Preconditions.checkArgument(functionMetadata != null); + return functionMetadata.getDescription(); + } + + public String getRuntime() { + Preconditions.checkArgument(functionMetadata != null); + return functionMetadata.getRuntime(); + } + + public String getHandler() { + Preconditions.checkArgument(functionMetadata != null); + return functionMetadata.getHandler(); + } + + public Integer getTimeout() { + Preconditions.checkArgument(functionMetadata != null); + return functionMetadata.getTimeout(); + } + + public Integer getMemorySize() { + Preconditions.checkArgument(functionMetadata != null); + return functionMetadata.getMemorySize(); + } + + public String getCreatedTime() { + Preconditions.checkArgument(functionMetadata != null); + return functionMetadata.getCreatedTime(); + } + + public String getLastModifiedTime() { + Preconditions.checkArgument(functionMetadata != null); + return functionMetadata.getLastModifiedTime(); + } + + public Integer getCodeSize() { + Preconditions.checkArgument(functionMetadata != null); + return functionMetadata.getCodeSize(); + } + + public String getCodeChecksum() { + + Preconditions.checkArgument(functionMetadata != null); + return functionMetadata.getCodeChecksum(); + } + + public CreateFunctionResponse setHeader(Map header) { + this.header = header; + return this; + } + + public Map getHeader() { + return header; + } + + public String getRequestId() { + return header.get("X-Fc-Request-Id"); + } + + public String getEtag() { + return header.get("Etag"); + } + + +} diff --git a/src/main/java/com/aliyuncs/fc/response/CreateServiceResponse.java b/src/main/java/com/aliyuncs/fc/response/CreateServiceResponse.java new file mode 100755 index 0000000..798b624 --- /dev/null +++ b/src/main/java/com/aliyuncs/fc/response/CreateServiceResponse.java @@ -0,0 +1,92 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package com.aliyuncs.fc.response; + +import com.aliyuncs.fc.model.LogConfig; +import com.aliyuncs.fc.model.ServiceMetadata; +import com.aliyuncs.fc.http.HttpResponse; + +import com.google.common.base.Preconditions; +import java.util.Map; + +/** + * TODO: add javadoc + */ +public class CreateServiceResponse extends HttpResponse { + + private Map header; + private ServiceMetadata serviceMetadata; + + public CreateServiceResponse setHeaders(Map header) { + this.header = header; + return this; + } + + public CreateServiceResponse setServiceMetadata(ServiceMetadata serviceMetadata) { + this.serviceMetadata = serviceMetadata; + return this; + } + + public String getServiceName() { + Preconditions.checkArgument(serviceMetadata != null); + return serviceMetadata.getServiceName(); + } + + public String getDescription() { + Preconditions.checkArgument(serviceMetadata != null); + return serviceMetadata.getDescription(); + } + + public String getRole() { + Preconditions.checkArgument(serviceMetadata != null); + return serviceMetadata.getRole(); + } + + public LogConfig getLogConfig() { + Preconditions.checkArgument(serviceMetadata != null); + return serviceMetadata.getLogConfig(); + } + + public String getServiceId() { + Preconditions.checkArgument(serviceMetadata != null); + return serviceMetadata.getServiceId(); + } + + public String getCreatedTime() { + return serviceMetadata.getCreatedTime(); + } + + public String getLastModifiedTime() { + Preconditions.checkArgument(serviceMetadata != null); + return serviceMetadata.getLastModifiedTime(); + } + + public Map getHeader() { + return this.header; + } + + public String getRequestId() { + return header.get("X-Fc-Request-Id"); + } + + public String getEtag() { + return header.get("Etag"); + } + +} diff --git a/src/main/java/com/aliyuncs/fc/response/CreateTriggerResponse.java b/src/main/java/com/aliyuncs/fc/response/CreateTriggerResponse.java new file mode 100755 index 0000000..178a107 --- /dev/null +++ b/src/main/java/com/aliyuncs/fc/response/CreateTriggerResponse.java @@ -0,0 +1,87 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package com.aliyuncs.fc.response; + +import com.aliyuncs.fc.model.OSSTriggerConfig; +import com.aliyuncs.fc.model.TriggerMetadata; +import com.aliyuncs.fc.http.HttpResponse; + +import com.google.common.base.Preconditions; +import java.util.Map; + +/** + * TODO: add javadoc + */ +public class CreateTriggerResponse extends HttpResponse { + + private Map header; + private TriggerMetadata triggerMetadata; + + public CreateTriggerResponse setHeader(Map header) { + this.header = header; + return this; + } + + public CreateTriggerResponse setTriggerMetadata(TriggerMetadata triggerMetadata) { + this.triggerMetadata = triggerMetadata; + return this; + } + + public Map getHeader() { + return header; + } + + public String getTriggerName() { + Preconditions.checkArgument(triggerMetadata != null); + return triggerMetadata.getTriggerName(); + } + public String getSourceARN() { + Preconditions.checkArgument(triggerMetadata != null); + return triggerMetadata.getSourceArn(); + } + public String getTriggerType() { + Preconditions.checkArgument(triggerMetadata != null); + return triggerMetadata.getTriggerType(); + } + public String getInvocationRole() { + Preconditions.checkArgument(triggerMetadata != null); + return triggerMetadata.getInvocationRole(); + } + public String getCreatedTime() { + Preconditions.checkArgument(triggerMetadata != null); + return triggerMetadata.getCreatedTime(); + } + public String getLastModifiedTime() { + Preconditions.checkArgument(triggerMetadata != null); + return triggerMetadata.getLastModifiedTime(); + } + public Object getTriggerConfig() { + Preconditions.checkArgument(triggerMetadata != null); + return triggerMetadata.getTriggerConfig(); + } + + public String getRequestId() { + return header.get("X-Fc-Request-Id"); + } + + public String getEtag() { + return header.get("Etag"); + } + +} diff --git a/src/main/java/com/aliyuncs/fc/response/DeleteFunctionResponse.java b/src/main/java/com/aliyuncs/fc/response/DeleteFunctionResponse.java new file mode 100755 index 0000000..d3e0aab --- /dev/null +++ b/src/main/java/com/aliyuncs/fc/response/DeleteFunctionResponse.java @@ -0,0 +1,48 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package com.aliyuncs.fc.response; + +import com.aliyuncs.fc.http.HttpResponse; +import java.util.Map; + +/** + * TODO: add javadoc + */ +public class DeleteFunctionResponse extends HttpResponse { + + private Map header = null; + + public Map getHeader() { + return header; + } + + public DeleteFunctionResponse setHeader(Map header) { + this.header = header; + return this; + } + + public String getRequestId() { + return header.get("X-Fc-Request-Id"); + } + + public String getEtag() { + return header.get("Etag"); + } + +} diff --git a/src/main/java/com/aliyuncs/fc/response/DeleteServiceResponse.java b/src/main/java/com/aliyuncs/fc/response/DeleteServiceResponse.java new file mode 100755 index 0000000..3b783a7 --- /dev/null +++ b/src/main/java/com/aliyuncs/fc/response/DeleteServiceResponse.java @@ -0,0 +1,48 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package com.aliyuncs.fc.response; + +import com.aliyuncs.fc.http.HttpResponse; +import java.util.Map; + +/** + * TODO: add javadoc + */ +public class DeleteServiceResponse extends HttpResponse { + + private Map header = null; + + public Map getHeader() { + return header; + } + + public DeleteServiceResponse setHeaders(Map header) { + this.header = header; + return this; + } + + public String getRequestId() { + return header.get("X-Fc-Request-Id"); + } + + public String getEtag() { + return header.get("Etag"); + } + +} diff --git a/src/main/java/com/aliyuncs/fc/response/DeleteTriggerResponse.java b/src/main/java/com/aliyuncs/fc/response/DeleteTriggerResponse.java new file mode 100755 index 0000000..252616b --- /dev/null +++ b/src/main/java/com/aliyuncs/fc/response/DeleteTriggerResponse.java @@ -0,0 +1,49 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package com.aliyuncs.fc.response; + +import com.aliyuncs.fc.http.HttpResponse; + +import java.util.Map; + +/** + * TODO: add javadoc + */ +public class DeleteTriggerResponse extends HttpResponse { + + private Map header = null; + + public Map getHeader() { + return header; + } + + public DeleteTriggerResponse setHeader(Map header) { + this.header = header; + return this; + } + + public String getRequestId() { + return header.get("X-Fc-Request-Id"); + } + + public String getEtag() { + return header.get("Etag"); + } + +} diff --git a/src/main/java/com/aliyuncs/fc/response/GetFunctionResponse.java b/src/main/java/com/aliyuncs/fc/response/GetFunctionResponse.java new file mode 100755 index 0000000..e9ed617 --- /dev/null +++ b/src/main/java/com/aliyuncs/fc/response/GetFunctionResponse.java @@ -0,0 +1,115 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package com.aliyuncs.fc.response; + +import com.aliyuncs.fc.model.FunctionMetadata; +import com.aliyuncs.fc.http.HttpResponse; + +import com.google.common.base.Preconditions; +import java.util.Map; + +/** + * TODO: add javadoc + */ +public class GetFunctionResponse extends HttpResponse { + + private Map header; + private FunctionMetadata functionMetadata; + + public void setFunctionMetadata(FunctionMetadata functionMetadata) { + this.functionMetadata = functionMetadata; + } + + public FunctionMetadata getFunctionMetadata() { + Preconditions.checkArgument(functionMetadata != null); + return functionMetadata; + } + + public String getFunctionName() { + Preconditions.checkArgument(functionMetadata != null); + return functionMetadata.getFunctionName(); + } + + public String getFunctionId() { + Preconditions.checkArgument(functionMetadata != null); + return functionMetadata.getFunctionId(); + } + + public String getDescription() { + Preconditions.checkArgument(functionMetadata != null); + return functionMetadata.getDescription(); + } + + public String getRuntime() { + Preconditions.checkArgument(functionMetadata != null); + return functionMetadata.getRuntime(); + } + + public String getHandler() { + Preconditions.checkArgument(functionMetadata != null); + return functionMetadata.getHandler(); + } + + public Integer getTimeout() { + Preconditions.checkArgument(functionMetadata != null); + return functionMetadata.getTimeout(); + } + + public Integer getMemorySize() { + Preconditions.checkArgument(functionMetadata != null); + return functionMetadata.getMemorySize(); + } + + public int getCodeSize() { + Preconditions.checkArgument(functionMetadata != null); + return functionMetadata.getCodeSize(); + } + + public String getCodeChecksum() { + Preconditions.checkArgument(functionMetadata != null); + return functionMetadata.getCodeChecksum(); + } + + public String getCreatedTime() { + Preconditions.checkArgument(functionMetadata != null); + return functionMetadata.getCreatedTime(); + } + + public String getLastModifiedTime() { + Preconditions.checkArgument(functionMetadata != null); + return functionMetadata.getLastModifiedTime(); + } + + public Map getHeader() { + return header; + } + + public void setHeader(Map header) { + this.header = header; + } + + public String getRequestId() { + return header.get("X-Fc-Request-Id"); + } + + public String getEtag() { + return header.get("Etag"); + } + +} diff --git a/src/main/java/com/aliyuncs/fc/response/GetServiceResponse.java b/src/main/java/com/aliyuncs/fc/response/GetServiceResponse.java new file mode 100755 index 0000000..b7ace02 --- /dev/null +++ b/src/main/java/com/aliyuncs/fc/response/GetServiceResponse.java @@ -0,0 +1,93 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package com.aliyuncs.fc.response; + +import com.aliyuncs.fc.model.LogConfig; +import com.aliyuncs.fc.model.ServiceMetadata; +import com.aliyuncs.fc.http.HttpResponse; + +import com.google.common.base.Preconditions; +import java.util.Map; + +/** + * TODO: add javadoc + */ +public class GetServiceResponse extends HttpResponse { + + private Map header; + private ServiceMetadata serviceMetadata; + + public Map getHeader() { + return header; + } + + public GetServiceResponse setHeader(Map header) { + this.header = header; + return this; + } + + public String getServiceName() { + Preconditions.checkArgument(serviceMetadata != null); + return serviceMetadata.getServiceName(); + } + + public String getDescription() { + Preconditions.checkArgument(serviceMetadata != null); + return serviceMetadata.getDescription(); + } + + public String getRole() { + Preconditions.checkArgument(serviceMetadata != null); + return serviceMetadata.getRole(); + } + + public LogConfig getLogConfig() { + Preconditions.checkArgument(serviceMetadata != null); + return serviceMetadata.getLogConfig(); + } + + public String getServiceId() { + Preconditions.checkArgument(serviceMetadata != null); + return serviceMetadata.getServiceId(); + } + + public String getCreatedTime() { + Preconditions.checkArgument(serviceMetadata != null); + return serviceMetadata.getCreatedTime(); + } + + public String getLastModifiedTime() { + Preconditions.checkArgument(serviceMetadata != null); + return serviceMetadata.getLastModifiedTime(); + } + + public GetServiceResponse setServiceMetadata(ServiceMetadata serviceMetadata) { + this.serviceMetadata = serviceMetadata; + return this; + } + + public String getRequestId() { + return header.get("X-Fc-Request-Id"); + } + + public String getEtag() { + return header.get("Etag"); + } + +} diff --git a/src/main/java/com/aliyuncs/fc/response/GetTriggerResponse.java b/src/main/java/com/aliyuncs/fc/response/GetTriggerResponse.java new file mode 100755 index 0000000..db7f635 --- /dev/null +++ b/src/main/java/com/aliyuncs/fc/response/GetTriggerResponse.java @@ -0,0 +1,93 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package com.aliyuncs.fc.response; + +import com.aliyuncs.fc.model.OSSTriggerConfig; +import com.aliyuncs.fc.model.TriggerMetadata; +import com.aliyuncs.fc.http.HttpResponse; + +import com.google.common.base.Preconditions; +import java.util.Map; + +/** + * TODO: add javadoc + */ +public class GetTriggerResponse extends HttpResponse { + + private Map header; + private TriggerMetadata triggerMetadata; + + public Map getHeader() { + return header; + } + + public GetTriggerResponse setHeader(Map header) { + this.header = header; + return this; + } + + public GetTriggerResponse setTriggerMetadata(TriggerMetadata triggerMetadata) { + this.triggerMetadata = triggerMetadata; + return this; + } + + public String getTriggerName() { + Preconditions.checkArgument(triggerMetadata != null); + return triggerMetadata.getTriggerName(); + } + + public String getSourceARN() { + Preconditions.checkArgument(triggerMetadata != null); + return triggerMetadata.getSourceArn(); + } + + public String getTriggerType() { + Preconditions.checkArgument(triggerMetadata != null); + return triggerMetadata.getTriggerType(); + } + + public String getInvocationRole() { + Preconditions.checkArgument(triggerMetadata != null); + return triggerMetadata.getInvocationRole(); + } + + public String getCreatedTime() { + Preconditions.checkArgument(triggerMetadata != null); + return triggerMetadata.getCreatedTime(); + } + + public String getLastModifiedTime() { + Preconditions.checkArgument(triggerMetadata != null); + return triggerMetadata.getLastModifiedTime(); + } + + public Object getTriggerConfig() { + Preconditions.checkArgument(triggerMetadata != null); + return triggerMetadata.getTriggerConfig(); + } + + public String getRequestId() { + return header.get("X-Fc-Request-Id"); + } + + public String getEtag() { + return header.get("Etag"); + } + +} diff --git a/src/main/java/com/aliyuncs/fc/response/InvokeFunctionResponse.java b/src/main/java/com/aliyuncs/fc/response/InvokeFunctionResponse.java new file mode 100755 index 0000000..5471613 --- /dev/null +++ b/src/main/java/com/aliyuncs/fc/response/InvokeFunctionResponse.java @@ -0,0 +1,60 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package com.aliyuncs.fc.response; + +import com.aliyuncs.fc.http.HttpResponse; + +import java.util.Map; + +/** + * TODO: add javadoc + */ +public class InvokeFunctionResponse extends HttpResponse { + + private Map header = null; + + private byte[] Payload = null; + + public Map getHeader() { + return header; + } + + public InvokeFunctionResponse setHeader(Map header) { + this.header = header; + return this; + } + + public byte[] getPayload() { + return Payload; + } + + public InvokeFunctionResponse setPayload(byte[] payload) { + Payload = payload; + return this; + } + + public String getRequestId() { + return header.get("X-Fc-Request-Id"); + } + + public String getEtag() { + return header.get("Etag"); + } + +} diff --git a/src/main/java/com/aliyuncs/fc/response/ListFunctionsResponse.java b/src/main/java/com/aliyuncs/fc/response/ListFunctionsResponse.java new file mode 100755 index 0000000..ea04e08 --- /dev/null +++ b/src/main/java/com/aliyuncs/fc/response/ListFunctionsResponse.java @@ -0,0 +1,73 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package com.aliyuncs.fc.response; + +import com.aliyuncs.fc.model.FunctionMetadata; +import com.aliyuncs.fc.http.HttpResponse; + +import java.util.Map; + +/** + * TODO: add javadoc + */ +public class ListFunctionsResponse extends HttpResponse { + + private Map header = null; + + private FunctionMetadata[] functions = null; + + private String nextToken = null; + + public String getNextToken() { + return nextToken; + } + + public ListFunctionsResponse setNextToken(String nextToken) { + this.nextToken = nextToken; + return this; + } + + public FunctionMetadata[] getFunctions() { + return functions; + } + + public ListFunctionsResponse setFunctions(FunctionMetadata[] functions) { + functions = functions; + return this; + } + + public Map getHeader() { + return header; + } + + public ListFunctionsResponse setHeader(Map header) { + this.header = header; + return this; + } + + public String getRequestId() { + return header.get("X-Fc-Request-Id"); + } + + public String getEtag() { + return header.get("Etag"); + } + + +} diff --git a/src/main/java/com/aliyuncs/fc/response/ListServicesResponse.java b/src/main/java/com/aliyuncs/fc/response/ListServicesResponse.java new file mode 100755 index 0000000..234be06 --- /dev/null +++ b/src/main/java/com/aliyuncs/fc/response/ListServicesResponse.java @@ -0,0 +1,70 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package com.aliyuncs.fc.response; + +import com.aliyuncs.fc.http.HttpResponse; + +import com.aliyuncs.fc.model.ServiceMetadata; +import java.util.Map; + +/** + * TODO: add javadoc + */ +public class ListServicesResponse extends HttpResponse { + + private Map header = null; + private ServiceMetadata[] services = null; + private String nextToken = null; + + public Map getHeader() { + return header; + } + + public ListServicesResponse setHeader(Map header) { + this.header = header; + return this; + } + + public ServiceMetadata[] getServices() { + return services; + } + + public ListServicesResponse setServices(ServiceMetadata[] services) { + this.services = services; + return this; + } + + public String getNextToken() { + return nextToken; + } + + public ListServicesResponse setNextToken(String nextToken) { + this.nextToken = nextToken; + return this; + } + + public String getRequestId() { + return header.get("X-Fc-Request-Id"); + } + + public String getEtag() { + return header.get("Etag"); + } + +} diff --git a/src/main/java/com/aliyuncs/fc/response/ListTriggersResponse.java b/src/main/java/com/aliyuncs/fc/response/ListTriggersResponse.java new file mode 100755 index 0000000..db80a14 --- /dev/null +++ b/src/main/java/com/aliyuncs/fc/response/ListTriggersResponse.java @@ -0,0 +1,75 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package com.aliyuncs.fc.response; + +import com.aliyuncs.fc.http.HttpResponse; +import com.aliyuncs.fc.model.TriggerMetadata; + +import com.google.gson.annotations.SerializedName; +import java.util.Map; + +/** + * TODO: add javadoc + */ +public class ListTriggersResponse extends HttpResponse { + + private Map header; + + @SerializedName("triggers") + private TriggerMetadata[] triggers; + + @SerializedName("nextToken") + private String nextToken; + + public Map getHeader() { + return header; + } + + public ListTriggersResponse setHeader(Map header) { + this.header = header; + return this; + } + + public TriggerMetadata[] getTriggers() { + return triggers; + } + + public ListTriggersResponse setTriggers(TriggerMetadata[] triggers) { + this.triggers = triggers; + return this; + } + + public String getNextToken() { + return nextToken; + } + + public ListTriggersResponse setNextToken(String nextToken) { + this.nextToken = nextToken; + return this; + } + + public String getRequestId() { + return header.get("X-Fc-Request-Id"); + } + + public String getEtag() { + return header.get("Etag"); + } + +} diff --git a/src/main/java/com/aliyuncs/fc/response/UpdateFunctionResponse.java b/src/main/java/com/aliyuncs/fc/response/UpdateFunctionResponse.java new file mode 100755 index 0000000..34775c5 --- /dev/null +++ b/src/main/java/com/aliyuncs/fc/response/UpdateFunctionResponse.java @@ -0,0 +1,116 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package com.aliyuncs.fc.response; + +import com.aliyuncs.fc.model.FunctionMetadata; +import com.aliyuncs.fc.http.HttpResponse; + +import com.google.common.base.Preconditions; +import java.util.Map; + +/** + * TODO: add javadoc + */ +public class UpdateFunctionResponse extends HttpResponse { + + private Map header; + private FunctionMetadata functionMetadata; + + public Map getHeader() { + return header; + } + + public UpdateFunctionResponse setHeader(Map header) { + this.header = header; + return this; + } + + public FunctionMetadata getFunctionMetadata() { + return functionMetadata; + } + + public UpdateFunctionResponse setFunctionMetadata(FunctionMetadata functionMetadata) { + this.functionMetadata = functionMetadata; + return this; + } + + public String getFunctionName() { + Preconditions.checkArgument(functionMetadata != null); + return functionMetadata.getFunctionName(); + } + + public String getFunctionId() { + Preconditions.checkArgument(functionMetadata != null); + return functionMetadata.getFunctionId(); + } + + public String getDescription() { + Preconditions.checkArgument(functionMetadata != null); + return functionMetadata.getDescription(); + } + + public String getRuntime() { + Preconditions.checkArgument(functionMetadata != null); + return functionMetadata.getRuntime(); + } + + public String getHandler() { + Preconditions.checkArgument(functionMetadata != null); + return functionMetadata.getHandler(); + } + + public Integer getTimeout() { + Preconditions.checkArgument(functionMetadata != null); + return functionMetadata.getTimeout(); + } + + public Integer getMemorySize() { + Preconditions.checkArgument(functionMetadata != null); + return functionMetadata.getMemorySize(); + } + + public int getCodeSize() { + Preconditions.checkArgument(functionMetadata != null); + return functionMetadata.getCodeSize(); + } + + public String getCodeChecksum() { + Preconditions.checkArgument(functionMetadata != null); + return functionMetadata.getCodeChecksum(); + } + + public String getCreatedTime() { + Preconditions.checkArgument(functionMetadata != null); + return functionMetadata.getCreatedTime(); + } + + public String getLastModifiedTime() { + Preconditions.checkArgument(functionMetadata != null); + return functionMetadata.getLastModifiedTime(); + } + + public String getRequestId() { + return header.get("X-Fc-Request-Id"); + } + + public String getEtag() { + return header.get("Etag"); + } + +} diff --git a/src/main/java/com/aliyuncs/fc/response/UpdateServiceResponse.java b/src/main/java/com/aliyuncs/fc/response/UpdateServiceResponse.java new file mode 100755 index 0000000..882aeea --- /dev/null +++ b/src/main/java/com/aliyuncs/fc/response/UpdateServiceResponse.java @@ -0,0 +1,93 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package com.aliyuncs.fc.response; + +import com.aliyuncs.fc.model.LogConfig; +import com.aliyuncs.fc.model.ServiceMetadata; +import com.aliyuncs.fc.http.HttpResponse; + +import com.google.common.base.Preconditions; +import java.util.Map; + +/** + * TODO: add javadoc + */ +public class UpdateServiceResponse extends HttpResponse { + + private Map header; + private ServiceMetadata serviceMetadata; + + public Map getHeader() { + return header; + } + + public UpdateServiceResponse setHeader(Map header) { + this.header = header; + return this; + } + + public String getServiceName() { + Preconditions.checkArgument(serviceMetadata != null); + return serviceMetadata.getServiceName(); + } + + public String getDescription() { + Preconditions.checkArgument(serviceMetadata != null); + return serviceMetadata.getDescription(); + } + + public String getRole() { + Preconditions.checkArgument(serviceMetadata != null); + return serviceMetadata.getRole(); + } + + public LogConfig getLogConfig() { + Preconditions.checkArgument(serviceMetadata != null); + return serviceMetadata.getLogConfig(); + } + + public String getServiceId() { + Preconditions.checkArgument(serviceMetadata != null); + return serviceMetadata.getServiceId(); + } + + public String getCreatedTime() { + Preconditions.checkArgument(serviceMetadata != null); + return serviceMetadata.getCreatedTime(); + } + + public String getLastModifiedTime() { + Preconditions.checkArgument(serviceMetadata != null); + return serviceMetadata.getLastModifiedTime(); + } + + public UpdateServiceResponse setServiceMetadata(ServiceMetadata serviceMetadata) { + this.serviceMetadata = serviceMetadata; + return this; + } + + public String getRequestId() { + return header.get("X-Fc-Request-Id"); + } + + public String getEtag() { + return header.get("Etag"); + } + +} diff --git a/src/main/java/com/aliyuncs/fc/response/UpdateTriggerResponse.java b/src/main/java/com/aliyuncs/fc/response/UpdateTriggerResponse.java new file mode 100755 index 0000000..6b9c364 --- /dev/null +++ b/src/main/java/com/aliyuncs/fc/response/UpdateTriggerResponse.java @@ -0,0 +1,92 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package com.aliyuncs.fc.response; + +import com.aliyuncs.fc.http.HttpResponse; +import com.aliyuncs.fc.model.TriggerMetadata; + +import com.google.common.base.Preconditions; +import java.util.Map; + +/** + * TODO: add javadoc + */ +public class UpdateTriggerResponse extends HttpResponse { + + private Map header; + private TriggerMetadata triggerMetadata; + + public Map getHeader() { + return header; + } + + public UpdateTriggerResponse setHeader(Map header) { + this.header = header; + return this; + } + + public UpdateTriggerResponse setTriggerMetadata(TriggerMetadata triggerMetadata) { + this.triggerMetadata = triggerMetadata; + return this; + } + + public String getTriggerName() { + Preconditions.checkArgument(triggerMetadata != null); + return triggerMetadata.getTriggerName(); + } + + public String getSourceArn() { + Preconditions.checkArgument(triggerMetadata != null); + return triggerMetadata.getSourceArn(); + } + + public String getTriggerType() { + Preconditions.checkArgument(triggerMetadata != null); + return triggerMetadata.getTriggerType(); + } + + public String getInvocationRole() { + Preconditions.checkArgument(triggerMetadata != null); + return triggerMetadata.getInvocationRole(); + } + + public String getCreatedTime() { + Preconditions.checkArgument(triggerMetadata != null); + return triggerMetadata.getCreatedTime(); + } + + public String getLastModifiedTime() { + Preconditions.checkArgument(triggerMetadata != null); + return triggerMetadata.getLastModifiedTime(); + } + + public Object getTriggerConfig() { + Preconditions.checkArgument(triggerMetadata != null); + return triggerMetadata.getTriggerConfig(); + } + + public String getRequestId() { + return header.get("X-Fc-Request-Id"); + } + + public String getEtag() { + return header.get("Etag"); + } + +} diff --git a/src/main/java/com/aliyuncs/fc/utils/Base64Helper.java b/src/main/java/com/aliyuncs/fc/utils/Base64Helper.java new file mode 100644 index 0000000..5214b56 --- /dev/null +++ b/src/main/java/com/aliyuncs/fc/utils/Base64Helper.java @@ -0,0 +1,120 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package com.aliyuncs.fc.utils; + +import java.io.UnsupportedEncodingException; + + +public class Base64Helper { + + private static final String BASE64_CODE = "ABCDEFGHIJKLMNOPQRSTUVWXYZ" + + "abcdefghijklmnopqrstuvwxyz" + "0123456789" + "+/"; + + private static final int[] BASE64_DECODE = { + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 62, -1, -1, -1, 63, + 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, -1, -1, -1, -2, -1, -1, + -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, + 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, -1, -1, -1, -1, -1, + -1, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, + 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + }; + + private static byte[] zeroPad(int length, byte[] bytes) { + byte[] padded = new byte[length]; + System.arraycopy(bytes, 0, padded, 0, bytes.length); + return padded; + } + + public synchronized static String encode(byte[] buff) { + if (null == buff) { + return null; + } + + StringBuilder strBuilder = new StringBuilder(""); + int paddingCount = (3 - (buff.length % 3)) % 3; + byte[] stringArray = zeroPad(buff.length + paddingCount, buff); + for (int i = 0; i < stringArray.length; i += 3) { + int j = ((stringArray[i] & 0xff) << 16) + + ((stringArray[i + 1] & 0xff) << 8) + + (stringArray[i + 2] & 0xff); + strBuilder.append(BASE64_CODE.charAt((j >> 18) & 0x3f)); + strBuilder.append(BASE64_CODE.charAt((j >> 12) & 0x3f)); + strBuilder.append(BASE64_CODE.charAt((j >> 6) & 0x3f)); + strBuilder.append(BASE64_CODE.charAt(j & 0x3f)); + } + int intPos = strBuilder.length(); + for (int i = paddingCount; i > 0; i--) { + strBuilder.setCharAt(intPos - i, '='); + } + + return strBuilder.toString(); + } + + public synchronized static String encode(String string, String encoding) + throws UnsupportedEncodingException { + if (null == string || null == encoding) { + return null; + } + byte[] stringArray = string.getBytes(encoding); + return encode(stringArray); + } + + public synchronized static String decode(String string, String encoding) throws + UnsupportedEncodingException { + if (null == string || null == encoding) { + return null; + } + int posIndex = 0; + int decodeLen = string.endsWith("==") ? (string.length() - 2) : + string.endsWith("=") ? (string.length() - 1) : string.length(); + byte[] buff = new byte[decodeLen * 3 / 4]; + int count4 = decodeLen - decodeLen % 4; + for (int i = 0; i < count4; i += 4) { + int c0 = BASE64_DECODE[string.charAt(i)]; + int c1 = BASE64_DECODE[string.charAt(i + 1)]; + int c2 = BASE64_DECODE[string.charAt(i + 2)]; + int c3 = BASE64_DECODE[string.charAt(i + 3)]; + buff[posIndex++] = (byte) (((c0 << 2) | (c1 >> 4)) & 0xFF); + buff[posIndex++] = (byte) ((((c1 & 0xF) << 4) | (c2 >> 2)) & 0xFF); + buff[posIndex++] = (byte) ((((c2 & 3) << 6) | c3) & 0xFF); + } + if (2 <= decodeLen % 4) { + int c0 = BASE64_DECODE[string.charAt(count4)]; + int c1 = BASE64_DECODE[string.charAt(count4 + 1)]; + buff[posIndex++] = (byte) (((c0 << 2) | (c1 >> 4)) & 0xFF); + if (3 == decodeLen % 4) { + int c2 = BASE64_DECODE[string.charAt(count4 + 2)]; + buff[posIndex++] = (byte) ((((c1 & 0xF) << 4) | (c2 >> 2)) & 0xFF); + } + } + return new String(buff, encoding); + } + + +} diff --git a/src/main/java/com/aliyuncs/fc/utils/ParameterHelper.java b/src/main/java/com/aliyuncs/fc/utils/ParameterHelper.java new file mode 100644 index 0000000..02b1da0 --- /dev/null +++ b/src/main/java/com/aliyuncs/fc/utils/ParameterHelper.java @@ -0,0 +1,110 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package com.aliyuncs.fc.utils; + +import com.google.gson.Gson; + +import java.security.MessageDigest; +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.util.Date; +import java.util.Locale; +import java.util.SimpleTimeZone; +import java.util.UUID; + +public class ParameterHelper { + + private final static String TIME_ZONE = "GMT"; + private final static String FORMAT_ISO8601 = "yyyy-MM-dd'T'HH:mm:ss'Z'"; + private final static String FORMAT_RFC2616 = "EEE, dd MMM yyyy HH:mm:ss zzz"; + + public ParameterHelper() { + } + + public static String getUniqueNonce() { + UUID uuid = UUID.randomUUID(); + return uuid.toString(); + } + + public static String getISO8601Time(Date date) { + Date nowDate = date; + if (null == date) { + nowDate = new Date(); + } + SimpleDateFormat df = new SimpleDateFormat(FORMAT_ISO8601); + df.setTimeZone(new SimpleTimeZone(0, TIME_ZONE)); + + return df.format(nowDate); + } + + public static String getRFC2616Date(Date date) { + Date nowDate = date; + if (null == date) { + nowDate = new Date(); + } + SimpleDateFormat df = new SimpleDateFormat(FORMAT_RFC2616, Locale.ENGLISH); + df.setTimeZone(new SimpleTimeZone(0, TIME_ZONE)); + return df.format(nowDate); + } + + public static Date parse(String strDate) throws ParseException { + if (null == strDate || "".equals(strDate)) { + return null; + } + try { + return parseISO8601(strDate); + } catch (ParseException exp) { + return parseRFC2616(strDate); + } + } + + public static Date parseISO8601(String strDate) throws ParseException { + if (null == strDate || "".equals(strDate)) { + return null; + } + SimpleDateFormat df = new SimpleDateFormat(FORMAT_ISO8601); + df.setTimeZone(new SimpleTimeZone(0, TIME_ZONE)); + return df.parse(strDate); + } + + public static Date parseRFC2616(String strDate) throws ParseException { + if (null == strDate || "".equals(strDate) || strDate.length() != FORMAT_RFC2616.length()) { + return null; + } + SimpleDateFormat df = new SimpleDateFormat(FORMAT_RFC2616, Locale.ENGLISH); + df.setTimeZone(new SimpleTimeZone(0, TIME_ZONE)); + return df.parse(strDate); + } + + public static String md5Sum(byte[] buff) { + try { + MessageDigest md = MessageDigest.getInstance("MD5"); + byte[] messageDigest = md.digest(buff); + return Base64Helper.encode(messageDigest); + } catch (Exception e) { + } + return null; + } + + public static String ObjectToJson(Object o) { + Gson gson = new Gson(); + String jsonStr = gson.toJson(o); + return jsonStr; + } +} \ No newline at end of file diff --git a/src/main/java/com/aliyuncs/fc/utils/XmlUtils.java b/src/main/java/com/aliyuncs/fc/utils/XmlUtils.java new file mode 100644 index 0000000..2522358 --- /dev/null +++ b/src/main/java/com/aliyuncs/fc/utils/XmlUtils.java @@ -0,0 +1,161 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package com.aliyuncs.fc.utils; + +import java.io.Closeable; +import java.io.IOException; +import java.io.InputStream; +import java.io.StringReader; +import java.util.ArrayList; +import java.util.List; + +import javax.xml.XMLConstants; +import javax.xml.parsers.DocumentBuilder; +import javax.xml.parsers.DocumentBuilderFactory; +import javax.xml.parsers.ParserConfigurationException; +import javax.xml.transform.Source; +import javax.xml.transform.dom.DOMSource; +import javax.xml.transform.stream.StreamSource; +import javax.xml.validation.Schema; +import javax.xml.validation.SchemaFactory; +import javax.xml.validation.Validator; + +import org.w3c.dom.Document; +import org.w3c.dom.Element; +import org.w3c.dom.Node; +import org.w3c.dom.NodeList; +import org.xml.sax.InputSource; +import org.xml.sax.SAXException; + +public final class XmlUtils { + + public static Document getDocument(String payload) + throws ParserConfigurationException, SAXException, IOException { + if (payload == null || payload.length() < 1) { + return null; + } + + StringReader sr = new StringReader(payload); + InputSource source = new InputSource(sr); + + return getDocument(source, null); + } + + public static Document getDocument(InputSource xml, InputStream xsd) + throws ParserConfigurationException, SAXException, IOException { + Document doc = null; + + try { + DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); + if (xsd != null) { + dbf.setNamespaceAware(true); + } + + DocumentBuilder builder = dbf.newDocumentBuilder(); + doc = builder.parse(xml); + + if (xsd != null) { + validateXml(doc, xsd); + } + } finally { + closeStream(xml.getByteStream()); + } + + return doc; + } + + public static Element getRootElementFromString(String payload) + throws ParserConfigurationException, SAXException, IOException { + + return getDocument(payload).getDocumentElement(); + } + + + public static List getChildElements(Element parent, String tagName) { + if (null == parent) { + return null; + } + NodeList nodes = parent.getElementsByTagName(tagName); + List elements = new ArrayList(); + + for (int i = 0; i < nodes.getLength(); i++) { + Node node = nodes.item(i); + if (node.getParentNode() == parent) { + elements.add((Element) node); + } + } + + return elements; + } + + + public static List getChildElements(Element parent) { + if (null == parent) { + return null; + } + + NodeList nodes = parent.getChildNodes(); + List elements = new ArrayList(); + + for (int i = 0; i < nodes.getLength(); i++) { + Node node = nodes.item(i); + if (node.getNodeType() == Node.ELEMENT_NODE) { + elements.add((Element) node); + } + } + + return elements; + } + + public static void validateXml(InputStream xml, InputStream xsd) + throws SAXException, IOException, ParserConfigurationException { + try { + DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); + dbf.setNamespaceAware(true); + Document doc = dbf.newDocumentBuilder().parse(xml); + validateXml(doc, xsd); + } finally { + closeStream(xml); + closeStream(xsd); + } + } + + public static void validateXml(Node root, InputStream xsd) + throws SAXException, IOException { + try { + Source source = new StreamSource(xsd); + Schema schema = SchemaFactory.newInstance( + XMLConstants.W3C_XML_SCHEMA_NS_URI).newSchema(source); + + Validator validator = schema.newValidator(); + validator.validate(new DOMSource(root)); + } finally { + closeStream(xsd); + } + } + + private static void closeStream(Closeable stream) { + if (stream != null) { + try { + stream.close(); + } catch (IOException e) { + } + } + } +} \ No newline at end of file diff --git a/src/main/java/com/aliyuncs/fc/utils/ZipUtils.java b/src/main/java/com/aliyuncs/fc/utils/ZipUtils.java new file mode 100644 index 0000000..2abfd93 --- /dev/null +++ b/src/main/java/com/aliyuncs/fc/utils/ZipUtils.java @@ -0,0 +1,59 @@ +package com.aliyuncs.fc.utils; + +import com.google.common.base.Preconditions; +import com.google.common.base.Strings; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; +import java.util.zip.ZipEntry; +import java.util.zip.ZipOutputStream; + +/** + * U + */ +public class ZipUtils { + + public static void zipDir(File dir, String zipName) throws IOException { + Preconditions.checkArgument(dir != null, "dir cannot be null"); + Preconditions.checkArgument(dir.isDirectory(), "dir must be a directory"); + Preconditions.checkArgument(!Strings.isNullOrEmpty(zipName), "zipName cannot be blank"); + List fileNames = new ArrayList(); + getFileNames(dir, fileNames); + // zip files one by one + // create ZipOutputStream to write to the zip file + FileOutputStream fos = new FileOutputStream(zipName); + ZipOutputStream zos = new ZipOutputStream(fos); + for (String filePath : fileNames) { + // for ZipEntry we need to keep only relative file path, so we used substring on absolute path + ZipEntry ze = new ZipEntry( + filePath.substring(dir.getAbsolutePath().length() + 1, filePath.length())); + zos.putNextEntry(ze); + // read the file and write to ZipOutputStream + FileInputStream fis = new FileInputStream(filePath); + byte[] buffer = new byte[1024]; + int len; + while ((len = fis.read(buffer)) > 0) { + zos.write(buffer, 0, len); + } + zos.closeEntry(); + fis.close(); + } + zos.close(); + fos.close(); + } + + private static void getFileNames(File dir, List fileNames) throws IOException { + File[] files = dir.listFiles(); + + for (File file : files) { + if (file.isFile()) { + fileNames.add(file.getAbsolutePath()); + } else { + getFileNames(file, fileNames); + } + } + } +} diff --git a/src/test/java/com/aliyuncs/fc/FunctionComputeClientTest.java b/src/test/java/com/aliyuncs/fc/FunctionComputeClientTest.java new file mode 100644 index 0000000..39c9053 --- /dev/null +++ b/src/test/java/com/aliyuncs/fc/FunctionComputeClientTest.java @@ -0,0 +1,949 @@ +package com.aliyuncs.fc; + +import static junit.framework.TestCase.assertEquals; +import static junit.framework.TestCase.assertFalse; +import static junit.framework.TestCase.assertNull; +import static junit.framework.TestCase.fail; +import static org.junit.Assert.assertNotEquals; +import static org.junit.Assert.assertTrue; + +import com.aliyuncs.fc.client.FunctionComputeClient; +import com.aliyuncs.fc.exceptions.ClientException; +import com.aliyuncs.fc.exceptions.ErrorCodes; +import com.aliyuncs.fc.model.Code; +import com.aliyuncs.fc.model.FunctionMetadata; +import com.aliyuncs.fc.model.OSSTriggerConfig; +import com.aliyuncs.fc.model.TriggerMetadata; +import com.aliyuncs.fc.request.CreateFunctionRequest; +import com.aliyuncs.fc.request.CreateServiceRequest; +import com.aliyuncs.fc.request.CreateTriggerRequest; +import com.aliyuncs.fc.request.DeleteFunctionRequest; +import com.aliyuncs.fc.request.DeleteServiceRequest; +import com.aliyuncs.fc.request.DeleteTriggerRequest; +import com.aliyuncs.fc.request.GetFunctionRequest; +import com.aliyuncs.fc.request.GetServiceRequest; +import com.aliyuncs.fc.request.GetTriggerRequest; +import com.aliyuncs.fc.request.InvokeFunctionRequest; +import com.aliyuncs.fc.request.ListFunctionsRequest; +import com.aliyuncs.fc.request.ListServicesRequest; +import com.aliyuncs.fc.request.ListTriggersRequest; +import com.aliyuncs.fc.request.UpdateFunctionRequest; +import com.aliyuncs.fc.request.UpdateServiceRequest; +import com.aliyuncs.fc.request.UpdateTriggerRequest; +import com.aliyuncs.fc.response.CreateFunctionResponse; +import com.aliyuncs.fc.response.CreateServiceResponse; +import com.aliyuncs.fc.response.CreateTriggerResponse; +import com.aliyuncs.fc.response.DeleteFunctionResponse; +import com.aliyuncs.fc.response.DeleteServiceResponse; +import com.aliyuncs.fc.response.DeleteTriggerResponse; +import com.aliyuncs.fc.response.GetFunctionResponse; +import com.aliyuncs.fc.response.GetServiceResponse; +import com.aliyuncs.fc.response.GetTriggerResponse; +import com.aliyuncs.fc.response.InvokeFunctionResponse; +import com.aliyuncs.fc.response.ListFunctionsResponse; +import com.aliyuncs.fc.response.ListServicesResponse; +import com.aliyuncs.fc.response.ListTriggersResponse; +import com.aliyuncs.fc.response.UpdateServiceResponse; +import com.aliyuncs.fc.response.UpdateTriggerResponse; +import com.aliyuncs.fc.utils.ZipUtils; +import com.google.common.base.Strings; +import com.google.gson.Gson; +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; +import java.io.PrintWriter; +import java.security.NoSuchAlgorithmException; +import java.text.DateFormat; +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.util.Arrays; +import java.util.Date; +import java.util.UUID; +import org.json.JSONException; +import org.junit.Before; +import org.junit.Test; + +/** + * Validation for FunctionComputeClient, tests including + * create/list/get/update service/function/trigger + */ +public class FunctionComputeClientTest { + + private static final DateFormat DATE_FORMAT = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss"); + private static final String VALIDATE_MSG = "cannot be blank"; + private static final String REGION = System.getenv("REGION"); + private static final String ROLE = System.getenv("ROLE"); + private static final String ACCESS_KEY = System.getenv("ACCESS_KEY"); + private static final String SECRET_KEY = System.getenv("SECRET_KEY"); + private static final String ACCOUNT_ID = System.getenv("ACCOUNT_ID"); + private static final String CODE_BUCKET = System.getenv("CODE_BUCKET"); + private static final String CODE_OBJECT = System.getenv("CODE_OBJECT"); + private static final String INVOCATION_ROLE = System.getenv("INVOCATION_ROLE"); + private static final String OSS_SOURCE_ARN = + String.format("acs:oss:%s:%s:%s", REGION, ACCOUNT_ID, CODE_BUCKET); + private static final String SERVICE_NAME = "testServiceJavaSDK"; + private static final String SERVICE_DESC_OLD = "service desc"; + private static final String SERVICE_DESC_NEW = "service desc updated"; + private static final String FUNCTION_NAME = "testFunction"; + private static final String FUNCTION_DESC_OLD = "function desc"; + private static final String FUNCTION_DESC_NEW = "function desc updated"; + private static final String TRIGGER_NAME = "testTrigger"; + private static final String TRIGGER_TYPE_OSS = "oss"; + + private FunctionComputeClient client; + + @Before + public void setup() { + // Create or clean up everything under the test service + client = new FunctionComputeClient(REGION, ACCOUNT_ID, ACCESS_KEY, SECRET_KEY); + GetServiceRequest getSReq = new GetServiceRequest(SERVICE_NAME); + try { + client.getService(getSReq); + ListFunctionsRequest listFReq = new ListFunctionsRequest(SERVICE_NAME); + ListFunctionsResponse listFResp = client.listFunctions(listFReq); + cleanUpFunctions(SERVICE_NAME, listFResp.getFunctions()); + cleanupService(SERVICE_NAME); + } catch (ClientException e) { + if (!ErrorCodes.SERVICE_NOT_FOUND.equals(e.getErrorCode())) { + throw new RuntimeException("Service setup failed", e); + } + } + } + + private void cleanupService(String serviceName) { + DeleteServiceRequest request = new DeleteServiceRequest(serviceName); + client.deleteService(request); + System.out.println("Service " + serviceName + " is deleted"); + } + + private void cleanUpFunctions(String serviceName, FunctionMetadata[] functions) { + for (FunctionMetadata function : functions) { + ListTriggersRequest listReq = new ListTriggersRequest(serviceName, + function.getFunctionName()); + ListTriggersResponse listTResp = client.listTriggers(listReq); + cleanUpTriggers(serviceName, function.getFunctionName(), listTResp.getTriggers()); + System.out.println( + "All triggers for Function " + function.getFunctionName() + " are deleted"); + DeleteFunctionRequest deleteFReq = new DeleteFunctionRequest(serviceName, + function.getFunctionName()); + client.deleteFunction(deleteFReq); + } + } + + private void cleanUpTriggers(String serviceName, String functionName, + TriggerMetadata[] triggers) { + for (TriggerMetadata trigger : triggers) { + DeleteTriggerRequest request = new DeleteTriggerRequest(serviceName, functionName, + trigger.getTriggerName()); + DeleteTriggerResponse response = client.deleteTrigger(request); + assertTrue(response.isSuccess()); + System.out.println("Trigger " + trigger.getTriggerName() + " is deleted"); + } + } + + private CreateFunctionResponse createFunction(String functionName) { + CreateFunctionRequest createFuncReq = new CreateFunctionRequest(SERVICE_NAME); + createFuncReq.setFunctionName(functionName); + createFuncReq.setDescription(FUNCTION_DESC_OLD); + createFuncReq.setMemorySize(128); + createFuncReq.setHandler("hello_world.handler"); + createFuncReq.setRuntime("nodejs4.4"); + createFuncReq.setCode(new Code().setOssBucketName(CODE_BUCKET).setOssObjectName(CODE_OBJECT)); + createFuncReq.setTimeout(10); + + return client.createFunction(createFuncReq); + } + + private CreateServiceResponse createService(String serviceName) { + CreateServiceRequest createSReq = new CreateServiceRequest(); + createSReq.setServiceName(serviceName); + createSReq.setDescription(SERVICE_DESC_OLD); + createSReq.setRole(ROLE); + return client.createService(createSReq); + } + + private CreateTriggerResponse createTrigger(String triggerName, String prefix, String suffix) { + CreateTriggerRequest createTReq = new CreateTriggerRequest(SERVICE_NAME, FUNCTION_NAME); + createTReq.setTriggerName(triggerName); + createTReq.setTriggerType(TRIGGER_TYPE_OSS); + createTReq.setInvocationRole(INVOCATION_ROLE); + createTReq.setSourceArn(OSS_SOURCE_ARN); + createTReq.setTriggerConfig( + new OSSTriggerConfig(new String[]{"oss:ObjectCreated:*"}, prefix, suffix)); + return client.createTrigger(createTReq); + } + + @Test + public void testCRUD() + throws ClientException, JSONException, NoSuchAlgorithmException, InterruptedException, ParseException { + + // Create Service + CreateServiceResponse createSResp = createService(SERVICE_NAME); + assertFalse(Strings.isNullOrEmpty(createSResp.getRequestId())); + assertFalse(Strings.isNullOrEmpty(createSResp.getServiceId())); + assertEquals(SERVICE_NAME, createSResp.getServiceName()); + assertEquals(SERVICE_DESC_OLD, createSResp.getDescription()); + assertEquals(ROLE, createSResp.getRole()); + GetServiceResponse svcOldResp = client.getService(new GetServiceRequest(SERVICE_NAME)); + + // Update Service + UpdateServiceRequest updateSReq = new UpdateServiceRequest(SERVICE_NAME); + updateSReq.setDescription(SERVICE_DESC_NEW); + Thread.sleep(1000L); + UpdateServiceResponse updateSResp = client.updateService(updateSReq); + verifyUpdate(svcOldResp.getServiceName(), updateSResp.getServiceName(), + svcOldResp.getServiceId(), updateSResp.getServiceId(), + svcOldResp.getLastModifiedTime(), updateSResp.getLastModifiedTime(), + svcOldResp.getCreatedTime(), updateSResp.getCreatedTime(), + svcOldResp.getDescription(), updateSResp.getDescription()); + + // Get Service + GetServiceRequest getSReq = new GetServiceRequest(SERVICE_NAME); + GetServiceResponse getSResp = client.getService(getSReq); + assertEquals(SERVICE_NAME, getSResp.getServiceName()); + assertEquals(svcOldResp.getServiceId(), getSResp.getServiceId()); + assertEquals(ROLE, getSResp.getRole()); + + // Create Function + CreateFunctionResponse createFResp = createFunction(FUNCTION_NAME); + assertFalse(Strings.isNullOrEmpty(createFResp.getRequestId())); + assertFalse(Strings.isNullOrEmpty(createFResp.getFunctionId())); + assertEquals(FUNCTION_NAME, createFResp.getFunctionName()); + assertEquals(FUNCTION_DESC_OLD, createFResp.getDescription()); + + // List Functions + ListFunctionsRequest listFReq = new ListFunctionsRequest(SERVICE_NAME); + ListFunctionsResponse listFResp = client.listFunctions(listFReq); + assertFalse(Strings.isNullOrEmpty(listFResp.getRequestId())); + assertEquals(1, listFResp.getFunctions().length); + FunctionMetadata funcOld = listFResp.getFunctions()[0]; + assertEquals(FUNCTION_NAME, funcOld.getFunctionName()); + + // Update Function + UpdateFunctionRequest updateFReq = new UpdateFunctionRequest(SERVICE_NAME, FUNCTION_NAME); + updateFReq.setDescription(FUNCTION_DESC_NEW); + Thread.sleep(1000L); + client.updateFunction(updateFReq); + listFResp = client.listFunctions(listFReq); + assertFalse(Strings.isNullOrEmpty(listFResp.getRequestId())); + assertEquals(1, listFResp.getFunctions().length); + FunctionMetadata funcNew = listFResp.getFunctions()[0]; + verifyUpdate(funcOld.getFunctionName(), funcNew.getFunctionName(), + funcOld.getFunctionId(), funcNew.getFunctionId(), + funcOld.getLastModifiedTime(), funcNew.getLastModifiedTime(), + funcOld.getCreatedTime(), funcNew.getCreatedTime(), + funcOld.getDescription(), funcNew.getDescription()); + + // Get Function + GetFunctionRequest getFReq = new GetFunctionRequest(SERVICE_NAME, FUNCTION_NAME); + GetFunctionResponse getFResp = client.getFunction(getFReq); + assertFalse(Strings.isNullOrEmpty(getFResp.getRequestId())); + assertEquals(FUNCTION_NAME, getFResp.getFunctionName()); + + // Invoke Function + InvokeFunctionRequest request = new InvokeFunctionRequest(SERVICE_NAME, FUNCTION_NAME); + InvokeFunctionResponse response = client.invokeFunction(request); + assertTrue(!Strings.isNullOrEmpty(response.getRequestId())); + assertEquals("hello world", new String(response.getContent())); + + // Create Trigger + String tfPrefix = "prefix"; + String tfSuffix = "suffix"; + + createTrigger(TRIGGER_NAME, tfPrefix, tfSuffix); + + // List Triggers + ListTriggersRequest listTReq = new ListTriggersRequest(SERVICE_NAME, FUNCTION_NAME); + ListTriggersResponse listTResp = client.listTriggers(listTReq); + assertFalse(Strings.isNullOrEmpty(listTResp.getRequestId())); + assertEquals(1, listTResp.getTriggers().length); + TriggerMetadata triggerOld = listTResp.getTriggers()[0]; + assertEquals(TRIGGER_NAME, triggerOld.getTriggerName()); + + // Update Trigger + String newInvocationRole = INVOCATION_ROLE + "_new"; + String tfPrefixNew = "prefix_new"; + String tfSuffixNew = "suffix_new"; + String[] eventsNew = new String[]{"oss:ObjectCreated:PutObject"}; + OSSTriggerConfig updateTriggerConfig = new OSSTriggerConfig( + new String[]{"oss:ObjectCreated:PutObject"}, tfPrefixNew, tfSuffixNew); + + UpdateTriggerRequest updateTReq = new UpdateTriggerRequest(SERVICE_NAME, FUNCTION_NAME, + TRIGGER_NAME); + updateTReq.setInvocationRole(newInvocationRole); + updateTReq.setTriggerConfig(updateTriggerConfig); + Thread.sleep(1000L); + UpdateTriggerResponse updateTResp = client.updateTrigger(updateTReq); + assertEquals(triggerOld.getTriggerName(), updateTResp.getTriggerName()); + assertNotEquals(triggerOld.getInvocationRole(), updateTResp.getInvocationRole()); + assertEquals(triggerOld.getSourceArn(), updateTResp.getSourceArn()); + Gson gson = new Gson(); + OSSTriggerConfig tcOld = gson + .fromJson(gson.toJson(triggerOld.getTriggerConfig()), OSSTriggerConfig.class); + OSSTriggerConfig tcNew = gson + .fromJson(gson.toJson(updateTResp.getTriggerConfig()), OSSTriggerConfig.class); + assertFalse(Arrays.deepEquals(tcOld.getEvents(), tcNew.getEvents())); + assertNotEquals(tcOld.getFilter().getKey().getPrefix(), + tcNew.getFilter().getKey().getPrefix()); + assertNotEquals(tcOld.getFilter().getKey().getSuffix(), + tcNew.getFilter().getKey().getSuffix()); + assertEquals(triggerOld.getCreatedTime(), updateTResp.getCreatedTime()); + assertEquals(triggerOld.getTriggerType(), updateTResp.getTriggerType()); + assertNotEquals(triggerOld.getInvocationRole(), updateTResp.getInvocationRole()); + + Date dateOld = DATE_FORMAT.parse(triggerOld.getLastModifiedTime()); + Date dateNew = DATE_FORMAT.parse(updateTResp.getLastModifiedTime()); + assertTrue(dateOld.before(dateNew)); + + // Get Trigger + GetTriggerRequest getTReq = new GetTriggerRequest(SERVICE_NAME, FUNCTION_NAME, + TRIGGER_NAME); + GetTriggerResponse getTResp = client.getTrigger(getTReq); + OSSTriggerConfig getTConfig = gson + .fromJson(gson.toJson(getTResp.getTriggerConfig()), OSSTriggerConfig.class); + assertFalse(Strings.isNullOrEmpty(getTResp.getRequestId())); + assertEquals(TRIGGER_NAME, getTResp.getTriggerName()); + assertEquals(OSS_SOURCE_ARN, getTResp.getSourceARN()); + assertEquals(TRIGGER_TYPE_OSS, getTResp.getTriggerType()); + assertEquals(newInvocationRole, getTResp.getInvocationRole()); + assertEquals(tfPrefixNew, getTConfig.getFilter().getKey().getPrefix()); + assertEquals(tfSuffixNew, getTConfig.getFilter().getKey().getSuffix()); + assertTrue(Arrays.deepEquals(eventsNew, getTConfig.getEvents())); + + // Delete Trigger + client.deleteTrigger(new DeleteTriggerRequest(SERVICE_NAME, FUNCTION_NAME, TRIGGER_NAME)); + + // Delete Function + DeleteFunctionRequest deleteFReq = new DeleteFunctionRequest(SERVICE_NAME, FUNCTION_NAME); + int numFunctionsOld = listFResp.getFunctions().length; + DeleteFunctionResponse deleteFResp = client.deleteFunction(deleteFReq); + assertFalse(Strings.isNullOrEmpty(deleteFResp.getRequestId())); + listFResp = client.listFunctions(listFReq); + + try { + getFunction(FUNCTION_NAME, listFResp.getFunctions()); + fail("Function " + FUNCTION_NAME + " failed to be deleted"); + } catch (RuntimeException e) { + int numFunctionsNew = (listFResp.getFunctions() == null) ? 0 : + listFResp.getFunctions().length; + assertEquals(numFunctionsOld, numFunctionsNew + 1); + } + GetFunctionResponse getFResp2 = null; + try { + getFResp2 = client.getFunction(getFReq); + fail( + "Get Function " + FUNCTION_NAME + " should have no function returned after delete"); + } catch (ClientException e) { + assertNull(getFResp2); + } + + // Delete Service + DeleteServiceRequest deleteSReq = new DeleteServiceRequest(SERVICE_NAME); + DeleteServiceResponse deleteSResp = client.deleteService(deleteSReq); + assertFalse(Strings.isNullOrEmpty(deleteSResp.getRequestId())); + + GetServiceResponse getSResp2 = null; + try { + getSResp2 = client.getService(getSReq); + fail("Get service " + FUNCTION_NAME + " should have no service returned after delete"); + } catch (ClientException e) { + assertNull(getSResp2); + } + } + + @Test + public void testListServices() { + final int numServices = 10; + final int limit = 3; + + // Create multiple services + for (int i = 0; i < numServices; i++) { + try { + client.getService(new GetServiceRequest(SERVICE_NAME + i)); + cleanupService(SERVICE_NAME + i); + } catch (ClientException e) { + if (!ErrorCodes.SERVICE_NOT_FOUND.equals(e.getErrorCode())) { + throw new RuntimeException("Cleanup failed"); + } + } + CreateServiceRequest request = new CreateServiceRequest(); + request.setServiceName(SERVICE_NAME + i); + request.setDescription(SERVICE_DESC_OLD); + request.setRole(ROLE); + CreateServiceResponse response = client.createService(request); + assertFalse(Strings.isNullOrEmpty(response.getRequestId())); + } + ListServicesRequest listRequest = new ListServicesRequest(); + listRequest.setLimit(limit); + listRequest.setPrefix(SERVICE_NAME); + ListServicesResponse listResponse = client.listServices(listRequest); + int numCalled = 1; + String nextToken = listResponse.getNextToken(); + while (nextToken != null) { + listRequest.setNextToken(nextToken); + listResponse = client.listServices(listRequest); + nextToken = listResponse.getNextToken(); + numCalled++; + } + assertEquals(numServices / limit + 1, numCalled); + + // Delete services + for (int i = 0; i < numServices; i++) { + cleanupService(SERVICE_NAME + i); + } + } + + @Test + public void testListFunctions() { + final int numServices = 10; + final int limit = 3; + + // Create service + createService(SERVICE_NAME); + + // Create multiple functions under the test service + for (int i = 0; i < numServices; i++) { + CreateFunctionResponse createFResp = createFunction(FUNCTION_NAME + i); + assertFalse(Strings.isNullOrEmpty(createFResp.getRequestId())); + } + ListFunctionsRequest listRequest = new ListFunctionsRequest(SERVICE_NAME); + listRequest.setLimit(limit); + listRequest.setPrefix(FUNCTION_NAME); + ListFunctionsResponse listResponse = client.listFunctions(listRequest); + int numCalled = 1; + String nextToken = listResponse.getNextToken(); + while (nextToken != null) { + listRequest.setNextToken(nextToken); + listResponse = client.listFunctions(listRequest); + nextToken = listResponse.getNextToken(); + numCalled++; + } + assertEquals(numServices / limit + 1, numCalled); + } + + @Test + public void testListTriggers() { + final int numTriggers = 5; + final int limit = 2; + + // Create service + createService(SERVICE_NAME); + createFunction(FUNCTION_NAME); + + // Create multiple trigger under the test function + for (int i = 0; i < numTriggers; i++) { + CreateTriggerResponse createTResp = createTrigger(TRIGGER_NAME + i, + "prefix" + i, "suffix" + i); + assertFalse(Strings.isNullOrEmpty(createTResp.getRequestId())); + } + + ListTriggersRequest listTReq = new ListTriggersRequest(SERVICE_NAME, FUNCTION_NAME); + listTReq.setLimit(limit); + ListTriggersResponse listTResp = client.listTriggers(listTReq); + int numCalled = 1; + String nextToken = listTResp.getNextToken(); + while (nextToken != null) { + listTReq.setNextToken(nextToken); + listTResp = client.listTriggers(listTReq); + nextToken = listTResp.getNextToken(); + numCalled++; + } + + assertEquals(numTriggers / limit + 1, numCalled); + + for (int i = 0; i < numTriggers; i++) { + DeleteTriggerResponse deleteTResp = client.deleteTrigger( + new DeleteTriggerRequest(SERVICE_NAME, FUNCTION_NAME, TRIGGER_NAME + i)); + assertFalse(Strings.isNullOrEmpty(deleteTResp.getRequestId())); + } + } + + @Test + public void testCreateServiceValidate() { + try { + CreateServiceRequest request = new CreateServiceRequest(); + client.createService(request); + fail("ClientException is expected"); + } catch (ClientException e) { + assertEquals(ErrorCodes.INVALID_ARGUMENT, e.getErrorCode()); + } + + try { + CreateServiceRequest request = new CreateServiceRequest(); + client.createService(request); + fail("ClientException is expected"); + } catch (ClientException e) { + assertEquals(ErrorCodes.INVALID_ARGUMENT, e.getErrorCode()); + } + } + + @Test + public void testCreateFunctionValidate() { + try { + CreateFunctionRequest request = new CreateFunctionRequest(null); + client.createFunction(request); + fail("ClientException is expected"); + } catch (ClientException e) { + assertTrue(e.getMessage().contains(VALIDATE_MSG)); + } + + try { + CreateFunctionRequest request = new CreateFunctionRequest(""); + client.createFunction(request); + fail("ClientException is expected"); + } catch (ClientException e) { + assertTrue(e.getMessage().contains(VALIDATE_MSG)); + } + } + + @Test + public void testCreateTriggerValidate() { + try { + CreateTriggerRequest request = new CreateTriggerRequest(SERVICE_NAME, null); + client.createTrigger(request); + fail("ClientException is expected"); + } catch (ClientException e) { + assertTrue(e.getMessage().contains(VALIDATE_MSG)); + } + + try { + CreateTriggerRequest request = new CreateTriggerRequest(SERVICE_NAME, ""); + client.createTrigger(request); + fail("ClientException is expected"); + } catch (ClientException e) { + assertTrue(e.getMessage().contains(VALIDATE_MSG)); + } + + try { + CreateTriggerRequest request = new CreateTriggerRequest(null, FUNCTION_NAME); + client.createTrigger(request); + fail("ClientException is expected"); + } catch (ClientException e) { + assertTrue(e.getMessage().contains(VALIDATE_MSG)); + } + + try { + CreateTriggerRequest request = new CreateTriggerRequest("", FUNCTION_NAME); + client.createTrigger(request); + fail("ClientException is expected"); + } catch (ClientException e) { + assertTrue(e.getMessage().contains(VALIDATE_MSG)); + } + } + + @Test + public void testGetServiceValidate() { + try { + GetServiceRequest request = new GetServiceRequest(null); + client.getService(request); + fail("ClientException is expected"); + } catch (ClientException e) { + assertTrue(e.getMessage().contains(VALIDATE_MSG)); + } + + try { + GetServiceRequest request = new GetServiceRequest(""); + client.getService(request); + fail("ClientException is expected"); + } catch (ClientException e) { + assertTrue(e.getMessage().contains(VALIDATE_MSG)); + } + } + + @Test + public void testGetFunctionValidate() { + try { + GetFunctionRequest request = new GetFunctionRequest(SERVICE_NAME, null); + client.getFunction(request); + fail("ClientException is expected"); + } catch (ClientException e) { + assertTrue(e.getMessage().contains(VALIDATE_MSG)); + } + + try { + GetFunctionRequest request = new GetFunctionRequest(SERVICE_NAME, ""); + client.getFunction(request); + fail("ClientException is expected"); + } catch (ClientException e) { + assertTrue(e.getMessage().contains(VALIDATE_MSG)); + } + + try { + GetFunctionRequest request = new GetFunctionRequest(null, FUNCTION_NAME); + client.getFunction(request); + fail("ClientException is expected"); + } catch (ClientException e) { + assertTrue(e.getMessage().contains(VALIDATE_MSG)); + } + + try { + GetFunctionRequest request = new GetFunctionRequest("", FUNCTION_NAME); + client.getFunction(request); + fail("ClientException is expected"); + } catch (ClientException e) { + assertTrue(e.getMessage().contains(VALIDATE_MSG)); + } + } + + @Test + public void testGetTriggerValidate() { + try { + GetTriggerRequest request = new GetTriggerRequest(SERVICE_NAME, FUNCTION_NAME, null); + client.getTrigger(request); + fail("ClientException is expected"); + } catch (ClientException e) { + assertTrue(e.getMessage().contains(VALIDATE_MSG)); + } + + try { + GetTriggerRequest request = new GetTriggerRequest(SERVICE_NAME, FUNCTION_NAME, ""); + client.getTrigger(request); + fail("ClientException is expected"); + } catch (ClientException e) { + assertTrue(e.getMessage().contains(VALIDATE_MSG)); + } + + try { + GetTriggerRequest request = new GetTriggerRequest(SERVICE_NAME, null, TRIGGER_NAME); + client.getTrigger(request); + fail("ClientException is expected"); + } catch (ClientException e) { + assertTrue(e.getMessage().contains(VALIDATE_MSG)); + } + + try { + GetTriggerRequest request = new GetTriggerRequest(SERVICE_NAME, "", TRIGGER_NAME); + client.getTrigger(request); + fail("ClientException is expected"); + } catch (ClientException e) { + assertTrue(e.getMessage().contains(VALIDATE_MSG)); + } + + try { + GetTriggerRequest request = new GetTriggerRequest(null, FUNCTION_NAME, TRIGGER_NAME); + client.getTrigger(request); + fail("ClientException is expected"); + } catch (ClientException e) { + assertTrue(e.getMessage().contains(VALIDATE_MSG)); + } + + try { + GetTriggerRequest request = new GetTriggerRequest("", FUNCTION_NAME, TRIGGER_NAME); + client.getTrigger(request); + fail("ClientException is expected"); + } catch (ClientException e) { + assertTrue(e.getMessage().contains(VALIDATE_MSG)); + } + } + + @Test + public void testInvokeFunctionValidate() { + try { + InvokeFunctionRequest request = new InvokeFunctionRequest(SERVICE_NAME, null); + client.invokeFunction(request); + fail("ClientException is expected"); + } catch (ClientException e) { + assertTrue(e.getMessage().contains(VALIDATE_MSG)); + } + + try { + InvokeFunctionRequest request = new InvokeFunctionRequest(SERVICE_NAME, ""); + client.invokeFunction(request); + fail("ClientException is expected"); + } catch (ClientException e) { + assertTrue(e.getMessage().contains(VALIDATE_MSG)); + } + + try { + InvokeFunctionRequest request = new InvokeFunctionRequest("", FUNCTION_NAME); + client.invokeFunction(request); + fail("ClientException is expected"); + } catch (ClientException e) { + assertTrue(e.getMessage().contains(VALIDATE_MSG)); + } + + try { + InvokeFunctionRequest request = new InvokeFunctionRequest(null, FUNCTION_NAME); + client.invokeFunction(request); + fail("ClientException is expected"); + } catch (ClientException e) { + assertTrue(e.getMessage().contains(VALIDATE_MSG)); + } + } + + @Test + public void testListFunctionsValidate() { + try { + ListFunctionsRequest request = new ListFunctionsRequest(null); + client.listFunctions(request); + fail("ClientException is expected"); + } catch (ClientException e) { + assertTrue(e.getMessage().contains(VALIDATE_MSG)); + } + + try { + ListFunctionsRequest request = new ListFunctionsRequest(""); + client.listFunctions(request); + fail("ClientException is expected"); + } catch (ClientException e) { + assertTrue(e.getMessage().contains(VALIDATE_MSG)); + } + } + + @Test + public void testListTriggersValidate() { + try { + ListTriggersRequest request = new ListTriggersRequest(null, FUNCTION_NAME); + client.listTriggers(request); + fail("ClientException is expected"); + } catch (ClientException e) { + assertTrue(e.getMessage().contains(VALIDATE_MSG)); + } + + try { + ListTriggersRequest request = new ListTriggersRequest("", FUNCTION_NAME); + client.listTriggers(request); + fail("ClientException is expected"); + } catch (ClientException e) { + assertTrue(e.getMessage().contains(VALIDATE_MSG)); + } + + try { + ListTriggersRequest request = new ListTriggersRequest(SERVICE_NAME, null); + client.listTriggers(request); + fail("ClientException is expected"); + } catch (ClientException e) { + assertTrue(e.getMessage().contains(VALIDATE_MSG)); + } + + try { + ListTriggersRequest request = new ListTriggersRequest(SERVICE_NAME, ""); + client.listTriggers(request); + fail("ClientException is expected"); + } catch (ClientException e) { + assertTrue(e.getMessage().contains(VALIDATE_MSG)); + } + } + + @Test + public void testUpdateServiceValidate() { + try { + UpdateServiceRequest request = new UpdateServiceRequest(null); + client.updateService(request); + fail("ClientException is expected"); + } catch (ClientException e) { + assertTrue(e.getMessage().contains(VALIDATE_MSG)); + } + + try { + UpdateServiceRequest request = new UpdateServiceRequest(""); + client.updateService(request); + fail("ClientException is expected"); + } catch (ClientException e) { + assertTrue(e.getMessage().contains(VALIDATE_MSG)); + } + } + + @Test + public void testUpdateFunctionValidate() { + try { + UpdateFunctionRequest request = new UpdateFunctionRequest(SERVICE_NAME, null); + client.updateFunction(request); + fail("ClientException is expected"); + } catch (ClientException e) { + assertTrue(e.getMessage().contains(VALIDATE_MSG)); + } + + try { + UpdateFunctionRequest request = new UpdateFunctionRequest(SERVICE_NAME, ""); + client.updateFunction(request); + fail("ClientException is expected"); + } catch (ClientException e) { + assertTrue(e.getMessage().contains(VALIDATE_MSG)); + } + + try { + UpdateFunctionRequest request = new UpdateFunctionRequest(null, FUNCTION_NAME); + client.updateFunction(request); + fail("ClientException is expected"); + } catch (ClientException e) { + assertTrue(e.getMessage().contains(VALIDATE_MSG)); + } + + try { + UpdateFunctionRequest request = new UpdateFunctionRequest("", FUNCTION_NAME); + client.updateFunction(request); + fail("ClientException is expected"); + } catch (ClientException e) { + assertTrue(e.getMessage().contains(VALIDATE_MSG)); + } + } + + @Test + public void testUpdateTriggerValidate() { + try { + UpdateTriggerRequest request = new UpdateTriggerRequest(SERVICE_NAME, FUNCTION_NAME, + null); + client.updateTrigger(request); + fail("ClientException is expected"); + } catch (ClientException e) { + assertTrue(e.getMessage().contains(VALIDATE_MSG)); + } + + try { + UpdateTriggerRequest request = new UpdateTriggerRequest(SERVICE_NAME, FUNCTION_NAME, + ""); + client.updateTrigger(request); + fail("ClientException is expected"); + } catch (ClientException e) { + assertTrue(e.getMessage().contains(VALIDATE_MSG)); + } + + try { + UpdateTriggerRequest request = new UpdateTriggerRequest(SERVICE_NAME, null, + TRIGGER_NAME); + client.updateTrigger(request); + fail("ClientException is expected"); + } catch (ClientException e) { + assertTrue(e.getMessage().contains(VALIDATE_MSG)); + } + + try { + UpdateTriggerRequest request = new UpdateTriggerRequest(SERVICE_NAME, "", TRIGGER_NAME); + client.updateTrigger(request); + fail("ClientException is expected"); + } catch (ClientException e) { + assertTrue(e.getMessage().contains(VALIDATE_MSG)); + } + + try { + UpdateTriggerRequest request = new UpdateTriggerRequest(null, FUNCTION_NAME, + TRIGGER_NAME); + client.updateTrigger(request); + fail("ClientException is expected"); + } catch (ClientException e) { + assertTrue(e.getMessage().contains(VALIDATE_MSG)); + } + + try { + UpdateTriggerRequest request = new UpdateTriggerRequest("", FUNCTION_NAME, + TRIGGER_NAME); + client.updateTrigger(request); + fail("ClientException is expected"); + } catch (ClientException e) { + assertTrue(e.getMessage().contains(VALIDATE_MSG)); + } + } + + @Test + public void testCreateFunctionSetDir() throws IOException { + createService(SERVICE_NAME); + + // Create a function + CreateFunctionRequest createFuncReq = new CreateFunctionRequest(SERVICE_NAME); + createFuncReq.setFunctionName(FUNCTION_NAME); + createFuncReq.setDescription("Function for test"); + createFuncReq.setMemorySize(128); + createFuncReq.setHandler("hello_world.handler"); + createFuncReq.setRuntime("nodejs4.4"); + + // Setup code directory + String tmpDir = "/tmp/fc_test_" + UUID.randomUUID(); + String funcFilePath = tmpDir + "/" + "hello_world.js"; + new File(tmpDir).mkdir(); + + PrintWriter out = new PrintWriter(funcFilePath); + out.println("'use strict'; module.exports.handler = function(event, context, callback) {console.log('hello world'); callback(null, 'hello world');};"); + out.close(); + + Code code = new Code().setDir(tmpDir); + createFuncReq.setCode(code); + createFuncReq.setTimeout(10); + client.createFunction(createFuncReq); + + // Invoke the function + InvokeFunctionRequest request = new InvokeFunctionRequest(SERVICE_NAME, FUNCTION_NAME); + InvokeFunctionResponse response = client.invokeFunction(request); + + assertEquals("hello world", new String(response.getContent())); + + // Cleanups + client.deleteFunction(new DeleteFunctionRequest(SERVICE_NAME, FUNCTION_NAME)); + client.deleteService(new DeleteServiceRequest(SERVICE_NAME)); + + new File(funcFilePath).delete(); + new File(tmpDir).delete(); + } + + @Test + public void testCreateFunctionSetZipFile() throws IOException { + createService(SERVICE_NAME); + + // Create a function + CreateFunctionRequest createFuncReq = new CreateFunctionRequest(SERVICE_NAME); + createFuncReq.setFunctionName(FUNCTION_NAME); + createFuncReq.setDescription("Function for test"); + createFuncReq.setMemorySize(128); + createFuncReq.setHandler("hello_world.handler"); + createFuncReq.setRuntime("nodejs4.4"); + + // Setup code directory + String tmpDir = "/tmp/fc_test_" + UUID.randomUUID(); + String funcFilePath = tmpDir + "/" + "hello_world.js"; + new File(tmpDir).mkdir(); + PrintWriter out = new PrintWriter(funcFilePath); + out.println("'use strict'; module.exports.handler = function(event, context, callback) {console.log('hello world'); callback(null, 'hello world');};"); + out.close(); + String zipFilePath = tmpDir + "/" + "hello_world.zip"; + ZipUtils.zipDir(new File(tmpDir), zipFilePath); + + File zipFile = new File(zipFilePath); + byte[] buffer = new byte[(int) zipFile.length()]; + FileInputStream fis = new FileInputStream(zipFilePath); + fis.read(buffer); + fis.close(); + Code code = new Code().setZipFile(buffer); + createFuncReq.setCode(code); + createFuncReq.setTimeout(10); + client.createFunction(createFuncReq); + + // Invoke the function + InvokeFunctionRequest request = new InvokeFunctionRequest(SERVICE_NAME, FUNCTION_NAME); + InvokeFunctionResponse response = client.invokeFunction(request); + + assertEquals("hello world", new String(response.getContent())); + + // Cleanups + client.deleteFunction(new DeleteFunctionRequest(SERVICE_NAME, FUNCTION_NAME)); + client.deleteService(new DeleteServiceRequest(SERVICE_NAME)); + + new File(zipFilePath).delete(); + new File(funcFilePath).delete(); + new File(tmpDir).delete(); + } + + private void verifyUpdate(String nameOld, String nameNew, String idOld, + String idNew, String lastModifiedTimeOld, String lastModifiedTimeNew, + String createdTimeOld, String createdTimeNew, String descOld, String descNew) + throws ParseException { + assertEquals(nameNew, nameOld); + assertEquals(idNew, idOld); + Date dateOld = DATE_FORMAT.parse(lastModifiedTimeOld); + Date dateNew = DATE_FORMAT.parse(lastModifiedTimeNew); + assertTrue(dateOld.before(dateNew)); + Date cDateOld = DATE_FORMAT.parse(createdTimeOld); + Date cDateNew = DATE_FORMAT.parse(createdTimeNew); + assertEquals(cDateNew, cDateOld); + + assertNotEquals(descNew, descOld); + } + + private FunctionMetadata getFunction(String functionName, FunctionMetadata[] functions) { + for (FunctionMetadata function : functions) { + if (functionName.equals(function.getFunctionName())) { + return function; + } + } + throw new RuntimeException("Function " + functionName + " does not exist"); + } +}