diff --git a/docs/packages/http.md b/docs/packages/http.md index df6e873a..ffb273a2 100644 --- a/docs/packages/http.md +++ b/docs/packages/http.md @@ -217,4 +217,233 @@ With this **keys**: -### Table of Contents +#### Table of Contents + +* [READ_REQUEST](#read_request) +* [EXTERNAL_CONNECTION](#external_connection) + * [Parameters](#parameters) +* [EXTERNAL_OUTPUT](#external_output) + * [Parameters](#parameters-1) +* [PASS_OUTPUT](#pass_output) + * [Parameters](#parameters-2) +* [POST_AND_SAVE_TO_VARIABLE](#post_and_save_to_variable) + * [Parameters](#parameters-3) +* [PARALLEL_GET](#parallel_get) + * [Parameters](#parameters-4) +* [PARALLEL_GET_ARRAY](#parallel_get_array) + * [Parameters](#parameters-5) +* [PARALLEL_POST](#parallel_post) + * [Parameters](#parameters-6) +* [PARALLEL_POST_ARRAY_WITHIN](#parallel_post_array_within) + * [Parameters](#parameters-7) +* [PARALLEL_POST_ARRAY](#parallel_post_array) + * [Parameters](#parameters-8) +* [PARALLEL_POST_ARRAY_DIFFERENT_DATA](#parallel_post_array_different_data) + * [Parameters](#parameters-9) + +### READ_REQUEST + +[packages/http/src/actions.ts:31-31](https://github.com/dyne/restroom-mw/blob/8db4074a7fb710ca3898d2dbf1660f32b07114d4/packages/http/src/actions.ts#L31-L31 "Source code on GitHub") + +`Given I read the http request`

+Read the http_request that is coming form the outside, it will return +a dictionary of the following form: + + { + http_request: { + base_url: '/api/http_request', + headers: { + 'accept-encoding': 'gzip, deflate', + connection: 'close', + 'content-length': '0', + host: '127.0.0.1:44267' + }, + http_version: '1.1', + method: 'POST', + path: '/', + protocol: 'http', + socket: { + local_address: '::ffff:127.0.0.1', + local_port: 44267, + remote_address: '::ffff:127.0.0.1', + remote_family: 'IPv6', + remote_port: 59794 + } + } + } + +Type: [string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String) + +### EXTERNAL_CONNECTION + +[packages/http/src/actions.ts:37-37](https://github.com/dyne/restroom-mw/blob/8db4074a7fb710ca3898d2dbf1660f32b07114d4/packages/http/src/actions.ts#L37-L37 "Source code on GitHub") + +`Given I have a endpoint named 'myEndpoint'`

+Set the endpoint to be used later in the other statements + +Type: [string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String) + +#### Parameters + +* `myEndpoint` **[string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)** Name of the variable containing the url's endpoint or the url's endpoint itself + +### EXTERNAL_OUTPUT + +[packages/http/src/actions.ts:44-44](https://github.com/dyne/restroom-mw/blob/8db4074a7fb710ca3898d2dbf1660f32b07114d4/packages/http/src/actions.ts#L44-L44 "Source code on GitHub") + +`Given I connect to 'myEndpoint' and save the output into 'myResult'`

+Connect to *myEndpoint* and store the result into *myResult* + +Type: [string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String) + +#### Parameters + +* `myEndpoint` **[string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)** Name of the variable containing the url's endpoint or the url's endpoint itself +* `myResult` **[string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)** Name of the varibale where will be store the reuslt + +### PASS_OUTPUT + +[packages/http/src/actions.ts:50-50](https://github.com/dyne/restroom-mw/blob/8db4074a7fb710ca3898d2dbf1660f32b07114d4/packages/http/src/actions.ts#L50-L50 "Source code on GitHub") + +`Then I pass the output to 'myEndpoint'`

