Merge pull request #7 from zowe/extender-scenario

extender-scenario for api
This commit is contained in:
Nakul Manchanda
2020-02-20 00:20:04 -05:00
committed by GitHub
31 changed files with 1040 additions and 1277 deletions

2
.gitignore vendored
View File

@@ -2,4 +2,4 @@ coverage/
node_modules/
.vscode/
output
steps.md
dist

142
README.md
View File

@@ -1,23 +1,14 @@
# sample-node-api
A sample node js api for finding cars and accounts for a dealership,its used here to demonstrate the steps to extend API/ML with your own rest api.
## Manual Installation
## Steps
**Note**
`Only rest api with https support can be deployed behind API/ML, make sure to enable https support in your rest api.
`
**Note**
Replace `/u/zowe/ibmuser/1.0.0/` with your zowe installation folder
Replace `ibmuser@my.mainframe.com` with your username and mainframe-ip
`
This sample express app, has https enabled already.
# Download and transfer project files
## PART I: Download & Build on local
### 1) Clone the repository, install node packages and verify routes locally
@@ -41,103 +32,56 @@ Open your local browser and try accessing
Don't transfer `node_modules` folder, we can do install npm install later on remote server itself to pull down required node packages
```
// on remote - Create placeholder directory for your node app
ssh ibmuser@my.mainframe.com
cd /u/zowe/ibmuser/1.0.0/
mkdir sample-node-api
cd sample-node-api
npm run build
scp -r dist ibmuser@my.mainframe.com:</usr/lpp/extender>/sample-node-api
```
## PART II: Deploy with Zowe on server
### 1) login
```
ssh ibmuser@my.mainframe.com
```
### 2) install dependencies
```
cd </usr/lpp/extender>/sample-node-api
npm install --only=prod
```
```
//on local - use scp to transfer project files
scp data.js ibmuser@my.mainframe.com:/u/zowe/ibmuser/1.0.0/sample-node-api
scp package.json ibmuser@my.mainframe.com:/u/zowe/ibmuser/1.0.0/sample-node-api
scp package-lock.json ibmuser@my.mainframe.com:/u/zowe/ibmuser/1.0.0/sample-node-api
scp sample-node-api.yml ibmuser@my.mainframe.com:/u/zowe/ibmuser/1.0.0/sample-node-api/sample-node-api.yml.1047
### 3) Manage lifecycle of service with core zowe components
scp -r scripts ibmuser@my.mainframe.com:/u/zowe/ibmuser/1.0.0/sample-node-api/scripts
scp -r server ibmuser@my.mainframe.com:/u/zowe/ibmuser/1.0.0/sample-node-api/server
scp -r sslcert ibmuser@my.mainframe.com:/u/zowe/ibmuser/1.0.0/sample-node-api/sslcert
Use property `EXTERNAL_COMPONENT` located in file `$INSTANCE_DIR/instance.env`
Append it with your service lifecycle scripts.
In our sample it is:
```
vi INSTANCE_DIR/instance.env
EXTERNAL_COMPONENTS=</usr/lpp/extender>/sample-node-api/bin
```
We expect following in service folder `start.sh`, `configure.sh` and `validate.sh`.
In our case its bin folder with relevant scripts.
`configure.sh` it adds static definition for sample-node-api to folder ${INSTANCE_DIR}/workspace/api-mediation/api-defs in IBM-850 encoding
`start.sh` starts node app on configured port
`env.sh` its custom script use to configure port for our node app, feel free to use your desired way
# Setup and Register API on host
### 4) Access newly deployed webservice
### 1) Install node packages required by project
```
// on remote
cd /u/zowe/ibmuser/1.0.0/sample-node-api
npm install
```
### 2) Modify startup script permission
Change unix permission of start up shell script `start-sample-node-api.sh`, so `run-zowe.sh` script can start a API
```
// on remote
cd /u/zowe/ibmuser/1.0.0/sample-node-api/scripts
chmod 755 start-sample-node-api.sh
chmod 755 restart-sample-node-api.sh
```
### 3) Register a plugin API/ML layer using yml file
**Note**
Require encoding for `sample-node-api.yml` is `IBM-850`, use `iconv` utility to convert it to correct format
Yaml config file needs to be present in api-defs folder along-with other statically discovered API example jobs.yml, uss.yml etc
```
// on remote
cd /u/zowe/ibmuser/1.0.0/sample-node-api
iconv -t IBM-850 -f IBM-1047 sample-node-api.yml.1047 > sample-node-api.yml
mv sample-node-api.yml ../api-mediation/api-defs/
```
### 4) Modify zowe startup script to include API startup script
Edit `run-zowe.sh` on remote append node app startup script
```
// on remote
cd /u/zowe/ibmuser/1.0.0/scripts/internal/
vi run-zowe.sh
```
Append following start command for sample-node-api, among similar command from another services
```
`dirname $0`/../../sample-node-api/scripts/start-sample-node-api.sh
```
# Run Project
### 1) Restart Zowe
Please see static definition file `sample-node-api.yml`
It configures service endpoint as `sample-node-api` with property `serviceId`
We also provide api gateway base path `api\v1` with property `gatewayUrl` in same file.
**Note**
Replace `ZOWESVR` below with name of your installed zowe instance
from TN3270 terminal
```
# stop/cancel
/c ZOWESVR
# start/restart
/s ZOWESVR
```
Or, we can use zowe helper scripts to restart zowe
```
ssh ibmuser@my.mainframe.com
cd /u/zowe/ibmuser/1.0.0/scripts
./zowe-stop.sh
./zowe-start.sh
```
### 2) Access newly deployed webservice behind api/v1
`https://my.mainframe.com:7554/api/v1/sample-node-api/accounts/`
`https://my.mainframe.com:7554/api/v1/sample-node-api/accounts/1/`
`https://my.mainframe.com:7554/api/v1/sample-node-api/accounts/1/cars/`
In effect, service can be accessed with following url:
`https://{host}:{GATEWAY_PORT}/{gatewayUrl}/{serviceId}/*`
where `GATEWAY_PORT` is configured in $INSTANCE_DIR/instance.env
Verify by accessing following:
`https://my.mainframe.com:7554/api/v1/sample-node-api/accounts/`
`https://my.mainframe.com:7554/api/v1/sample-node-api/accounts/1/`
`https://my.mainframe.com:7554/api/v1/sample-node-api/accounts/1/cars/`

