From 68ef03e944bdc3e681ef59c5ebeace60dd409e60 Mon Sep 17 00:00:00 2001 From: Ritchie Date: Thu, 5 Dec 2013 17:42:06 -0800 Subject: [PATCH 1/9] SLA-725 support PORT and HOST environment for PaaS support --- lib/application.js | 19 ++++++++++++++ test/app.test.js | 62 ++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 81 insertions(+) diff --git a/lib/application.js b/lib/application.js index 347004db..51896c9a 100644 --- a/lib/application.js +++ b/lib/application.js @@ -231,6 +231,25 @@ app.boot = function(options) { assertIsValidConfig('model', modelConfig); assertIsValidConfig('data source', dataSourceConfig); + appConfig.host = + process.env.npm_config_host || + process.env.OPENSHIFT_SLS_IP || + process.env.OPENSHIFT_NODEJS_IP || + process.env.HOST || + appConfig.host || + process.env.npm_package_config_host || + app.get('host'); + + appConfig.port = + process.env.npm_config_port || + process.env.OPENSHIFT_SLS_PORT || + process.env.OPENSHIFT_NODEJS_PORT || + process.env.PORT || + appConfig.port || + process.env.npm_package_config_port || + app.get('port') || + 3000; + if(appConfig.host !== undefined) { assert(typeof appConfig.host === 'string', 'app.host must be a string'); app.set('host', appConfig.host); diff --git a/test/app.test.js b/test/app.test.js index bf47ff30..3787503a 100644 --- a/test/app.test.js +++ b/test/app.test.js @@ -77,6 +77,68 @@ describe('app', function() { assert.equal(this.app.get('host'), '127.0.0.1'); }); + describe('PaaS and npm env variables', function() { + beforeEach(function() { + this.boot = function () { + var app = loopback(); + app.boot({ + app: { + port: undefined, + host: undefined + } + }); + return app; + } + }); + + it('should be honored', function() { + var assertHonored = function (portKey, hostKey) { + process.env[hostKey] = randomPort(); + process.env[portKey] = randomHost(); + var app = this.boot(); + assert.equal(app.get('port'), process.env[portKey]); + assert.equal(app.get('host'), process.env[hostKey]); + delete process.env[portKey]; + delete process.env[hostKey]; + }.bind(this); + + assertHonored('OPENSHIFT_SLS_PORT', 'OPENSHIFT_NODEJS_IP'); + assertHonored('npm_config_port', 'npm_config_host'); + assertHonored('npm_package_config_port', 'npm_package_config_host'); + assertHonored('OPENSHIFT_SLS_PORT', 'OPENSHIFT_SLS_IP'); + assertHonored('PORT', 'HOST'); + }); + + it('should be honored in order', function() { + process.env.npm_config_host = randomHost(); + process.env.OPENSHIFT_SLS_IP = randomHost(); + process.env.OPENSHIFT_NODEJS_IP = randomHost(); + process.env.HOST = randomHost(); + process.env.npm_package_config_host = randomHost(); + + var app = this.boot(); + assert.equal(app.get('host'), process.env.npm_config_host); + + process.env.npm_config_port = randomPort(); + process.env.OPENSHIFT_SLS_PORT = randomPort(); + process.env.OPENSHIFT_NODEJS_PORT = randomPort(); + process.env.PORT = randomPort(); + process.env.npm_package_config_port = randomPort(); + + var app = this.boot(); + assert.equal(app.get('host'), process.env.npm_config_host); + assert.equal(app.get('port'), process.env.npm_config_port); + }); + + function randomHost() { + return Math.random().toString().split('.')[1]; + } + + function randomPort() { + return Math.floor(Math.random() * 10000); + } + }); + it('Instantiate models', function () { assert(app.models); assert(app.models.FooBarBatBaz); From 6c1029b164eb77ddb7da7e99646bd055d936b42b Mon Sep 17 00:00:00 2001 From: Miroslav Bajtos Date: Fri, 6 Dec 2013 16:40:10 +0100 Subject: [PATCH 2/9] docs: describe http mapping of arguments --- docs/api-model-remote.md | 57 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 57 insertions(+) diff --git a/docs/api-model-remote.md b/docs/api-model-remote.md index d45171a2..e93998e8 100644 --- a/docs/api-model-remote.md +++ b/docs/api-model-remote.md @@ -44,6 +44,12 @@ The arguments description defines either a single argument as an object or an or * arg: argument name * type: argument datatype; must be a[loopback type](http://wiki.strongloop.com/display/DOC/LoopBack+types). * required: Boolean value indicating if argument is required. + * root: For callback arguments: set this property to true if your function + has a single callback argument that should be used as the root object + returned to remote caller. Otherwise a map (argument-name to argument-value) + is returned. + * http: For input arguments: a function or an object describing mapping from HTTP request + to the argument value, as explained below. For example, a single argument, specified as an object: @@ -60,6 +66,57 @@ Multiple arguments, specified as an array: ] ``` + +**HTTP mapping of input arguments** + +There are two ways how to specify HTTP mapping for input parameters (what the +method accepts). + +The first way is to provide an object with a `source` property, that can have +one of these values: + +| source | description | +|---|---| +| body | The whole request body is used as the value. | +| form | The value is looked up using `req.param`, which searches route arguments, the request body and the query string.| +| query | An alias for form (see above). | +| path | An alias for form (see above). | +| req | The whole HTTP reqest object is used as the value. | + +For example, an argument getting the whole request body as the value: + +```js +{ arg: 'data', type: 'object', http: { source: 'body' } } +``` + +The second way is to specify your custom mapping function: + +```js +{ + arg: 'custom', + type: 'number', + http: function(ctx) { + // ctx is LoopBack Context object + + // 1. Get the HTTP request object as provided by Express + var req = ctx.req; + + // 2. Get 'a' and 'b' from query string or form data + // and return their sum as the value + return +req.param('a') + req.param('b'); + } +} +``` + +When there is no mapping specified, LoopBack will look up the value +using the following algorithm (assuming `name` as the name of the input +parameter to resolve): + + 1. If there is a HTTP request parameter `args` with a JSON content, + then its content is parsed and the value of `args['name']` is used + if it is defined. + 2. Otherwise `req.param('name')` is returned. + ## Remote hooks Run a function before or after a remote method is called by a client. From f8fe17b22922ac7c5298fa0f4f8962c69ca465ea Mon Sep 17 00:00:00 2001 From: Rand McKinney Date: Fri, 6 Dec 2013 10:06:22 -0800 Subject: [PATCH 3/9] Minor formatting and wording fixes. --- docs/api-model-remote.md | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/docs/api-model-remote.md b/docs/api-model-remote.md index e93998e8..69f91aa4 100644 --- a/docs/api-model-remote.md +++ b/docs/api-model-remote.md @@ -42,12 +42,11 @@ The options argument is a JSON object, described in the following table. The arguments description defines either a single argument as an object or an ordered set of arguments as an array. Each individual argument has keys for: * arg: argument name - * type: argument datatype; must be a[loopback type](http://wiki.strongloop.com/display/DOC/LoopBack+types). + * type: argument datatype; must be a [loopback type](http://wiki.strongloop.com/display/DOC/LoopBack+types). * required: Boolean value indicating if argument is required. - * root: For callback arguments: set this property to true if your function - has a single callback argument that should be used as the root object - returned to remote caller. Otherwise a map (argument-name to argument-value) - is returned. + * root: For callback arguments: set this property to `true` if your function + has a single callback argument to use as the root object + returned to remote caller. Otherwise the root object returned is a map (argument-name to argument-value). * http: For input arguments: a function or an object describing mapping from HTTP request to the argument value, as explained below. @@ -69,13 +68,14 @@ Multiple arguments, specified as an array: **HTTP mapping of input arguments** -There are two ways how to specify HTTP mapping for input parameters (what the -method accepts). +There are two ways to specify HTTP mapping for input parameters (what the method accepts): +* Provide an object with a `source` property +* Specify a custom mapping function -The first way is to provide an object with a `source` property, that can have -one of these values: +To use the first way to specify HTTP mapping for input parameters, provide an object with a `source` property +that has one of the values shown in the following table. -| source | description | +| Value of source property | Description | |---|---| | body | The whole request body is used as the value. | | form | The value is looked up using `req.param`, which searches route arguments, the request body and the query string.| @@ -89,7 +89,8 @@ For example, an argument getting the whole request body as the value: { arg: 'data', type: 'object', http: { source: 'body' } } ``` -The second way is to specify your custom mapping function: +The use the second way to specify HTTP mapping for input parameters, specify a custom mapping function +that looks like this: ```js { @@ -108,13 +109,12 @@ The second way is to specify your custom mapping function: } ``` -When there is no mapping specified, LoopBack will look up the value +If you don't specify a mapping, LoopBack will look up the value using the following algorithm (assuming `name` as the name of the input parameter to resolve): 1. If there is a HTTP request parameter `args` with a JSON content, - then its content is parsed and the value of `args['name']` is used - if it is defined. + then the value of `args['name']` is used if it is defined. 2. Otherwise `req.param('name')` is returned. ## Remote hooks From 9b42878d51339385cd8e414e90b61efdac6a6a4a Mon Sep 17 00:00:00 2001 From: Rand McKinney Date: Fri, 6 Dec 2013 10:10:28 -0800 Subject: [PATCH 4/9] Small fix to link text --- docs/api-model-remote.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/api-model-remote.md b/docs/api-model-remote.md index 69f91aa4..f1af8a67 100644 --- a/docs/api-model-remote.md +++ b/docs/api-model-remote.md @@ -32,8 +32,8 @@ The options argument is a JSON object, described in the following table. | Option | Required? | Description | | ----- | ----- | ----- | -| accepts | No | Describes the remote method's arguments, as explained below. The callback is an assumed argument; do not specify. | -| returns | No | Describes the remote method's callback arguments, as explained below.. The err argument is assumed; do not specify. | +| accepts | No | Describes the remote method's arguments; See Argument description. The `callback` argument is assumed; do not specify. | +| returns | No | Describes the remote method's callback arguments; See Argument description. The `err` argument is assumed; do not specify. | | http | No | HTTP routing information:
  • **http.path**: path (relative to the model) at which the method is exposed. May be a path fragment (for example, `/:myArg`) that will be populated by an arg of the same name in the `accepts` description. For example, the `stats` method above will be at the whole path `/products/stats`.
  • **http.verb**: HTTP method (verb) from which the method is available (one of: get, post, put, del, or all).
From 52026fc55c19fc5bf7e19e34a9736ccbd8e80d68 Mon Sep 17 00:00:00 2001 From: Rand McKinney Date: Fri, 6 Dec 2013 10:18:31 -0800 Subject: [PATCH 5/9] Fix list format and minor wording fix. --- docs/api-model-remote.md | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/docs/api-model-remote.md b/docs/api-model-remote.md index f1af8a67..d1bf56a0 100644 --- a/docs/api-model-remote.md +++ b/docs/api-model-remote.md @@ -69,8 +69,8 @@ Multiple arguments, specified as an array: **HTTP mapping of input arguments** There are two ways to specify HTTP mapping for input parameters (what the method accepts): -* Provide an object with a `source` property -* Specify a custom mapping function + * Provide an object with a `source` property + * Specify a custom mapping function To use the first way to specify HTTP mapping for input parameters, provide an object with a `source` property that has one of the values shown in the following table. @@ -109,9 +109,8 @@ that looks like this: } ``` -If you don't specify a mapping, LoopBack will look up the value -using the following algorithm (assuming `name` as the name of the input -parameter to resolve): +If you don't specify a mapping, LoopBack will determine the value +as follows (assuming `name` as the name of the input parameter to resolve): 1. If there is a HTTP request parameter `args` with a JSON content, then the value of `args['name']` is used if it is defined. From 0a269b83c54967bb2a63643b7f9cc8c1147e6b02 Mon Sep 17 00:00:00 2001 From: Rand McKinney Date: Fri, 6 Dec 2013 10:20:34 -0800 Subject: [PATCH 6/9] Add blank line before list so it lays out properly. --- docs/api-model-remote.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/api-model-remote.md b/docs/api-model-remote.md index d1bf56a0..ae1255b1 100644 --- a/docs/api-model-remote.md +++ b/docs/api-model-remote.md @@ -69,6 +69,7 @@ Multiple arguments, specified as an array: **HTTP mapping of input arguments** There are two ways to specify HTTP mapping for input parameters (what the method accepts): + * Provide an object with a `source` property * Specify a custom mapping function From 8300ba6c0895c2573c0ac4d767a5f955d95d91ff Mon Sep 17 00:00:00 2001 From: Raymond Feng Date: Fri, 6 Dec 2013 10:24:29 -0800 Subject: [PATCH 7/9] Make loopback-datasource-juggler a peer dep --- package.json | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/package.json b/package.json index e3200f1e..780662be 100644 --- a/package.json +++ b/package.json @@ -16,7 +16,6 @@ "dependencies": { "debug": "~0.7.2", "express": "~3.4.0", - "loopback-datasource-juggler": "~1.2.0", "strong-remoting": "~1.1.0", "inflection": "~1.2.5", "passport": "~0.1.17", @@ -29,7 +28,11 @@ "uid2": "0.0.3", "async": "~0.2.9" }, + "peerDependencies": { + "loopback-datasource-juggler": "~1.2.0" + }, "devDependencies": { + "loopback-datasource-juggler": "~1.2.0", "mocha": "~1.14.0", "strong-task-emitter": "0.0.x", "supertest": "~0.8.1" From fb149e63a0d884dd75d953772f2f3aa5a8e5690c Mon Sep 17 00:00:00 2001 From: Raymond Feng Date: Fri, 6 Dec 2013 10:41:59 -0800 Subject: [PATCH 8/9] Bump version --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 780662be..d58b2876 100644 --- a/package.json +++ b/package.json @@ -9,7 +9,7 @@ "Platform", "mBaaS" ], - "version": "1.3.1", + "version": "1.3.2", "scripts": { "test": "mocha -R spec" }, From 2e9d34af370176c6028d8baeafd241dfe4e03ee0 Mon Sep 17 00:00:00 2001 From: Raymond Feng Date: Fri, 6 Dec 2013 10:47:08 -0800 Subject: [PATCH 9/9] Bump version --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index d58b2876..f6853850 100644 --- a/package.json +++ b/package.json @@ -9,7 +9,7 @@ "Platform", "mBaaS" ], - "version": "1.3.2", + "version": "1.3.3", "scripts": { "test": "mocha -R spec" },