+Perform a post to *myEndpoint* with data the zencode output + +Type: [string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String) + +#### Parameters + +* `myEndpoint` **[string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)** Name of the variable containing the url's endpoint or the url's endpoint itself + +### POST_AND_SAVE_TO_VARIABLE + +[packages/http/src/actions.ts:61-61](https://github.com/dyne/restroom-mw/blob/8db4074a7fb710ca3898d2dbf1660f32b07114d4/packages/http/src/actions.ts#L61-L61 "Source code on GitHub") + +`Given I connect to 'myEndpoint' and pass it the content of 'myVariable' and save the output into 'myResult'`

+Perform a post to *myEndpoint* with data contained in *myVariable* and store the result in *myResult* which +will be a dictionary with two entries: + +* **status**: will contain the status code +* **result**: in case of success will contain the result otherwise it is a empty string + +Type: [string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String) + +#### Parameters + +* `myEndpoint` **[string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)** Name of the variable containing the url's endpoint or the url's endpoint itself +* `myVairable` **[string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)** Name of the variable containing the post data +* `myResult` **[string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)** Name of the varibale where will be store the reuslt of the post + +### PARALLEL_GET + +[packages/http/src/actions.ts:72-72](https://github.com/dyne/restroom-mw/blob/8db4074a7fb710ca3898d2dbf1660f32b07114d4/packages/http/src/actions.ts#L72-L72 "Source code on GitHub") + +`Given I execute parallel GET to 'myEndpoint' and save the result named 'myResult' within the object 'myObject'`

+By repeating this statment *n* times it will perform *n* parallel get to *myEndpoint* and store the result in +*myObject.myResult* which will be a dictionary with two entries: + +* **status**: will contain the status code +* **result**: in case of success will contain the result otherwise it is a empty string + +Type: [string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String) + +#### Parameters + +* `myEndpoint` **[string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)** Name of the variable containing the url's endpoint or the url's endpoint itself +* `myResult` **[string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)** Name of the varibale where will be store the reuslt of the get +* `myObject` **[string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)** Name of the varibale where will be store myResult + +### PARALLEL_GET_ARRAY + +[packages/http/src/actions.ts:82-82](https://github.com/dyne/restroom-mw/blob/8db4074a7fb710ca3898d2dbf1660f32b07114d4/packages/http/src/actions.ts#L82-L82 "Source code on GitHub") + +`Given I execute parallel GET to array 'myEndpointArray' and save the result named 'myResult' within the object 'myObject'`

+Perform parallel get to array *myEndpointArray* and store the result in *myObject.myResult* which will be an array of dictionary with two entries: + +* **status**: will contain the status code +* **result**: in case of success will contain the result otherwise it is a empty string + +Type: [string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String) + +#### Parameters + +* `myEndpointArray` **[string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)** Name of the variable containing the array of urls' endpoint +* `myResult` **[string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)** Name of the varibale where will be store the reuslt of the get +* `myObject` **[string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)** Name of the varibale where will be store myResult + +### PARALLEL_POST + +[packages/http/src/actions.ts:94-94](https://github.com/dyne/restroom-mw/blob/8db4074a7fb710ca3898d2dbf1660f32b07114d4/packages/http/src/actions.ts#L94-L94 "Source code on GitHub") + +`Given I execute parallel POST with 'myData' to 'myEndpoint' and save the result named 'myResult' within the object 'myObject'`

+By repeating this statment *n* times it will perform *n* parallel post to *myEndpoint* with data contained in *myData* and store the result in +*myObject.myResult* which will be an array of dictionary with two entries: + +* **status**: will contain the status code +* **result**: in case of success will contain the result otherwise it is a empty string + +Type: [string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String) + +#### Parameters + +* `myData` **[string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)** Name of the variable containing the data of the post +* `myEndpoint` **[string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)** Name of the variable containing the url's endpoint +* `myResult` **[string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)** Name of the varibale where will be store the reuslt of the post +* `myObject` **[string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)** Name of the varibale where will be store myResult + +### PARALLEL_POST_ARRAY_WITHIN + +[packages/http/src/actions.ts:106-106](https://github.com/dyne/restroom-mw/blob/8db4074a7fb710ca3898d2dbf1660f32b07114d4/packages/http/src/actions.ts#L106-L106 "Source code on GitHub") + +`Given I execute parallel POST with 'myData' to array 'myEndpointArray' and save the result named 'myResult' within the object 'myObject'`