63
bin/configure-2.sh Normal file
View File

@@ -0,0 +1,63 @@
#!/bin/sh
################################################################################
# This program and the accompanying materials are made available under the terms of the
# Eclipse Public License v2.0 which accompanies this distribution, and is available at
# https://www.eclipse.org/legal/epl-v20.html
#
# SPDX-License-Identifier: EPL-2.0
#
# Copyright IBM Corporation 2020
################################################################################
# Variables required on shell:
# STATIC_DEF_CONFIG_DIR=${INSTANCE_DIR}/workspace/api-mediation/api-defs
# ZOWE_EXPLORER_HOST
# MY_API_NAME
# MY_API_PORT
echo 'sample-node-api configure begin'
echo "LAUNCH_COMPONENT: ${LAUNCH_COMPONENT} "
COMPONENT_DIR=$(dirname "${LAUNCH_COMPONENT}")
echo "COMPONENT_DIR: ${COMPONENT_DIR}"
echo 'load sample-node-api config'
# load config from env
. ${COMPONENT_DIR}/bin/env.sh
echo 'make sample-node-api.ebcidic.yml with replaced env variable'
# Add static definition for sample-node-api
cat <<EOF >${STATIC_DEF_CONFIG_DIR}/${MY_API_NAME}.ebcidic.yml
#
services:
- serviceId: ${MY_API_NAME}
title: ${MY_API_NAME}
description: Example ${MY_API_NAME} Application
catalogUiTileId: ${MY_API_NAME}
instanceBaseUrls:
- https://${ZOWE_EXPLORER_HOST}:${MY_API_PORT}/
homePageRelativeUrl: # Home page is at the same URL
routedServices:
- gatewayUrl: api/v1 # [api/ui/ws]/v{majorVersion}
serviceRelativeUrl:
apiInfo:
- apiId: com.ibm.${MY_API_NAME}
gatewayUrl: api/v1
version: 0.0.1
catalogUiTiles:
${MY_API_NAME}:
title: ${MY_API_NAME}
description: Example ${MY_API_NAME} Application
EOF
echo 'change sample-node-api.ebcidic.yml encoding from ibm-1047 to ibm-850'
# basically this yml file is only thing we need to do register our service with apiml
iconv -f IBM-1047 -t IBM-850 ${STATIC_DEF_CONFIG_DIR}/${MY_API_NAME}.ebcidic.yml > $STATIC_DEF_CONFIG_DIR/${MY_API_NAME}.yml
rm ${STATIC_DEF_CONFIG_DIR}/${MY_API_NAME}.ebcidic.yml
chmod 770 $STATIC_DEF_CONFIG_DIR/${MY_API_NAME}.yml
echo 'sample-node-api configure done'

