update to latest yang-js/yang-express and adapt schema/server to conform to latest interface changes
diff --git a/README.md b/README.md
index d555b27..cbbbe22 100644
--- a/README.md
+++ b/README.md
@@ -51,7 +51,7 @@
## Reference Guides
-- [API Guide](./src/api/README.md) - provides a walkthrough on *interacting with the REST API endpoints*
+- [API Guide](./src/README.md) - provides a walkthrough on *interacting with the REST API endpoints*
- [Modeler's Guide](./schema/README.md) - provides information on *current YANG models for XOS and CORD* and what's coming up next
- [Developer's Guide](./src/README.md) - provides technical detail on *controller logic and dynamic interfaces* and how to best leverage YANG model-driven developer tools for getting things done *fast*.
diff --git a/package.json b/package.json
index 582aba4..60a7266 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "yang-cord",
- "version": "1.1.1",
+ "version": "1.1.2",
"description": "YANG model-driven CORD",
"author": "Peter K. Lee <peter@corenova.com>",
"license": "Apache-2.0",
@@ -32,8 +32,8 @@
"minimist": "^1.2.0",
"node-uuid": "^1.4.7",
"superagent": "^2.0.0",
- "yang-express": "^0.3.3",
- "yang-js": "^0.15.12"
+ "yang-express": "^0.3.5",
+ "yang-js": "^0.15.13"
},
"optionalDependencies": {
"corenova": "^1.0.0"
@@ -56,6 +56,6 @@
"prepublish": "npm run build",
"pretest": "npm run build",
"test": "mocha",
- "start": "node lib/api/server.js"
+ "start": "node lib/server.js"
}
}
diff --git a/schema/xos-core.yang b/schema/xos-core.yang
index 3de5ba3..846da5c 100644
--- a/schema/xos-core.yang
+++ b/schema/xos-core.yang
@@ -75,7 +75,7 @@
mandatory true;
}
- list subscribed-tenants {
+ list subscribed-tenant {
config false;
// not exactly clear how this is populated
}
diff --git a/src/README.md b/src/README.md
index 8959ec9..3858028 100644
--- a/src/README.md
+++ b/src/README.md
@@ -1,3 +1,443 @@
-# Developer's Guide
-
-Coming soon!
+# API Guide
+
+This document provides a comprehensive overview of the REST API
+interactions enabled via the
+[yang-express](http://github.com/corenova/yang-express) middleware
+framework built on [Express.js](http://expressjs.com).
+
+While much care has been taken to auto-generate the API endpoint
+routing to conform as closely as possible to
+[RESTCONF](https://datatracker.ietf.org/doc/draft-ietf-netconf-restconf),
+there are many key deviations and currently no plans to adapt the
+default REST API generator to be RESTCONF compatible.
+
+Instead, the REST API generated by the YANG data models are much more
+closely aligned to conventional REST APIs developed for use in the **web
+application development** community. Also, there's currently no support
+for XML but instead follows the
+[YANG-JSON](https://datatracker.ietf.org/doc/draft-ietf-netmod-yang-json)
+specifications for representing configuration data in JSON.
+
+Below is the primary snippet from [server.coffee](./server.coffee)
+demonstrating how to use
+[yang-express](http://github.com/corenova/yang-express) middleware
+framework to fire up a web server instance capable of serving up the
+YANG model-driven CORD reference implementation.
+
+```coffeescript
+yang = require('yang-js')
+app = require('yang-express') ->
+ @set 'pkginfo', require('../../package.json')
+ @set 'initial state', require('../../sample-data.json')
+ @enable 'openapi', 'restjson', 'websocket'
+
+ cord = @link yang.require('cord-core')
+ xos = @link yang.require('xos-core')
+
+ cord.on 'update', (prop) ->
+ console.log "[#{prop.path}] got updated, should consider persisting the change somewhere"
+```
+
+Yep, it's really that simple.
+
+## CORD API Reference
+
+The following section presents various CRUD operations that are
+*runtime generated* from the `cord-core` YANG module. These operations
+are essentially interpreted and served **during runtime** depending on
+the YANG runtime model along with the configuration data state at any given
+point in time. Basically, it performs *adaptive* API routing and
+rendering.
+
+### Open-API Specification (Swagger 2.0)
+
+Initial partial-support for dynamic **openapi** specification
+generation has been introduced with the latest
+[yang-express](http://github.com/corenova/yang-express) middleware
+framework. It can send back JSON or YAML based specification output
+depending on the requesting client's `Accept` header. It defaults to
+JSON output.
+
+You can give it a try by issuing one of the following:
+```bash
+$ curl localhost:5050/swagger.spec
+$ curl localhost:5050/swagger.spec -H 'accept: text/yaml'
+```
+
+We'll plan to fully support the **openapi** specification along the way.
+
+### View Subscribers
+
+Valid URIs:
+
+- GET /cord-core:subscriber
+- GET /cord:subscriber
+- GET /subscriber
+
+Request:
+```bash
+$ curl localhost:5050/cord:subscriber
+```
+Response:
+```json
+{
+ "cord-core:subscriber": [
+ {
+ "id": 1,
+ "service-specific-id": 1000,
+ "humanReadableName": "cordSubscriber-1",
+ "status": "enabled",
+ "demo": false,
+ "uplink-speed": 1000000000,
+ "downlink-speed": 1000000000,
+ "kind": "cord-subscriber",
+ "related": {}
+ },
+ {
+ "id": 2,
+ "service-specific-id": 1001,
+ "humanReadableName": "cordSubscriber-2",
+ "status": "enabled",
+ "demo": false,
+ "uplink-speed": 1000000000,
+ "downlink-speed": 1000000000,
+ "kind": "cord-subscriber",
+ "related": {}
+ }
+ ]
+}
+```
+
+### View Details for a Subscriber
+
+Valid URIs:
+
+- GET /cord-core:subscriber/:id
+- GET /cord:subscriber/:id
+- GET /subscriber/:id
+
+Request:
+```bash
+$ curl localhost:5050/cord:subscriber/1
+```
+Response:
+```json
+{
+ "cord-core:subscriber": {
+ "id": 1,
+ "service-specific-id": 1000,
+ "humanReadableName": "cordSubscriber-1",
+ "status": "enabled",
+ "demo": false,
+ "uplink-speed": 1000000000,
+ "downlink-speed": 1000000000,
+ "kind": "cord-subscriber",
+ "related": {}
+ }
+}
+```
+
+### Update a Subscriber
+
+Valid URIs:
+
+- PUT /cord-core:subscriber/:id
+- PUT /cord:subscriber/:id
+- PUT /subscriber/:id
+
+Request:
+```bash
+$ curl -X PUT localhost:5050/cord:subscriber/1 -H 'content-type: application/json' -d '{ "id": 10, "status": "suspended", "services": { "cdn": { "enabled": true } } }'
+```
+Response:
+```json
+{
+ "cord-core:subscriber": {
+ "id": 10,
+ "service-specific-id": 1000,
+ "humanReadableName": "cordSubscriber-10",
+ "status": "suspended",
+ "demo": false,
+ "uplink-speed": 1000000000,
+ "downlink-speed": 1000000000,
+ "kind": "cord-subscriber",
+ "related": {},
+ "services": {
+ "cdn": {
+ "enabled": true
+ }
+ }
+ }
+}
+```
+
+This operation highlights an interesting scenario related to
+*invisible* YANG schema properties. Any configuration tree segment
+that does not contain any data behave as *shadow* properties, which
+basically means they spring to life once valid data gets placed into
+it but stays *invisible* otherwise.
+
+### Delete a Subscriber
+
+Valid URIs:
+
+- DELETE /cord-core:subscriber/:id
+- DELETE /cord:subscriber/:id
+- DELETE /subscriber/:id
+
+Request:
+```bash
+$ curl -X DELETE localhost:5050/cord:subscriber/2
+```
+Response:
+```
+HTTP 204
+```
+
+### Create a new Subscriber
+
+Valid URIs:
+
+- POST /cord-core:subscriber
+- POST /cord:subscriber
+- POST /subscriber
+
+Request:
+```bash
+$ curl -X POST localhost:5050/cord:subscriber -H 'content-type: application/json' -d '{ "id": 12, "service-specific-id": 2020, "demo": true }'
+```
+Response:
+```json
+{
+ "cord-core:subscriber": [
+ {
+ "id": 12,
+ "service-specific-id": 2020,
+ "demo": true,
+ "humanReadableName": "cordSubscriber-12",
+ "status": "enabled",
+ "uplink-speed": 1000000000,
+ "downlink-speed": 1000000000,
+ "kind": "cord-subscriber",
+ "related": {}
+ }
+ ]
+}
+```
+The POST operation is only available on YANG `list` schema elements as
+well as `rpc` and `action` elements. This operation also accepts
+**bulk create** request data by supplying a JSON array.
+
+### Describe the Subscriber Model
+
+This operation provides discovery of a given data model's
+characteristics as well as other data node elements available inside
+the data model. It can be used by REST API consumers to auto-discover
+additional paths and metadata associated with the target entity. It's
+also useful for *dynamically generating API documentation* for a given
+data model.
+
+Valid URIs:
+
+- OPTIONS /cord-core:subscriber
+- OPTIONS /cord:subscriber
+- OPTIONS /subscriber
+
+Request:
+```bash
+$ curl -X OPTIONS localhost:5050/cord:subscriber
+```
+Response:
+```json
+{
+ "name": "cord-core:subscriber",
+ "kind": "list",
+ "path": "/cord-core:subscriber",
+ "exists": true,
+ "key": "id",
+ "description": "Authorative list of all subscriber instances",
+ "data": {
+ "humanReadableName": {
+ "kind": "leaf",
+ "config": false,
+ "type": {
+ "string": {
+ "pattern": "/^cordSubscriber-\\w+$/"
+ }
+ }
+ },
+ "status": {
+ "kind": "leaf",
+ "type": {
+ "enumeration": {
+ "enum": {
+ "enabled": {
+ "description": "Enabled",
+ "value": "1"
+ },
+ "suspended": {
+ "description": "Suspended",
+ "value": "2"
+ },
+ "delinquent": {
+ "description": "Delinquent",
+ "value": "3"
+ },
+ "violation": {
+ "description": "Copyright Violation",
+ "value": "4"
+ }
+ }
+ }
+ },
+ "default": "enabled"
+ },
+ "demo": {
+ "kind": "leaf",
+ "type": "boolean",
+ "default": "false"
+ },
+ "uplink-speed": {
+ "kind": "leaf",
+ "type": {
+ "dev:bandwidth": {
+ "range": "1000000..max"
+ }
+ },
+ "default": "1000000000",
+ "units": "bps"
+ },
+ "downlink-speed": {
+ "kind": "leaf",
+ "type": {
+ "dev:bandwidth": {
+ "range": "1000000..max"
+ }
+ },
+ "default": "1000000000",
+ "units": "bps"
+ },
+ "id": {
+ "kind": "leaf",
+ "type": {
+ "unique-identifier": {
+ "type": {
+ "uint32": {
+ "range": "1..max"
+ },
+ "yang:uuid": {
+ "pattern": "/[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}/"
+ }
+ }
+ }
+ },
+ "mandatory": true
+ },
+ "kind": {
+ "kind": "leaf",
+ "type": {
+ "identityref": {
+ "base": "kind"
+ }
+ },
+ "default": "generic"
+ },
+ "name": {
+ "kind": "leaf",
+ "type": {
+ "string": {
+ "length": "0..255"
+ }
+ },
+ "description": "Specify name of the TenantRoot"
+ },
+ "service-specific-attribute": {
+ "kind": "leaf",
+ "type": "string"
+ },
+ "service-specific-id": {
+ "kind": "leaf",
+ "type": {
+ "unique-identifier": {
+ "type": {
+ "uint32": {
+ "range": "1..max"
+ },
+ "yang:uuid": {
+ "pattern": "/[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}/"
+ }
+ }
+ }
+ },
+ "mandatory": true
+ },
+ "delete": {
+ "kind": "action"
+ },
+ "services": {
+ "kind": "container",
+ "description": "Contains various services available to the subscriber"
+ },
+ "device": {
+ "kind": "list",
+ "key": "mac"
+ },
+ "subscribed-tenants": {
+ "kind": "list",
+ "config": false
+ }
+ }
+}
+```
+
+### Additional Endpoints
+
+There are a number of additional operational endpoints dynamically
+rendered for the YANG data model. Since YANG is a **hierarchical**
+data modeling language, you can have deeply nested structures of
+various `containers` and `lists`. The appropriate CRUD operations can
+take effect as deep into the endpoint entity hierarchy according to
+the YANG schema.
+
+Here's a sample list of various URIs for the Subscriber model:
+
+Methods | Endpoint URI
+--- | ---
+GET/POST | /cord:subscriber
+GET/PUT/DELETE | /cord:subscriber/:id
+GET/PUT | /cord:subscriber/:id/services/cdn
+GET/POST | /cord:subscriber/:id/device
+GET/PUT/DELETE | /cord:subscriber/:id/device/:mac
+GET/PUT | /cord:subscriber/:id/device/:mac/features
+
+### Validations
+
+Whenever POST/PUT requests are transacted, the incoming data is YANG
+schema validated to ensure fitness of the data before it gets applied
+into the runtime configuration data state.
+
+For example, if you tried to POST /cord:subscriber without the
+`mandatory` *id* and *service-specific-id* properties, it will
+generate an error and reject the request.
+
+Also, if you tried to PUT using data values that do not conform to the
+underlying YANG schema for that data element, it will generate an
+error and reject the requst.
+
+Invalid Request:
+```bash
+$ curl -X PUT localhost:5050/cord:subscriber/10 -H 'content-type: application/json' -d '{ "status": false }'
+```
+Error Response:
+```json
+{
+ "error": {
+ "message": "[enumeration] type violation for 'false' on enabled,suspended,delinquent,violation"
+ }
+}
+```
+
+For additional information on comprehensive validation enforcement
+support, please refer to [yang-js](http://github.com/corenova/yang-js)
+YANG compliance status report.
+
diff --git a/src/api/README.md b/src/api/README.md
deleted file mode 100644
index 3858028..0000000
--- a/src/api/README.md
+++ /dev/null
@@ -1,443 +0,0 @@
-# API Guide
-
-This document provides a comprehensive overview of the REST API
-interactions enabled via the
-[yang-express](http://github.com/corenova/yang-express) middleware
-framework built on [Express.js](http://expressjs.com).
-
-While much care has been taken to auto-generate the API endpoint
-routing to conform as closely as possible to
-[RESTCONF](https://datatracker.ietf.org/doc/draft-ietf-netconf-restconf),
-there are many key deviations and currently no plans to adapt the
-default REST API generator to be RESTCONF compatible.
-
-Instead, the REST API generated by the YANG data models are much more
-closely aligned to conventional REST APIs developed for use in the **web
-application development** community. Also, there's currently no support
-for XML but instead follows the
-[YANG-JSON](https://datatracker.ietf.org/doc/draft-ietf-netmod-yang-json)
-specifications for representing configuration data in JSON.
-
-Below is the primary snippet from [server.coffee](./server.coffee)
-demonstrating how to use
-[yang-express](http://github.com/corenova/yang-express) middleware
-framework to fire up a web server instance capable of serving up the
-YANG model-driven CORD reference implementation.
-
-```coffeescript
-yang = require('yang-js')
-app = require('yang-express') ->
- @set 'pkginfo', require('../../package.json')
- @set 'initial state', require('../../sample-data.json')
- @enable 'openapi', 'restjson', 'websocket'
-
- cord = @link yang.require('cord-core')
- xos = @link yang.require('xos-core')
-
- cord.on 'update', (prop) ->
- console.log "[#{prop.path}] got updated, should consider persisting the change somewhere"
-```
-
-Yep, it's really that simple.
-
-## CORD API Reference
-
-The following section presents various CRUD operations that are
-*runtime generated* from the `cord-core` YANG module. These operations
-are essentially interpreted and served **during runtime** depending on
-the YANG runtime model along with the configuration data state at any given
-point in time. Basically, it performs *adaptive* API routing and
-rendering.
-
-### Open-API Specification (Swagger 2.0)
-
-Initial partial-support for dynamic **openapi** specification
-generation has been introduced with the latest
-[yang-express](http://github.com/corenova/yang-express) middleware
-framework. It can send back JSON or YAML based specification output
-depending on the requesting client's `Accept` header. It defaults to
-JSON output.
-
-You can give it a try by issuing one of the following:
-```bash
-$ curl localhost:5050/swagger.spec
-$ curl localhost:5050/swagger.spec -H 'accept: text/yaml'
-```
-
-We'll plan to fully support the **openapi** specification along the way.
-
-### View Subscribers
-
-Valid URIs:
-
-- GET /cord-core:subscriber
-- GET /cord:subscriber
-- GET /subscriber
-
-Request:
-```bash
-$ curl localhost:5050/cord:subscriber
-```
-Response:
-```json
-{
- "cord-core:subscriber": [
- {
- "id": 1,
- "service-specific-id": 1000,
- "humanReadableName": "cordSubscriber-1",
- "status": "enabled",
- "demo": false,
- "uplink-speed": 1000000000,
- "downlink-speed": 1000000000,
- "kind": "cord-subscriber",
- "related": {}
- },
- {
- "id": 2,
- "service-specific-id": 1001,
- "humanReadableName": "cordSubscriber-2",
- "status": "enabled",
- "demo": false,
- "uplink-speed": 1000000000,
- "downlink-speed": 1000000000,
- "kind": "cord-subscriber",
- "related": {}
- }
- ]
-}
-```
-
-### View Details for a Subscriber
-
-Valid URIs:
-
-- GET /cord-core:subscriber/:id
-- GET /cord:subscriber/:id
-- GET /subscriber/:id
-
-Request:
-```bash
-$ curl localhost:5050/cord:subscriber/1
-```
-Response:
-```json
-{
- "cord-core:subscriber": {
- "id": 1,
- "service-specific-id": 1000,
- "humanReadableName": "cordSubscriber-1",
- "status": "enabled",
- "demo": false,
- "uplink-speed": 1000000000,
- "downlink-speed": 1000000000,
- "kind": "cord-subscriber",
- "related": {}
- }
-}
-```
-
-### Update a Subscriber
-
-Valid URIs:
-
-- PUT /cord-core:subscriber/:id
-- PUT /cord:subscriber/:id
-- PUT /subscriber/:id
-
-Request:
-```bash
-$ curl -X PUT localhost:5050/cord:subscriber/1 -H 'content-type: application/json' -d '{ "id": 10, "status": "suspended", "services": { "cdn": { "enabled": true } } }'
-```
-Response:
-```json
-{
- "cord-core:subscriber": {
- "id": 10,
- "service-specific-id": 1000,
- "humanReadableName": "cordSubscriber-10",
- "status": "suspended",
- "demo": false,
- "uplink-speed": 1000000000,
- "downlink-speed": 1000000000,
- "kind": "cord-subscriber",
- "related": {},
- "services": {
- "cdn": {
- "enabled": true
- }
- }
- }
-}
-```
-
-This operation highlights an interesting scenario related to
-*invisible* YANG schema properties. Any configuration tree segment
-that does not contain any data behave as *shadow* properties, which
-basically means they spring to life once valid data gets placed into
-it but stays *invisible* otherwise.
-
-### Delete a Subscriber
-
-Valid URIs:
-
-- DELETE /cord-core:subscriber/:id
-- DELETE /cord:subscriber/:id
-- DELETE /subscriber/:id
-
-Request:
-```bash
-$ curl -X DELETE localhost:5050/cord:subscriber/2
-```
-Response:
-```
-HTTP 204
-```
-
-### Create a new Subscriber
-
-Valid URIs:
-
-- POST /cord-core:subscriber
-- POST /cord:subscriber
-- POST /subscriber
-
-Request:
-```bash
-$ curl -X POST localhost:5050/cord:subscriber -H 'content-type: application/json' -d '{ "id": 12, "service-specific-id": 2020, "demo": true }'
-```
-Response:
-```json
-{
- "cord-core:subscriber": [
- {
- "id": 12,
- "service-specific-id": 2020,
- "demo": true,
- "humanReadableName": "cordSubscriber-12",
- "status": "enabled",
- "uplink-speed": 1000000000,
- "downlink-speed": 1000000000,
- "kind": "cord-subscriber",
- "related": {}
- }
- ]
-}
-```
-The POST operation is only available on YANG `list` schema elements as
-well as `rpc` and `action` elements. This operation also accepts
-**bulk create** request data by supplying a JSON array.
-
-### Describe the Subscriber Model
-
-This operation provides discovery of a given data model's
-characteristics as well as other data node elements available inside
-the data model. It can be used by REST API consumers to auto-discover
-additional paths and metadata associated with the target entity. It's
-also useful for *dynamically generating API documentation* for a given
-data model.
-
-Valid URIs:
-
-- OPTIONS /cord-core:subscriber
-- OPTIONS /cord:subscriber
-- OPTIONS /subscriber
-
-Request:
-```bash
-$ curl -X OPTIONS localhost:5050/cord:subscriber
-```
-Response:
-```json
-{
- "name": "cord-core:subscriber",
- "kind": "list",
- "path": "/cord-core:subscriber",
- "exists": true,
- "key": "id",
- "description": "Authorative list of all subscriber instances",
- "data": {
- "humanReadableName": {
- "kind": "leaf",
- "config": false,
- "type": {
- "string": {
- "pattern": "/^cordSubscriber-\\w+$/"
- }
- }
- },
- "status": {
- "kind": "leaf",
- "type": {
- "enumeration": {
- "enum": {
- "enabled": {
- "description": "Enabled",
- "value": "1"
- },
- "suspended": {
- "description": "Suspended",
- "value": "2"
- },
- "delinquent": {
- "description": "Delinquent",
- "value": "3"
- },
- "violation": {
- "description": "Copyright Violation",
- "value": "4"
- }
- }
- }
- },
- "default": "enabled"
- },
- "demo": {
- "kind": "leaf",
- "type": "boolean",
- "default": "false"
- },
- "uplink-speed": {
- "kind": "leaf",
- "type": {
- "dev:bandwidth": {
- "range": "1000000..max"
- }
- },
- "default": "1000000000",
- "units": "bps"
- },
- "downlink-speed": {
- "kind": "leaf",
- "type": {
- "dev:bandwidth": {
- "range": "1000000..max"
- }
- },
- "default": "1000000000",
- "units": "bps"
- },
- "id": {
- "kind": "leaf",
- "type": {
- "unique-identifier": {
- "type": {
- "uint32": {
- "range": "1..max"
- },
- "yang:uuid": {
- "pattern": "/[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}/"
- }
- }
- }
- },
- "mandatory": true
- },
- "kind": {
- "kind": "leaf",
- "type": {
- "identityref": {
- "base": "kind"
- }
- },
- "default": "generic"
- },
- "name": {
- "kind": "leaf",
- "type": {
- "string": {
- "length": "0..255"
- }
- },
- "description": "Specify name of the TenantRoot"
- },
- "service-specific-attribute": {
- "kind": "leaf",
- "type": "string"
- },
- "service-specific-id": {
- "kind": "leaf",
- "type": {
- "unique-identifier": {
- "type": {
- "uint32": {
- "range": "1..max"
- },
- "yang:uuid": {
- "pattern": "/[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}/"
- }
- }
- }
- },
- "mandatory": true
- },
- "delete": {
- "kind": "action"
- },
- "services": {
- "kind": "container",
- "description": "Contains various services available to the subscriber"
- },
- "device": {
- "kind": "list",
- "key": "mac"
- },
- "subscribed-tenants": {
- "kind": "list",
- "config": false
- }
- }
-}
-```
-
-### Additional Endpoints
-
-There are a number of additional operational endpoints dynamically
-rendered for the YANG data model. Since YANG is a **hierarchical**
-data modeling language, you can have deeply nested structures of
-various `containers` and `lists`. The appropriate CRUD operations can
-take effect as deep into the endpoint entity hierarchy according to
-the YANG schema.
-
-Here's a sample list of various URIs for the Subscriber model:
-
-Methods | Endpoint URI
---- | ---
-GET/POST | /cord:subscriber
-GET/PUT/DELETE | /cord:subscriber/:id
-GET/PUT | /cord:subscriber/:id/services/cdn
-GET/POST | /cord:subscriber/:id/device
-GET/PUT/DELETE | /cord:subscriber/:id/device/:mac
-GET/PUT | /cord:subscriber/:id/device/:mac/features
-
-### Validations
-
-Whenever POST/PUT requests are transacted, the incoming data is YANG
-schema validated to ensure fitness of the data before it gets applied
-into the runtime configuration data state.
-
-For example, if you tried to POST /cord:subscriber without the
-`mandatory` *id* and *service-specific-id* properties, it will
-generate an error and reject the request.
-
-Also, if you tried to PUT using data values that do not conform to the
-underlying YANG schema for that data element, it will generate an
-error and reject the requst.
-
-Invalid Request:
-```bash
-$ curl -X PUT localhost:5050/cord:subscriber/10 -H 'content-type: application/json' -d '{ "status": false }'
-```
-Error Response:
-```json
-{
- "error": {
- "message": "[enumeration] type violation for 'false' on enabled,suspended,delinquent,violation"
- }
-}
-```
-
-For additional information on comprehensive validation enforcement
-support, please refer to [yang-js](http://github.com/corenova/yang-js)
-YANG compliance status report.
-
diff --git a/src/api/server.coffee b/src/server.coffee
similarity index 68%
rename from src/api/server.coffee
rename to src/server.coffee
index e9dbd4e..46a1e1b 100644
--- a/src/api/server.coffee
+++ b/src/server.coffee
@@ -7,24 +7,25 @@
# http://www.apache.org/licenses/LICENSE-2.0
#
-yang = require('yang-js')
+Yang = require('yang-js')
app = require('yang-express') ->
- @set 'pkginfo', require('../../package.json')
- @set 'initial state', require('../../sample-data.json')
- @enable 'openapi', 'restjson', 'websocket'
+ @enable 'yangapi'
+ @enable 'openapi', require('../package.json')
+ @enable 'restjson'
+ @enable 'websocket'
- cord = @link yang.require('cord-core')
- xos = @link yang.require('xos-core')
+ data = require('../sample-data.json')
+ cord = @link Yang.require('cord-core'), data
+ xos = @link Yang.require('xos-core'), data
cord.on 'update', (prop) ->
console.log "[#{prop.path}] got updated, should consider persisting the change somewhere"
-
+
module.exports = app
# only start if directly invoked
if require.main is module
- path = require('path')
argv = require('minimist')(process.argv.slice(2))
argv.port ?= 5050
app.listen argv.port