+Perform parallel post to array *myEndpointArray* with data contained in *myData* and store the result in +*myObject.myResult* which will be an array of dictionary with two entries: + +* **status**: will contain the status code +* **result**: in case of success will contain the result otherwise it is a empty string + +Type: [string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String) + +#### Parameters + +* `myData` **[string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)** Name of the variable containing the data of the post +* `myEndpointArray` **[string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)** Name of the variable containing the array of urls' endpoint +* `myResult` **[string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)** Name of the varibale where will be store the reuslt of the post +* `myObject` **[string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)** Name of the varibale where will be store myResult + +### PARALLEL_POST_ARRAY + +[packages/http/src/actions.ts:117-117](https://github.com/dyne/restroom-mw/blob/8db4074a7fb710ca3898d2dbf1660f32b07114d4/packages/http/src/actions.ts#L117-L117 "Source code on GitHub") + +`Given I execute parallel POST with 'myData' to array 'myEndpointArray' and save the result named 'myResult'`

+Perform parallel post to array *myEndpointArray* with data contained in *myData* and store the result in +*myResult* which will be an array of dictionary with two entries: + +* **status**: will contain the status code +* **result**: in case of success will contain the result otherwise it is a empty string + +Type: [string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String) + +#### Parameters + +* `myData` **[string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)** Name of the variable containing the data of the post +* `myEndpointArray` **[string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)** Name of the variable containing the array of urls' endpoint +* `myResult` **[string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)** Name of the varibale where will be store the reuslt of the post + +### PARALLEL_POST_ARRAY_DIFFERENT_DATA + +[packages/http/src/actions.ts:128-128](https://github.com/dyne/restroom-mw/blob/8db4074a7fb710ca3898d2dbf1660f32b07114d4/packages/http/src/actions.ts#L128-L128 "Source code on GitHub") + +`Given I execute parallel POST with array 'myDataArray' to array 'myEndpointArray' and save the result named 'myResult'`

+Perform parallel post to array *myEndpointArray* and for the *n-th* endpoint uses the *n-th* entry found in the *myDataArray* as data +and store the result in *myResult* which will be an array of dictionary with two entries: + +* **status**: will contain the status code +* **result**: in case of success will contain the result otherwise it is a empty string + +Type: [string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String) + +#### Parameters + +* `myDataArray` **[string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)** Name of the variable containing the array of data of the post +* `myEndpointArray` **[string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)** Name of the variable containing the array of urls' endpoint +* `myResult` **[string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)** Name of the varibale where will be store the reuslt of the post diff --git a/packages/http/src/actions.ts b/packages/http/src/actions.ts index 66ab774b..00ee7ebb 100644 --- a/packages/http/src/actions.ts +++ b/packages/http/src/actions.ts @@ -1,11 +1,129 @@ -export const READ_REQUEST = "read the http request"; -export const EXTERNAL_CONNECTION = "have a endpoint named {}"; -export const EXTERNAL_OUTPUT = "connect to {} and save the output into {}"; -export const PASS_OUTPUT = "pass the output to {}"; -export const POST_AND_SAVE_TO_VARIABLE = "connect to {} and pass it the content of {} and save the output into {}"; -export const PARALLEL_GET = "execute parallel GET to {} and save the result named {} within the object {}"; -export const PARALLEL_GET_ARRAY = "execute parallel GET to array {} and save the result named {} within the object {}"; -export const PARALLEL_POST = "execute parallel POST with {} to {} and save the result named {} within the object {}"; -export const PARALLEL_POST_ARRAY_WITHIN = "execute parallel POST with {} to array {} and save the result named {} within the object {}"; -export const PARALLEL_POST_ARRAY = "execute parallel POST with {} to array {} and save the result named {}"; - +export enum Action { + /** + * `Given I read the http request`