42
bin/configure.sh Normal file
View File

@@ -0,0 +1,42 @@
#!/bin/sh
################################################################################
# This program and the accompanying materials are made available under the terms of the
# Eclipse Public License v2.0 which accompanies this distribution, and is available at
# https://www.eclipse.org/legal/epl-v20.html
#
# SPDX-License-Identifier: EPL-2.0
#
# Copyright IBM Corporation 2020
################################################################################
# Variables required on shell:
# STATIC_DEF_CONFIG_DIR=${INSTANCE_DIR}/workspace/api-mediation/api-defs
# ZOWE_EXPLORER_HOST
# MY_API_NAME
# MY_API_PORT
echo 'sample-node-api configure begin'
echo "LAUNCH_COMPONENT: ${LAUNCH_COMPONENT} "
COMPONENT_DIR=$(dirname "${LAUNCH_COMPONENT}")
echo "COMPONENT_DIR: ${COMPONENT_DIR}"
# load config from env
echo 'load sample-node-api config'
. ${COMPONENT_DIR}/bin/env.sh
echo 'Add static definition for sample-node-api'
#configure based on env.sh
sed -e "s/mymainframe.ibm.com/${ZOWE_EXPLORER_HOST}/g" \
-e "s/18000/${MY_API_PORT}/g" \
${COMPONENT_DIR}/${MY_API_NAME}.yml \
> ${STATIC_DEF_CONFIG_DIR}/${MY_API_NAME}.ebcidic.yml
echo 'change sample-node-api.ebcidic.yml encoding from ibm-1047 to ibm-850'
# basically this yml file is only thing we need to do register our service with apiml
iconv -f IBM-1047 -t IBM-850 ${STATIC_DEF_CONFIG_DIR}/${MY_API_NAME}.ebcidic.yml > $STATIC_DEF_CONFIG_DIR/${MY_API_NAME}.yml
rm ${STATIC_DEF_CONFIG_DIR}/${MY_API_NAME}.ebcidic.yml
chmod 770 $STATIC_DEF_CONFIG_DIR/${MY_API_NAME}.yml
echo 'sample-node-api configure done'

2
bin/env.sh Normal file
View File

@@ -0,0 +1,2 @@
MY_API_NAME='sample-node-api'
MY_API_PORT='18000'

42
bin/start.sh Normal file
View File

@@ -0,0 +1,42 @@
#!/bin/sh
################################################################################
# This program and the accompanying materials are made available under the terms of the
# Eclipse Public License v2.0 which accompanies this distribution, and is available at
# https://www.eclipse.org/legal/epl-v20.html
#
# SPDX-License-Identifier: EPL-2.0
#
# Copyright IBM Corporation 2020
################################################################################
# Variables required on shell:
# NODE_HOME
# MY_API_NAME
# MY_API_PORT
# KEYSTORE_KEY
# KEYSTORE_CERTIFICATE
echo 'sample-node-api start begin'
# find node bin
NODE_BIN=${NODE_HOME}/bin/node
echo "LAUNCH_COMPONENT: ${LAUNCH_COMPONENT} "
COMPONENT_DIR=$(dirname "${LAUNCH_COMPONENT}")
echo "COMPONENT_DIR: ${COMPONENT_DIR}"
# load config from env
echo 'load sample-node-api config'
. ${COMPONENT_DIR}/bin/env.sh
echo "start sample-node-api app on port ${MY_API_PORT}"
#start component
$NODE_BIN $COMPONENT_DIR/server/app.js \
--service ${MY_API_NAME} \
--port ${MY_API_PORT} \
--key ${KEYSTORE_KEY} \
--cert ${KEYSTORE_CERTIFICATE} \
-v &
echo 'sample-node-api start done'

