├── .eslintignore ├── .eslintrc.json ├── .github └── stale.yml ├── .gitignore ├── .jshintrc ├── .snyk ├── .travis.yml ├── CONTRIBUTING.md ├── LICENSE ├── README.md ├── package-lock.json ├── package.json ├── src ├── Api.ts ├── ApiRequester.ts ├── Service.ts └── ZosConnect.ts ├── test ├── Api.ts ├── ApiRequester.ts ├── Service.ts └── ZosConnect.ts ├── tsconfig.json └── tslint.json /.eslintignore: -------------------------------------------------------------------------------- 1 | built/** -------------------------------------------------------------------------------- /.eslintrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "env": { 3 | "browser": false, 4 | "commonjs": false, 5 | "es6": true, 6 | "node": true, 7 | "mocha": true 8 | }, 9 | "parserOptions": { 10 | "ecmaFeatures": { 11 | "jsx": true 12 | }, 13 | "sourceType": "module" 14 | }, 15 | "rules": { 16 | "no-const-assign": "warn", 17 | "no-this-before-super": "warn", 18 | "no-undef": "warn", 19 | "no-unreachable": "warn", 20 | "no-unused-vars": "warn", 21 | "constructor-super": "warn", 22 | "valid-typeof": "warn", 23 | "no-console": "off", 24 | "no-restricted-syntax": "off", 25 | "comma-dangle": "off", 26 | "strict": "off" 27 | }, 28 | "extends": "airbnb-base" 29 | } -------------------------------------------------------------------------------- /.github/stale.yml: -------------------------------------------------------------------------------- 1 | # Number of days of inactivity before an issue becomes stale 2 | daysUntilStale: 60 3 | # Number of days of inactivity before a stale issue is closed 4 | daysUntilClose: 7 5 | # Issues with these labels will never be considered stale 6 | exemptLabels: 7 | - pinned 8 | - security 9 | - enhancement 10 | # Label to use when marking an issue as stale 11 | staleLabel: wontfix 12 | # Comment to post when marking an issue as stale. Set to `false` to disable 13 | markComment: > 14 | This issue has been automatically marked as stale because it has not had 15 | recent activity. It will be closed if no further activity occurs. Thank you 16 | for your contributions. 17 | # Comment to post when closing a stale issue. Set to `false` to disable 18 | closeComment: false -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules/ 2 | coverage/ 3 | .vscode/ 4 | lib/ 5 | .nyc_output/ 6 | *.tgz 7 | -------------------------------------------------------------------------------- /.jshintrc: -------------------------------------------------------------------------------- 1 | { 2 | "esversion": 6 3 | } -------------------------------------------------------------------------------- /.snyk: -------------------------------------------------------------------------------- 1 | # Snyk (https://snyk.io) policy file, patches or ignores known vulnerabilities. 2 | version: v1.14.1 3 | ignore: {} 4 | # patches apply the minimum changes required to fix a vulnerability 5 | patch: 6 | SNYK-JS-LODASH-450202: 7 | - request-promise > request-promise-core > lodash: 8 | patched: '2019-07-03T23:57:31.312Z' 9 | - snyk > snyk-mvn-plugin > lodash: 10 | patched: '2019-07-04T08:45:09.127Z' 11 | - snyk > lodash: 12 | patched: '2019-07-04T08:45:09.127Z' 13 | - snyk > snyk-nodejs-lockfile-parser > lodash: 14 | patched: '2019-07-04T08:45:09.127Z' 15 | - snyk > @snyk/dep-graph > lodash: 16 | patched: '2019-07-04T08:45:09.127Z' 17 | - snyk > inquirer > lodash: 18 | patched: '2019-07-04T08:45:09.127Z' 19 | - snyk > snyk-nuget-plugin > lodash: 20 | patched: '2019-07-04T08:45:09.127Z' 21 | - snyk > snyk-config > lodash: 22 | patched: '2019-07-04T08:45:09.127Z' 23 | - snyk > @snyk/dep-graph > graphlib > lodash: 24 | patched: '2019-07-04T08:45:09.127Z' 25 | - snyk > snyk-nodejs-lockfile-parser > graphlib > lodash: 26 | patched: '2019-07-04T08:45:09.127Z' 27 | - snyk > snyk-go-plugin > graphlib > lodash: 28 | patched: '2019-07-04T08:45:09.127Z' 29 | - snyk > snyk-php-plugin > @snyk/composer-lockfile-parser > lodash: 30 | patched: '2019-07-04T08:45:09.127Z' 31 | - snyk > @snyk/snyk-cocoapods-plugin > @snyk/dep-graph > lodash: 32 | patched: '2019-10-10T20:50:45.386Z' 33 | - snyk > snyk-nuget-plugin > dotnet-deps-parser > lodash: 34 | patched: '2019-10-10T20:50:45.386Z' 35 | - snyk > @snyk/snyk-cocoapods-plugin > @snyk/dep-graph > graphlib > lodash: 36 | patched: '2019-10-10T20:50:45.386Z' 37 | - snyk > @snyk/snyk-cocoapods-plugin > @snyk/cocoapods-lockfile-parser > @snyk/dep-graph > lodash: 38 | patched: '2019-10-10T20:50:45.386Z' 39 | - snyk > @snyk/snyk-cocoapods-plugin > @snyk/cocoapods-lockfile-parser > @snyk/dep-graph > graphlib > lodash: 40 | patched: '2019-10-10T20:50:45.386Z' 41 | SNYK-JS-HTTPSPROXYAGENT-469131: 42 | - snyk > proxy-agent > https-proxy-agent: 43 | patched: '2019-10-03T23:58:28.317Z' 44 | - snyk > proxy-agent > pac-proxy-agent > https-proxy-agent: 45 | patched: '2019-10-03T23:58:28.317Z' 46 | SNYK-JS-TREEKILL-536781: 47 | - snyk > snyk-sbt-plugin > tree-kill: 48 | patched: '2019-12-11T23:57:57.644Z' 49 | SNYK-JS-LODASH-567746: 50 | - request-promise > request-promise-core > lodash: 51 | patched: '2020-04-30T23:58:11.496Z' 52 | - snyk > @snyk/dep-graph > lodash: 53 | patched: '2020-04-30T23:58:11.496Z' 54 | - snyk > @snyk/snyk-cocoapods-plugin > @snyk/dep-graph > lodash: 55 | patched: '2020-04-30T23:58:11.496Z' 56 | - snyk > snyk-nuget-plugin > dotnet-deps-parser > lodash: 57 | patched: '2020-04-30T23:58:11.496Z' 58 | - snyk > @snyk/snyk-cocoapods-plugin > @snyk/cocoapods-lockfile-parser > @snyk/ruby-semver > lodash: 59 | patched: '2020-04-30T23:58:11.496Z' 60 | - snyk > lodash: 61 | patched: '2020-04-30T23:58:11.496Z' 62 | - snyk > inquirer > lodash: 63 | patched: '2020-04-30T23:58:11.496Z' 64 | - snyk > snyk-config > lodash: 65 | patched: '2020-04-30T23:58:11.496Z' 66 | - snyk > snyk-mvn-plugin > lodash: 67 | patched: '2020-04-30T23:58:11.496Z' 68 | - snyk > snyk-nodejs-lockfile-parser > lodash: 69 | patched: '2020-04-30T23:58:11.496Z' 70 | - snyk > snyk-nuget-plugin > lodash: 71 | patched: '2020-04-30T23:58:11.496Z' 72 | - snyk > @snyk/dep-graph > graphlib > lodash: 73 | patched: '2020-04-30T23:58:11.496Z' 74 | - snyk > snyk-go-plugin > graphlib > lodash: 75 | patched: '2020-04-30T23:58:11.496Z' 76 | - snyk > snyk-nodejs-lockfile-parser > graphlib > lodash: 77 | patched: '2020-04-30T23:58:11.496Z' 78 | - snyk > snyk-php-plugin > @snyk/composer-lockfile-parser > lodash: 79 | patched: '2020-04-30T23:58:11.496Z' 80 | - snyk > @snyk/snyk-cocoapods-plugin > @snyk/dep-graph > graphlib > lodash: 81 | patched: '2020-04-30T23:58:11.496Z' 82 | - snyk > @snyk/snyk-cocoapods-plugin > @snyk/cocoapods-lockfile-parser > @snyk/dep-graph > graphlib > lodash: 83 | patched: '2020-04-30T23:58:11.496Z' 84 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: node_js 2 | before_script: 3 | - npm run build 4 | node_js: 5 | - '10' 6 | - '12' 7 | deploy: 8 | skip_cleanup: true 9 | provider: npm 10 | edge: true 11 | email: smithson@uk.ibm.com 12 | api_key: 13 | secure: Rjwcx2kB2DBQbsSy+1HWdM9c8ter7bchgis/PIKSR6BSrCFl9D2K+RVI5FDuGLJxf4g2oU/4UYF9sFJ82fbtwJhWrwAzHVDpPg6hszlB/GCxaIGvzS92UtovBZ/EgqXMW2a6EfF4OrZ3XUBRpEwwyhKjEbBW2WKfCDil8qLGwsB5mHfCvMxk5XuGQlH0pswv25pgWfxX5wUxZyP1o0c8guHodRm6//WGtDzKwCDOUt+DM9uYgNb3eGteNLcFMe53OTnUpjHLthSJlGoBVki2cmPl72R3K50dC2sX0r/+xLS8BgBvSnX0tZ3vP5PMyLTmLoEyBCDaOc53DCFaDqw0uTizRePzQoTverg9/Kplw6fnbsJm5jKKcWOGtWP2Z2yVbxAFc3aZxQutY2ntwMhQvxeFqExEv7GnDIS7VD4mKtFdtzMwW9DMPTa6YzeLUClgASec/n3vfo11YW0AMnRbgE/DpV68bzWp3PX4bYZ2iES6n7NQQpu+eW8zbjQvEBRohncI01ChGVqOeRGK8/XvrhegJQU0vgGAXOPQiEmANTs5UgcczePIP3ISJjbIx3BD3LH9/1SyqNfa8aUYsPtNuFPkh89TSuA6sEZ9BiZptmDvzWxtHE27f7oa4d3Gl10HEQdcYfto+Hl2Pw64I+A3ZLnfFGF18o8LkJQsbZvDOeU= 14 | on: 15 | tags: true 16 | repo: zosconnect/zosconnect-node 17 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Issues 2 | 3 | If you encounter an issue with the Node.js library, you are welcome to submit 4 | a [bug report](https://github.com/zosconnect/zosconnect-node/issues). 5 | Before that, please search for similar issues. It's possible somebody has 6 | already encountered this issue. 7 | 8 | # Pull Requests 9 | 10 | If you want to contribute to the repository, follow these steps: 11 | 12 | 1. Fork the repo. 13 | 2. Develop and test your code changes: `npm install -d && npm test`. 14 | 3. Add a test for your changes. Only refactoring and documentation changes require no new tests. 15 | 4. Make the test pass. 16 | 5. Commit your changes. 17 | 6. Push to your fork and submit a pull request. 18 | 7. Sign your pull request. 19 | 20 | Signing your request is a simple line at the end of your pull request. If you can certify as described at [developercertificate.org](http://developercertificate.org) then add: 21 | ``` 22 | Signed-off-by: Joe Smith 23 | ``` 24 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | 2 | Apache License 3 | Version 2.0, January 2004 4 | http://www.apache.org/licenses/ 5 | 6 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 7 | 8 | 1. Definitions. 9 | 10 | "License" shall mean the terms and conditions for use, reproduction, 11 | and distribution as defined by Sections 1 through 9 of this document. 12 | 13 | "Licensor" shall mean the copyright owner or entity authorized by 14 | the copyright owner that is granting the License. 15 | 16 | "Legal Entity" shall mean the union of the acting entity and all 17 | other entities that control, are controlled by, or are under common 18 | control with that entity. For the purposes of this definition, 19 | "control" means (i) the power, direct or indirect, to cause the 20 | direction or management of such entity, whether by contract or 21 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 22 | outstanding shares, or (iii) beneficial ownership of such entity. 23 | 24 | "You" (or "Your") shall mean an individual or Legal Entity 25 | exercising permissions granted by this License. 26 | 27 | "Source" form shall mean the preferred form for making modifications, 28 | including but not limited to software source code, documentation 29 | source, and configuration files. 30 | 31 | "Object" form shall mean any form resulting from mechanical 32 | transformation or translation of a Source form, including but 33 | not limited to compiled object code, generated documentation, 34 | and conversions to other media types. 35 | 36 | "Work" shall mean the work of authorship, whether in Source or 37 | Object form, made available under the License, as indicated by a 38 | copyright notice that is included in or attached to the work 39 | (an example is provided in the Appendix below). 40 | 41 | "Derivative Works" shall mean any work, whether in Source or Object 42 | form, that is based on (or derived from) the Work and for which the 43 | editorial revisions, annotations, elaborations, or other modifications 44 | represent, as a whole, an original work of authorship. For the purposes 45 | of this License, Derivative Works shall not include works that remain 46 | separable from, or merely link (or bind by name) to the interfaces of, 47 | the Work and Derivative Works thereof. 48 | 49 | "Contribution" shall mean any work of authorship, including 50 | the original version of the Work and any modifications or additions 51 | to that Work or Derivative Works thereof, that is intentionally 52 | submitted to Licensor for inclusion in the Work by the copyright owner 53 | or by an individual or Legal Entity authorized to submit on behalf of 54 | the copyright owner. For the purposes of this definition, "submitted" 55 | means any form of electronic, verbal, or written communication sent 56 | to the Licensor or its representatives, including but not limited to 57 | communication on electronic mailing lists, source code control systems, 58 | and issue tracking systems that are managed by, or on behalf of, the 59 | Licensor for the purpose of discussing and improving the Work, but 60 | excluding communication that is conspicuously marked or otherwise 61 | designated in writing by the copyright owner as "Not a Contribution." 62 | 63 | "Contributor" shall mean Licensor and any individual or Legal Entity 64 | on behalf of whom a Contribution has been received by Licensor and 65 | subsequently incorporated within the Work. 66 | 67 | 2. Grant of Copyright License. Subject to the terms and conditions of 68 | this License, each Contributor hereby grants to You a perpetual, 69 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 70 | copyright license to reproduce, prepare Derivative Works of, 71 | publicly display, publicly perform, sublicense, and distribute the 72 | Work and such Derivative Works in Source or Object form. 73 | 74 | 3. Grant of Patent License. Subject to the terms and conditions of 75 | this License, each Contributor hereby grants to You a perpetual, 76 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 77 | (except as stated in this section) patent license to make, have made, 78 | use, offer to sell, sell, import, and otherwise transfer the Work, 79 | where such license applies only to those patent claims licensable 80 | by such Contributor that are necessarily infringed by their 81 | Contribution(s) alone or by combination of their Contribution(s) 82 | with the Work to which such Contribution(s) was submitted. If You 83 | institute patent litigation against any entity (including a 84 | cross-claim or counterclaim in a lawsuit) alleging that the Work 85 | or a Contribution incorporated within the Work constitutes direct 86 | or contributory patent infringement, then any patent licenses 87 | granted to You under this License for that Work shall terminate 88 | as of the date such litigation is filed. 89 | 90 | 4. Redistribution. You may reproduce and distribute copies of the 91 | Work or Derivative Works thereof in any medium, with or without 92 | modifications, and in Source or Object form, provided that You 93 | meet the following conditions: 94 | 95 | (a) You must give any other recipients of the Work or 96 | Derivative Works a copy of this License; and 97 | 98 | (b) You must cause any modified files to carry prominent notices 99 | stating that You changed the files; and 100 | 101 | (c) You must retain, in the Source form of any Derivative Works 102 | that You distribute, all copyright, patent, trademark, and 103 | attribution notices from the Source form of the Work, 104 | excluding those notices that do not pertain to any part of 105 | the Derivative Works; and 106 | 107 | (d) If the Work includes a "NOTICE" text file as part of its 108 | distribution, then any Derivative Works that You distribute must 109 | include a readable copy of the attribution notices contained 110 | within such NOTICE file, excluding those notices that do not 111 | pertain to any part of the Derivative Works, in at least one 112 | of the following places: within a NOTICE text file distributed 113 | as part of the Derivative Works; within the Source form or 114 | documentation, if provided along with the Derivative Works; or, 115 | within a display generated by the Derivative Works, if and 116 | wherever such third-party notices normally appear. The contents 117 | of the NOTICE file are for informational purposes only and 118 | do not modify the License. You may add Your own attribution 119 | notices within Derivative Works that You distribute, alongside 120 | or as an addendum to the NOTICE text from the Work, provided 121 | that such additional attribution notices cannot be construed 122 | as modifying the License. 123 | 124 | You may add Your own copyright statement to Your modifications and 125 | may provide additional or different license terms and conditions 126 | for use, reproduction, or distribution of Your modifications, or 127 | for any such Derivative Works as a whole, provided Your use, 128 | reproduction, and distribution of the Work otherwise complies with 129 | the conditions stated in this License. 130 | 131 | 5. Submission of Contributions. Unless You explicitly state otherwise, 132 | any Contribution intentionally submitted for inclusion in the Work 133 | by You to the Licensor shall be under the terms and conditions of 134 | this License, without any additional terms or conditions. 135 | Notwithstanding the above, nothing herein shall supersede or modify 136 | the terms of any separate license agreement you may have executed 137 | with Licensor regarding such Contributions. 138 | 139 | 6. Trademarks. This License does not grant permission to use the trade 140 | names, trademarks, service marks, or product names of the Licensor, 141 | except as required for reasonable and customary use in describing the 142 | origin of the Work and reproducing the content of the NOTICE file. 143 | 144 | 7. Disclaimer of Warranty. Unless required by applicable law or 145 | agreed to in writing, Licensor provides the Work (and each 146 | Contributor provides its Contributions) on an "AS IS" BASIS, 147 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 148 | implied, including, without limitation, any warranties or conditions 149 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 150 | PARTICULAR PURPOSE. You are solely responsible for determining the 151 | appropriateness of using or redistributing the Work and assume any 152 | risks associated with Your exercise of permissions under this License. 153 | 154 | 8. Limitation of Liability. In no event and under no legal theory, 155 | whether in tort (including negligence), contract, or otherwise, 156 | unless required by applicable law (such as deliberate and grossly 157 | negligent acts) or agreed to in writing, shall any Contributor be 158 | liable to You for damages, including any direct, indirect, special, 159 | incidental, or consequential damages of any character arising as a 160 | result of this License or out of the use or inability to use the 161 | Work (including but not limited to damages for loss of goodwill, 162 | work stoppage, computer failure or malfunction, or any and all 163 | other commercial damages or losses), even if such Contributor 164 | has been advised of the possibility of such damages. 165 | 166 | 9. Accepting Warranty or Additional Liability. While redistributing 167 | the Work or Derivative Works thereof, You may choose to offer, 168 | and charge a fee for, acceptance of support, warranty, indemnity, 169 | or other liability obligations and/or rights consistent with this 170 | License. However, in accepting such obligations, You may act only 171 | on Your own behalf and on Your sole responsibility, not on behalf 172 | of any other Contributor, and only if You agree to indemnify, 173 | defend, and hold each Contributor harmless for any liability 174 | incurred by, or claims asserted against, such Contributor by reason 175 | of your accepting any such warranty or additional liability. 176 | 177 | END OF TERMS AND CONDITIONS 178 | 179 | APPENDIX: How to apply the Apache License to your work. 180 | 181 | To apply the Apache License to your work, attach the following 182 | boilerplate notice, with the fields enclosed by brackets "[]" 183 | replaced with your own identifying information. (Don't include 184 | the brackets!) The text should be enclosed in the appropriate 185 | comment syntax for the file format. We also recommend that a 186 | file or class name and description of purpose be included on the 187 | same "printed page" as the copyright notice for easier 188 | identification within third-party archives. 189 | 190 | Copyright 2015 IBM Corporation 191 | 192 | Licensed under the Apache License, Version 2.0 (the "License"); 193 | you may not use this file except in compliance with the License. 194 | You may obtain a copy of the License at 195 | 196 | http://www.apache.org/licenses/LICENSE-2.0 197 | 198 | Unless required by applicable law or agreed to in writing, software 199 | distributed under the License is distributed on an "AS IS" BASIS, 200 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 201 | See the License for the specific language governing permissions and 202 | limitations under the License. 203 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | [![Build status](https://travis-ci.org/zosconnect/zosconnect-node.svg?branch=master)](https://travis-ci.org/zosconnect/zosconnect-node) 2 | [![codecov.io](https://codecov.io/github/zosconnect/zosconnect-node/coverage.svg?branch=master)](http://codecov.io/github/zosconnect/zosconnect-node?branch=master) 3 | [![Dependencies](https://david-dm.org/zosconnect/zosconnect-node.svg)](https://david-dm.org/zosconnect/zosconnect-node) 4 | [![Module LTS Adopted'](https://img.shields.io/badge/Module%20LTS-Adopted-brightgreen.svg?style=flat)](http://github.com/CloudNativeJS/ModuleLTS) 5 | 6 | 7 | 8 | **Table of Contents** 9 | 10 | - [Node zosconnect](#node-zosconnect) 11 | - [Installing](#installing) 12 | - [Usage](#usage) 13 | - [Connecting to z/OS Connect](#connecting-to-zos-connect) 14 | - [HTTPs Support](#https-support) 15 | - [Basic Authentication](#basic-authentication) 16 | - [Managing Items](#managing-items) 17 | - [Migrating from Version 3](#migrating-from-version-3) 18 | - [Module Long Term Support Policy](#module-long-term-support-policy) 19 | - [License](#license) 20 | 21 | 22 | 23 | ## Node zosconnect 24 | 25 | A wrapper service for z/OS® Connect EE, enabling node applications to manage z/OS Connect EE APIs, Services and API Requesters. Version 3 of this module pre-reqs z/OS Connect EE V3.0.14 or later. 26 | 27 | ### Installing 28 | 29 | ``` 30 | npm install @zosconnect/zosconnect-node 31 | ``` 32 | 33 | ### Usage 34 | 35 | #### Connecting to z/OS Connect 36 | 37 | ```js 38 | var options = { 39 | uri:'http://mainframe:8080' 40 | } 41 | var zosconnect = new ZosConnect(options); 42 | ``` 43 | 44 | ##### HTTPs Support 45 | Create the options object with locations for the CA certificate file and optionally the client certificate and client private key (if using client authentication). If the strictSSL option is set to false then invalid SSL certificates can be used which may be of use in development environments. 46 | ```js 47 | var fs = require('fs'); 48 | var path = require('path'); 49 | var caFile = path.resolve(__dirname, 'ca.pem'); 50 | var certFile = path.resolve(__dirname, 'cert.pem'); 51 | var keyFile = path.resolve(__dirname, 'key.pem'); 52 | var options = { 53 | uri:'https://mainframe:9443', 54 | ca: fs.readFileSync(caFile), 55 | cert: fs.readFileSync(certFile), 56 | key: fs.readFileSync(keyFile), 57 | passphrase: 'passw0rd', 58 | strictSSL: true 59 | } 60 | ``` 61 | 62 | ##### Basic Authentication 63 | Add the authentication credentials to the options object. 64 | ```js 65 | var options = { 66 | uri: 'http://mainframe:9080', 67 | auth: { 68 | user: 'userId', 69 | pass: 'password' 70 | } 71 | } 72 | ``` 73 | 74 | #### Managing Items 75 | APIs, Services and API Requesters can be retrieved and managed either by getting a list of all the installed items, or by getting a particular item by name. Once the application as an Object representing that item it can be further managed by calling methods on that Object. 76 | 77 | ### Migrating from Version 3 78 | 79 | With the deprecation of the request module the dependencies of this module have been updated. The only change is the type of the options object passed into the zosconnect has changed from a `request.optionsWithUri` to a `http.RequestOptions | https.RequestOptions` 80 | 81 | ### Module Long Term Support Policy 82 | This module adopts the [Module Long Term Support (LTS)](http://github.com/CloudNativeJS/ModuleLTS) policy, with the following End Of Life (EOL) dates: 83 | 84 | | Module Version | Release Date | Minimum EOL | EOL With | Status | 85 | |------------------|--------------|-------------|--------------|---------| 86 | | 4.x.x | May 2020 | Apr 2022 | Node 12 | Current | 87 | | 3.x.x | Nov 2018 | Apr 2021 | Node 10 | LTS | 88 | | 2.x.x | Jul 2018 | Apr 2021 | Node 10 | LTS | 89 | | 1.x.x | Jul 2017 | Dec 2019 | Node 8 | LTS | 90 | 91 | ### License 92 | ``` 93 | Licensed under the Apache License, Version 2.0 (the "License"); 94 | you may not use this file except in compliance with the License. 95 | You may obtain a copy of the License at 96 | 97 | http://www.apache.org/licenses/LICENSE-2.0 98 | 99 | Unless required by applicable law or agreed to in writing, software 100 | distributed under the License is distributed on an "AS IS" BASIS, 101 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 102 | See the License for the specific language governing permissions and 103 | limitations under the License. 104 | ``` 105 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@zosconnect/zosconnect-node", 3 | "version": "4.1.2", 4 | "description": "Node module for managing z/OS Connect EE artefacts", 5 | "main": "lib/ZosConnect.js", 6 | "types": "lib/ZosConnect.d.ts", 7 | "files": [ 8 | "lib" 9 | ], 10 | "publishConfig": { 11 | "access": "public" 12 | }, 13 | "dependencies": { 14 | "@types/extend": "^3.0.1", 15 | "@types/got": "^9.6.11", 16 | "extend": "^3.0.2", 17 | "got": "^11.1.3", 18 | "snyk": "^1.321.0" 19 | }, 20 | "devDependencies": { 21 | "@types/chai": "^4.2.11", 22 | "@types/chai-as-promised": "^7.1.2", 23 | "@types/mocha": "^5.2.7", 24 | "@types/nock": "^9.3.1", 25 | "@types/node": "^14.0.1", 26 | "chai": "^4.2.0", 27 | "chai-as-promised": "^7.1.1", 28 | "codecov": "^3.5.0", 29 | "doctoc": "^1.4.0", 30 | "mocha": "^7.1.2", 31 | "nock": "^11.0.0", 32 | "nyc": "^14.1.1", 33 | "source-map-support": "^0.5.19", 34 | "ts-node": "^7.0.1", 35 | "tslint": "^5.20.1", 36 | "typescript": "^3.9.2" 37 | }, 38 | "scripts": { 39 | "build": "tsc", 40 | "lint": "tslint src/**/*.ts", 41 | "test": "nyc mocha -r ts-node/register test/**/*.ts", 42 | "posttest": "npm run lint", 43 | "snyk-protect": "snyk protect", 44 | "prepare": "npm run snyk-protect" 45 | }, 46 | "nyc": { 47 | "extension": [ 48 | ".ts", 49 | ".tsx" 50 | ], 51 | "exclude": [ 52 | "**/*.d.ts", 53 | "coverage", 54 | "lib" 55 | ], 56 | "reporter": [ 57 | "text", 58 | "html" 59 | ], 60 | "all": true 61 | }, 62 | "repository": { 63 | "type": "git", 64 | "url": "https://github.com/zosconnect/zosconnect-node.git" 65 | }, 66 | "keywords": [ 67 | "z/OS", 68 | "z/OS Connect" 69 | ], 70 | "author": "", 71 | "license": "Apache-2.0", 72 | "snyk": true 73 | } 74 | -------------------------------------------------------------------------------- /src/Api.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2018 IBM Corp. All Rights Reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | import extend = require("extend"); 18 | import got from "got"; 19 | import * as http from "http"; 20 | import * as https from "https"; 21 | import url = require("url"); 22 | 23 | export class Api { 24 | 25 | private apiAdminUrl: string; 26 | private options: {}; 27 | private apiName: string; 28 | private version: string; 29 | private description: string; 30 | private apiUrl: string = ""; 31 | private documentation: {}; 32 | private status: string = ""; 33 | private services: string[]; 34 | 35 | constructor(apiAdminUrl: string, options: {}, apiName: string, 36 | version: string, description: string) { 37 | this.apiAdminUrl = apiAdminUrl; 38 | this.options = options; 39 | this.apiName = apiName; 40 | this.version = version; 41 | this.description = description; 42 | } 43 | 44 | /** 45 | * Mark the API as started and available for requests. 46 | */ 47 | public async start(): Promise { 48 | let opOptions = {}; 49 | let requestOptions = {} as https.RequestOptions; 50 | requestOptions = extend(requestOptions, this.options); 51 | const uri = this.apiAdminUrl + "?status=started"; 52 | requestOptions.method = "PUT"; 53 | requestOptions.headers = { 54 | "Content-Type": "application/json", 55 | }; 56 | opOptions = extend(opOptions, requestOptions); 57 | const apiJson = JSON.parse((await got(uri, opOptions)).body); 58 | this.status = apiJson.status; 59 | } 60 | 61 | /** 62 | * Mark the API as stopped and unavailable for requests. 63 | */ 64 | public async stop(): Promise { 65 | let opOptions = {}; 66 | let requestOptions = {} as https.RequestOptions; 67 | requestOptions = extend(requestOptions, this.options); 68 | const uri = this.apiAdminUrl + "?status=stopped"; 69 | requestOptions.method = "PUT"; 70 | requestOptions.headers = { 71 | "Content-Type": "application/json", 72 | }; 73 | opOptions = extend(opOptions, requestOptions); 74 | const apiJson = JSON.parse((await got(uri, opOptions)).body); 75 | this.status = apiJson.status; 76 | } 77 | 78 | /** 79 | * Update the API with a new version. 80 | * 81 | * @param aarFile The new AAR file 82 | */ 83 | public async update(aarFile: Buffer): Promise { 84 | let opOptions = {}; 85 | let requestOptions = {} as https.RequestOptions; 86 | requestOptions = extend(requestOptions, this.options); 87 | requestOptions.method = "PUT"; 88 | const uri = this.apiAdminUrl + "?status=started"; 89 | // tslint:disable-next-line:no-string-literal 90 | requestOptions["body"] = aarFile; 91 | requestOptions.headers = { 92 | "Content-Type": "application/zip", 93 | }; 94 | opOptions = extend(opOptions, requestOptions); 95 | await this.stop(); 96 | const apiJson = JSON.parse((await got(uri, opOptions)).body); 97 | this.version = apiJson.version; 98 | this.description = apiJson.description; 99 | const baseURL = new url.URL(this.apiAdminUrl); 100 | this.apiUrl = `${baseURL.protocol}//${baseURL.host}${new url.URL(apiJson.apiUrl).pathname}`; 101 | this.documentation = apiJson.documentation; 102 | this.status = apiJson.status; 103 | this.services = []; 104 | apiJson.services.forEach((service) => this.services.push(service.name)); 105 | } 106 | 107 | /** 108 | * Delete the API. 109 | */ 110 | public async delete(): Promise { 111 | let opOptions = {}; 112 | opOptions = extend(opOptions, this.options); 113 | await got.delete(this.apiAdminUrl, opOptions); 114 | } 115 | 116 | /** 117 | * @returns The name of the API. 118 | */ 119 | public getApiName(): string { 120 | return this.apiName; 121 | } 122 | 123 | /** 124 | * @returns The description of the API. 125 | */ 126 | public getDescription(): string { 127 | return this.description; 128 | } 129 | 130 | /** 131 | * @returns The version of the API. 132 | */ 133 | public getVersion(): string { 134 | return this.version; 135 | } 136 | 137 | /** 138 | * @returns The base URL for the API. 139 | */ 140 | public async getApiUrl(): Promise { 141 | if (this.apiUrl === "") { 142 | await this.getApiInfo(); 143 | } 144 | return this.apiUrl; 145 | } 146 | 147 | /** 148 | * @returns The status of the API. 149 | */ 150 | public async getStatus(): Promise { 151 | if (this.status === "") { 152 | await this.getApiInfo(); 153 | } 154 | return this.status; 155 | } 156 | 157 | /** 158 | * @param type The type of documentation to retrieve, e.g. swagger 159 | * @returns The documentation for the requested types. 160 | */ 161 | public async getDocumentation(type: string): Promise { 162 | let opOptions = {}; 163 | if (this.documentation === undefined) { 164 | await this.getApiInfo(); 165 | } 166 | const docUrl = this.documentation[type]; 167 | if (docUrl === undefined) { 168 | throw new Error(`Documentation of type ${type} not available`); 169 | } 170 | opOptions = extend(opOptions, this.options); 171 | const baseURL = new url.URL(this.apiAdminUrl); 172 | const uri = `${baseURL.protocol}//${baseURL.host}${new url.URL(docUrl).pathname}`; 173 | return (await got(uri, opOptions)).body; 174 | } 175 | 176 | public async getServices(): Promise { 177 | if (this.services === undefined) { 178 | await this.getApiInfo(); 179 | } 180 | return this.services; 181 | } 182 | 183 | private async getApiInfo(): Promise { 184 | let opOptions = {}; 185 | opOptions = extend(opOptions, this.options); 186 | const apiJson = JSON.parse((await got.get(this.apiAdminUrl, opOptions)).body); 187 | const baseURL = new url.URL(this.apiAdminUrl); 188 | this.apiUrl = `${baseURL.protocol}//${baseURL.host}${new url.URL(apiJson.apiUrl).pathname}`; 189 | this.documentation = apiJson.documentation; 190 | this.status = apiJson.status; 191 | this.services = []; 192 | apiJson.services.forEach((service) => this.services.push(service.name)); 193 | } 194 | } 195 | -------------------------------------------------------------------------------- /src/ApiRequester.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2018 IBM Corp. All Rights Reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | import extend = require("extend"); 18 | import got from "got"; 19 | import * as http from "http"; 20 | import * as https from "https"; 21 | 22 | export class ApiRequester { 23 | private apiRequesterUrl: string; 24 | private options: {}; 25 | private name: string; 26 | private version: string; 27 | private description: string; 28 | private connection: string; 29 | private status: string; 30 | 31 | constructor(apiRequsterUrl: string, options: {}, name: string, 32 | version: string, description: string, connection: string, status: string) { 33 | this.apiRequesterUrl = apiRequsterUrl; 34 | this.options = options; 35 | this.name = name; 36 | this.version = version; 37 | this.description = description; 38 | this.connection = connection; 39 | this.status = status; 40 | } 41 | 42 | /** 43 | * Mark the API Requester as started and available for requests. 44 | */ 45 | public async start() { 46 | let opOptions = {}; 47 | let requestOptions = {} as https.RequestOptions; 48 | requestOptions = extend(requestOptions, this.options); 49 | requestOptions.method = "PUT"; 50 | const uri = this.apiRequesterUrl + "?status=started"; 51 | requestOptions.headers = { 52 | "Content-Type": "application/json", 53 | }; 54 | opOptions = extend(opOptions, requestOptions); 55 | const response = JSON.parse((await got(uri, opOptions)).body); 56 | this.status = response.status; 57 | } 58 | 59 | /** 60 | * Mark the API Requester as stopped and unavailable for requests. 61 | */ 62 | public async stop() { 63 | let opOptions = {}; 64 | let requestOptions = {} as https.RequestOptions; 65 | requestOptions = extend(requestOptions, this.options); 66 | requestOptions.method = "PUT"; 67 | const uri = this.apiRequesterUrl + "?status=stopped"; 68 | requestOptions.headers = { 69 | "Content-Type": "application/json", 70 | }; 71 | opOptions = extend(opOptions, requestOptions); 72 | const response = JSON.parse((await got(uri, opOptions)).body); 73 | this.status = response.status; 74 | } 75 | 76 | /** 77 | * Update the API Requester with the new version. 78 | * @param araFile The ARA file. 79 | */ 80 | public async update(araFile: Buffer) { 81 | let opOptions = {}; 82 | let requestOptions = {} as https.RequestOptions; 83 | requestOptions = extend(requestOptions, this.options); 84 | requestOptions.method = "PUT"; 85 | const uri = this.apiRequesterUrl + "?status=started"; 86 | // tslint:disable-next-line:no-string-literal 87 | requestOptions["body"] = araFile; 88 | requestOptions.headers = { 89 | "Content-Type": "application/zip", 90 | }; 91 | opOptions = extend(opOptions, requestOptions); 92 | await this.stop(); 93 | const json = JSON.parse((await got(uri, opOptions)).body); 94 | this.version = json.version; 95 | this.connection = json.connection; 96 | this.description = json.description; 97 | this.status = json.status; 98 | } 99 | 100 | /** 101 | * Delete the API Requester from the server. 102 | */ 103 | public async delete() { 104 | let opOptions = {}; 105 | opOptions = extend(opOptions, this.options); 106 | await got.delete(this.apiRequesterUrl, opOptions); 107 | } 108 | 109 | /** 110 | * @returns The name of the API Requester. 111 | */ 112 | public getName(): string { 113 | return this.name; 114 | } 115 | 116 | /** 117 | * @returns The description of the API Requester. 118 | */ 119 | public getDescription(): string { 120 | return this.description; 121 | } 122 | 123 | /** 124 | * @returns The version of the API Requester. 125 | */ 126 | public getVersion(): string { 127 | return this.version; 128 | } 129 | 130 | /** 131 | * @returns The connection used by the API Requester. 132 | */ 133 | public getConnection(): string { 134 | return this.connection; 135 | } 136 | 137 | /** 138 | * @returns The status of the API Requester. 139 | */ 140 | public getStatus(): string { 141 | return this.status; 142 | } 143 | } 144 | -------------------------------------------------------------------------------- /src/Service.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2018 IBM Corp. All Rights Reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | import extend = require("extend"); 18 | import got from "got"; 19 | import * as http from "http"; 20 | import * as https from "https"; 21 | import url = require("url"); 22 | 23 | export class Service { 24 | 25 | private serviceUri: string; 26 | private options: {}; 27 | private serviceName: string; 28 | private description: string; 29 | private serviceProvider: string; 30 | private serviceInvokeUrl: string = ""; 31 | private status: string = ""; 32 | 33 | constructor(serviceUri: string, options: {}, serviceName: string, 34 | description: string, serviceProvider: string) { 35 | this.serviceUri = serviceUri; 36 | this.options = options; 37 | this.serviceName = serviceName; 38 | this.description = description; 39 | this.serviceProvider = serviceProvider; 40 | } 41 | 42 | /** 43 | * Mark the Service as started and available to process requests. 44 | */ 45 | public async start(): Promise { 46 | let opOptions = {}; 47 | let requestOptions = {} as https.RequestOptions; 48 | requestOptions = extend(requestOptions, this.options); 49 | requestOptions.method = "PUT"; 50 | const uri = this.serviceUri + "?status=started"; 51 | requestOptions.headers = { 52 | "Content-Type": "application/json", 53 | }; 54 | opOptions = extend(opOptions, requestOptions); 55 | const response = JSON.parse((await got(uri, opOptions)).body); 56 | this.status = response.zosConnect.serviceStatus; 57 | } 58 | 59 | /** 60 | * Mark the Service as stopped and unavailable to process requests. 61 | */ 62 | public async stop(): Promise { 63 | let opOptions = {}; 64 | let requestOptions = {} as https.RequestOptions; 65 | requestOptions = extend(requestOptions, this.options); 66 | requestOptions.method = "PUT"; 67 | const uri = this.serviceUri + "?status=stopped"; 68 | requestOptions.headers = { 69 | "Content-Type": "application/json", 70 | }; 71 | opOptions = extend(opOptions, requestOptions); 72 | const response = JSON.parse((await got(uri, opOptions)).body); 73 | this.status = response.zosConnect.serviceStatus; 74 | } 75 | 76 | /** 77 | * Update the Service with a new version. 78 | * @param sarFile The new SAR file for the Service 79 | */ 80 | public async update(sarFile: Buffer): Promise { 81 | let opOptions = {}; 82 | let requestOptions = {} as https.RequestOptions; 83 | requestOptions = extend(requestOptions, this.options); 84 | requestOptions.method = "PUT"; 85 | const uri = this.serviceUri + "?status=started"; 86 | // tslint:disable-next-line:no-string-literal 87 | requestOptions["body"] = sarFile; 88 | requestOptions.headers = { 89 | "Content-Type": "application/zip", 90 | }; 91 | opOptions = extend(opOptions, requestOptions); 92 | await this.stop(); 93 | const serviceData = JSON.parse((await got(uri, opOptions)).body); 94 | this.description = serviceData.zosConnect.serviceDescription; 95 | this.status = serviceData.zosConnect.serviceStatus; 96 | const baseUrl = new url.URL(this.serviceUri); 97 | this.serviceInvokeUrl = 98 | `${baseUrl.protocol}//${baseUrl.host}${new url.URL(serviceData.zosConnect.serviceInvokeURL).pathname}`; 99 | } 100 | 101 | /** 102 | * Delete the Service from the server. 103 | */ 104 | public async delete(): Promise { 105 | let opOptions = {}; 106 | opOptions = extend(opOptions, this.options); 107 | await got.delete(this.serviceUri, opOptions); 108 | } 109 | 110 | /** 111 | * @returns The name of the Service. 112 | */ 113 | public getName(): string { 114 | return this.serviceName; 115 | } 116 | 117 | /** 118 | * @returns The Services description. 119 | */ 120 | public getDescription(): string { 121 | return this.description; 122 | } 123 | 124 | /** 125 | * @returns The service provider for the Service. 126 | */ 127 | public getServiceProvider(): string { 128 | return this.serviceProvider; 129 | } 130 | 131 | /** 132 | * @returns The status of the Service. 133 | */ 134 | public async getStatus(): Promise { 135 | if (this.status === "") { 136 | await this.getServiceInfo(); 137 | } 138 | return this.status; 139 | } 140 | 141 | /** 142 | * @returns The URL that the Service can be invoked on. 143 | */ 144 | public async getServiceInvokeUrl(): Promise { 145 | if (this.status === "") { 146 | await this.getServiceInfo(); 147 | } 148 | return this.serviceInvokeUrl; 149 | } 150 | 151 | private async getServiceInfo(): Promise { 152 | let opOptions = {}; 153 | opOptions = extend(opOptions, this.options); 154 | const serviceJson = JSON.parse((await got.get(this.serviceUri, opOptions)).body); 155 | const baseUrl = new url.URL(this.serviceUri); 156 | const invokeUrl = new url.URL(serviceJson.zosConnect.serviceInvokeURL); 157 | this.serviceInvokeUrl = 158 | `${baseUrl.protocol}//${baseUrl.host}${invokeUrl.pathname}${invokeUrl.search}`; 159 | this.status = serviceJson.zosConnect.serviceStatus; 160 | } 161 | } 162 | -------------------------------------------------------------------------------- /src/ZosConnect.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2018 IBM Corp. All Rights Reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | import extend = require("extend"); 18 | import got from "got"; 19 | import * as http from "http"; 20 | import * as https from "https"; 21 | import url = require("url"); 22 | import { Api } from "./Api"; 23 | import { ApiRequester } from "./ApiRequester"; 24 | import { Service } from "./Service"; 25 | 26 | /** 27 | * Object which represents a z/OS Connect EE server. 28 | * 29 | * Can be used to retrieve and create artifacts on the server. 30 | */ 31 | export class ZosConnect { 32 | 33 | private options: {}; 34 | private uri: string; 35 | 36 | /** 37 | * Establish a connection to the server ready to work with APIs, Services and API Requesters. 38 | * 39 | * @param options A {@link http.RequestOptions}|{@link https.RequestOptions} which describes the 40 | * connection to the server 41 | */ 42 | constructor(uri: string, options: http.RequestOptions | https.RequestOptions) { 43 | if (options === null || options === undefined) { 44 | throw new Error("An options object is required"); 45 | } 46 | 47 | if (uri === null || uri === undefined) { 48 | throw new Error("Required uri or url not specified"); 49 | } 50 | 51 | this.uri = uri; 52 | this.options = extend(this.options, options); 53 | if ("rejectUnauthorized" in this.options) { 54 | this.options = Object.assign(this.options, 55 | {https: {rejectUnauthorized: (options as https.RequestOptions).rejectUnauthorized}}); 56 | // tslint:disable-next-line:no-string-literal 57 | delete this.options["rejectUnauthorized"]; 58 | } 59 | if ("auth" in this.options) { 60 | const parts = (options as https.RequestOptions).auth.split(/:/); 61 | this.options = Object.assign(this.options, {username : parts[0]}); 62 | this.options = Object.assign(this.options, {password : parts[1]}); 63 | // tslint:disable-next-line:no-string-literal 64 | delete this.options["auth"]; 65 | } 66 | } 67 | 68 | /** 69 | * Retrieve all the Services that are installed in the server. 70 | * 71 | * @returns An array of all the Service objects. 72 | */ 73 | public async getServices(): Promise { 74 | let opOptions = {}; 75 | opOptions = extend(opOptions, this.options); 76 | const requestUri = this.uri + "/zosConnect/services"; 77 | 78 | const json = JSON.parse((await got(requestUri, opOptions)).body); 79 | const services: Service[] = []; 80 | for (const service of json.zosConnectServices) { 81 | let serviceOptions = {}; 82 | serviceOptions = extend(serviceOptions, this.options); 83 | const serviceOptionsUri = requestUri + `/${service.ServiceName}`; 84 | services.push(new Service(serviceOptionsUri, serviceOptions, service.ServiceName, service.ServiceDescription, 85 | service.ServiceProvider)); 86 | } 87 | return services; 88 | } 89 | 90 | /** 91 | * Retrieve the named Service from the server. 92 | * 93 | * @param serviceName The name of the service. 94 | * @returns The {@link Service} 95 | */ 96 | public async getService(serviceName: string): Promise { 97 | let opOptions = {}; 98 | opOptions = extend(opOptions, this.options); 99 | const requestUri = this.uri + `/zosConnect/services/${serviceName}`; 100 | 101 | const serviceData = JSON.parse((await got(requestUri, opOptions)).body); 102 | const invokeUrl = url.parse(serviceData.zosConnect.serviceInvokeURL); 103 | return new Service(requestUri, opOptions, serviceName, serviceData.zosConnect.serviceDescription, 104 | serviceData.zosConnect.serviceProvider); 105 | } 106 | 107 | /** 108 | * Retrieve all the APIs that are intalled in the server. 109 | * 110 | * @returns An array of all the API objects. 111 | */ 112 | public async getApis(): Promise { 113 | let opOptions = {}; 114 | opOptions = extend(opOptions, this.options); 115 | const requestUri = this.uri + "/zosConnect/apis"; 116 | const json = JSON.parse((await got(requestUri, opOptions)).body); 117 | const apis = []; 118 | for (const api of json.apis) { 119 | let apiOptions = {}; 120 | apiOptions = extend(apiOptions, this.options); 121 | const apiUri = requestUri + `/${api.name}`; 122 | apis.push(new Api(apiUri, apiOptions, api.name, api.version, api.description)); 123 | } 124 | return apis; 125 | 126 | } 127 | 128 | /** 129 | * Retrieve the named API from the server. 130 | * 131 | * @param apiName The name of the API to retrieve. 132 | * @returns The {@link Api} 133 | */ 134 | public async getApi(apiName: string): Promise { 135 | let opOptions = {}; 136 | opOptions = extend(opOptions, this.options); 137 | const requestUri = this.uri + `/zosConnect/apis/${apiName}`; 138 | const json = JSON.parse((await got(requestUri, opOptions)).body); 139 | const apiUrl = url.parse(json.apiUrl); 140 | return new Api(requestUri, opOptions, apiName, json.version, json.description); 141 | } 142 | 143 | /** 144 | * Install a new API. 145 | * 146 | * @param aarFile The AAR file to install. 147 | * @returns The {@link Api} that was installed 148 | */ 149 | public async createApi(aarFile: Buffer): Promise { 150 | let opOptions = {}; 151 | let requestOptions = {} as https.RequestOptions; 152 | requestOptions = extend(requestOptions, this.options); 153 | const requestUri = this.uri + "/zosConnect/apis"; 154 | requestOptions.method = "POST"; 155 | // tslint:disable-next-line:no-string-literal 156 | requestOptions["body"] = aarFile; 157 | requestOptions.headers = { 158 | "Content-Type": "application/zip", 159 | }; 160 | opOptions = extend(opOptions, requestOptions); 161 | const json = JSON.parse((await got(requestUri, opOptions)).body); 162 | const apiUrl = url.parse(json.apiUrl); 163 | return new Api(requestUri + json.name, opOptions, json.name, json.version, json.description); 164 | } 165 | 166 | /** 167 | * Install a new Service. 168 | * 169 | * @param sarFile The SAR file to install. 170 | * @returns The {@link Service} that was installed. 171 | */ 172 | public async createService(sarFile: Buffer): Promise { 173 | let opOptions = {}; 174 | let requestOptions = {} as https.RequestOptions; 175 | requestOptions = extend(requestOptions, this.options); 176 | const requestUri = this.uri + "/zosConnect/services"; 177 | requestOptions.method = "POST"; 178 | // tslint:disable-next-line:no-string-literal 179 | requestOptions["body"] = sarFile; 180 | requestOptions.headers = { 181 | "Content-Type": "application/zip", 182 | }; 183 | opOptions = extend(opOptions, requestOptions); 184 | const serviceData = JSON.parse((await got(requestUri, opOptions)).body); 185 | return new Service(requestUri + serviceData.zosConnect.serviceName, opOptions, serviceData.zosConnect.serviceName, 186 | serviceData.zosConnect.serviceDescription, serviceData.zosConnect.serviceProvider); 187 | } 188 | 189 | /** 190 | * Retrieve all the API Requsters installed in the server. 191 | * 192 | * @returns An array of the API Requester objects. 193 | */ 194 | public async getApiRequesters(): Promise { 195 | let opOptions = {}; 196 | opOptions = extend(opOptions, this.options); 197 | const requestUri = this.uri + "/zosConnect/apiRequesters"; 198 | const json = JSON.parse((await got(requestUri, opOptions)).body); 199 | const apis = []; 200 | for (const apiRequester of json.apiRequesters) { 201 | let apiRequesterOptions = {}; 202 | apiRequesterOptions = extend(apiRequesterOptions, this.options); 203 | const apiRequesterUri = requestUri + `/${apiRequester.name}`; 204 | apis.push(new ApiRequester(apiRequesterUri, apiRequesterOptions, apiRequester.name, apiRequester.version, 205 | apiRequester.description, apiRequester.connectionRef, apiRequester.status)); 206 | } 207 | return apis; 208 | } 209 | 210 | /** 211 | * Retrieve the named API Requester. 212 | * @param name The name of the API Requester. 213 | * @returns The {@link ApiRequester} 214 | */ 215 | public async getApiRequester(name: string): Promise { 216 | let opOptions = {}; 217 | opOptions = extend(opOptions, this.options); 218 | const requestUri = this.uri + `/zosConnect/apiRequesters/${name}`; 219 | const json = JSON.parse((await got(requestUri, opOptions)).body); 220 | return new ApiRequester(requestUri, opOptions, json.name, json.version, json.description, json.connection, 221 | json.status); 222 | } 223 | 224 | /** 225 | * Install a new API Requester. 226 | * @param araFile The ARA file. 227 | * @returns The {@link ApiRequester} that was installed. 228 | */ 229 | public async createApiRequester(araFile: Buffer): Promise { 230 | let opOptions = {}; 231 | let requestOptions = {} as https.RequestOptions; 232 | requestOptions = extend(requestOptions, this.options); 233 | const requestUri = this.uri + "/zosConnect/apiRequesters"; 234 | requestOptions.method = "POST"; 235 | // tslint:disable-next-line:no-string-literal 236 | requestOptions["body"] = araFile; 237 | requestOptions.headers = { 238 | "Content-Type": "application/zip", 239 | }; 240 | opOptions = extend(opOptions, requestOptions); 241 | const apiRequester = JSON.parse((await got(requestUri, opOptions)).body); 242 | const apiRequesterUri = requestUri + "/" + apiRequester.name; 243 | return new ApiRequester(apiRequesterUri, opOptions, apiRequester.name, apiRequester.version, 244 | apiRequester.description, apiRequester.connection, apiRequester.status); 245 | } 246 | } 247 | -------------------------------------------------------------------------------- /test/Api.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2015 IBM Corp. All Rights Reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | import * as nock from "nock"; 17 | 18 | import * as chai from "chai"; 19 | import * as chaiAsPromised from "chai-as-promised"; 20 | import { Api } from "../src/Api"; 21 | 22 | before(() => { 23 | chai.should(); 24 | chai.use(chaiAsPromised); 25 | }); 26 | 27 | describe("api", () => { 28 | const api = new Api("http://test:9080/zosConnect/apis/dateApi", { }, "dateTime", 29 | "1.0.0", "Date Time API"); 30 | describe("#start", () => { 31 | it("should start the api", () => { 32 | nock("http://test:9080") 33 | .put("/zosConnect/apis/dateApi") 34 | .query({ status: "started" }) 35 | .reply(200, { 36 | apiUrl: "http://test:9080/dateTime", 37 | description: "Date Time API", 38 | documentation: { 39 | swagger: "http://test:9080/dateTime/api-docs", 40 | }, 41 | name: "dateTime", 42 | status: "started", 43 | version: "1.0.0", 44 | services: [ 45 | { 46 | name: "service1", 47 | uri: "http://test:9080/zosConnect/services/service1", 48 | }, 49 | ], 50 | }); 51 | return api.start().should.be.fulfilled; 52 | }); 53 | 54 | it("should return not found", () => { 55 | nock("http://test:9080") 56 | .put("/zosConnect/apis/dateApi") 57 | .query({ status: "started" }) 58 | .reply(404); 59 | return api.start().should.be.rejectedWith(Error); 60 | }); 61 | 62 | it("should return an error", () => { 63 | nock("http://test:9080") 64 | .put("/zosConnect/apis/dateApi") 65 | .query({ status: "started" }) 66 | .replyWithError("something fatal happened"); 67 | return api.start().should.be.rejectedWith("something fatal happened"); 68 | }); 69 | }); 70 | 71 | describe("#stop", () => { 72 | it("should stop the api", () => { 73 | nock("http://test:9080") 74 | .put("/zosConnect/apis/dateApi") 75 | .query({ status: "stopped" }) 76 | .reply(200, { 77 | apiUrl: "http://test:9080/dateTime", 78 | description: "Date Time API", 79 | documentation: { 80 | swagger: "http://test:9080/dateTime/api-docs", 81 | }, 82 | name: "dateTime", 83 | status: "stopped", 84 | version: "1.0.0", 85 | services: [ 86 | { 87 | name: "service1", 88 | uri: "http://test:9080/zosConnect/services/service1", 89 | }, 90 | ], 91 | }); 92 | return api.stop().should.be.fulfilled; 93 | }); 94 | 95 | it("should return not found", () => { 96 | nock("http://test:9080") 97 | .put("/zosConnect/apis/dateApi") 98 | .query({ status: "stopped" }) 99 | .reply(404); 100 | api.stop().should.be.rejectedWith(Error); 101 | }); 102 | 103 | it("should return an error", () => { 104 | nock("http://test:9080") 105 | .put("/zosConnect/apis/dateApi") 106 | .query({ status: "stopped" }) 107 | .replyWithError("something fatal happened"); 108 | api.stop().should.be.rejectedWith("something fatal happened"); 109 | }); 110 | }); 111 | 112 | describe("#update", () => { 113 | it("should update the API", () => { 114 | nock("http://test:9080") 115 | .put("/zosConnect/apis/dateApi") 116 | .query({ status: "stopped" }) 117 | .reply(200, { 118 | apiUrl: "http://test:9080/dateTime", 119 | description: "Date Time API", 120 | documentation: { 121 | swagger: "http://test:9080/dateTime/api-docs", 122 | }, 123 | name: "dateTime", 124 | status: "stopped", 125 | version: "1.0.0", 126 | services: [ 127 | { 128 | name: "service1", 129 | uri: "http://test:9080/zosConnect/services/service1", 130 | }, 131 | ], 132 | }); 133 | nock("http://test:9080") 134 | .put("/zosConnect/apis/dateApi") 135 | .query({ status: "started" }) 136 | .reply(200, { 137 | apiUrl: "http://test:9080/dateTime", 138 | description: "Date Time API", 139 | documentation: { 140 | swagger: "http://test:9080/dateTime/api-docs", 141 | }, 142 | name: "dateTime", 143 | status: "stopped", 144 | version: "1.0.0", 145 | services: [ 146 | { 147 | name: "service1", 148 | uri: "http://test:9080/zosConnect/services/service1", 149 | }, 150 | ], 151 | }); 152 | return api.update(Buffer.from("foo")).should.be.fulfilled; 153 | }); 154 | 155 | it("should fail to stop the API", () => { 156 | nock("http://test:9080") 157 | .put("/zosConnect/apis/dateApi") 158 | .query({ status: "stopped" }) 159 | .reply(404); 160 | api.update(Buffer.from("foo")).should.be.rejectedWith(Error); 161 | }); 162 | 163 | it("should fail to stop the API due to error", () => { 164 | nock("http://test:9080") 165 | .put("/zosConnect/apis/dateApi") 166 | .query({ status: "stopped" }) 167 | .replyWithError("something fatal happened"); 168 | api.update(Buffer.from("foo")).should.be.rejectedWith("something fatal happened"); 169 | }); 170 | 171 | it("should fail the update", () => { 172 | nock("http://test:9080") 173 | .put("/zosConnect/apis/dateApi") 174 | .query({ status: "stopped" }) 175 | .reply(200, { 176 | apiUrl: "http://test:9080/dateTime", 177 | description: "Date Time API", 178 | documentation: { 179 | swagger: "http://test:9080/dateTime/api-docs", 180 | }, 181 | name: "dateTime", 182 | status: "stopped", 183 | version: "1.0.0", 184 | services: [ 185 | { 186 | name: "service1", 187 | uri: "http://test:9080/zosConnect/services/service1", 188 | }, 189 | ], 190 | }); 191 | nock("http://test:9080") 192 | .put("/zosConnect/apis/dateApi") 193 | .query({ status: "started" }) 194 | .reply(404); 195 | api.update(Buffer.from("foo")).should.be.rejectedWith(Error); 196 | }); 197 | 198 | it("should fail the update due to error", () => { 199 | nock("http://test:9080") 200 | .put("/zosConnect/apis/dateApi") 201 | .query({ status: "stopped" }) 202 | .reply(200, { 203 | apiUrl: "http://test:9080/dateTime", 204 | description: "Date Time API", 205 | documentation: { 206 | swagger: "http://test:9080/dateTime/api-docs", 207 | }, 208 | name: "dateTime", 209 | status: "stopped", 210 | version: "1.0.0", 211 | services: [ 212 | { 213 | name: "service1", 214 | uri: "http://test:9080/zosConnect/services/service1", 215 | }, 216 | ], 217 | }); 218 | nock("http://test:9080") 219 | .put("/zosConnect/apis/dateApi") 220 | .query({ status: "started" }) 221 | .replyWithError("Something fatal happened"); 222 | api.update(Buffer.from("foo")).should.be.rejectedWith("Something fatal happened"); 223 | }); 224 | }); 225 | 226 | describe("#delete", () => { 227 | it("should delete the api", () => { 228 | nock("http://test:9080") 229 | .delete("/zosConnect/apis/dateApi") 230 | .reply(200, { 231 | name: "dateTime", 232 | }); 233 | return api.delete().should.be.fulfilled; 234 | }); 235 | 236 | it("should fail the delete", () => { 237 | nock("http://test:9080") 238 | .delete("/zosConnect/apis/dateApi") 239 | .reply(403); 240 | return api.delete().should.be.rejectedWith(Error); 241 | }); 242 | 243 | it("should fail due to error", () => { 244 | nock("http://test:9080") 245 | .delete("/zosConnect/apis/dateApi") 246 | .replyWithError("Something fatal happened"); 247 | return api.delete().should.be.rejectedWith("Something fatal happened"); 248 | }); 249 | }); 250 | 251 | describe("#getApiName", () => { 252 | it("should return the API Name", () => api.getApiName().should.equal("dateTime")); 253 | }); 254 | 255 | describe("#getVersion", () => { 256 | it("should return the API Version", () => api.getVersion().should.equal("1.0.0")); 257 | }); 258 | 259 | describe("#getDescription", () => { 260 | it("should return the API Description", () => api.getDescription().should.equal("Date Time API")); 261 | }); 262 | 263 | describe("#getApiUrl", () => { 264 | const localApi = new Api("http://test:9080/zosConnect/apis/dateApi", { }, "dateTime", 265 | "1.0.0", "Date Time API"); 266 | it("should return the API URL", () => { 267 | nock("http://test:9080") 268 | .get("/zosConnect/apis/dateApi") 269 | .reply(200, { 270 | apiUrl: "http://test:9080/dateTime", 271 | description: "Date Time API", 272 | documentation: { 273 | swagger: "http://test:9080/dateTime/api-docs", 274 | }, 275 | name: "dateTime", 276 | status: "started", 277 | version: "1.0.0", 278 | services: [ 279 | { 280 | name: "service1", 281 | uri: "http://test:9080/zosConnect/services/service1", 282 | }, 283 | ], 284 | }); 285 | return localApi.getApiUrl().should.eventually.equal("http://test:9080/dateTime"); 286 | }); 287 | 288 | it("should return API URL without calling the server", () => { 289 | return localApi.getApiUrl().should.eventually.equal("http://test:9080/dateTime"); 290 | }); 291 | }); 292 | 293 | describe("#getStatus", () => { 294 | const localApi = new Api("http://test:9080/zosConnect/apis/dateApi", { }, "dateTime", 295 | "1.0.0", "Date Time API"); 296 | it("should return the status of the API", () => { 297 | nock("http://test:9080") 298 | .get("/zosConnect/apis/dateApi") 299 | .reply(200, { 300 | apiUrl: "http://test:9080/dateTime", 301 | description: "Date Time API", 302 | documentation: { 303 | swagger: "http://test:9080/dateTime/api-docs", 304 | }, 305 | name: "dateTime", 306 | status: "Started", 307 | version: "1.0.0", 308 | services: [ 309 | { 310 | name: "service1", 311 | uri: "http://test:9080/zosConnect/services/service1", 312 | }, 313 | ], 314 | }); 315 | localApi.getStatus().should.eventually.equal("Started"); 316 | }); 317 | 318 | it("should return the status of the API without calling the server", () => { 319 | return localApi.getStatus().should.eventually.equal("Started"); 320 | }); 321 | }); 322 | 323 | describe("#getDocumentation", () => { 324 | const localApi = new Api("http://test:9080/zosConnect/apis/dateApi", { }, "dateTime", 325 | "1.0.0", "Date Time API"); 326 | it("should return the swagger", () => { 327 | nock("http://test:9080") 328 | .get("/zosConnect/apis/dateApi") 329 | .reply(200, { 330 | apiUrl: "http://test:9080/dateTime", 331 | description: "Date Time API", 332 | documentation: { 333 | swagger: "http://test:9080/dateTime/api-docs", 334 | }, 335 | name: "dateTime", 336 | status: "started", 337 | version: "1.0.0", 338 | services: [ 339 | { 340 | name: "service1", 341 | uri: "http://test:9080/zosConnect/services/service1", 342 | }, 343 | ], 344 | }); 345 | nock("http://test:9080") 346 | .get("/dateTime/api-docs") 347 | .reply(200, {version: 2}); 348 | return localApi.getDocumentation("swagger").should.eventually.equal("{\"version\":2}"); 349 | }); 350 | 351 | it("should fail to get RAML", () => { 352 | return localApi.getDocumentation("RAML").should.be.rejected; 353 | }); 354 | }); 355 | 356 | describe("#getServices", () => { 357 | const localApi = new Api("http://test:9080/zosConnect/apis/dateApi", { }, "dateTime", 358 | "1.0.0", "Date Time API"); 359 | it("should return the list of service names", () => { 360 | nock("http://test:9080") 361 | .get("/zosConnect/apis/dateApi") 362 | .reply(200, { 363 | apiUrl: "http://test:9080/dateTime", 364 | description: "Date Time API", 365 | documentation: { 366 | swagger: "http://test:9080/dateTime/api-docs", 367 | }, 368 | name: "dateTime", 369 | status: "started", 370 | version: "1.0.0", 371 | services: [ 372 | { 373 | name: "service1", 374 | uri: "http://test:9080/zosConnect/services/service1", 375 | }, 376 | ], 377 | }); 378 | return localApi.getServices().should.eventually.have.members(["service1"]); 379 | }); 380 | 381 | it("should return the list of service names without calling the server", () => { 382 | return localApi.getServices().should.eventually.have.members(["service1"]); 383 | }); 384 | }); 385 | }); 386 | -------------------------------------------------------------------------------- /test/ApiRequester.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2015 IBM Corp. All Rights Reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | import * as nock from "nock"; 17 | 18 | import * as chai from "chai"; 19 | import * as chaiAsPromised from "chai-as-promised"; 20 | import { ApiRequester } from "../src/ApiRequester"; 21 | 22 | before(() => { 23 | chai.should(); 24 | chai.use(chaiAsPromised); 25 | }); 26 | 27 | describe("apiRequester", () => { 28 | describe("#start", () => { 29 | const apiRequester = new ApiRequester( 30 | "http://test:9080/zosConnect/apiRequesters/Book_Inventory", 31 | { }, "Book_Inventory", "1.0.0", "API requester for Book_Inventory app", "BookConnref", "Started"); 32 | 33 | it("should start the API Requester", () => { 34 | nock("http://test:9080") 35 | .put("/zosConnect/apiRequesters/Book_Inventory") 36 | .query({ status: "started" }) 37 | .reply(200, { 38 | name: "Book_Inventory", 39 | version: "1.0.0", 40 | description: "API requester for Book_Inventory app", 41 | status: "Started", 42 | connection: "BookConnref", 43 | }); 44 | return apiRequester.start().should.be.fulfilled; 45 | }); 46 | 47 | it("should return not found", () => { 48 | nock("http://test:9080") 49 | .put("/zosConnect/apiRequesters/Book_Inventory") 50 | .query({ status: "started" }) 51 | .reply(404); 52 | return apiRequester.start().should.be.rejectedWith(Error); 53 | }); 54 | 55 | it("should return an error", () => { 56 | nock("http://test:9080") 57 | .put("/zosConnect/apiRequesters/Book_Inventory") 58 | .query({ status: "started" }) 59 | .replyWithError("something fatal happened"); 60 | return apiRequester.start().should.be.rejectedWith("something fatal happened"); 61 | }); 62 | }); 63 | 64 | describe("#stop", () => { 65 | const apiRequester = new ApiRequester( 66 | "http://test:9080/zosConnect/apiRequesters/Book_Inventory", 67 | { }, "Book_Inventory", "1.0.0", "API requester for Book_Inventory app", "BookConnref", "Started"); 68 | 69 | it("should stop the API Requester", () => { 70 | nock("http://test:9080") 71 | .put("/zosConnect/apiRequesters/Book_Inventory") 72 | .query({ status: "stopped" }) 73 | .reply(200, { 74 | name: "Book_Inventory", 75 | version: "1.0.0", 76 | description: "API requester for Book_Inventory app", 77 | status: "Stopped", 78 | connection: "BookConnref", 79 | }); 80 | return apiRequester.stop().should.be.fulfilled; 81 | }); 82 | 83 | it("should return not found", () => { 84 | nock("http://test:9080") 85 | .put("/zosConnect/apiRequesters/Book_Inventory") 86 | .query({ status: "stopped" }) 87 | .reply(404); 88 | apiRequester.stop().should.be.rejectedWith(Error); 89 | }); 90 | 91 | it("should return an error", () => { 92 | nock("http://test:9080") 93 | .put("/zosConnect/apiRequesters/Book_Inventory") 94 | .query({ status: "stopped" }) 95 | .replyWithError("something fatal happened"); 96 | apiRequester.stop().should.be.rejectedWith("something fatal happened"); 97 | }); 98 | }); 99 | 100 | describe("#update", () => { 101 | const apiRequester = new ApiRequester( 102 | "http://test:9080/zosConnect/apiRequesters/Book_Inventory", 103 | { }, "Book_Inventory", "1.0.0", "API requester for Book_Inventory app", "BookConnref", "Started"); 104 | 105 | it("should update the API Requester", () => { 106 | nock("http://test:9080") 107 | .put("/zosConnect/apiRequesters/Book_Inventory") 108 | .query({ status: "stopped" }) 109 | .reply(200, { 110 | name: "Book_Inventory", 111 | version: "1.0.0", 112 | description: "API requester for Book_Inventory app", 113 | status: "Stopped", 114 | connection: "BookConnref", 115 | }); 116 | nock("http://test:9080") 117 | .put("/zosConnect/apiRequesters/Book_Inventory") 118 | .query({ status: "started" }) 119 | .reply(200, { 120 | name: "Book_Inventory", 121 | version: "1.0.0", 122 | description: "API requester for Book_Inventory app", 123 | status: "Started", 124 | connection: "BookConnref", 125 | }); 126 | return apiRequester.update(Buffer.from("foo")).should.be.fulfilled; 127 | }); 128 | 129 | it("should fail to stop the API Requester", () => { 130 | nock("http://test:9080") 131 | .put("/zosConnect/apiRequesters/Book_Inventory") 132 | .query({ status: "stopped" }) 133 | .reply(404); 134 | apiRequester.update(Buffer.from("foo")).should.be.rejectedWith(Error); 135 | }); 136 | 137 | it("should fail to stop the API Requester due to error", () => { 138 | nock("http://test:9080") 139 | .put("/zosConnect/apiRequesters/Book_Inventory") 140 | .query({ status: "stopped" }) 141 | .replyWithError("something fatal happened"); 142 | apiRequester.update(Buffer.from("foo")).should.be.rejectedWith("something fatal happened"); 143 | }); 144 | 145 | it("should fail the update", () => { 146 | nock("http://test:9080") 147 | .put("/zosConnect/apiRequesters/Book_Inventory") 148 | .query({ status: "stopped" }) 149 | .reply(200, { 150 | name: "Book_Inventory", 151 | version: "1.0.0", 152 | description: "API requester for Book_Inventory app", 153 | status: "Stopped", 154 | connection: "BookConnref", 155 | }); 156 | nock("http://test:9080") 157 | .put("/zosConnect/apiRequesters/Book_Inventory") 158 | .query({ status: "started" }) 159 | .reply(404); 160 | apiRequester.update(Buffer.from("foo")).should.be.rejectedWith(Error); 161 | }); 162 | 163 | it("should fail the update due to error", () => { 164 | nock("http://test:9080") 165 | .put("/zosConnect/apiRequesters/Book_Inventory") 166 | .query({ status: "stopped" }) 167 | .reply(200, { 168 | name: "Book_Inventory", 169 | version: "1.0.0", 170 | description: "API requester for Book_Inventory app", 171 | status: "Stopped", 172 | connection: "BookConnref", 173 | }); 174 | nock("http://test:9080") 175 | .put("/zosConnect/apiRequesters/Book_Inventory") 176 | .query({ status: "started" }) 177 | .replyWithError("Something fatal happened"); 178 | apiRequester.update(Buffer.from("foo")).should.be.rejectedWith("Something fatal happened"); 179 | }); 180 | }); 181 | 182 | describe("#delete", () => { 183 | const apiRequester = new ApiRequester( 184 | "http://test:9080/zosConnect/apiRequesters/Book_Inventory", 185 | { }, "Book_Inventory", "1.0.0", "API requester for Book_Inventory app", "BookConnref", "Started"); 186 | 187 | it("should delete the API Requester", () => { 188 | nock("http://test:9080") 189 | .delete("/zosConnect/apiRequesters/Book_Inventory") 190 | .reply(200, { 191 | name: "Book_Inventory", 192 | }); 193 | return apiRequester.delete().should.be.fulfilled; 194 | }); 195 | 196 | it("should fail the delete", () => { 197 | nock("http://test:9080") 198 | .delete("/zosConnect/apiRequesters/Book_Inventory") 199 | .reply(403); 200 | return apiRequester.delete().should.be.rejectedWith(Error); 201 | }); 202 | 203 | it("should fail due to error", () => { 204 | nock("http://test:9080") 205 | .delete("/zosConnect/apiRequesters/Book_Inventory") 206 | .replyWithError("Something fatal happened"); 207 | return apiRequester.delete().should.be.rejectedWith("Something fatal happened"); 208 | }); 209 | }); 210 | 211 | describe("#getName", () => { 212 | const apiRequester = new ApiRequester( 213 | "http://test:9080/zosConnect/apiRequesters/Book_Inventory", 214 | { }, "Book_Inventory", "1.0.0", "API requester for Book_Inventory app", "BookConnref", "Started"); 215 | 216 | it("should return the API Name", () => apiRequester.getName().should.equal("Book_Inventory")); 217 | }); 218 | 219 | describe("#getVersion", () => { 220 | const apiRequester = new ApiRequester( 221 | "http://test:9080/zosConnect/apiRequesters/Book_Inventory", 222 | { }, "Book_Inventory", "1.0.0", "API requester for Book_Inventory app", "BookConnref", "Started"); 223 | 224 | it("should return the API Version", () => apiRequester.getVersion().should.equal("1.0.0")); 225 | }); 226 | 227 | describe("#getDescription", () => { 228 | const apiRequester = new ApiRequester( 229 | "http://test:9080/zosConnect/apiRequesters/Book_Inventory", 230 | { }, "Book_Inventory", "1.0.0", "API requester for Book_Inventory app", "BookConnref", "Started"); 231 | 232 | it("should return the API Description", () => apiRequester.getDescription().should 233 | .equal("API requester for Book_Inventory app")); 234 | }); 235 | 236 | describe("#getConnection", () => { 237 | const apiRequester = new ApiRequester( 238 | "http://test:9080/zosConnect/apiRequesters/Book_Inventory", 239 | { }, "Book_Inventory", "1.0.0", "API requester for Book_Inventory app", "BookConnref", "Started"); 240 | 241 | it("should return the connection ref", () => apiRequester.getConnection().should.equal("BookConnref")); 242 | }); 243 | 244 | describe("#getStatus", () => { 245 | const apiRequester = new ApiRequester( 246 | "http://test:9080/zosConnect/apiRequesters/Book_Inventory", 247 | { }, "Book_Inventory", "1.0.0", "API requester for Book_Inventory app", "BookConnref", "Started"); 248 | 249 | it("should return the API Requester status", () => apiRequester.getStatus().should.equal("Started")); 250 | }); 251 | }); 252 | -------------------------------------------------------------------------------- /test/Service.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2015 IBM Corp. All Rights Reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | import * as nock from "nock"; 18 | 19 | import * as chai from "chai"; 20 | import * as chaiAsPromised from "chai-as-promised"; 21 | import { Service } from "../src/Service"; 22 | 23 | before(() => { 24 | chai.should(); 25 | chai.use(chaiAsPromised); 26 | }); 27 | 28 | describe("service", () => { 29 | const dateTimeService = new Service("http://test:9080/zosConnect/services/dateTimeService", { }, 30 | "dateTimeService", "Get the date and time from the server", "SampleServiceProvider"); 31 | describe("#start", () => { 32 | it("should start the service", () => { 33 | nock("http://test:9080") 34 | .put("/zosConnect/services/dateTimeService") 35 | .query({ status: "started" }) 36 | .reply(200, { 37 | zosConnect: { 38 | dataXformProvider: "DATA_UNAVAILABLE", 39 | serviceDescription: "Get the date and time from the server", 40 | serviceInvokeURL: 41 | "http://192.168.99.100:9080/zosConnect/services/dateTimeService?action=invoke", 42 | serviceName: "dateTimeService", 43 | serviceProvider: "zOSConnect Reference Service Provider", 44 | serviceStatus: "Started", 45 | serviceURL: "http://192.168.99.100:9080/zosConnect/services/dateTimeService", 46 | }, 47 | }); 48 | return dateTimeService.start().should.be.fulfilled; 49 | }); 50 | 51 | it("should return not found", () => { 52 | nock("http://test:9080") 53 | .put("/zosConnect/services/dateTimeService") 54 | .query({ status: "started" }) 55 | .reply(404); 56 | return dateTimeService.start().should.be.rejectedWith(Error); 57 | }); 58 | 59 | it("should return an error", () => { 60 | nock("http://test:9080") 61 | .put("/zosConnect/services/dateTimeService") 62 | .query({ status: "started" }) 63 | .replyWithError("something fatal happened"); 64 | return dateTimeService.start().should.be.rejectedWith("something fatal happened"); 65 | }); 66 | }); 67 | 68 | describe("#stop", () => { 69 | it("should stop the service", () => { 70 | nock("http://test:9080") 71 | .put("/zosConnect/services/dateTimeService") 72 | .query({ status: "stopped" }) 73 | .reply(200, { 74 | zosConnect: { 75 | dataXformProvider: "DATA_UNAVAILABLE", 76 | serviceDescription: "Get the date and time from the server", 77 | serviceInvokeURL: 78 | "http://192.168.99.100:9080/zosConnect/services/dateTimeService?action=invoke", 79 | serviceName: "dateTimeService", 80 | serviceProvider: "zOSConnect Reference Service Provider", 81 | serviceStatus: "Started", 82 | serviceURL: "http://192.168.99.100:9080/zosConnect/services/dateTimeService", 83 | }, 84 | }); 85 | return dateTimeService.stop().should.be.fulfilled; 86 | }); 87 | 88 | it("should return not found", () => { 89 | nock("http://test:9080") 90 | .put("/zosConnect/services/dateTimeService") 91 | .query({ status: "stopped" }) 92 | .reply(404); 93 | return dateTimeService.stop().should.be.rejectedWith(Error); 94 | }); 95 | 96 | it("should return an error", () => { 97 | nock("http://test:9080") 98 | .put("/zosConnect/services/dateTimeService") 99 | .query({ status: "stopped" }) 100 | .replyWithError("something fatal happened"); 101 | return dateTimeService.stop().should.be.rejectedWith("something fatal happened"); 102 | }); 103 | }); 104 | 105 | describe("#update", () => { 106 | it("should update the API", () => { 107 | nock("http://test:9080") 108 | .put("/zosConnect/services/dateTimeService") 109 | .query({ status: "stopped" }) 110 | .reply(200, { 111 | dateTimeService: { 112 | configParm: "", 113 | }, 114 | zosConnect: { 115 | dataXformProvider: "DATA_UNAVAILABLE", 116 | serviceDescription: "Get the date and time from the server", 117 | serviceInvokeURL: 118 | "http://test:9080/zosConnect/services/dateTimeService?action=invoke", 119 | serviceName: "dateTimeService", 120 | serviceProvider: "zOSConnect Reference Service Provider", 121 | serviceURL: "http://test:9080/zosConnect/services/dateTimeService", 122 | serviceStatus: "Stopped", 123 | }, 124 | }); 125 | nock("http://test:9080") 126 | .put("/zosConnect/services/dateTimeService") 127 | .query({ status: "started" }) 128 | .reply(200, { 129 | dateTimeService: { 130 | configParm: "", 131 | }, 132 | zosConnect: { 133 | dataXformProvider: "DATA_UNAVAILABLE", 134 | serviceDescription: "Get the date and time from the server", 135 | serviceInvokeURL: 136 | "http://test:9080/zosConnect/services/dateTimeService?action=invoke", 137 | serviceName: "dateTimeService", 138 | serviceProvider: "zOSConnect Reference Service Provider", 139 | serviceURL: "http://test:9080/zosConnect/services/dateTimeService", 140 | serviceStatus: "Stopped", 141 | }, 142 | }); 143 | return dateTimeService.update(Buffer.from("foo")).should.be.fulfilled; 144 | }); 145 | 146 | it("should fail to stop the API", () => { 147 | nock("http://test:9080") 148 | .put("/zosConnect/services/dateTimeService") 149 | .query({ status: "stopped" }) 150 | .reply(404); 151 | return dateTimeService.update(Buffer.from("foo")).should.be.rejectedWith(Error); 152 | }); 153 | 154 | it("should fail to stop the API due to error", () => { 155 | nock("http://test:9080") 156 | .put("/zosConnect/services/dateTimeService") 157 | .query({ status: "stopped" }) 158 | .replyWithError("something fatal happened"); 159 | return dateTimeService.update(Buffer.from("foo")).should.be.rejectedWith("something fatal happened"); 160 | }); 161 | 162 | it("should fail the update", () => { 163 | nock("http://test:9080") 164 | .put("/zosConnect/services/dateTimeService") 165 | .query({ status: "stopped" }) 166 | .reply(200, { 167 | dateTimeService: { 168 | configParm: "", 169 | }, 170 | zosConnect: { 171 | dataXformProvider: "DATA_UNAVAILABLE", 172 | serviceDescription: "Get the date and time from the server", 173 | serviceInvokeURL: 174 | "http://test:9080/zosConnect/services/dateTimeService?action=invoke", 175 | serviceName: "dateTimeService", 176 | serviceProvider: "zOSConnect Reference Service Provider", 177 | serviceURL: "http://test:9080/zosConnect/services/dateTimeService", 178 | serviceStatus: "Stopped", 179 | }, 180 | }); 181 | nock("http://test:9080") 182 | .put("/zosConnect/services/dateTimeService") 183 | .query({ status: "started" }) 184 | .reply(404); 185 | return dateTimeService.update(Buffer.from("foo")).should.be.rejectedWith(Error); 186 | }); 187 | 188 | it("should fail the update due to error", () => { 189 | nock("http://test:9080") 190 | .put("/zosConnect/services/dateTimeService") 191 | .query({ status: "stopped" }) 192 | .reply(200, { 193 | dateTimeService: { 194 | configParm: "", 195 | }, 196 | zosConnect: { 197 | dataXformProvider: "DATA_UNAVAILABLE", 198 | serviceDescription: "Get the date and time from the server", 199 | serviceInvokeURL: 200 | "http://test:9080/zosConnect/services/dateTimeService?action=invoke", 201 | serviceName: "dateTimeService", 202 | serviceProvider: "zOSConnect Reference Service Provider", 203 | serviceURL: "http://test:9080/zosConnect/services/dateTimeService", 204 | serviceStatus: "Stopped", 205 | }, 206 | }); 207 | nock("http://test:9080") 208 | .put("/zosConnect/services/dateTimeService") 209 | .query({ status: "started" }) 210 | .replyWithError("Something fatal happened"); 211 | return dateTimeService.update(Buffer.from("foo")).should.be.rejectedWith("Something fatal happened"); 212 | }); 213 | }); 214 | 215 | describe("#delete", () => { 216 | it("should delete the service", () => { 217 | nock("http://test:9080") 218 | .delete("/zosConnect/services/dateTimeService") 219 | .reply(200, { 220 | name: "dateTime", 221 | }); 222 | return dateTimeService.delete().should.be.fulfilled; 223 | }); 224 | 225 | it("should fail the delete", () => { 226 | nock("http://test:9080") 227 | .delete("/zosConnect/services/dateTimeService") 228 | .reply(403); 229 | return dateTimeService.delete().should.be.rejectedWith(Error); 230 | }); 231 | 232 | it("should fail due to error", () => { 233 | nock("http://test:9080") 234 | .delete("/zosConnect/services/dateTimeService") 235 | .replyWithError("Something fatal happened"); 236 | return dateTimeService.delete().should.be.rejectedWith("Something fatal happened"); 237 | }); 238 | }); 239 | 240 | describe("getName", () => { 241 | it("should return the service name", () => dateTimeService.getName().should.equal("dateTimeService")); 242 | }); 243 | 244 | describe("getDescription", () => { 245 | it("should return the service description", 246 | () => dateTimeService.getDescription().should.equal("Get the date and time from the server")); 247 | }); 248 | 249 | describe("getServiceProvider", () => { 250 | it("should return the service provider name", 251 | () => dateTimeService.getServiceProvider().should.equal("SampleServiceProvider")); 252 | }); 253 | 254 | describe("#getStatus", () => { 255 | const localService = new Service("http://test:9080/zosConnect/services/dateTimeService", { }, 256 | "dateTimeService", "Get the date and time from the server", "SampleServiceProvider"); 257 | it("should return the status of the service", () => { 258 | nock("http://test:9080") 259 | .get("/zosConnect/services/dateTimeService") 260 | .reply(200, { 261 | dateTimeService: { 262 | configParm: "", 263 | }, 264 | zosConnect: { 265 | dataXformProvider: "DATA_UNAVAILABLE", 266 | serviceDescription: "Get the date and time from the server", 267 | serviceInvokeURL: 268 | "http://test:9080/zosConnect/services/dateTimeService?action=invoke", 269 | serviceName: "dateTimeService", 270 | serviceProvider: "zOSConnect Reference Service Provider", 271 | serviceURL: "http://test:9080/zosConnect/services/dateTimeService", 272 | serviceStatus: "Started", 273 | }, 274 | }); 275 | return localService.getStatus().should.eventually.equal("Started"); 276 | }); 277 | 278 | it("should return the status of the service without calling the server", () => { 279 | return localService.getStatus().should.eventually.equal("Started"); 280 | }); 281 | }); 282 | 283 | describe("#getServiceInvokeUrl", () => { 284 | const localService = new Service("http://test:9080/zosConnect/services/dateTimeService", { }, 285 | "dateTimeService", "Get the date and time from the server", "SampleServiceProvider"); 286 | it("should return the service invoke URL", () => { 287 | nock("http://test:9080") 288 | .get("/zosConnect/services/dateTimeService") 289 | .reply(200, { 290 | dateTimeService: { 291 | configParm: "", 292 | }, 293 | zosConnect: { 294 | dataXformProvider: "DATA_UNAVAILABLE", 295 | serviceDescription: "Get the date and time from the server", 296 | serviceInvokeURL: 297 | "http://test:9080/zosConnect/services/dateTimeService?action=invoke", 298 | serviceName: "dateTimeService", 299 | serviceProvider: "zOSConnect Reference Service Provider", 300 | serviceURL: "http://test:9080/zosConnect/services/dateTimeService", 301 | serviceStatus: "Started", 302 | }, 303 | }); 304 | return localService.getServiceInvokeUrl().should.eventually.equal( 305 | "http://test:9080/zosConnect/services/dateTimeService?action=invoke"); 306 | }); 307 | 308 | it("should return the service invoke URL without calling the server", () => { 309 | return localService.getServiceInvokeUrl().should.eventually.equal( 310 | "http://test:9080/zosConnect/services/dateTimeService?action=invoke"); 311 | }); 312 | }); 313 | }); 314 | -------------------------------------------------------------------------------- /test/ZosConnect.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2015 IBM Corp. All Rights Reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | import * as nock from "nock"; 18 | 19 | import * as chai from "chai"; 20 | import * as chaiAsPromised from "chai-as-promised"; 21 | import { Api } from "../src/Api"; 22 | import { ApiRequester } from "../src/ApiRequester"; 23 | import { Service } from "../src/Service"; 24 | import { ZosConnect } from "../src/ZosConnect"; 25 | 26 | before(() => { 27 | chai.should(); 28 | chai.use(chaiAsPromised); 29 | }); 30 | 31 | describe("zosconnect", () => { 32 | describe("#ctor", () => { 33 | it("should throw an error for no object", 34 | () => { (() => { const zosConnect = new ZosConnect("", null); }).should.Throw(); }); 35 | 36 | it("should throw an error if no uri or url specified", 37 | () => { (() => { const zosConnect = new ZosConnect(null, {}); }).should.Throw(); }); 38 | }); 39 | 40 | describe("#getservices", () => { 41 | it("should return a list of services", () => { 42 | const zosconnect = new ZosConnect("http://test:9080", {rejectUnauthorized: true, auth: "foo:bar"}); 43 | nock("http://test:9080") 44 | .get("/zosConnect/services") 45 | .reply(200, { 46 | zosConnectServices: [ 47 | { 48 | ServiceDescription: "Get the date and time from the server", 49 | ServiceName: "dateTimeService", 50 | ServiceProvider: "zOSConnect Reference Service Provider", 51 | ServiceURL: "http://192.168.99.100:9080/zosConnect/services/dateTimeService", 52 | }, 53 | ], 54 | }); 55 | return zosconnect.getServices().should.eventually.deep.equal( 56 | [new Service("http://test:9080/zosConnect/services/dateTimeService", { https: { rejectUnauthorized: true}, 57 | username: "foo", password: "bar"}, 58 | "dateTimeService", "Get the date and time from the server", "zOSConnect Reference Service Provider")]); 59 | }); 60 | 61 | it("should return an error for a security problem", () => { 62 | const zosconnect = new ZosConnect("http://test:9080", {}); 63 | nock("http://test:9080") 64 | .get("/zosConnect/services") 65 | .reply(403); 66 | return zosconnect.getServices().should.be.rejectedWith("403"); 67 | }); 68 | 69 | it("should return an error", () => { 70 | const zosconnect = new ZosConnect("http://test:9080", {}); 71 | nock("http://test:9080") 72 | .get("/zosConnect/services") 73 | .replyWithError("bad things occurred"); 74 | return zosconnect.getServices().should.be.rejectedWith("bad things occurred"); 75 | }); 76 | }); 77 | 78 | describe("#getservice", () => { 79 | it("should return a service", () => { 80 | const zosconnect = new ZosConnect("http://test:9080", {}); 81 | nock("http://test:9080") 82 | .get("/zosConnect/services/dateTimeService") 83 | .reply(200, { 84 | dateTimeService: { 85 | configParm: "", 86 | }, 87 | zosConnect: { 88 | dataXformProvider: "DATA_UNAVAILABLE", 89 | serviceDescription: "Get the date and time from the server", 90 | serviceInvokeURL: 91 | "http://test:9080/zosConnect/services/dateTimeService?action=invoke", 92 | serviceName: "dateTimeService", 93 | serviceProvider: "zOSConnect Reference Service Provider", 94 | serviceURL: "http://test:9080/zosConnect/services/dateTimeService", 95 | }, 96 | }, 97 | ); 98 | return zosconnect.getService("dateTimeService").should.eventually.be.a("Object"); 99 | }); 100 | 101 | it("should return an error for unknown service", () => { 102 | const zosconnect = new ZosConnect("http://test:9080", {}); 103 | nock("http://test:9080") 104 | .get("/zosConnect/services/unknown") 105 | .reply(404); 106 | return zosconnect.getService("unknown").should.be.rejectedWith("404"); 107 | }); 108 | 109 | it("should return an error for network error", () => { 110 | const zosconnect = new ZosConnect("http://test:9080", {}); 111 | nock("http://test:9080") 112 | .get("/zosConnect/services/dateTimeService") 113 | .replyWithError("something fatal occurred"); 114 | return zosconnect.getService("dateTimeService").should.be 115 | .rejectedWith("something fatal occurred"); 116 | }); 117 | }); 118 | 119 | describe("#getApis", () => { 120 | it("should return a list of APIs", () => { 121 | const zosconnect = new ZosConnect("http://test:9080", {}); 122 | nock("http://test:9080") 123 | .get("/zosConnect/apis") 124 | .reply(200, { 125 | apis: [ 126 | { 127 | adminUrl: "http://test:9080/zosConnect/apis/healthApi", 128 | description: "Health API", 129 | name: "healthApi", 130 | version: "1.0.0", 131 | }, 132 | ], 133 | }); 134 | return zosconnect.getApis().should.eventually.deep.equal([ 135 | new Api("http://test:9080/zosConnect/apis/healthApi", { }, 136 | "healthApi", "1.0.0", "Health API")]); 137 | }); 138 | 139 | it("should return an error for a security problem", () => { 140 | const zosconnect = new ZosConnect("http://test:9080", { }); 141 | nock("http://test:9080") 142 | .get("/zosConnect/apis") 143 | .reply(403); 144 | return zosconnect.getApis().should.be.rejectedWith("403"); 145 | }); 146 | 147 | it("should return an error", () => { 148 | const zosconnect = new ZosConnect("http://test:9080", { }); 149 | nock("http://test:9080") 150 | .get("/zosConnect/apis") 151 | .replyWithError("bad things occurred"); 152 | return zosconnect.getApis().should.be.rejectedWith("bad things occurred"); 153 | }); 154 | }); 155 | 156 | describe("#getApi", () => { 157 | const zosconnect = new ZosConnect("http://test:9080", { }); 158 | it("should return an API", () => { 159 | nock("http://test:9080") 160 | .get("/zosConnect/apis/healthApi") 161 | .reply(200, { 162 | apiUrl: "http://192.168.99.100:9080/health", 163 | description: "Health API", 164 | documentation: { 165 | swagger: "http://192.168.99.100:9080/health/api-docs", 166 | }, 167 | name: "healthApi", 168 | status: "started", 169 | version: "1.0.0", 170 | }); 171 | return zosconnect.getApi("healthApi").should.eventually.be.a("Object"); 172 | }); 173 | 174 | it("should return an error for a security problem", () => { 175 | nock("http://test:9080") 176 | .get("/zosConnect/apis/healthApi") 177 | .reply(403); 178 | zosconnect.getApi("healthApi").should.be.rejectedWith("403"); 179 | }); 180 | 181 | it("should return an error", () => { 182 | nock("http://test:9080") 183 | .get("/zosConnect/apis/healthApi") 184 | .replyWithError("bad things occurred"); 185 | zosconnect.getApi("healthApi").should.be.rejectedWith("bad things occurred"); 186 | }); 187 | }); 188 | 189 | describe("#createApi", () => { 190 | const zosconnect = new ZosConnect("http://test:9080", { }); 191 | it("should install an API", () => { 192 | nock("http://test:9080") 193 | .post("/zosConnect/apis") 194 | .reply(201, { 195 | apiUrl: "http://192.168.99.100:9080/health", 196 | description: "Health API", 197 | documentation: { 198 | swagger: "http://192.168.99.100:9080/health/api-docs", 199 | }, 200 | name: "healthApi", 201 | status: "started", 202 | version: "1.0.0", 203 | }); 204 | return zosconnect.createApi(Buffer.from("foo")).should.eventually.be.a("Object"); 205 | }); 206 | 207 | it("should return an error for a conflict problem", () => { 208 | nock("http://test:9080") 209 | .post("/zosConnect/apis") 210 | .reply(409); 211 | return zosconnect.createApi(Buffer.from("apiPackage")).should.be 212 | .rejectedWith("409"); 213 | }); 214 | 215 | it("should return an error", () => { 216 | nock("http://test:9080") 217 | .post("/zosConnect/apis") 218 | .replyWithError("bad things occurred"); 219 | return zosconnect.createApi(Buffer.from("apiPackage")).should.be.rejectedWith("bad things occurred"); 220 | }); 221 | }); 222 | 223 | describe("#createService", () => { 224 | const zosconnect = new ZosConnect("http://test:9080", { }); 225 | it("should install a Service", () => { 226 | nock("http://test:9080") 227 | .post("/zosConnect/services") 228 | .reply(201, { 229 | dateTimeService: { 230 | configParm: "", 231 | }, 232 | zosConnect: { 233 | dataXformProvider: "DATA_UNAVAILABLE", 234 | serviceDescription: "Get the date and time from the server", 235 | serviceInvokeURL: 236 | "http://test:9080/zosConnect/services/dateTimeService?action=invoke", 237 | serviceName: "dateTimeService", 238 | serviceProvider: "zOSConnect Reference Service Provider", 239 | serviceURL: "http://test:9080/zosConnect/services/dateTimeService", 240 | }, 241 | }); 242 | return zosconnect.createService(Buffer.from("foo")).should.eventually.be.a("Object"); 243 | }); 244 | 245 | it("should return an error for a conflict problem", () => { 246 | nock("http://test:9080") 247 | .post("/zosConnect/services") 248 | .reply(409); 249 | return zosconnect.createService(Buffer.from("sarFile")).should.be 250 | .rejectedWith("409"); 251 | }); 252 | 253 | it("should return an error", () => { 254 | nock("http://test:9080") 255 | .post("/zosConnect/services") 256 | .replyWithError("bad things occurred"); 257 | return zosconnect.createService(Buffer.from("sarFile")).should.be.rejectedWith("bad things occurred"); 258 | }); 259 | }); 260 | 261 | describe("#getApiRequesters", () => { 262 | const zosconnect = new ZosConnect("http://test:9080", { }); 263 | it("should return a list of API Requesters", () => { 264 | nock("http://test:9080") 265 | .get("/zosConnect/apiRequesters") 266 | .reply(200, { 267 | apiRequesters: [ 268 | { 269 | name: "Book_Inventory", 270 | version: "1.0.0", 271 | description: "API requester for Book_Inventory app", 272 | status: "Started", 273 | connectionRef: "BookConnref", 274 | }, 275 | ], 276 | }); 277 | return zosconnect.getApiRequesters().should.eventually.deep.equal([ 278 | new ApiRequester("http://test:9080/zosConnect/apiRequesters/Book_Inventory", { }, 279 | "Book_Inventory", "1.0.0", "API requester for Book_Inventory app", "BookConnref", "Started")]); 280 | }); 281 | 282 | it("should return an error for a security problem", () => { 283 | nock("http://test:9080") 284 | .get("/zosConnect/apiRequesters") 285 | .reply(403); 286 | return zosconnect.getApiRequesters().should.be.rejectedWith("403"); 287 | }); 288 | 289 | it("should return an error", () => { 290 | nock("http://test:9080") 291 | .get("/zosConnect/apiRequesters") 292 | .replyWithError("bad things occurred"); 293 | return zosconnect.getApiRequesters().should.be.rejectedWith("bad things occurred"); 294 | }); 295 | }); 296 | 297 | describe("#getApiRequester", () => { 298 | const zosconnect = new ZosConnect("http://test:9080", { }); 299 | it("should return an API Requester", () => { 300 | nock("http://test:9080") 301 | .get("/zosConnect/apiRequesters/Book_Inventory") 302 | .reply(200, { 303 | name: "Book_Inventory", 304 | version: "1.0.0", 305 | description: "API requester for Book_Inventory app", 306 | status: "Started", 307 | connectionRef: "BookConnref", 308 | }); 309 | return zosconnect.getApiRequester("Book_Inventory").should.eventually.be.a("Object"); 310 | }); 311 | 312 | it("should return an error for a security problem", () => { 313 | nock("http://test:9080") 314 | .get("/zosConnect/apiRequesters/Book_Inventory") 315 | .reply(403); 316 | zosconnect.getApiRequester("Book_Inventory").should.be.rejectedWith("403"); 317 | }); 318 | 319 | it("should return an error", () => { 320 | nock("http://test:9080") 321 | .get("/zosConnect/apiRequesters/Book_Inventory") 322 | .replyWithError("bad things occurred"); 323 | zosconnect.getApiRequester("Book_Inventory").should.be.rejectedWith("bad things occurred"); 324 | }); 325 | }); 326 | 327 | describe("#createApiRequester", () => { 328 | const zosconnect = new ZosConnect("http://test:9080", { }); 329 | it("should install an API Requester", () => { 330 | nock("http://test:9080") 331 | .post("/zosConnect/apiRequesters") 332 | .reply(201, { 333 | name: "Book_Inventory", 334 | version: "1.0.0", 335 | description: "API requester for Book_Inventory app", 336 | status: "Started", 337 | connectionRef: "BookConnref", 338 | }); 339 | return zosconnect.createApiRequester(Buffer.from("foo")).should.eventually.be.a("Object"); 340 | }); 341 | 342 | it("should return an error for a conflict problem", () => { 343 | nock("http://test:9080") 344 | .post("/zosConnect/apiRequesters") 345 | .reply(409); 346 | return zosconnect.createApiRequester(Buffer.from("sarFile")).should.be 347 | .rejectedWith("409"); 348 | }); 349 | 350 | it("should return an error", () => { 351 | nock("http://test:9080") 352 | .post("/zosConnect/apiRequesters") 353 | .replyWithError("bad things occurred"); 354 | return zosconnect.createApiRequester(Buffer.from("sarFile")).should.be.rejectedWith("bad things occurred"); 355 | }); 356 | }); 357 | }); 358 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "module": "commonjs", 4 | "outDir": "./lib", 5 | "target": "es6", 6 | "declaration": true, 7 | "declarationDir": "./lib", 8 | "sourceMap": true 9 | }, 10 | "include": [ 11 | "./src/**/*" 12 | ] 13 | } -------------------------------------------------------------------------------- /tslint.json: -------------------------------------------------------------------------------- 1 | { 2 | "defaultSeverity": "error", 3 | "extends": [ 4 | "tslint:recommended" 5 | ], 6 | "jsRules": {}, 7 | "rules": { 8 | "object-literal-sort-keys":false 9 | }, 10 | "rulesDirectory": [] 11 | } --------------------------------------------------------------------------------