diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
new file mode 100644
index 0000000..f978251
--- /dev/null
+++ b/CONTRIBUTING.md
@@ -0,0 +1,151 @@
+### Contributing ###
+
+Thank you for your interest in `loopback`, an open source project
+administered by StrongLoop.
+
+Contributing to `loopback` is easy. In a few simple steps:
+
+ * Ensure that your effort is aligned with the project's roadmap by
+ talking to the maintainers, especially if you are going to spend a
+ lot of time on it.
+
+ * Make something better or fix a bug.
+
+ * Adhere to code style outlined in the [Google C++ Style Guide][] and
+ [Google Javascript Style Guide][].
+
+ * Sign the [Contributor License Agreement](https://cla.strongloop.com/agreements/strongloop/loopback)
+
+ * Submit a pull request through Github.
+
+
+### Contributor License Agreement ###
+
+```
+ Individual Contributor License Agreement
+
+ By signing this Individual Contributor License Agreement
+ ("Agreement"), and making a Contribution (as defined below) to
+ StrongLoop, Inc. ("StrongLoop"), You (as defined below) accept and
+ agree to the following terms and conditions for Your present and
+ future Contributions submitted to StrongLoop. Except for the license
+ granted in this Agreement to StrongLoop and recipients of software
+ distributed by StrongLoop, You reserve all right, title, and interest
+ in and to Your Contributions.
+
+ 1. Definitions
+
+ "You" or "Your" shall mean the copyright owner or the individual
+ authorized by the copyright owner that is entering into this
+ Agreement with StrongLoop.
+
+ "Contribution" shall mean any original work of authorship,
+ including any modifications or additions to an existing work, that
+ is intentionally submitted by You to StrongLoop for inclusion in,
+ or documentation of, any of the products owned or managed by
+ StrongLoop ("Work"). For purposes of this definition, "submitted"
+ means any form of electronic, verbal, or written communication
+ sent to StrongLoop or its representatives, including but not
+ limited to communication or electronic mailing lists, source code
+ control systems, and issue tracking systems that are managed by,
+ or on behalf of, StrongLoop for the purpose of discussing and
+ improving the Work, but excluding communication that is
+ conspicuously marked or otherwise designated in writing by You as
+ "Not a Contribution."
+
+ 2. You Grant a Copyright License to StrongLoop
+
+ Subject to the terms and conditions of this Agreement, You hereby
+ grant to StrongLoop and recipients of software distributed by
+ StrongLoop, a perpetual, worldwide, non-exclusive, no-charge,
+ royalty-free, irrevocable copyright license to reproduce, prepare
+ derivative works of, publicly display, publicly perform,
+ sublicense, and distribute Your Contributions and such derivative
+ works under any license and without any restrictions.
+
+ 3. You Grant a Patent License to StrongLoop
+
+ Subject to the terms and conditions of this Agreement, You hereby
+ grant to StrongLoop and to recipients of software distributed by
+ StrongLoop a perpetual, worldwide, non-exclusive, no-charge,
+ royalty-free, irrevocable (except as stated in this Section)
+ patent license to make, have made, use, offer to sell, sell,
+ import, and otherwise transfer the Work under any license and
+ without any restrictions. The patent license You grant to
+ StrongLoop under this Section applies only to those patent claims
+ licensable by You that are necessarily infringed by Your
+ Contributions(s) alone or by combination of Your Contributions(s)
+ with the Work to which such Contribution(s) was submitted. If any
+ entity institutes a patent litigation against You or any other
+ entity (including a cross-claim or counterclaim in a lawsuit)
+ alleging that Your Contribution, or the Work to which You have
+ contributed, constitutes direct or contributory patent
+ infringement, any patent licenses granted to that entity under
+ this Agreement for that Contribution or Work shall terminate as
+ of the date such litigation is filed.
+
+ 4. You Have the Right to Grant Licenses to StrongLoop
+
+ You represent that You are legally entitled to grant the licenses
+ in this Agreement.
+
+ If Your employer(s) has rights to intellectual property that You
+ create, You represent that You have received permission to make
+ the Contributions on behalf of that employer, that Your employer
+ has waived such rights for Your Contributions, or that Your
+ employer has executed a separate Corporate Contributor License
+ Agreement with StrongLoop.
+
+ 5. The Contributions Are Your Original Work
+
+ You represent that each of Your Contributions are Your original
+ works of authorship (see Section 8 (Submissions on Behalf of
+ Others) for submission on behalf of others). You represent that to
+ Your knowledge, no other person claims, or has the right to claim,
+ any right in any intellectual property right related to Your
+ Contributions.
+
+ You also represent that You are not legally obligated, whether by
+ entering into an agreement or otherwise, in any way that conflicts
+ with the terms of this Agreement.
+
+ You represent that Your Contribution submissions include complete
+ details of any third-party license or other restriction (including,
+ but not limited to, related patents and trademarks) of which You
+ are personally aware and which are associated with any part of
+ Your Contributions.
+
+ 6. You Don't Have an Obligation to Provide Support for Your Contributions
+
+ You are not expected to provide support for Your Contributions,
+ except to the extent You desire to provide support. You may provide
+ support for free, for a fee, or not at all.
+
+ 6. No Warranties or Conditions
+
+ StrongLoop acknowledges that unless required by applicable law or
+ agreed to in writing, You provide Your Contributions on an "AS IS"
+ BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, EITHER
+ EXPRESS OR IMPLIED, INCLUDING, WITHOUT LIMITATION, ANY WARRANTIES
+ OR CONDITIONS OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY, OR
+ FITNESS FOR A PARTICULAR PURPOSE.
+
+ 7. Submission on Behalf of Others
+
+ If You wish to submit work that is not Your original creation, You
+ may submit it to StrongLoop separately from any Contribution,
+ identifying the complete details of its source and of any license
+ or other restriction (including, but not limited to, related
+ patents, trademarks, and license agreements) of which You are
+ personally aware, and conspicuously marking the work as
+ "Submitted on Behalf of a Third-Party: [named here]".
+
+ 8. Agree to Notify of Change of Circumstances
+
+ You agree to notify StrongLoop of any facts or circumstances of
+ which You become aware that would make these representations
+ inaccurate in any respect. Email us at callback@strongloop.com.
+```
+
+[Google C++ Style Guide]: https://google-styleguide.googlecode.com/svn/trunk/cppguide.xml
+[Google Javascript Style Guide]: https://google-styleguide.googlecode.com/svn/trunk/javascriptguide.xml
diff --git a/LICENSE.md b/LICENSE.md
new file mode 100644
index 0000000..29d7815
--- /dev/null
+++ b/LICENSE.md
@@ -0,0 +1,9 @@
+Copyright (c) 2013-2015 StrongLoop, Inc and other contributors.
+
+loopback uses a dual license model.
+
+You may use this library under the terms of the [MIT License][],
+or under the terms of the [StrongLoop Subscription Agreement][].
+
+[MIT License]: http://opensource.org/licenses/MIT
+[StrongLoop Subscription Agreement]: http://strongloop.com/license
diff --git a/README.md b/README.md
index 0b7ff14..ae3896d 100644
--- a/README.md
+++ b/README.md
@@ -1,12 +1,217 @@
-# loopback-example-connector
+# loopback-example-connector (SOAP)
-LoopBack connector examples.
+The SOAP connector enables LoopBack applications to interact with
+[SOAP](http://www.w3.org/TR/soap)-based web services described using
+[WSDL](http://www.w3.org/TR/wsdl). This example app illustrates calling a [periodic table SOAP web service](http://www.webservicex.net/periodictable.asmx) from a LoopBack app,
+where you define a remote method to call each SOAP web service operation.
+This is a simple example of a LoopBack app "proxying" or intermediating a web service.
-## Getting started
+For more information, see the
+SOAP connector documentation.
-Switch to a branch to view the corresponding connector example in the table
-below:
+## Installation
-Connector|Branch
-:--|:--
-SOAP|
+Clone this repo and install dependencies from npm:
+
+
+```shell
+$ git clone https://github.com/strongloop-community/loopback-example-connector.git -b soap
+$ cd loopback-example-connector
+$ npm install
+```
+
+## Run the example
+
+1. In the project root directory, run the app by entering this command:
+ ```
+ node .
+ ```
+
+ You'll see this in the console:
+ ```
+ Web server listening at: http://0.0.0.0:3000
+ Browse your REST API at http://0.0.0.0:3000/explorer
+ ```
+
+2. Open [API Explorer](http://0.0.0.0:3000/explorer) in your web browser.
+3. Under the **periodicTable** model, you'll see two endpoints: `GET /periodicTables/GetAtomicNumber` and `GET /periodicTables/GetAtomicWeight`.
+4. Click on `GetAtomicNumber` and in the **elementName** parameter field, enter the name of an element, for example, "Gold" or "Oxygen". In the **Response Body** field, you'll see an XML response from the web service that looks something like this (NOTE: line feeds have been added in the example below for readability, but in practice the response will be on a single line):
+
+ ```
+ {
+ "GetAtomicNumberResult": "\r\n \r\n
+ 26\r\n
+ Iron\r\n
+ Fe\r\n
+ 55.847\r\n
+ 3300\r\n
+ 7.9\r\n
+ 1.6400000000000001\r\n
+ 1.17\r\n
+ 1808\r\n
+ 7874\r\n
\r\n"
+ }
+ ```
+
+### Additional example code
+
+The app includes two other files `periodictable-ws.js` and `stock-ws.js` that illustrate other ways of programmatically calling a SOAP web service. NOTE: the [stock quote web service](http://www.webservicex.net/stockquote.asmx) may not be consistently available.
+
+## Recreate the app
+
+**Prerequisites**: If you haven't already done so, follow the [Installation instructions](http://loopback.io/doc/en/lb3/Installation.html) for the LoopBack CLI. In a nutshell:
+```
+$ npm install -g loopback-cli
+```
+
+To create this app yourself, follow the steps in this section:
+- [Scaffold the app](#scaffold-the-app)
+- [Create a SOAP data source](#create-a-soap-data-source)
+- [Create a periodicTable model](#create-a-periodictable-model)
+- [Add remote methods](#add-remote-methods)
+- [Try it out!](#try-it-out)
+
+### Scaffold the app
+
+Scaffold a new application. Enter this command:
+
+```
+$ lb app
+```
+
+When prompted, respond as follows:
+1. `What's the name of your application?`
+
Give the app any name you wish, for example "my-soap-demo".
+The tool will create a directory with that name (`my-soap-demo`).
+1. `Enter name of the directory to contain the project:`
+
Press Enter to accept the default (directory has the same name as the app).
+1. `Which version of LoopBack would you like to use?`
+
Choose `3.x (current)`
+1. `What kind of application do you have in mind?`
+
Choose `empty-server (An empty LoopBack API, without any configured models or datasources) `
+
+The tool will then scaffold the app and install all the dependencies from npm.
+
+### Create a SOAP data source
+
+Go into the app root directory:
+```
+$ cd my-soap-demo
+```
+
+Use the [data source generator](http://loopback.io/doc/en/lb3/Data-source-generator.html) to add a SOAP data source to your application. Enter this command:
+
+```shell
+$ lb datasource
+```
+
+When prompted, respond as follows:
+
+1. `Enter the datasource name:`
+
Enter "soapDS".
+1. ` Select the connector for soapDS:`
+
Use your arrow key to scroll down to `SOAP webservices (supported by StrongLoop)` and press Enter.
+1. `URL to the SOAP web service endpoint:`
+
Copy and paste the URL of the periodic table web service:
+ ```
+ http://www.webservicex.net/periodictable.asmx
+ ```
+1. `HTTP URL or local file system path to the WSDL file:`
+
Copy and paste this URL of the periodic table web service WSDL:
+ ```
+ http://www.webservicex.net/periodictable.asmx?WSDL
+ ```
+1. `Expose operations as REST APIs: (Y/n)`
+
Press Enter to accept the default (yes).
+1. `Maps WSDL binding operations to Node.js methods:`
+
Copy and paste the stringified JSON below. The JSON defines the service, port, and operation for each operation that will be called in the SOAP service.
+ ```
+ {"getAtomicWeight":{"service":"periodictable","port":"periodictableSoap","operation":"GetAtomicWeight"},"getAtomicNumber":{"service":"periodictable","port":"periodictableSoap","operation":"GetAtomicNumber"}}
+ ```
+ NOTE: The JSON you enter must **not** have any line endings, that is, it must be on a single line.
+1. `Install loopback-connector-soap@^3.0`
+
Press Enter to install the connector from npm.
+
+The data source generator then creates an entry for the data source in the `server/datasources.json` file and installs all the necessary dependencies.
+
+### Create a periodicTable model
+
+Use the [model generator](http://loopback.io/doc/en/lb3/Model-generator.html) to add a model to represent the periodic Table web service. Enter this command:
+
+```shell
+$ lb model
+```
+
+When prompted, respond as follows:
+
+1. `Enter the model name:`
Enter "periodicTable".
+1. `Enter the model name: periodicTable`
Select `soapDS` that you previously created.
+1. `Select model's base class` Select `Model`.
+1. `Expose periodicTable via the REST API? (Y/n)`
Press Enter to accept the default (yes).
+1. `Custom plural form (used to build REST URL):`
Press Enter for no custom plural.
+1. `Common model or server only?`
Select `server` because this will be a server-only model.
+1. `Property name:`
Press Enter when first prompted, because this model will not have any properties.
+
+The tool will create two files in the `server` directory: `periodicTable.json` and `periodicTable.js`.
+
+### Add remote methods
+
+Edit `server/models/periodic-table.js` and add the code shown below to the stubbed-out function.
+
+This code defines two functions, `Periodictable.getAtomicnumber` and `Periodictable.getAtomicweight` and adds them as remote methods to the `Periodictable` model, as described in [Remote methods](https://loopback.io/doc/en/lb3/Remote-methods.html).
+
+```javascript
+'use strict';
+
+module.exports = function(Periodictable) {
+
+ // External PeriodTable WebService operation exposed as REST APIs through LoopBack
+ Periodictable.getAtomicnumber = function (elementName, cb) {
+ Periodictable.GetAtomicNumber({ElementName: elementName || 'Copper'}, function (err, response) {
+ var result = response;
+ cb(err, result);
+ });
+ };
+
+ // External PeriodTable WebService operation exposed as REST APIs through LoopBack
+ Periodictable.getAtomicweight = function(elementName, callback) {
+ Periodictable.GetAtomicWeight({ElementName: elementName || 'Copper'}, function (err, response) {
+ var result = response;
+ callback(err, result);
+ });
+ }
+
+ // Map to REST/HTTP
+ Periodictable.remoteMethod(
+ 'getAtomicnumber', {
+ accepts: [
+ {arg: 'elementName', type: 'string', required: true,
+ http: {source: 'query'}}
+ ],
+ returns: {arg: 'result', type: 'object', root: true},
+ http: {verb: 'get', path: '/GetAtomicNumber'}
+ }
+ );
+
+ Periodictable.remoteMethod(
+ 'getAtomicweight', {
+ accepts: [
+ {arg: 'elementName', type: 'string', required: true,
+ http: {source: 'query'}}
+ ],
+ returns: {arg: 'result', type: 'object', root: true},
+ http: {verb: 'get', path: '/GetAtomicWeight'}
+ }
+ );
+
+};
+```
+
+### Try it out!
+
+Now, run your app:
+```
+node .
+```
+
+Follow the same steps [as before](#run-the-example) and your app should behave the same as the one in this repository.
diff --git a/package.json b/package.json
new file mode 100644
index 0000000..931b6ed
--- /dev/null
+++ b/package.json
@@ -0,0 +1,40 @@
+{
+ "name": "loopback-example-connector",
+ "version": "1.0.0",
+ "main": "server/server.js",
+ "description": "LoopBack SOAP connector example",
+ "repository": {
+ "type": "git",
+ "url": "git+https://github.com/strongloop/loopback-example-connector.git"
+ },
+ "bugs": {
+ "url": "https://github.com/strongloop/loopback-example-connector/issues"
+ },
+ "homepage": "https://github.com/strongloop/loopback-example-connector#readme",
+ "engines": {
+ "node": ">=4"
+ },
+ "scripts": {
+ "lint": "eslint .",
+ "start": "node .",
+ "posttest": "npm run lint && nsp check"
+ },
+ "dependencies": {
+ "compression": "^1.0.3",
+ "cors": "^2.5.2",
+ "helmet": "^1.3.0",
+ "loopback": "^3.0.0",
+ "loopback-boot": "^2.6.5",
+ "loopback-component-explorer": "^4.0.0",
+ "loopback-connector-soap": "^3.0.1",
+ "serve-favicon": "^2.0.1",
+ "strong-error-handler": "^2.0.0"
+ },
+ "devDependencies": {
+ "eslint": "^3.17.1",
+ "eslint-config-loopback": "^8.0.0",
+ "nsp": "^2.1.0"
+ },
+ "author": "StrongLoop ",
+ "license": "MIT"
+}
diff --git a/periodictable-ws.js b/periodictable-ws.js
new file mode 100644
index 0000000..22d9d53
--- /dev/null
+++ b/periodictable-ws.js
@@ -0,0 +1,37 @@
+var loopback = require('loopback');
+app = loopback();
+ds = app.datasources['soapDS'];
+
+var ds = loopback.createDataSource('soap',
+ {
+ connector: require('loopback-connector-soap'),
+ wsdl: 'http://www.webservicex.net/periodictable.asmx?WSDL' // The url to WSDL
+ });
+
+// Unfortunately, the methods from the connector are mixed in asynchronously
+// This is a hack to wait for the methods to be injected
+ds.once('connected', function () {
+
+ // Set up a before-execute hook to dump out the request object
+ ds.connector.observe('before execute', function(ctx, next) {
+ //console.log('Http Request: ', ctx.req);
+ next();
+ });
+
+ // Create the model
+ var PeriodictableService = ds.createModel('PeriodictableService', {});
+
+ console.log(' \n Response from external WebService, http://www.webservicex.net/periodictable.asmx');
+ PeriodictableService.GetAtomicNumber({ElementName: 'Iron'}, function (err, response) {
+ console.log('\n GetAtomicNumber for Iron: \n %j', response);
+ });
+
+ PeriodictableService.GetAtomicWeight({ElementName: 'Gold'}, function (err, response) {
+ console.log('\n GetAtomicWeight for Gold: \n %j', response);
+ });
+
+ PeriodictableService.GetElementSymbol({ElementName: 'Silver'}, function (err, response) {
+ console.log('\n GetElementSymbol for Silver: \n %j', response);
+ });
+
+});
diff --git a/server/boot/root.js b/server/boot/root.js
new file mode 100644
index 0000000..6adce90
--- /dev/null
+++ b/server/boot/root.js
@@ -0,0 +1,8 @@
+'use strict';
+
+module.exports = function(server) {
+ // Install a `/` route that returns server status
+ var router = server.loopback.Router();
+ router.get('/', server.loopback.status());
+ server.use(router);
+};
diff --git a/server/component-config.json b/server/component-config.json
new file mode 100644
index 0000000..f36959a
--- /dev/null
+++ b/server/component-config.json
@@ -0,0 +1,5 @@
+{
+ "loopback-component-explorer": {
+ "mountPath": "/explorer"
+ }
+}
diff --git a/server/config.json b/server/config.json
new file mode 100644
index 0000000..d371cd2
--- /dev/null
+++ b/server/config.json
@@ -0,0 +1,22 @@
+{
+ "restApiRoot": "/api",
+ "host": "0.0.0.0",
+ "port": 3000,
+ "remoting": {
+ "context": false,
+ "rest": {
+ "handleErrors": false,
+ "normalizeHttpPath": false,
+ "xml": false
+ },
+ "json": {
+ "strict": false,
+ "limit": "100kb"
+ },
+ "urlencoded": {
+ "extended": true,
+ "limit": "100kb"
+ },
+ "cors": false
+ }
+}
diff --git a/server/datasources.json b/server/datasources.json
new file mode 100644
index 0000000..e344673
--- /dev/null
+++ b/server/datasources.json
@@ -0,0 +1,21 @@
+{
+ "soapDS": {
+ "url": "http://www.webservicex.net/periodictable.asmx",
+ "name": "soapDS",
+ "wsdl": "http://www.webservicex.net/periodictable.asmx?WSDL",
+ "remotingEnabled": true,
+ "operations": {
+ "getAtomicWeight": {
+ "service": "periodictable",
+ "port": "periodictableSoap",
+ "operation": "GetAtomicWeight"
+ },
+ "getAtomicNumber": {
+ "service": "periodictable",
+ "port": "periodictableSoap",
+ "operation": "GetAtomicNumber"
+ }
+ },
+ "connector": "soap"
+ }
+}
diff --git a/server/middleware.development.json b/server/middleware.development.json
new file mode 100644
index 0000000..071c11a
--- /dev/null
+++ b/server/middleware.development.json
@@ -0,0 +1,10 @@
+{
+ "final:after": {
+ "strong-error-handler": {
+ "params": {
+ "debug": true,
+ "log": true
+ }
+ }
+ }
+}
diff --git a/server/middleware.json b/server/middleware.json
new file mode 100644
index 0000000..cde21fe
--- /dev/null
+++ b/server/middleware.json
@@ -0,0 +1,50 @@
+{
+ "initial:before": {
+ "loopback#favicon": {}
+ },
+ "initial": {
+ "compression": {},
+ "cors": {
+ "params": {
+ "origin": true,
+ "credentials": true,
+ "maxAge": 86400
+ }
+ },
+ "helmet#xssFilter": {},
+ "helmet#frameguard": {
+ "params": [
+ "deny"
+ ]
+ },
+ "helmet#hsts": {
+ "params": {
+ "maxAge": 0,
+ "includeSubdomains": true
+ }
+ },
+ "helmet#hidePoweredBy": {},
+ "helmet#ieNoOpen": {},
+ "helmet#noSniff": {},
+ "helmet#noCache": {
+ "enabled": false
+ }
+ },
+ "session": {},
+ "auth": {},
+ "parse": {},
+ "routes": {
+ "loopback#rest": {
+ "paths": [
+ "${restApiRoot}"
+ ]
+ }
+ },
+ "files": {},
+ "final": {
+ "loopback#urlNotFound": {}
+ },
+ "final:after": {
+ "strong-error-handler": {}
+ }
+}
diff --git a/server/model-config.json b/server/model-config.json
new file mode 100644
index 0000000..d189583
--- /dev/null
+++ b/server/model-config.json
@@ -0,0 +1,20 @@
+{
+ "_meta": {
+ "sources": [
+ "loopback/common/models",
+ "loopback/server/models",
+ "../common/models",
+ "./models"
+ ],
+ "mixins": [
+ "loopback/common/mixins",
+ "loopback/server/mixins",
+ "../common/mixins",
+ "./mixins"
+ ]
+ },
+ "periodicTable": {
+ "dataSource": "soapDS",
+ "public": true
+ }
+}
diff --git a/server/models/periodic-table.js b/server/models/periodic-table.js
new file mode 100644
index 0000000..7908b45
--- /dev/null
+++ b/server/models/periodic-table.js
@@ -0,0 +1,44 @@
+'use strict';
+
+module.exports = function(Periodictable) {
+
+ // External PeriodTable WebService operation exposed as REST APIs through LoopBack
+ Periodictable.getAtomicnumber = function (elementName, cb) {
+ Periodictable.GetAtomicNumber({ElementName: elementName || 'Copper'}, function (err, response) {
+ var result = response;
+ cb(err, result);
+ });
+ };
+
+ // External PeriodTable WebService operation exposed as REST APIs through LoopBack
+ Periodictable.getAtomicweight = function(elementName, callback) {
+ Periodictable.GetAtomicWeight({ElementName: elementName || 'Copper'}, function (err, response) {
+ var result = response;
+ callback(err, result);
+ });
+ }
+
+ // Map to REST/HTTP
+ Periodictable.remoteMethod(
+ 'getAtomicnumber', {
+ accepts: [
+ {arg: 'elementName', type: 'string', required: true,
+ http: {source: 'query'}}
+ ],
+ returns: {arg: 'result', type: 'object', root: true},
+ http: {verb: 'get', path: '/GetAtomicNumber'}
+ }
+ );
+
+ Periodictable.remoteMethod(
+ 'getAtomicweight', {
+ accepts: [
+ {arg: 'elementName', type: 'string', required: true,
+ http: {source: 'query'}}
+ ],
+ returns: {arg: 'result', type: 'object', root: true},
+ http: {verb: 'get', path: '/GetAtomicWeight'}
+ }
+ );
+
+};
diff --git a/server/models/periodic-table.json b/server/models/periodic-table.json
new file mode 100644
index 0000000..b1536ad
--- /dev/null
+++ b/server/models/periodic-table.json
@@ -0,0 +1,13 @@
+{
+ "name": "periodicTable",
+ "base": "Model",
+ "idInjection": true,
+ "options": {
+ "validateUpsert": true
+ },
+ "properties": {},
+ "validations": [],
+ "relations": {},
+ "acls": [],
+ "methods": {}
+}
diff --git a/server/server.js b/server/server.js
new file mode 100644
index 0000000..2ae5f41
--- /dev/null
+++ b/server/server.js
@@ -0,0 +1,30 @@
+'use strict';
+
+var loopback = require('loopback');
+var boot = require('loopback-boot');
+
+var app = module.exports = loopback();
+
+app.start = function() {
+ // start the web server
+ return app.listen(function() {
+ app.emit('started');
+ var baseUrl = app.get('url').replace(/\/$/, '');
+ console.log('Web server listening at: %s', baseUrl);
+ if (app.get('loopback-component-explorer')) {
+ var explorerPath = app.get('loopback-component-explorer').mountPath;
+ console.log('Browse your REST API at %s%s', baseUrl, explorerPath);
+ }
+
+ });
+};
+
+// Bootstrap the application, configure models, datasources and middleware.
+// Sub-apps like REST API are mounted via boot scripts.
+boot(app, __dirname, function(err) {
+ if (err) throw err;
+
+ // start the server if `$ node server.js`
+ if (require.main === module)
+ app.start();
+});
diff --git a/stock-ws.js b/stock-ws.js
new file mode 100644
index 0000000..09c5cd2
--- /dev/null
+++ b/stock-ws.js
@@ -0,0 +1,41 @@
+var loopback = require('loopback');
+
+var ds = loopback.createDataSource('soap',
+ {
+ connector: require('loopback-connector-soap'),
+ wsdl: 'http://www.webservicex.net/stockquote.asmx?WSDL', // The url to WSDL
+ url: 'http://www.webservicex.net/stockquote.asmx', // The service endpoint
+
+ // Map SOAP service/port/operation to Node.js methods
+ operations: {
+ // The key is the method name
+ stockQuote: {
+ service: 'StockQuote', // The WSDL service name
+ port: 'StockQuoteSoap', // The WSDL port name
+ operation: 'GetQuote' // The WSDL operation name
+ },
+ // The key is the method name
+ stockQuote12: {
+ service: 'StockQuote', // The WSDL service name
+ port: 'StockQuoteSoap12', // The WSDL port name
+ operation: 'GetQuote' // The WSDL operation name
+ }
+ }
+ });
+
+// Unfortunately, the methods from the connector are mixed in asynchronously
+// This is a hack to wait for the methods to be injected
+ds.once('connected', function () {
+// Create the model
+ var StockQuote = ds.createModel('StockQuote', {});
+
+ StockQuote.stockQuote({symbol: 'IBM'}, function (err, response) {
+ console.log('Response: ', response);
+ });
+
+ StockQuote.stockQuote12({symbol: 'FB'}, function (err, response) {
+ console.log('Response: ', response);
+ });
+
+
+});