1563
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@@ -5,19 +5,19 @@
"main": "index.js",
"scripts": {
"start": "node server/app.js",
"test": "istanbul cover ./node_modules/cucumber/bin/cucumber-js -- test/features/*feature --require test/support/ --report cobertura --report html --tags \"not @leave\""
"build": "npm run clean && cp -r server dist/server && cp -r bin dist/bin && cp *.yml dist && cp *.json dist && cp *.js dist && rimraf dist/package-lock.json",
"clean": "rimraf dist && mkdirp dist"
},
"author": "",
"license": "EPL-2.0",
"dependencies": {
"assert": "^1.4.1",
"cors": "^2.8.5",
"cucumber": "^5.1.0",
"express": "^4.16.4",
"istanbul": "^0.4.5",
"supertest": "^3.4.2"
"yargs": "^8.0.2"
},
"devDependencies": {
"node-fetch": "^2.3.0"
"mkdirp": "^1.0.3",
"node-fetch": "^2.3.0",
"rimraf": "^3.0.2"
}
}

View File

@@ -1,40 +0,0 @@
#!/bin/sh
# pre-req
# 1. sample-node-api root should be directly under zowe installation directory eg /u/zowe/ibmuser/1.0.1/sample-node-api/
# 2. register-sample-api.sh make this executable chmod 755
echo 'register sample api'
zowe_base_path = '/u/zowe/ibmuser/1.0.1'
api_defs_path = "$zowe_base_path/api-mediation/api-defs"
run_zowe_path = "$zowe_base_path/scripts/internal/run-zowe.sh"
if [ -d $api_defs_path ]
then
echo "Error: Unable to locate $api_defs_path folder"
exit(1)
fi
if [ -f $run_zowe_path ]
then
echo "Error: Unable to locate $run_zowe_path script"
exit(1)
fi
echo 'making scripts start/restart script executable'
chmod 755 start-sample-node-api.sh
chmod 755 restart-sample-node-api.sh
echo 'change yaml file from 1047 to 850 format'
iconv -t IBM-850 -f IBM-1047 sample-node-api.yml > sample-node-api.yml.850
echo 'move yaml file to api-defs folder'
mv sample-node-api.yml.850 ${api_defs_path}/sample-node-api.yml
echo 'appending sample api startup script to run-zowe.sh'
if ! grep -q 'start-sample-node-api.sh' "$file_path"; then
`dirname $0`/../../sample-node-api/scripts/start-sample-node-api.sh >> $run_zowe_path
fi
echo 'done'

View File

@@ -1,8 +0,0 @@
#!/bin/sh
echo 'restarting sample node api...'
# ps -elf | awk '/node/ && /app.js/ && !/sh -c/' | awk '{print $2}' | xargs kill -9 $1
ps -elf | awk '/node/ && /app.js/ && !/sh -c/' | awk '{print $3}' | xargs kill -9 $1
./start-sample-node-api.sh
sleep 30
echo 'restart sample node api done'

View File

@@ -1,25 +0,0 @@
#!/bin/sh
# find node bin
# export NODE_HOME=/usr/lpp/IBM/cnj/IBM/node-v6.14.4-os390-s390x
# export NODE_HOME=/Z23B/usr/lpp/IBM/cnj/IBM/node-v6.14.4-os390-s390x
# export NODE_HOME=/u/nodejs/node-v6.16.0-os390-s390x
echo 'starting sample node api...'
if [ ! -z "$NODE_HOME" ]; then
NODE_BIN=${NODE_HOME}/bin/node
NPM_CLI=${NODE_HOME}/lib/node_modules/npm/bin/npm-cli.js
else
echo "Error: cannot find node bin, node app did not start"
exit 1
fi
# get current script directory
SCRIPT_DIR=$(dirname "$0")
# get to new node app source directory
cd "$SCRIPT_DIR/.."
# start service
$NODE_BIN server/app.js &
echo 'starting sample node api done'

View File

@@ -1,5 +0,0 @@
#!/bin/sh
echo 'stopping sample node api...'
ps -elf | awk '/node/ && /app.js/ && !/sh -c/' | awk '{print $2}' | xargs kill -9 $1
echo 'stop sample node api done'

View File

