added API Guide documentation and updated Modeler's Guide
diff --git a/README.md b/README.md
index 87c730a..6e594e4 100644
--- a/README.md
+++ b/README.md
@@ -1,8 +1,9 @@
# YANG model-driven CORD
This is a **work-in-progress** effort to create
-[YANG](http://tools.ietf.org/html/rfc6020) data models for the [CORD](http://opencord.org)
-project and deliver flexible service compositions.
+[YANG](http://tools.ietf.org/html/rfc6020) data models for the
+[CORD](http://opencord.org) project and deliver flexible service
+compositions.
You may contact Larry Peterson <llp@onlab.us> and Peter Lee
<peter@corenova.com> to learn more about this initiative and find out
@@ -19,8 +20,8 @@
Following the installation, you can **start** an instance of the YANG
model-driven REST API web server. It utilizes
[yang-express](http://github.com/corenova/yang-express) middleware
-framework built on Express.js to provide dynamic YANG model-driven API
-routing capability.
+framework built on [Express.js](http://expressjs.com) to provide
+dynamic YANG model-driven API routing capability.
```bash
$ npm start
@@ -35,7 +36,7 @@
## Reference Guides
-- [API Overview](./doc/api-overview.md) - provides walkthrough on *interacting with the REST API endpoints*
+- [API Guide](./src/api/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 020544f..8cdacbe 100644
--- a/package.json
+++ b/package.json
@@ -25,7 +25,7 @@
"corenova-node": "corenova",
"xos-core": "./schema/xos-core.yang",
"cord-core": "./lib/cord-core.js",
- "cord-device": "./schema/cord-device.yang",
+ "cord-device": "./lib/cord-device.js",
"cord-subscriber": "./lib/cord-subscriber.js"
},
"dependencies": {
@@ -44,7 +44,7 @@
"rimraf": "^2.5.2",
"should": "~3.1.3"
},
- "main": "./lib/server.js",
+ "main": "./lib/cord-core.js",
"scripts": {
"clean": "rimraf dist/* lib/*",
"prebuild": "npm run clean -s && mkdir -p dist",
@@ -53,6 +53,6 @@
"prepublish": "npm run build",
"pretest": "npm run build",
"test": "mocha",
- "start": "node lib/server.js"
+ "start": "node lib/api/server.js"
}
}
diff --git a/schema/README.md b/schema/README.md
index 07a0319..3e6ecd8 100644
--- a/schema/README.md
+++ b/schema/README.md
@@ -8,8 +8,8 @@
The initial effort is centered around capturing the CORD Subscriber
model and its dependent models. We'll be reguarly updating this
-document as we capture any additional models from XOS/CORD repository
-in the coming days.
+document as we capture additional models from XOS/CORD repository in
+the coming days.
## XOS Data Models
@@ -27,7 +27,7 @@
we're considering this YANG module to be the **master** module that
all other modules derive from and augments into this module. You can
see this *augment* behavior in the
-[cord-subscriber.yang](./cord-subscriber.yang) schema.
+[cord-core.yang](./cord-core.yang) schema.
As we capture more XOS data models, we will likely organize the
additional models as separate YANG modules, such as `xos-service`,
diff --git a/schema/old/xos-core-service.yang b/schema/experimental/xos-core-service.yang
similarity index 100%
rename from schema/old/xos-core-service.yang
rename to schema/experimental/xos-core-service.yang
diff --git a/src/api/README.md b/src/api/README.md
new file mode 100644
index 0000000..db51bae
--- /dev/null
+++ b/src/api/README.md
@@ -0,0 +1,263 @@
+# 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
+[YANGJSON](https://datatracker.ietf.org/doc/draft-ietf-netmod-yang-json)
+specifications for representing configuration data in JSON.
+
+Below is the complete 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')
+
+require('yang-express').run {
+
+ port: 5050
+ models: [
+ yang.require 'cord-core'
+ yang.require 'xos-core'
+ ]
+ data: require '../../sample-data.json'
+
+}
+```
+
+Yes, 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 **while running** depending on
+the YANG runtime model and the configuration data state at any given
+point in time. Basically, it's performing *adaptive* API routing and
+rendering.
+
+### View Subscribers
+
+Valid URIs:
+
+- GET /cord-core:subscriber
+- GET /cord:subscriber
+- GET /subscriber
+
+Request:
+```bash
+$ curl localhost:5050/cord:subscriber
+```
+Response:
+```
+{
+ "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:
+```
+{
+ "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:
+```
+{
+ "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:
+```
+{
+ "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.
+
+### 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:
+
+| 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 does 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:
+```
+{
+ "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/api/server.coffee
new file mode 100644
index 0000000..5fa7b8e
--- /dev/null
+++ b/src/api/server.coffee
@@ -0,0 +1,23 @@
+#
+# Author: Peter K. Lee (peter@corenova.com)
+#
+# All rights reserved. This program and the accompanying materials
+# are made available under the terms of the Apache License, Version 2.0
+# which accompanies this distribution, and is available at
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+
+require('events').EventEmitter.defaultMaxListeners = 100
+
+yang = require('yang-js')
+
+require('yang-express').run {
+
+ port: 5050
+ models: [
+ yang.require 'cord-core'
+ yang.require 'xos-core'
+ ]
+ data: require '../../sample-data.json'
+
+}
diff --git a/src/server.coffee b/src/server.coffee
deleted file mode 100644
index fd1f395..0000000
--- a/src/server.coffee
+++ /dev/null
@@ -1,13 +0,0 @@
-require('events').EventEmitter.defaultMaxListeners = 100
-yang = require('yang-js').register()
-
-require('yang-express').run {
-
- port: 5050
- models: [
- yang.require 'cord-core'
- yang.require 'xos-core'
- ]
- data: require '../sample-data.json'
-
-}