+ * Read the http_request that is coming form the outside, it will return + * a dictionary of the following form: + * ``` + * { + * http_request: { + * base_url: '/api/http_request', + * headers: { + * 'accept-encoding': 'gzip, deflate', + * connection: 'close', + * 'content-length': '0', + * host: '127.0.0.1:44267' + * }, + * http_version: '1.1', + * method: 'POST', + * path: '/', + * protocol: 'http', + * socket: { + * local_address: '::ffff:127.0.0.1', + * local_port: 44267, + * remote_address: '::ffff:127.0.0.1', + * remote_family: 'IPv6', + * remote_port: 59794 + * } + * } + * } + * ``` + */ + READ_REQUEST = "read the http request", + /** + * `Given I have a endpoint named 'myEndpoint'`

+ * Set the endpoint to be used later in the other statements + * @param {string} myEndpoint - Name of the variable containing the url's endpoint or the url's endpoint itself + */ + EXTERNAL_CONNECTION = "have a endpoint named {}", + /** + * `Given I connect to 'myEndpoint' and save the output into 'myResult'`

+ * Connect to *myEndpoint* and store the result into *myResult* + * @param {string} myEndpoint - Name of the variable containing the url's endpoint or the url's endpoint itself + * @param {string} myResult - Name of the varibale where will be store the reuslt + */ + EXTERNAL_OUTPUT = "connect to {} and save the output into {}", + /** + * `Then I pass the output to 'myEndpoint'`

+ * Perform a post to *myEndpoint* with data the zencode output + * @param {string} myEndpoint - Name of the variable containing the url's endpoint or the url's endpoint itself + */ + PASS_OUTPUT = "pass the output to {}", + /** + * `Given I connect to 'myEndpoint' and pass it the content of 'myVariable' and save the output into 'myResult'`

+ * Perform a post to *myEndpoint* with data contained in *myVariable* and store the result in *myResult* which + * will be a dictionary with two entries: + * * **status**: will contain the status code + * * **result**: in case of success will contain the result otherwise it is a empty string + * @param {string} myEndpoint - Name of the variable containing the url's endpoint or the url's endpoint itself + * @param {string} myVairable - Name of the variable containing the post data + * @param {string} myResult - Name of the varibale where will be store the reuslt of the post + */ + POST_AND_SAVE_TO_VARIABLE = "connect to {} and pass it the content of {} and save the output into {}", + /** + * `Given I execute parallel GET to 'myEndpoint' and save the result named 'myResult' within the object 'myObject'`

+ * By repeating this statment *n* times it will perform *n* parallel get to *myEndpoint* and store the result in + * *myObject.myResult* which will be a dictionary with two entries: + * * **status**: will contain the status code + * * **result**: in case of success will contain the result otherwise it is a empty string + * @param {string} myEndpoint - Name of the variable containing the url's endpoint or the url's endpoint itself + * @param {string} myResult - Name of the varibale where will be store the reuslt of the get + * @param {string} myObject - Name of the varibale where will be store myResult + */ + PARALLEL_GET = "execute parallel GET to {} and save the result named {} within the object {}", + /** + * `Given I execute parallel GET to array 'myEndpointArray' and save the result named 'myResult' within the object 'myObject'`

+ * Perform parallel get to array *myEndpointArray* and store the result in *myObject.myResult* which will be an array of dictionary with two entries: + * * **status**: will contain the status code + * * **result**: in case of success will contain the result otherwise it is a empty string + * @param {string} myEndpointArray - Name of the variable containing the array of urls' endpoint + * @param {string} myResult - Name of the varibale where will be store the reuslt of the get + * @param {string} myObject - Name of the varibale where will be store myResult + */ + PARALLEL_GET_ARRAY = "execute parallel GET to array {} and save the result named {} within the object {}", + /** + * `Given I execute parallel POST with 'myData' to 'myEndpoint' and save the result named 'myResult' within the object 'myObject'`

+ * By repeating this statment *n* times it will perform *n* parallel post to *myEndpoint* with data contained in *myData* and store the result in + * *myObject.myResult* which will be an array of dictionary with two entries: + * * **status**: will contain the status code + * * **result**: in case of success will contain the result otherwise it is a empty string + * @param {string} myData - Name of the variable containing the data of the post + * @param {string} myEndpoint - Name of the variable containing the url's endpoint + * @param {string} myResult - Name of the varibale where will be store the reuslt of the post + * @param {string} myObject - Name of the varibale where will be store myResult + */ + PARALLEL_POST = "execute parallel POST with {} to {} and save the result named {} within the object {}", + /** + * `Given I execute parallel POST with 'myData' to array 'myEndpointArray' and save the result named 'myResult' within the object 'myObject'`

+ * Perform parallel post to array *myEndpointArray* with data contained in *myData* and store the result in + * *myObject.myResult* which will be an array of dictionary with two entries: + * * **status**: will contain the status code + * * **result**: in case of success will contain the result otherwise it is a empty string + * @param {string} myData - Name of the variable containing the data of the post + * @param {string} myEndpointArray - Name of the variable containing the array of urls' endpoint + * @param {string} myResult - Name of the varibale where will be store the reuslt of the post + * @param {string} myObject - Name of the varibale where will be store myResult + */ + PARALLEL_POST_ARRAY_WITHIN = "execute parallel POST with {} to array {} and save the result named {} within the object {}", + /** + * `Given I execute parallel POST with 'myData' to array 'myEndpointArray' and save the result named 'myResult'`

+ * Perform parallel post to array *myEndpointArray* with data contained in *myData* and store the result in + * *myResult* which will be an array of dictionary with two entries: + * * **status**: will contain the status code + * * **result**: in case of success will contain the result otherwise it is a empty string + * @param {string} myData - Name of the variable containing the data of the post + * @param {string} myEndpointArray - Name of the variable containing the array of urls' endpoint + * @param {string} myResult - Name of the varibale where will be store the reuslt of the post + */ + PARALLEL_POST_ARRAY = "execute parallel POST with {} to array {} and save the result named {}", + /** + * `Given I execute parallel POST with array 'myDataArray' to array 'myEndpointArray' and save the result named 'myResult'`

+ * Perform parallel post to array *myEndpointArray* and for the *n-th* endpoint uses the *n-th* entry found in the *myDataArray* as data + * and store the result in *myResult* which will be an array of dictionary with two entries: + * * **status**: will contain the status code + * * **result**: in case of success will contain the result otherwise it is a empty string + * @param {string} myDataArray - Name of the variable containing the array of data of the post + * @param {string} myEndpointArray - Name of the variable containing the array of urls' endpoint + * @param {string} myResult - Name of the varibale where will be store the reuslt of the post + */ + PARALLEL_POST_ARRAY_DIFFERENT_DATA = "execute parallel POST with array {} to array {} and save the result named {}", +} diff --git a/packages/http/src/index.ts b/packages/http/src/index.ts index 457008bf..df0b3b54 100644 --- a/packages/http/src/index.ts +++ b/packages/http/src/index.ts @@ -4,18 +4,7 @@ import { Zencode } from "@restroom-mw/zencode"; import axios from "axios"; import { NextFunction, Request, Response } from "express"; import https from "https"; -import { - READ_REQUEST, - EXTERNAL_CONNECTION, - EXTERNAL_OUTPUT, - PARALLEL_GET, - PARALLEL_GET_ARRAY, - PARALLEL_POST, - PARALLEL_POST_ARRAY_WITHIN, - PARALLEL_POST_ARRAY, - PASS_OUTPUT, - POST_AND_SAVE_TO_VARIABLE, -} from "./actions"; +import { Action } from "./actions"; import { checkEndpointDefined, checkForDuplicates, @@ -40,7 +29,7 @@ export default (req: Request, res: Response, next: NextFunction) => { let { zencode, keys, data } = params; content = rr.combineDataKeys(data, keys); - if (zencode.match(READ_REQUEST)) { + if (zencode.match(Action.READ_REQUEST)) { const httpRequest = { base_url: req.baseUrl, http_version: req.httpVersion, @@ -60,13 +49,13 @@ export default (req: Request, res: Response, next: NextFunction) => { data.http_request = httpRequest; } - if (zencode.match(EXTERNAL_CONNECTION)) { - externalSourceKeys = zencode.paramsOf(EXTERNAL_CONNECTION); + if (zencode.match(Action.EXTERNAL_CONNECTION)) { + externalSourceKeys = zencode.paramsOf(Action.EXTERNAL_CONNECTION); checkForDuplicates(externalSourceKeys); } - if (zencode.match(PARALLEL_GET_ARRAY)) { - for (const [urlsName, i, o] of chunks(zencode.paramsOf(PARALLEL_GET_ARRAY), 3)) { + if (zencode.match(Action.PARALLEL_GET_ARRAY)) { + for (const [urlsName, i, o] of chunks(zencode.paramsOf(Action.PARALLEL_GET_ARRAY), 3)) { const urls = content[urlsName] for(let j = 0; j < urls.length; j++) { parallel_promises.push(axios.get(urls[j], { validateStatus: () => true })); @@ -78,8 +67,8 @@ export default (req: Request, res: Response, next: NextFunction) => { } } - if (zencode.match(PARALLEL_GET)) { - for (const [url, i, o] of chunks(zencode.paramsOf(PARALLEL_GET), 3)) { + if (zencode.match(Action.PARALLEL_GET)) { + for (const [url, i, o] of chunks(zencode.paramsOf(Action.PARALLEL_GET), 3)) { parallel_promises.push(axios.get(content[url], { validateStatus: () => true })); parallel_params.push({ output: o, @@ -88,8 +77,8 @@ export default (req: Request, res: Response, next: NextFunction) => { } } - if (zencode.match(PARALLEL_POST_ARRAY_WITHIN)) { - for (const [d, urlsName, i, o] of chunks(zencode.paramsOf(PARALLEL_POST_ARRAY_WITHIN), 4)) { + if (zencode.match(Action.PARALLEL_POST_ARRAY_WITHIN)) { + for (const [d, urlsName, i, o] of chunks(zencode.paramsOf(Action.PARALLEL_POST_ARRAY_WITHIN), 4)) { const urls = content[urlsName] for(let j = 0; j < urls.length; j++) { parallel_promises.push(axios.post(urls[j], content[d], { validateStatus: () => true })); @@ -101,8 +90,8 @@ export default (req: Request, res: Response, next: NextFunction) => { } } - if (zencode.match(PARALLEL_POST_ARRAY)) { - for (const [d, urlsName, i] of chunks(zencode.paramsOf(PARALLEL_POST_ARRAY), 3)) { + if (zencode.match(Action.PARALLEL_POST_ARRAY)) { + for (const [d, urlsName, i] of chunks(zencode.paramsOf(Action.PARALLEL_POST_ARRAY), 3)) { const urls = content[urlsName] for(let j = 0; j < urls.length; j++) { parallel_promises.push(axios.post(urls[j], content[d], { validateStatus: () => true })) @@ -114,9 +103,23 @@ export default (req: Request, res: Response, next: NextFunction) => { } } - if (zencode.match(PARALLEL_POST)) { + if (zencode.match(Action.PARALLEL_POST_ARRAY_DIFFERENT_DATA)) { + for (const [dataName, urlsName, i] of chunks(zencode.paramsOf(Action.PARALLEL_POST_ARRAY_DIFFERENT_DATA), 3)) { + const urls = content[urlsName]; + const data = content[dataName]; + for(let j = 0; j < urls.length; j++) { + parallel_promises.push(axios.post(urls[j], data[j], { validateStatus: () => true })); + parallel_params.push({ + output: null, + index: [i, j], + }); + } + } + } + + if (zencode.match(Action.PARALLEL_POST)) { for (const [d, url, i, o] of chunks( - zencode.paramsOf(PARALLEL_POST), + zencode.paramsOf(Action.PARALLEL_POST), 4 )) { parallel_promises.push(axios.post(content[url], content[d])); @@ -152,9 +155,9 @@ export default (req: Request, res: Response, next: NextFunction) => { }); } - if (zencode.match(POST_AND_SAVE_TO_VARIABLE)) { + if (zencode.match(Action.POST_AND_SAVE_TO_VARIABLE)) { for (const [url, postData, variable] of chunks( - zencode.paramsOf(POST_AND_SAVE_TO_VARIABLE), + zencode.paramsOf(Action.POST_AND_SAVE_TO_VARIABLE), 3 )) { let error: any = null; @@ -169,8 +172,8 @@ export default (req: Request, res: Response, next: NextFunction) => { } } - if (zencode.match(EXTERNAL_OUTPUT)) { - const allExternalOutputs = zencode.paramsOf(EXTERNAL_OUTPUT); + if (zencode.match(Action.EXTERNAL_OUTPUT)) { + const allExternalOutputs = zencode.paramsOf(Action.EXTERNAL_OUTPUT); checkEndpointDefined(externalSourceKeys); //join the two values in each EXTERNAL_OUTPUT @@ -212,10 +215,10 @@ export default (req: Request, res: Response, next: NextFunction) => { } } - if (zencode.match(PASS_OUTPUT)) { + if (zencode.match(Action.PASS_OUTPUT)) { // run checks ACTION PASS_OUTPUT endpoints have been defined in zencode, keys, or data const allPassOutputs = zencode - .paramsOf(PASS_OUTPUT) + .paramsOf(Action.PASS_OUTPUT) .map((urlKey: string) => { return { urlKey }; }); @@ -226,8 +229,8 @@ export default (req: Request, res: Response, next: NextFunction) => { rr.onSuccess(async (params) => { const { result, zencode } = params; - if (zencode.match(PASS_OUTPUT)) { - const allPassOutputs = zencode.paramsOf(PASS_OUTPUT); + if (zencode.match(Action.PASS_OUTPUT)) { + const allPassOutputs = zencode.paramsOf(Action.PASS_OUTPUT); for (const output of allPassOutputs) { try { const url = content[output]; diff --git a/packages/http/src/utils.ts b/packages/http/src/utils.ts index e253560c..08f7c698 100644 --- a/packages/http/src/utils.ts +++ b/packages/http/src/utils.ts @@ -1,5 +1,5 @@ import { ObjectLiteral } from "@restroom-mw/types"; -import { EXTERNAL_CONNECTION } from "./actions"; +import { Action } from "./actions"; const checkForNestedBoolean = (obj: any) => { function recurse(obj: ObjectLiteral, current: string) { @@ -30,7 +30,7 @@ const runChecks = ( ) => { const contentKeys = Object.keys(content); endpoints.forEach((endpoint: { urlKey: string }) => { - //Check that all endpoints (urlKeys) have been defined using statement EXTERNAL_CONNECTION + //Check that all endpoints (urlKeys) have been defined using statement Action.EXTERNAL_CONNECTION if (externalSourceKeys.includes(endpoint.urlKey) === false) { console.log( "FAILED CHECK: endpoint has not been defined in zencode: " + @@ -38,7 +38,7 @@ const runChecks = ( ); throw new Error(`[HTTP] Endpoint "${endpoint.urlKey}" has not been defined in zencode, please define it with - the following zencode sentence "${EXTERNAL_CONNECTION}"`); + the following zencode sentence "${Action.EXTERNAL_CONNECTION}"`); } // check that all endpoints (urlKeys) are properties in either data or keys @@ -61,7 +61,7 @@ const checkForDuplicates = (externalSourceKeys: string[]) => { if (duplicateFound) { throw new Error(`[HTTP] Found a duplicate. Please ensure there are no duplicates - when defining endpoints in "${EXTERNAL_CONNECTION}"`); + when defining endpoints in "${Action.EXTERNAL_CONNECTION}"`); } } @@ -69,7 +69,7 @@ const checkEndpointDefined = (externalSourceKeys: string[]) => { if (!externalSourceKeys.length) throw new Error(`[HTTP] Endpoints are missing, please define them with the - following zencode sentence "${EXTERNAL_CONNECTION}"`); + following zencode sentence "${Action.EXTERNAL_CONNECTION}"`); } function* chunks(arr: string[], n: number) { diff --git a/packages/http/tests/index.js b/packages/http/tests/index.js index 6fb0742a..53cf0b3c 100644 --- a/packages/http/tests/index.js +++ b/packages/http/tests/index.js @@ -349,6 +349,25 @@ test.skip("Parallel post for arrays", async (t) => { t.is(res.body.allResults.results.length, 3) }); +test("Parallel post with array of data for array of urls", async (t) => { + const app = express(); + app.use(bodyParser.json()); + app.use(http); + app.use("/*", zencode); + + const res = await request(app).post("/http-post-array-different-data"); + t.is(res.status, 200); + t.is(res.body.result.length, 4); + t.is(res.body.result[0].status, 200); + t.is(res.body.result[0].result.output, 'test_1'); + t.is(res.body.result[1].status, 200); + t.is(res.body.result[1].result.output, 'test_2'); + t.is(res.body.result[2].status, 200); + t.is(res.body.result[2].result.output, 'test_3'); + t.is(res.body.result[3].status, 200); + t.is(res.body.result[3].result.output, 'test_4'); +}); + test("Check broken http", async (t) => { const app = express(); app.use(bodyParser.json()); diff --git a/test/http/http-post-array-different-data.keys b/test/http/http-post-array-different-data.keys new file mode 100644 index 00000000..85b940d2 --- /dev/null +++ b/test/http/http-post-array-different-data.keys @@ -0,0 +1,30 @@ +{ + "urls": [ + https://apiroom.net/api/matteocristino/Return_input_as_output, + https://apiroom.net/api/matteocristino/Return_input_as_output, + https://apiroom.net/api/matteocristino/Return_input_as_output, + https://apiroom.net/api/matteocristino/Return_input_as_output + ], + "data": [ + { + "data": { + "input": "test_1" + } + }, + { + "data": { + "input": "test_2" + } + }, + { + "data": { + "input": "test_3" + } + }, + { + "data": { + "input": "test_4" + } + }, + ] +} diff --git a/test/http/http-post-array-different-data.zen b/test/http/http-post-array-different-data.zen new file mode 100644 index 00000000..9856ce72 --- /dev/null +++ b/test/http/http-post-array-different-data.zen @@ -0,0 +1,10 @@ +Rule caller restroom-mw + +# The contract behind the urls is a simple rename API, that is: +# Given I have a 'string' named 'input' +# When I rename 'input' to 'output' +# Then print the 'output' +Given I execute parallel POST with array 'data' to array 'urls' and save the result named 'result' +Given I have a 'string array' named 'result' + +Then print the 'result'