@@ -1,4 +0,0 @@
const fetch = require('node-fetch');
fetch('https://mymainframe.ibm.com:18000/accounts', { method: 'GET' })
.then(res => res.json()) // expecting a json response
.then(json => console.log(json));

View File

@@ -1,32 +1,142 @@
/*
This program and the accompanying materials are
made available under the terms of the Eclipse Public License v2.0 which accompanies
this distribution, and is available at https://www.eclipse.org/legal/epl-v20.html
SPDX-License-Identifier: EPL-2.0
Copyright IBM Corporation 2020
*/
const express = require('express');
const http = require('http');
const https = require('https');
const fs = require('fs');
const path = require("path");
const cors = require('cors')
const { HTTPS_PORT } = require('./config.json');
function buildConfig(argv) {
const config = {
'port': argv.port /*|| port*/,
'https': {
'key': argv.key /*|| key*/,
'cert': argv.cert /*|| cert*/,
'pfx': argv.pfx,
'passphrase': argv.pass,
}
};
return config;
}
function loadCertificateFiles(config) {
// load https certs file content
if (config && config.https) {
['key', 'cert', 'pfx'].forEach(key => {
if (config.https[key]) {
let file = config.https[key];
config.https[key] = fs.readFileSync(file);
}
});
}
return config;
};
function validateParams (argv) {
let isValid = true;
const serviceFor=argv.s;
if((argv.p==='' || !argv.p) && isValid) {
isValid = false;
process.stderr.write(`[${serviceFor}] port configuration is missing\n`);
}
if( (argv.k==='' && argv.c==='' && argv.x==='' && argv.w==='') && isValid) {
isValid = false;
process.stderr.write(`[${serviceFor}] https configuration is missing\n`);
}
if( ( (argv.k==='' && argv.c>'') || (argv.k>'' && argv.c==='')
|| (argv.x==='' && argv.w>'' && argv.k==='' && argv.c==='')
|| (argv.x==='' && argv.w>'' && !(argv.k>'' && argv.c>''))
|| (argv.x>'' && argv.w==='') ) && isValid) {
isValid = false;
process.stderr.write(`[${serviceFor}] https configuration is missing\n`);
}
if(!isValid) {
process.stderr.write(`[${serviceFor}] is failed to start, error:\n`);
process.exit(1);
return false;
}
return true;
}
var argv = require('yargs')
.usage('Usage: $0 [options]')
.option('s', {
alias: 'service',
description: 'service-for path',
default: ''
})
.option('p', {
alias: 'port',
description: 'listening port'
})
.option('k', {
alias: 'key',
default: '',
description: 'server key'
})
.option('c', {
alias: 'cert',
default: '',
description: 'server cert',
})
.option('x', {
alias: 'pfx',
default: '',
description: 'server pfx',
})
.option('w', {
alias: 'pass',
default: '',
description: 'server pfx passphrase',
})
.option('v', {
alias: 'verbose',
default: false,
description: 'show request logs',
type: 'boolean'
})
.help('h')
.alias('h', 'help')
.check(validateParams)
.argv;
let config = buildConfig(argv);
config = loadCertificateFiles(config);
const {https:{key, cert}} = config;
const credentials = { key, cert };
const privateKey = fs.readFileSync(path.resolve(__dirname, "../sslcert/server.key"), 'utf8');
const certificate = fs.readFileSync(path.resolve(__dirname, "../sslcert/server.cert"), 'utf8');
const credentials = { key: privateKey, cert: certificate };
const app = express();
//TODO: use for whitelist only
app.use(cors());
const routes = require('./routes/index.route');
const cli = require('./cli/index.route');
app.get('/', (req, res) => res.send('Hello World!'));
app.use(routes);
app.use('/cli', cli);
// const httpServer = http.createServer(app);
const httpsServer = https.createServer(credentials, app);
// httpServer.listen(HTTP_PORT);
httpsServer.listen(HTTPS_PORT);
console.log(`server listening at port ${HTTPS_PORT}`);
httpsServer.listen(config.port);
console.log(`server listening at port ${config.port}`);
module.exports = { app };

View File

@@ -1,15 +0,0 @@
const express = require('express');
const router = express.Router({ mergeParams: true });
const accountsController = require('../controllers/accounts.controller');
const accountsCarsRoute = require('./accountsCars.route');
router.route('/')
.get(accountsController.getAll);
router.route('/:_id')
.get(accountsController.get);
router.use('/:Account_id', accountsCarsRoute);
module.exports = router;

View File

@@ -1,12 +0,0 @@
const express = require('express');
const router = express.Router({ mergeParams: true });
const accountsCarsController = require('../controllers/accountsCars.controller');
router.route('/cars')
.get(accountsCarsController.getAll);
router.route('/cars/:_id')
.get(accountsCarsController.get);
module.exports = router;

View File

@@ -1,12 +0,0 @@
const express = require('express');
const router = express.Router({ mergeParams: true });
const carsController = require('../controllers/cars.controller');
router.route('/')
.get(carsController.getAll);
router.route('/:_id')
.get(carsController.get);
module.exports = router;

View File

@@ -1,10 +0,0 @@
const express = require('express');
const cars = require('./cars.route');
const accounts = require('./accounts.route');
const router = express.Router();
router.use('/cars', cars);
router.use('/accounts', accounts);
module.exports = router;

View File

@@ -1,3 +1,7 @@
{
"HTTPS_PORT": 18000
"port": "18000",
"https": {
"key": "../sslcert/server.key",
"cert": "../sslcert/server.cert"
}
}

View File

@@ -1,3 +1,13 @@
/*
This program and the accompanying materials are
made available under the terms of the Eclipse Public License v2.0 which accompanies
this distribution, and is available at https://www.eclipse.org/legal/epl-v20.html
SPDX-License-Identifier: EPL-2.0
Copyright IBM Corporation 2020
*/
const accountsService = require('../services/accounts.service');
const get = function(req, res){

View File

@@ -1,3 +1,13 @@
/*
This program and the accompanying materials are
made available under the terms of the Eclipse Public License v2.0 which accompanies
this distribution, and is available at https://www.eclipse.org/legal/epl-v20.html
SPDX-License-Identifier: EPL-2.0
Copyright IBM Corporation 2020
*/
const accountsCarsService = require('../services/accountsCars.service');
const get = function(req, res){

View File

@@ -1,3 +1,13 @@
/*
This program and the accompanying materials are
made available under the terms of the Eclipse Public License v2.0 which accompanies
this distribution, and is available at https://www.eclipse.org/legal/epl-v20.html
SPDX-License-Identifier: EPL-2.0
Copyright IBM Corporation 2020
*/
const carsService = require('../services/cars.service');
const get = function(req, res){

View File

@@ -1,3 +1,13 @@
/*
This program and the accompanying materials are
made available under the terms of the Eclipse Public License v2.0 which accompanies
this distribution, and is available at https://www.eclipse.org/legal/epl-v20.html
SPDX-License-Identifier: EPL-2.0
Copyright IBM Corporation 2020
*/
const express = require('express');
const router = express.Router({ mergeParams: true });

View File

@@ -1,9 +1,19 @@
/*
This program and the accompanying materials are
made available under the terms of the Eclipse Public License v2.0 which accompanies
this distribution, and is available at https://www.eclipse.org/legal/epl-v20.html
SPDX-License-Identifier: EPL-2.0
Copyright IBM Corporation 2020
*/
const express = require('express');
const router = express.Router({ mergeParams: true });
const accountsCarsController = require('../controllers/accountsCars.controller');
/*
// Add missing feature
// un-comment this to implement two new routes
// accounts/:id/cars & accounts/:id/cars/:id2
@@ -13,6 +23,6 @@ router.route('/cars')
router.route('/cars/:_id')
.get(accountsCarsController.get);
*/
module.exports = router;

View File

@@ -1,3 +1,13 @@
/*
This program and the accompanying materials are
made available under the terms of the Eclipse Public License v2.0 which accompanies
this distribution, and is available at https://www.eclipse.org/legal/epl-v20.html
SPDX-License-Identifier: EPL-2.0
Copyright IBM Corporation 2020
*/
const express = require('express');
const router = express.Router({ mergeParams: true });

View File

@@ -1,3 +1,13 @@
/*
This program and the accompanying materials are
made available under the terms of the Eclipse Public License v2.0 which accompanies
this distribution, and is available at https://www.eclipse.org/legal/epl-v20.html
SPDX-License-Identifier: EPL-2.0
Copyright IBM Corporation 2020
*/
const express = require('express');
const cars = require('./cars.route');
const accounts = require('./accounts.route');

View File

@@ -1,3 +1,13 @@
/*
This program and the accompanying materials are
made available under the terms of the Eclipse Public License v2.0 which accompanies
this distribution, and is available at https://www.eclipse.org/legal/epl-v20.html
SPDX-License-Identifier: EPL-2.0
Copyright IBM Corporation 2020
*/
const data = require('../../data');
const get = function(_id){

View File

@@ -1,3 +1,13 @@
/*
This program and the accompanying materials are
made available under the terms of the Eclipse Public License v2.0 which accompanies
this distribution, and is available at https://www.eclipse.org/legal/epl-v20.html
SPDX-License-Identifier: EPL-2.0
Copyright IBM Corporation 2020
*/
const data = require('../../data');
const carsService = require('./cars.service');

View File

@@ -1,3 +1,13 @@
/*
This program and the accompanying materials are
made available under the terms of the Eclipse Public License v2.0 which accompanies
this distribution, and is available at https://www.eclipse.org/legal/epl-v20.html
SPDX-License-Identifier: EPL-2.0
Copyright IBM Corporation 2020
*/
const data = require('../../data');
const get = function(_id){

View File

@@ -1,61 +0,0 @@
@1
Feature: initial REST feature
As a <role>
I can <do something>
So that <I can get some value>
Scenario: connect
When I GET the endpoint "/"
Then I should get a 200 with body
"""
Hello World!
"""
Scenario: get cars
When I GET the endpoint "/cars"
Then I should get a 200 with body
"""
[{"_id":0,"Name":"chevrolet chevelle malibu","Miles_per_Gallon":18,"Cylinders":8,"Displacement":307,"Horsepower":130,"Weight_in_lbs":3504,"Acceleration":12,"Year":"1970-01-01","Origin":"USA"},{"_id":1,"Name":"buick skylark 320","Miles_per_Gallon":15,"Cylinders":8,"Displacement":350,"Horsepower":165,"Weight_in_lbs":3693,"Acceleration":11.5,"Year":"1970-01-01","Origin":"USA"},{"_id":2,"Name":"plymouth satellite","Miles_per_Gallon":18,"Cylinders":8,"Displacement":318,"Horsepower":150,"Weight_in_lbs":3436,"Acceleration":11,"Year":"1970-01-01","Origin":"USA"},{"_id":3,"Name":"amc rebel sst","Miles_per_Gallon":16,"Cylinders":8,"Displacement":304,"Horsepower":150,"Weight_in_lbs":3433,"Acceleration":12,"Year":"1970-01-01","Origin":"USA"},{"_id":4,"Name":"ford torino","Miles_per_Gallon":17,"Cylinders":8,"Displacement":302,"Horsepower":140,"Weight_in_lbs":3449,"Acceleration":10.5,"Year":"1970-01-01","Origin":"USA"},{"_id":5,"Name":"ford galaxie 500","Miles_per_Gallon":15,"Cylinders":8,"Displacement":429,"Horsepower":198,"Weight_in_lbs":4341,"Acceleration":10,"Year":"1970-01-01","Origin":"USA"},{"_id":6,"Name":"chevrolet impala","Miles_per_Gallon":14,"Cylinders":8,"Displacement":454,"Horsepower":220,"Weight_in_lbs":4354,"Acceleration":9,"Year":"1970-01-01","Origin":"USA"},{"_id":7,"Name":"plymouth fury iii","Miles_per_Gallon":14,"Cylinders":8,"Displacement":440,"Horsepower":215,"Weight_in_lbs":4312,"Acceleration":8.5,"Year":"1970-01-01","Origin":"USA"},{"_id":8,"Name":"pontiac catalina","Miles_per_Gallon":14,"Cylinders":8,"Displacement":455,"Horsepower":225,"Weight_in_lbs":4425,"Acceleration":10,"Year":"1970-01-01","Origin":"USA"},{"_id":9,"Name":"amc ambassador dpl","Miles_per_Gallon":15,"Cylinders":8,"Displacement":390,"Horsepower":190,"Weight_in_lbs":3850,"Acceleration":8.5,"Year":"1970-01-01","Origin":"USA"}]
"""
Scenario: get car
When I GET the endpoint "/cars/0"
Then I should get a 200 with body
"""
{"_id":0,"Name":"chevrolet chevelle malibu","Miles_per_Gallon":18,"Cylinders":8,"Displacement":307,"Horsepower":130,"Weight_in_lbs":3504,"Acceleration":12,"Year":"1970-01-01","Origin":"USA"}
"""
Scenario: get accounts
When I GET the endpoint "/accounts"
Then I should get a 200 with body
"""
[{"_id":"0","name":{"first":"Deidre","last":"Hayes"},"email":"deidre.hayes@undefined.me","phone":"+1 (839) 577-3100","address":"507 Church Avenue, Heil, Wyoming, 1754"},{"_id":"1","name":{"first":"Maldonado","last":"Sellers"},"email":"maldonado.sellers@undefined.biz","phone":"+1 (834) 573-2841","address":"286 Hewes Street, Abiquiu, Maine, 2447"},{"_id":"2","name":{"first":"Elvia","last":"Aguilar"},"email":"elvia.aguilar@undefined.io","phone":"+1 (826) 486-2932","address":"457 Buffalo Avenue, Caberfae, Connecticut, 2648"},{"_id":"3","name":{"first":"Chris","last":"Mullins"},"email":"chris.mullins@undefined.org","phone":"+1 (884) 425-2397","address":"642 Vandalia Avenue, Driftwood, California, 213"},{"_id":"4","name":{"first":"Vargas","last":"Oneal"},"email":"vargas.oneal@undefined.info","phone":"+1 (893) 576-3106","address":"413 Bedford Avenue, Bynum, Federated States Of Micronesia, 1793"}]
"""
Scenario: get account
When I GET the endpoint "/accounts/0"
Then I should get a 200 with body
"""
{"_id":"0","name":{"first":"Deidre","last":"Hayes"},"email":"deidre.hayes@undefined.me","phone":"+1 (839) 577-3100","address":"507 Church Avenue, Heil, Wyoming, 1754"}
"""
Scenario: get cars with account
When I GET the endpoint "/accounts/0/cars"
Then I should get a 200 with body
"""
[{"_id":0,"Name":"chevrolet chevelle malibu","Miles_per_Gallon":18,"Cylinders":8,"Displacement":307,"Horsepower":130,"Weight_in_lbs":3504,"Acceleration":12,"Year":"1970-01-01","Origin":"USA"},{"_id":1,"Name":"buick skylark 320","Miles_per_Gallon":15,"Cylinders":8,"Displacement":350,"Horsepower":165,"Weight_in_lbs":3693,"Acceleration":11.5,"Year":"1970-01-01","Origin":"USA"}]
"""
Scenario: get cars with account
When I GET the endpoint "/accounts/0/cars"
Then I should get a 200 with body
"""
[{"_id":0,"Name":"chevrolet chevelle malibu","Miles_per_Gallon":18,"Cylinders":8,"Displacement":307,"Horsepower":130,"Weight_in_lbs":3504,"Acceleration":12,"Year":"1970-01-01","Origin":"USA"},{"_id":1,"Name":"buick skylark 320","Miles_per_Gallon":15,"Cylinders":8,"Displacement":350,"Horsepower":165,"Weight_in_lbs":3693,"Acceleration":11.5,"Year":"1970-01-01","Origin":"USA"}]
"""
Scenario: get account
When I GET the endpoint "/accounts/0/cars/0"
Then I should get a 200 with body
"""
{"_id":0,"Name":"chevrolet chevelle malibu","Miles_per_Gallon":18,"Cylinders":8,"Displacement":307,"Horsepower":130,"Weight_in_lbs":3504,"Acceleration":12,"Year":"1970-01-01","Origin":"USA"}
"""

View File

@@ -1,21 +0,0 @@
const { When, Then } = require("cucumber")
const assert = require("assert")
const request = require("supertest");
const app = require(process.cwd() + "/server/app").app;
When('I GET the endpoint {string}', function (path) {
this.request = request(app).get(path);
});
Then('I should get a {int} with body', function (status, body, done) {
this.request.expect(status).expect(body).end(done);
});
Then('I should get the message', function (message) {
if (this.response + "" !== message) {
console.log("EXPECTED", message)
console.log("ACTUAL", this.response + "")
}
assert(this.response + "" == message);
});