RIFT OSM R1 Initial Submission

Signed-off-by: Jeremy Mordkoff <jeremy.mordkoff@riftio.com>
diff --git a/rwlaunchpad/mock/CMakeLists.txt b/rwlaunchpad/mock/CMakeLists.txt
new file mode 100644
index 0000000..7695cda
--- /dev/null
+++ b/rwlaunchpad/mock/CMakeLists.txt
@@ -0,0 +1,27 @@
+
+# 
+#   Copyright 2016 RIFT.IO Inc
+#
+#   Licensed under the Apache License, Version 2.0 (the "License");
+#   you may not use this file except in compliance with the License.
+#   You may obtain a copy of the License at
+#
+#       http://www.apache.org/licenses/LICENSE-2.0
+#
+#   Unless required by applicable law or agreed to in writing, software
+#   distributed under the License is distributed on an "AS IS" BASIS,
+#   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+#   See the License for the specific language governing permissions and
+#   limitations under the License.
+#
+
+cmake_minimum_required(VERSION 2.0)
+
+include(rift_plugin)
+
+set(subdirs
+    plugins
+    )
+
+rift_add_subdirs(SUBDIR_LIST ${subdirs})
+
diff --git a/rwlaunchpad/mock/README b/rwlaunchpad/mock/README
new file mode 100644
index 0000000..6f66c17
--- /dev/null
+++ b/rwlaunchpad/mock/README
@@ -0,0 +1,44 @@
+
+TO test the LP mocklet via command line:
+
+Part 1:  Run the test server infrastructure
+
+1. ssh into a VM, navigate to your workspace rift root and run ./rift-shell
+2. navigate to:
+    modules/core/mc/rwmc/test
+
+3. run:
+    $ python3 ./mission_control.py -m ethsim -c --skip-prepare-vm --mock --skip-ui
+
+The --skip-ui option prevents the server infrastructure from loading Composer
+and the UI (to save time loading, especially if you are going to be running
+the server in your own dev environment).
+
+Part 2: Run the mocklet
+
+1. repeat step 1 above
+2. navigate to:
+    modules/core/mc/rwlp_dts_mock
+
+
+3. If the rwlp_dts_mock/node_modules directory does not exist, run:
+
+    $ npm install
+
+4. Start the mocklet after the server (mission_control.py) has completed initialization
+
+To start the mocklet:
+
+    $ node lp_mock_client.js
+
+5. After the mocklet has started, open another terminal window (can be
+anywhere that can access the restconf server on your VM) and run the following:
+
+Seed the descriptors and instance config objects, run:
+
+    $ ./set_data.sh <vm-ip-address>
+
+Now you are ready to test retrieving an ns-instance-opdata object
+
+    $ get_ns_instance_opdata.sh <vm-ip-address>
+
diff --git a/rwlaunchpad/mock/data/nfvi-metrics.json b/rwlaunchpad/mock/data/nfvi-metrics.json
new file mode 100644
index 0000000..8620b5e
--- /dev/null
+++ b/rwlaunchpad/mock/data/nfvi-metrics.json
@@ -0,0 +1,33 @@
+[
+    {
+        "nfvi_metric": {
+                "vm": {
+                    "active_vm": 1,
+                    "inactive_vm": 1
+                },
+                "memory": {
+                    "used": {
+                        "value": 1
+                    },
+                    "total": {
+                        "value": 2
+                    },
+                    "utilization": {
+                        "value": 1
+                    }
+                },
+                "storage" : {
+                    "used": {
+                        "value": 1
+                    },
+                    "total": {
+                        "value": 2
+                    },
+                    "utilization": {
+                        "value": 1
+                    }
+                }
+        }
+    }
+]
+
diff --git a/rwlaunchpad/mock/data/ns-instance-config.json b/rwlaunchpad/mock/data/ns-instance-config.json
new file mode 100644
index 0000000..29af367
--- /dev/null
+++ b/rwlaunchpad/mock/data/ns-instance-config.json
@@ -0,0 +1,19 @@
+{
+    "nsr": [
+        {
+            "id": "a636c6de-6dd0-11e5-9e8f-6cb3113b406f",
+            "nsd-ref": "a631e8c6-663a-11e5-b122-6cb3113b406f",
+            "admin-status": "ENABLED"
+        },
+        {
+            "id": "c8c6cc24-6dd0-11e5-9e8f-6cb3113b406f",
+            "nsd-ref": "b631e8c6-663a-11e5-b122-6cb3113b406f",
+            "admin-status": "ENABLED"
+        },
+        {
+            "id": "c8c6cf3a-6dd0-11e5-9e8f-6cb3113b406f",
+            "nsd-ref": "c631e8c6-663a-11e5-b122-6cb3113b406f",
+            "admin-status": "DISABLED"
+        }
+    ]
+}
diff --git a/rwlaunchpad/mock/data/nsd_catalog.json b/rwlaunchpad/mock/data/nsd_catalog.json
new file mode 100644
index 0000000..0c6c6ec
--- /dev/null
+++ b/rwlaunchpad/mock/data/nsd_catalog.json
@@ -0,0 +1,44 @@
+{
+    "nsd": [
+        {
+            "id": "a631e8c6-663a-11e5-b122-6cb3113b406f",
+            "name": "Network Service Descriptor 1",
+            "short-name": "NSD1",
+            "vendor": "RIFT.io",
+            "description": "This is a description. It doesn't say much",
+            "version": "0.0.1",
+            "connection-point": [
+                {
+                    "name": "cp-name"
+                }
+            ]
+        },
+        {
+            "id": "b631e8c6-663a-11e5-b122-6cb3113b406f",
+            "name": "Network Service Descriptor 2",
+            "short-name": "NSD2",
+            "vendor": "RIFT.io",
+            "description": "This is a description. It doesn't say much",
+            "version": "0.0.1",
+            "connection-point": [
+                {
+                    "name": "cp-name"
+                }
+            ]
+        },
+        {
+            "id": "c631e8c6-663a-11e5-b122-6cb3113b406f",
+            "name": "Network Service Descriptor 3",
+            "short-name": "NSD3",
+            "vendor": "RIFT.io",
+            "description": "This is a description. It doesn't say much",
+            "version": "0.0.1",
+            "connection-point": [
+                {
+                    "name": "cp-name"
+                }
+            ]
+        }
+    ]
+}
+
diff --git a/rwlaunchpad/mock/data/nsr-templates.json b/rwlaunchpad/mock/data/nsr-templates.json
new file mode 100644
index 0000000..4c512e5
--- /dev/null
+++ b/rwlaunchpad/mock/data/nsr-templates.json
@@ -0,0 +1,57 @@
+[
+    {
+        "create_time": 1445876693,
+        "epa_param": {
+                "ovs_acceleration": {
+                    "vm": 2
+                },
+                "ovs_offload": {
+                    "vm": 2
+                },
+                "ddio": {
+                    "vm": 2
+                },
+                "cat": {
+                    "vm": 2
+                },
+                "cmt": {
+                    "vm": 2
+                }
+        },
+        "monitoring_param": [
+            {
+                "id": "monitoring-param-1",
+                "name": "rate",
+                "description": "Generalized rate monitoring param",
+                "group_tag": "group-a",
+                "min_value": 0,
+                "max_value": 100,
+                "current_value": 0,
+                "widget_type": "GAUGE",
+                "units": "gbps"
+            },
+            {
+                "id": "monitoring-param-2",
+                "name": "size",
+                "description": "Generalized size monitoring param",
+                "group_tag": "group-a",
+                "min_value": 0,
+                "max_value": 100,
+                "current_value": 0,
+                "widget_type": "GAUGE",
+                "units": "gb"
+            },
+            {
+                "id": "monitoring-param-3",
+                "name": "size22",
+                "description": "Generalized size monitoring param",
+                "group_tag": "group-b",
+                "min_value": 0,
+                "max_value": 100,
+                "current_value": 0,
+                "widget_type": "GAUGE",
+                "units": "gb"
+            }
+        ]
+    }
+]
diff --git a/rwlaunchpad/mock/data/ping-pong-ns-instance-config.json b/rwlaunchpad/mock/data/ping-pong-ns-instance-config.json
new file mode 100644
index 0000000..e7d6bb7
--- /dev/null
+++ b/rwlaunchpad/mock/data/ping-pong-ns-instance-config.json
@@ -0,0 +1,10 @@
+{
+    "nsr": [
+        {
+            "id": "f5f41f36-78f6-11e5-b9ba-6cb3113b406f",
+            "nsd-ref": "da1dfbcc-626b-11e5-998d-6cb3113b406f",
+            "admin-status": "ENABLED"
+        }
+    ]
+}
+
diff --git a/rwlaunchpad/mock/data/ping-pong-nsd.json b/rwlaunchpad/mock/data/ping-pong-nsd.json
new file mode 100644
index 0000000..7ad9f6b
--- /dev/null
+++ b/rwlaunchpad/mock/data/ping-pong-nsd.json
@@ -0,0 +1,118 @@
+{
+    "nsd": [
+        {
+            "id": "da1dfbcc-626b-11e5-998d-6cb3113b406f",
+            "name": "ping-pong-nsd",
+            "vendor": "RIFT.io",
+            "description": "Toy NS",
+            "version": "1.0",
+            "connection-point": [
+                {
+                    "name": "ping-pong-nsd/cp0",
+                    "type": "VPORT"
+                },
+                {
+                    "name": "ping-pong-nsd/cp1",
+                    "type": "VPORT"
+                }
+            ],
+            "vld": [
+                {
+                    "id": "ba1c03a8-626b-11e5-998d-6cb3113b406f",
+                    "name": "ping-pong-vld",
+                    "short-name": "ping-pong-vld",
+                    "vendor": "RIFT.io",
+                    "description": "Toy VL",
+                    "version": "1.0",
+                    "type": "ELAN",
+                    "vnfd-connection-point-ref": [
+                        {
+                            "member-vnf-index-ref": 0,
+                            "vnfd-id-ref": "ba145e82-626b-11e5-998d-6cb3113b406f",
+                            "vnfd-connection-point-ref": "ping-pong-vnfd/cp0"
+                        }
+                    ]
+                }
+            ],
+            "constituent-vnfd": [
+                {
+                    "member-vnf-index": 0,
+                    "vnfd-id-ref": "ba145e82-626b-11e5-998d-6cb3113b406f"
+                },
+                {
+                    "member-vnf-index": 1,
+                    "vnfd-id-ref": "ba1947da-626b-11e5-998d-6cb3113b406f"
+                }
+            ],
+            "monitoring-param": [
+                 {
+                    "id": "ping-tx-rate-mp",
+                    "name": "Ping Transmit Rate",
+                    "description": "Ping transmit rate",
+                    "group-tag": "group-1",
+                    "min-value": 0,
+                    "max-value": 100,
+                    "current-value": 0,
+                    "widget-type": "GAUGE",
+                    "units": "gbps"
+                },
+                {
+                    "id": "ping-rc-rate-mp",
+                    "name": "Ping Receive Rate",
+                    "description": "Ping receive rate",
+                    "group-tag": "group-1",
+                    "min-value": 0,
+                    "max-value": 100,
+                    "current-value": 0,
+                    "widget-type": "GAUGE",
+                    "units": "gbps"
+                },
+                {
+                    "id": "ping-packet-size-mp",
+                    "name": "Ping Packet Size",
+                    "description": "Ping packet size",
+                    "group-tag": "group-2",
+                    "min-value": 0,
+                    "max-value": 100,
+                    "current-value": 10,
+                    "widget-type": "GAUGE",
+                    "units": "gbps"
+                },
+                {
+                    "id": "pong-tx-rate-mp",
+                    "name": "Pong Transmit Rate 2",
+                    "description": "Pong transmit rate",
+                    "group-tag": "group-2",
+                    "min-value": 0,
+                    "max-value": 100,
+                    "current-value": 0,
+                    "widget-type": "GAUGE",
+                    "units": "gbps"
+                },
+                {
+                    "id": "pong-rc-rate-mp",
+                    "name": "Pong Receive Rate 2",
+                    "description": "Pong eceive rate",
+                    "group-tag": "group-2",
+                    "min-value": 0,
+                    "max-value": 100,
+                    "current-value": 0,
+                    "widget-type": "GAUGE",
+                    "units": "gbps"
+                },
+                {
+                    "id": "pong-packet-size-mp",
+                    "name": "Pong Packet Size",
+                    "description": "Pong packet size",
+                    "group-tag": "group-2",
+                    "min-value": 0,
+                    "max-value": 100,
+                    "current-value": 10,
+                    "widget-type": "TEXTBOX",
+                    "units": "mb"
+                }
+            ]
+        }
+    ]
+}
+
diff --git a/rwlaunchpad/mock/data/ping-pong-vnfd.json b/rwlaunchpad/mock/data/ping-pong-vnfd.json
new file mode 100644
index 0000000..c96ee40
--- /dev/null
+++ b/rwlaunchpad/mock/data/ping-pong-vnfd.json
@@ -0,0 +1,396 @@
+{
+    "vnfd": [
+        {
+            "id": "ba145e82-626b-11e5-998d-6cb3113b406f",
+            "name": "ping-vnfd",
+            "short-name": "ping-vnfd",
+            "vendor": "RIFT.io",
+            "description": "This is an example RIFT.ware VNF",
+            "version": "1.0",
+            "internal-vld": [
+                {
+                    "id" : "ba1478fe-626b-11e5-998d-6cb3113b406f",
+                    "name": "fabric",
+                    "short-name": "fabric",
+                    "description": "Virtual link for internal fabric",
+                    "type": "ELAN"
+                }
+            ],
+            "connection-point": [
+                {
+                    "name": "ping-vnfd/cp0",
+                    "type": "VPORT"
+                },
+                {
+                    "name": "ping-vnfd/cp1",
+                    "type": "VPORT"
+                }
+            ],
+            "vdu": [
+                {
+                    "id": "ba14a504-626b-11e5-998d-6cb3113b406f",
+                    "name": "iovdu",
+                    "count": 2,
+                    "vm-flavor": {
+                        "vcpu-count": 4,
+                        "memory-mb": 1638,
+                        "storage-gb": 16
+                    },
+                    "guest-epa": {
+                        "trusted-execution": true,
+                        "mempage-size": "PREFER_LARGE",
+                        "cpu-pinning-policy": "DEDICATED",
+                        "cpu-thread-pinning-policy": "AVOID",
+                        "numa-node-policy": {
+                            "node-cnt": 2,
+                            "mem-policy": "PREFERRED",
+                            "node": [
+                                {
+                                    "id": 1,
+                                    "vcpu": [ 0, 1 ],
+                                    "memory-mb": 8192
+                                }
+                            ]
+                        }
+                    },
+                    "hypervisor-epa": {
+                            "type": "PREFER_KVM"
+                    },
+                    "host-epa": {
+                        "cpu-model": "PREFER_SANDYBRIDGE",
+                        "cpu-arch": "PREFER_X86_64",
+                        "cpu-vendor": "PREFER_INTEL",
+                        "cpu-socket-count": "PREFER_TWO",
+                        "cpu-feature": [ "PREFER_AES", "PREFER_CAT" ]
+                    },
+                    "image": "rw_openstack.qcow2",
+                    "internal-connection-point": [
+                        {
+                            "id": "ba153744-626b-11e5-998d-6cb3113b406f",
+                            "type": "VPORT"
+                        },
+                        {
+                            "id": "ba15577e-626b-11e5-998d-6cb3113b406f",
+                            "type": "VPORT"
+                        }
+                    ],
+                    "internal-interface": [
+                        {
+                            "name": "eth0",
+                            "vdu-internal-connection-point-ref": "ba153744-626b-11e5-998d-6cb3113b406f",
+                            "virtual-interface": {
+                                "type": "VIRTIO"
+                            }
+                        },
+                        {
+                            "name": "eth1",
+                            "vdu-internal-connection-point-ref": "ba15577e-626b-11e5-998d-6cb3113b406f",
+                            "virtual-interface": {
+                                "type": "VIRTIO"
+                            }
+                        }
+                    ],
+                    "external-interface": [
+                        {
+                            "name": "eth0",
+                            "vnfd-connection-point-ref": "ping-vnfd/cp0",
+                            "virtual-interface": {
+                                "type": "VIRTIO"
+                            }
+                        },
+                        {
+                            "name": "eth1",
+                            "vnfd-connection-point-ref": "ping-vnfd/cp1",
+                            "virtual-interface": {
+                                "type": "VIRTIO"
+                            }
+                        }
+                    ]
+                }
+            ],
+            "monitoring-param": [
+                {
+                    "id": "ping-tx-rate-mp",
+                    "name": "Ping Transmit Rate",
+                    "description": "Ping transmit rate",
+                    "group-tag": "group-1",
+                    "min-value": 0,
+                    "max-value": 100,
+                    "current-value": 10,
+                    "widget-type": "GAUGE",
+                    "units": "gbps"
+                },
+                {
+                    "id": "ping-rc-rate-mp",
+                    "name": "Ping Receive Rate",
+                    "description": "Ping receive rate",
+                    "group-tag": "group-1",
+                    "min-value": 0,
+                    "max-value": 100,
+                    "current-value": 10,
+                    "widget-type": "GAUGE",
+                    "units": "gbps"
+                },
+                {
+                    "id": "ping-packet-size-mp",
+                    "name": "Ping Packet Size",
+                    "description": "Ping packet size",
+                    "group-tag": "group-2",
+                    "min-value": 0,
+                    "max-value": 100,
+                    "current-value": 10,
+                    "widget-type": "GAUGE",
+                    "units": "gbps"
+                }
+            ],
+            "rw-vnfd:control-param": [
+                {
+                    "id": "ping-transmit-rate-cp1",
+                    "name": "Transmit Rate",
+                    "description": "Ping transmit rate",
+                    "group-tag": "group-3",
+                    "min-value": 0,
+                    "max-value": 100,
+                    "current-value": 10,
+                    "step-value": 1,
+                    "units": "gbps",
+                    "widget-type": "GAUGE",
+                    "url": "https://%s/api/operations/set-control-param",
+                    "operation": "POST",
+                    "payload": "{\"set-control-param\":{\"id\":\"%s\",\"obj-code\":\"VNFR\",\"control-id\":\"ping-transmit-rate-cp1\",\"value\":10} }"
+                },
+                {
+                    "id": "ping-packet-size-cp1",
+                    "name": "Ping Packet Size",
+                    "description": "Packet size",
+                    "group-tag": "group-4",
+                    "min-value": 0,
+                    "max-value": 100,
+                    "current-value": 10,
+                    "step-value": 1,
+                    "units": "gbps",
+                    "widget-type": "GAUGE",
+                    "url": "https://%s/api/operations/set-control-param",
+                    "operation": "POST",
+                    "payload": "{\"set-control-param\":{\"id\":\"%s\",\"obj-code\":\"VNFR\",\"control-id\":\"ping-packet-size-cp1\",\"value\":10 } }"
+                }
+            ],
+            "rw-vnfd:action-param" : [
+                {
+                    "id": "start-vnfr",
+                    "name": "Start PING",
+                    "description": "Start the PUNG VNFR",
+                    "group-tag": "start-vnfr",
+                    "url": "https://%s/api/operations/start-vnfr",
+                    "operation": "POST",
+                    "payload": "{\"start-vnfr\": { \"id\": \"%s\" }  }"
+                },
+                {
+                    "id": "stop-vnfr",
+                    "name": "Stop PING",
+                    "description": "Stop the PING VNFR",
+                    "group-tag": "stop-vnfr",
+                    "url": "https://%s/api/operations/stop-vnfr",
+                    "operation": "POST",
+                    "payload": "{\"stop-vnfr\": { \"id\": \"%s\" }  }"
+                }
+            ]
+        },
+        {
+            "id": "ba1947da-626b-11e5-998d-6cb3113b406f",
+            "name": "pong-vnfd",
+            "short-name": "pong-vnfd",
+            "vendor": "RIFT.io",
+            "description": "This is an example RIFT.ware VNF",
+            "version": "1.0",
+            "internal-vld": [
+                {
+                    "id" : "ba1478fe-626b-11e5-998d-6cb3113b406f",
+                    "name": "fabric",
+                    "short-name": "fabric",
+                    "description": "Virtual link for internal fabric",
+                    "type": "ELAN"
+                }
+            ],
+            "connection-point": [
+                {
+                    "name": "pong-vnfd/cp0",
+                    "type": "VPORT"
+                },
+                {
+                    "name": "pong-vnfd/cp1",
+                    "type": "VPORT"
+                }
+            ],
+            "vdu": [
+                {
+                    "id": "ba14a504-626b-11e5-998d-6cb3113b406f",
+                    "name": "iovdu",
+                    "count": 2,
+                    "vm-flavor": {
+                        "vcpu-count": 4,
+                        "memory-mb": 1638,
+                        "storage-gb": 16
+                    },
+                    "guest-epa": {
+                        "trusted-execution": true,
+                        "mempage-size": "PREFER_LARGE",
+                        "cpu-pinning-policy": "DEDICATED",
+                        "cpu-thread-pinning-policy": "AVOID",
+                        "numa-node-policy": {
+                            "node-cnt": 2,
+                            "mem-policy": "PREFERRED",
+                            "node": [
+                                {
+                                    "id": 1,
+                                    "vcpu": [ 0, 1 ],
+                                    "memory-mb": 8192
+                                }
+                            ]
+                        }
+                    },
+                    "hypervisor-epa": {
+                            "type": "PREFER_KVM"
+                    },
+                    "host-epa": {
+                        "cpu-model": "PREFER_SANDYBRIDGE",
+                        "cpu-arch": "PREFER_X86_64",
+                        "cpu-vendor": "PREFER_INTEL",
+                        "cpu-socket-count": "PREFER_TWO",
+                        "cpu-feature": [ "PREFER_AES", "PREFER_CAT" ]
+                    },
+                    "image": "rw_openstack.qcow2",
+                    "internal-connection-point": [
+                        {
+                            "id": "ba153744-626b-11e5-998d-6cb3113b406f",
+                            "type": "VPORT"
+                        },
+                        {
+                            "id": "ba15577e-626b-11e5-998d-6cb3113b406f",
+                            "type": "VPORT"
+                        }
+                    ],
+                    "internal-interface": [
+                        {
+                            "name": "eth0",
+                            "vdu-internal-connection-point-ref": "ba153744-626b-11e5-998d-6cb3113b406f",
+                            "virtual-interface": {
+                                "type": "VIRTIO"
+                            }
+                        },
+                        {
+                            "name": "eth1",
+                            "vdu-internal-connection-point-ref": "ba15577e-626b-11e5-998d-6cb3113b406f",
+                            "virtual-interface": {
+                                "type": "VIRTIO"
+                            }
+                        }
+                    ],
+                    "external-interface": [
+                        {
+                            "name": "eth0",
+                            "vnfd-connection-point-ref": "pong-vnfd/cp0",
+                            "virtual-interface": {
+                                "type": "VIRTIO"
+                            }
+                        },
+                        {
+                            "name": "eth1",
+                            "vnfd-connection-point-ref": "pong-vnfd/cp1",
+                            "virtual-interface": {
+                                "type": "VIRTIO"
+                            }
+                        }
+                    ]
+                }
+            ],
+            "monitoring-param": [
+                {
+                    "id": "pong-tx-rate-mp",
+                    "name": "Pong Transmit Rate",
+                    "description": "Pong transmit rate",
+                    "group-tag": "group-1",
+                    "min-value": 0,
+                    "max-value": 100,
+                    "current-value": 10,
+                    "widget-type": "GAUGE",
+                    "units": "gbps"
+                },
+                {
+                    "id": "pong-rx-rate-mp",
+                    "name": "Pong Receive Rate",
+                    "description": "Pong receive rate",
+                    "group-tag": "group-1",
+                    "min-value": 0,
+                    "max-value": 100,
+                    "current-value": 10,
+                    "widget-type": "GAUGE",
+                    "units": "gbps"
+                },
+                {
+                    "id": "pong-packet-size-mp",
+                    "name": "Pong Packet Size",
+                    "description": "Pong packet size",
+                    "group-tag": "group-2",
+                    "min-value": 0,
+                    "max-value": 100,
+                    "current-value": 10,
+                    "widget-type": "TEXTBOX",
+                    "units": "mb"
+                }
+            ],
+            "rw-vnfd:control-param" : [
+                {
+                    "id": "pong-receive-rate-cp1",
+                    "name": "Pong Receive Rate",
+                    "description": "Pong receive rate",
+                    "group-tag": "group-3",
+                    "min-value": 0,
+                    "max-value": 100,
+                    "current-value": 0,
+                    "step-value": 1,
+                    "units": "gbps",
+                    "widget-type": "GAUGE",
+                    "url": "https://{host}/api/operations/vnfr-control-param/",
+                    "operation": "POST",
+                    "payload": "{\"set-control-param\":{\"id\":\"%s\",\"obj-code\":\"VNFR\",\"control-id\":\"pong-receive-rate-cp1\",\"value\":10} }"
+                },
+                {
+                    "id": "pong-packet-size-cp1",
+                    "name": "Pong Packaet Size",
+                    "description": "Packet size",
+                    "group-tag": "group-4",
+                    "min-value": 0,
+                    "max-value": 100,
+                    "current-value": 0,
+                    "step-value": 1,
+                    "units": "gbps",
+                    "widget-type": "GAUGE",
+                    "url": "https://%s/api/operations/set-control-param",
+                    "operation": "POST",
+                    "payload": "{\"set-control-param\":{\"id\":\"%s\",\"obj-code\":\"VNFR\",\"control-id\":\"pong-packet-size-cp1\",\"value\":10 } }"
+                }
+            ],
+            "rw-vnfd:action-param" : [
+                {
+                    "id": "start-vnfr",
+                    "name": "Start PONG",
+                    "description": "Start the PONG VNFR",
+                    "group-tag": "start-vnfr",
+                    "url": "https://%s/api/operations/start-vnfr",
+                    "operation": "POST",
+                    "payload": "{\"start-vnfr\": { \"id\": \"%s\" }  }"
+                },
+                {
+                    "id": "stop-vnfr",
+                    "name": "Stop PONG",
+                    "description": "Stop the PONG VNFR",
+                    "group-tag": "stop-vnfr",
+                    "url": "https://%s/api/operations/stop-vnfr",
+                    "operation": "POST",
+                    "payload": "{\"stop-vnfr\": { \"id\": \"%s\" }  }"
+                }
+            ]
+       }
+   ]
+}
diff --git a/rwlaunchpad/mock/data/simmp-rules.json b/rwlaunchpad/mock/data/simmp-rules.json
new file mode 100644
index 0000000..d92f835
--- /dev/null
+++ b/rwlaunchpad/mock/data/simmp-rules.json
@@ -0,0 +1,11 @@
+{
+    "description": "Rules for Simulating monitoring params",
+    "mp-mapper": {
+        "ping-tx-rate-mp": "tx_rc_rate",
+        "ping-rc-rate-mp": "tx_rc_rate",
+        "pong-tx-rate-mp": "tx_rc_rate",
+        "pong-rc-rate-mp": "tx_rc_rate",
+        "ping-packet-size-mp": "packet_size",
+        "pong-packet-size-mp": "packet_size"
+    }
+}
diff --git a/rwlaunchpad/mock/data/vld_catalog.json b/rwlaunchpad/mock/data/vld_catalog.json
new file mode 100644
index 0000000..0de0e29
--- /dev/null
+++ b/rwlaunchpad/mock/data/vld_catalog.json
@@ -0,0 +1,16 @@
+{
+    "vld": [
+        {
+            "id": "a631e8c6-663a-11e5-b122-6cb3113b406f",
+            "name": "vld-one"
+        },
+        {
+            "id": "b631e8c6-663a-11e5-b122-6cb3113b406f",
+            "name": "vld-two"
+        },
+        {
+            "id": "c631e8c6-663a-11e5-b122-6cb3113b406f",
+            "name": "vld-three"
+        }
+    ]
+}
diff --git a/rwlaunchpad/mock/data/vnfd_catalog.json b/rwlaunchpad/mock/data/vnfd_catalog.json
new file mode 100644
index 0000000..1951980
--- /dev/null
+++ b/rwlaunchpad/mock/data/vnfd_catalog.json
@@ -0,0 +1,47 @@
+{
+    "vnfd": [
+        {
+            "id": "a200a0a0-663a-11e5-b122-6cb3113b406f",
+            "name": "Virtual Network Descriptor 1",
+            "short-name": "VNFD1",
+            "vendor": "RIFT.io",
+            "description": "This is a description. It doesn't say much",
+            "version": "0.0.1",
+            "internal-vld": [
+                    {
+                        "id" : "68981800-7201-11e5-9fc4-bf5ad0442ce5",
+                        "name": "Zathrus",
+                        "short-name": "zathrus",
+                        "description": "Virtual link for zathrus",
+                        "type": "ELAN",
+                        "root-bandwidth": 42,
+                        "leaf-bandwidth": 42,
+                        "internal-connection-point-ref": [
+
+                            ]
+                    }
+              ]
+        },
+        {
+            "id": "b200a0a0-663a-11e5-b122-6cb3113b406f",
+            "name": "vnfd-two",
+            "short-name": "VNFD2",
+            "vendor": "RIFT.io",
+             "description": "This is a description. It doesn't say much",
+            "version": "0.0.1",
+            "internal-vld": [
+
+            ]
+        },
+        {
+            "id": "c200a0a0-663a-11e5-b122-6cb3113b406f",
+            "name": "vnfd-three",
+            "short-name": "VNFD03",
+            "vendor": "RIFT.io",
+            "description": "This is a description. It doesn't say much",
+            "version": "0.0.1",
+            "internal-vld": [
+            ]
+        }
+    ]
+}
diff --git a/rwlaunchpad/mock/data/vnfr-templates.json b/rwlaunchpad/mock/data/vnfr-templates.json
new file mode 100644
index 0000000..a93dafb
--- /dev/null
+++ b/rwlaunchpad/mock/data/vnfr-templates.json
@@ -0,0 +1,54 @@
+[
+    {
+        "action_param": [
+            {
+                "id": "actionparam01",
+                "name": "Start Me Up",
+                "description": "This is a description. It doesn't say much",
+                "group_tag": "control-group1",
+                "url": "http://localhost:8091/vnfr/1/start"
+            },
+            {
+                "id": "actionparam02",
+                "name": "Stop me",
+                "description": "This is a description. It doesn't say much",
+                "group_tag": "control-group1",
+                "url": "http://localhost:8091/vnfr/1/stop",
+                "operation": "POST"
+            }
+        ],
+       "control_param": [
+            {
+                "id": "controlparam01",
+                "name": "Control Param 1",
+                "description": "This is a description. It doesn't say much",
+                "group_tag": "control-group1",
+                "min_value": 0,
+                "max_value": 100,
+                "current_value": 0,
+                "step_value": 1,
+                "units": "smoots",
+                "widget_type": "HISTOGRAM",
+                "url": "http://localhost:8091/vnfr/1/control-1",
+                "operation": "POST",
+                "payload": "{ \"test\": \"sample value\" }"
+            },
+            {
+                "id": "controlparam02",
+                "name": "Control Param 2",
+                "description": "This is a description. It doesn't say much",
+                "group_tag": "control-group1",
+                "min_value": 0,
+                "max_value": 100,
+                "current_value": 0,
+                "step_value": 1,
+                "units": "smoots",
+                "widget_type": "GAUGE",
+                "url": "http://localhost:8091/vnfr/1/control-2",
+                "operation": "POST",
+                "payload": "{ \"test\": \"sample value\" }"
+            }
+        ]
+    }
+]
+
diff --git a/rwlaunchpad/mock/data_model.js b/rwlaunchpad/mock/data_model.js
new file mode 100644
index 0000000..ef56c68
--- /dev/null
+++ b/rwlaunchpad/mock/data_model.js
@@ -0,0 +1,569 @@
+/*
+ *  This module provides the data model layer for the Launchpad Mocklet
+ */
+
+var util = require('util');
+var uuid = require('node-uuid');
+var _ = require('lodash');
+
+// Our modules
+var simmp_module = require('./simmp.js');
+
+// Data packages
+// TODO: Make these parameters to pass to the data model
+// instead of hardcoding them as requires here
+var simmp_rules = require('./data/simmp-rules.json');
+var nsr_templates = require('./data/nsr-templates.json');
+var vnfr_templates = require('./data/vnfr-templates.json');
+
+/*
+ * Generic  to throw on data model exceptions
+ */
+function DataModelException(message) {
+    this.message = message;
+    this.name = "DataModelException";
+}
+
+/*
+ * This 
+ * This function is temporary until all needed features are implemented in this mocklet
+ */
+function NotImplementedException(message) {
+    this.message = "You have fallen off the edge of the world: "+message;
+    this.name = 'NotImplementedException';
+}
+
+
+/*
+ * Class to handle simulating events over time for monitoring params
+ */
+MonitoringParam = function(values, time_function) {
+    this.values = values;
+    this.timeFunc = time_function;
+}
+
+MonitoringParam.prototype.timeStep = function(elapsed_seconds) {
+    this.values.current_value = this.timeFunc(this.values.current_value,
+            elapsed_seconds);
+    return this.values.current_value;
+};
+
+/*
+ * DataModel constructor
+ *
+ * Arguments
+ *   restconf_host - Host name and port. eg: 'localhost:8008'
+ */
+DataModel = function (restconf_host) {
+    this.restconf_host = restconf_host ? restconf_host : "localhost:8008";
+
+    this.simmp = new simmp_module.SimMp(simmp_rules);
+    if (!this.simmp) {
+        throw "simmp failed to initialize";
+    }
+    // Time data for event simulation (monitoring params)
+    this.start_time = Date.now();
+    this.previous_time =this.start_time;
+
+    // Store descriptors
+    this.descriptors = { nsd: {}, vnfd: {}, vld: {} };
+
+    // Store instance config data. Currently only NS Yang implements config data
+    this.config_records = { nsr: {}, vnfr: {}, vlr: {} };
+
+    // Stores Virtual Network Function instance records
+    this.vnfr_records = { };
+
+    // Stores Network Service instance operational records
+    this.ns_opdata_records = { };
+
+    // Manage which mock data to use next
+    this.vnfr_template_index = 0;
+    this.nsr_template_index = 0;
+
+    // Operational (running) state for opdata records
+    // 'on', 'off'
+    // TBD: do restarting
+    this.opstate = { nsr: {}, vnfr: {} };
+
+    // Store MonitoringParam objects
+    this.monitoring_params = {nsr: {}, vnfr: {} };
+}
+
+
+/*
+ * creates a descriptor name from the record name
+ */
+DataModel.prototype.rec2desc = function (record_type) {
+    if (record_type.charAt(record_type.lenth-1) == 'r') {
+        return record_type.slice(0, -1)+'d';
+    } else if (["ns","vnf","vl"].indexOf(record_type_) != -1) {
+        return record_type + 'd';
+    } else {
+        throw new DataModelException('"%s" is not a supported record type', record_type);
+    }
+};
+
+DataModel.prototype.setDescriptor = function(descriptor_type, descriptor) {
+        if (!this.descriptors.hasOwnProperty(descriptor_type)) {
+            throw new DataModelException('"%s" is not a supported descriptor type', descriptor_type);
+        }
+
+        this.descriptors[descriptor_type][descriptor.id] = descriptor;
+};
+
+DataModel.prototype.setConfigRecord = function(record_type, record) {
+         if (!this.config_records.hasOwnProperty(record_type)) {
+            throw new DataModelException('"%s" is not a supported record type', record_type);
+        }
+
+        this.config_records[record_type][record.id] = record;
+};
+
+DataModel.prototype.findConfigRecord = function(record_type, record_id) {
+        if (this.config_records.hasOwnProperty(record_type)) {
+            return this.config_records[record_type][record_id];
+        } else {
+            return null;
+        }
+};
+
+/*
+ *
+ */
+DataModel.prototype.updateControlParam = function(record_type, record_id,
+        control_id, value) {
+    if (record_type == 'vnfr') {
+        var record = this.vnfr_records[record_id];
+    } else {
+        var record = this.ns_opdata_records[record_id];
+    }
+    // find the control param
+    if ('control_param' in record) {
+        for (var i=0; i < record.control_param.length; i++) {
+            if (control_id == record.control_param[i].id) {
+                // Make sure value is within min and max values
+                if (value >= record.control_param[i].min_value &&
+                    value <= record.control_param[i].max_value) {
+
+                    record.control_param[i].current_value = value;
+                    return 'SUCCESS';
+                } else {
+                    var errmsg = 'value "'+value+'" out of range. '+
+                        'Needs to be within '+ record_control_param[i].min_value +
+                        ' and ' + record_control_param[i].max_value;
+                    throw new DataModelException(errmsg);
+                }
+            }
+        }
+    } else {
+        var errmsg = 'Record type "' + record_type + '" with id "'+
+            record_id + '" does not have any control params';
+        throw new DataModelException(errmsg);
+    }
+};
+
+/*
+ * NS functions
+ *
+ * General comments on NS instance config/opdata:
+ *  For each ns-instance-config, the descriptor needs to be added first
+ */
+
+// TODO: Consolidate the template handling functions
+DataModel.prototype.nextNsrTemplate = function() {
+    var nsr_template = _.clone(nsr_templates[this.nsr_template_index], true);
+    this.nsr_template_index += 1;
+    if (this.nsr_template_index >= nsr_templates.length) {
+        this.nsr_template_index = 0;
+    }
+    return nsr_template;
+};
+
+DataModel.prototype.getNsdConnectionPoints = function(nsd_id) {
+    var nsd =  this.descriptors['nsd'][nsd_id];
+    if (!nsd) {
+        throw new DataModelException("NSD ID '%s' does not exist", nsd_id);
+    }
+    // console.log("\n\nnsd = %s", JSON.stringify(nsd));
+    return nsd['connection_point'];
+};
+
+
+DataModel.prototype.createNsrControlParams = function(ns_instance_config_id) {
+    // TODO: find all VNFDs associated with this NS instance
+    // then either call this.createVnfrControlParams if you want to talk
+    // VNFR specific control params or we can generalize 'createVnfrControlParams'
+    // to pass in 'record_id' instead of vnfr_id.
+    //
+    var control_params = [];
+
+    return control_params;
+};
+
+/*
+ * Sets an ns-instance-config object record and creates an
+ * ns-instance-opdata record.
+ *
+ * If the NS instance opdata record matching the id of the ns-instance-config
+ * already exists, then remove the ns-instance-opdate record and reconstruct.
+ */
+DataModel.prototype.setNsInstanceConfig = function(ns_instance_config) {
+    // we are updating an existing ns-instance record set
+    // There is an issue that subsequent 'PUT' actions do not transfer
+    // the whole data to the mocklet. So we need to retrieve the existingt
+    // ns-instance-config to get the nsd-ref
+
+    // TODO: Consider creating a 'set_or_update' method for ns-instance-config
+    var ns_config = this.findConfigRecord('nsr', ns_instance_config.id);
+    if (ns_config) {
+        ns_config.admin_status = ns_instance_config.admin_status;
+    } else {
+        this.setConfigRecord('nsr', ns_instance_config);
+        ns_config = ns_instance_config;
+    }
+    if (ns_config.id in this.ns_opdata_records) {
+        delete this.ns_opdata_records[ns_config.id];
+    }
+    // if ns-instance-config is 'ENABLED', then create an ns-instance-opdata
+    if (ns_config.admin_status == 'ENABLED') {
+        ns_opdata = this.generateNsInstanceOpdata(ns_config);
+        // set the ns instance opdata. Doesn't matter if it already exists
+        this.ns_opdata_records[ns_opdata.ns_instance_config_ref] = ns_opdata;
+    }
+};
+
+DataModel.prototype.generateMonitoringParams = function(descriptor_type, descriptor_id) {
+    console.log('Called generateMonitoringParams');
+    if (!(descriptor_type in this.descriptors)) {
+        throw DataModelException('descriptor type "%s" not found');
+    }
+    var descriptor = this.descriptors[descriptor_type][descriptor_id];
+    var a_simmp = this.simmp;
+    if (descriptor) {
+        if ('monitoring_param' in descriptor) {
+            return descriptor['monitoring_param'].map(function(obj) {
+                var simFunc = a_simmp.createSimMonitorFunc(obj);
+                return new MonitoringParam(_.clone(obj, true), simFunc);
+            });
+        } else {
+            console.log('Descriptor(type=%s) with (id=%s) does not have ' +
+               'monitoring params', descriptor_type, descriptor_id);
+            return [];
+        }
+    } else {
+        throw new DataModelException("Cannot find descriptor %s with id '%s'",
+                descriptor_type, descriptor_id);
+    }
+};
+
+DataModel.prototype.updateMonitoringParams = function(instance_type, instance_id) {
+    var sim_mp = this.monitoring_params[instance_type][instance_id];
+    if (sim_mp) {
+        var time_now = Date.now();
+        var elapsed_seconds = (time_now - this.previous_time) / 1000;
+        var monitoring_params = sim_mp.map(function(obj) {
+            obj.timeStep(elapsed_seconds);
+            return obj.values;
+        });
+        this.previous_time = time_now;
+        return monitoring_params;
+    } else {
+        // TODO: Figure out hosw we want to handle this case
+        return [];
+    }
+};
+
+/*
+ * Creates an ns-instance-opdata object, but does not add it to the data
+ * store.
+ */
+DataModel.prototype.generateNsInstanceOpdata = function (ns_config) {
+    var nsr_template = this.nextNsrTemplate();
+
+    // HACK: We need to get control and action param from the nsr
+    // or have a function that synchronizes the next array element in
+    // the templates
+    var vnfr_template = this.nextVnfrTemplate();
+
+    var nsd_id = ns_config.nsd_ref;
+    var connection_points = this.getNsdConnectionPoints(ns_config.nsd_ref);
+    var sim_mp = this.generateMonitoringParams('nsd', nsd_id);
+    // save for using in update
+    this.monitoring_params['nsr'][ns_config.id] = sim_mp;
+    var monitoring_params = sim_mp.map(function(obj) {
+        // not time stepping when we create them
+        return obj.values;
+    });
+
+    return {
+        ns_instance_config_ref: ns_config.id,
+        'connection_point' : _.clone(connection_points, true),
+        epa_param: _.clone(nsr_template['epa_param'], true),
+        // NOTE: Remarked out until nfvi metrics figured out
+        //nfvi_metric: _.clone(nsr_template['nfvi_metric'], true),
+        monitoring_param: monitoring_params,
+        //monitoring_param: _.clone(nsr_template['monitoring_param'], true),
+        create_time: nsr_template['create_time'],
+        action_param: vnfr_template['action_param'],
+        // TODO: control_param: this.createNsrControlParams(ns_config.id);
+        control_param: vnfr_template['control_param']
+    };
+};
+
+DataModel.prototype.getNsInstanceOpdata = function() {
+    var opdata_records = [];
+    var config_records = this.config_records['nsr'];
+    for (config_record_id in config_records) {
+        if (config_records[config_record_id]['admin_status'] == 'ENABLED') {
+            console.log('Is ENABLED: ns-instance-config record with id %s', config_record_id);
+
+            ns_op_rec = this.ns_opdata_records[config_record_id];
+            if (ns_op_rec) {
+                // TODO: update monitoring params
+                ns_op_rec.monitoring_param = this.updateMonitoringParams(
+                        'nsr', config_record_id);
+                opdata_records.push(ns_op_rec);
+            } else {
+                console.log('NO RECORD FOUND for ns config id: %s', config_record_id);
+            }
+        } else {
+            console.log('Either no admin status record or not enabled');
+        }
+    }
+    return opdata_records;
+};
+
+
+/* =============
+ * VNF functions
+ * =============
+ */
+
+/*
+ * Gets the next VNFR template from the array of VNFR templates and 
+ * increments the VNFR template counter. Wraps back to the first VNFR
+ * template when the last one is used.
+ */
+DataModel.prototype.nextVnfrTemplate = function() {
+    var vnfr_template = _.clone(vnfr_templates[this.vnfr_template_index], true);
+    this.vnfr_template_index += 1;
+    if (this.vnfr_template_index >= vnfr_templates.length) {
+        this.vnfr_template_index = 0;
+    }
+    return vnfr_template;
+}
+
+/*
+ * Arguments
+ *  vnfd - VNF Descriptor object
+ *  vnfr_id - VNFR unique identifier
+ *  host  - host name and port
+ */
+DataModel.prototype.createVnfrActionParams = function(vnfd, vnfr_id) {
+    // Canned start, stop for now
+    // TBD: read action params from VNFD and create here
+    // Use
+    var action_param = [
+        {
+            id: uuid.v1(),
+            name: "Start Me",
+            description: "Start this VNFR",
+            group_tag: "start-vnfr",
+            url: "https://"+this.restconf_host+"/api/operations/start-vnfr",
+            operation: "POST",
+            payload: '{"start-vnfr": { "id": "'+vnfr_id+'"}}'
+        },
+        {
+            id: uuid.v1(),
+            name: "Stop Me",
+            description: "Stop this VNFR",
+            group_tag: "stop-vnfr",
+            url: "https://"+this.restconf_host+"/api/operations/stop-vnfr",
+            operation: "POST",
+            payload: '{"stop-vnfr": { "id": "'+vnfr_id+'"}}'
+        }
+    ];
+    return action_param;
+};
+
+DataModel.prototype.createVnfrControlParams = function(vnfd, vnfr_id,
+        vnfr_template) {
+    console.log("Called Datamodel.prototype.createVnfrControlParams");
+    if (vnfr_template) {
+        console.log("returning clone of vnfr_template['control_param']");
+        return _.clone(vnfr_template['control_param'], true);
+    } else {
+        if (vnfd.control_param) {
+            console.log("VNFD's control-param="+JSON.stringify(vnfd.control_param));
+            var a_restconf_host = this.restconf_host;
+            var cp_arry = _.clone(vnfd.control_param, true);
+            var control_params = vnfd.control_param.map(function(obj) {
+                var cp = _.clone(obj, true);
+                cp.url = util.format(cp.url, a_restconf_host);
+                console.log("\ncontrol-param payload before:"+ cp.payload);
+                cp.payload = util.format(cp.payload, vnfr_id);
+                console.log("\ncontrol-param payload after:"+ cp.payload+"\n");
+                return cp;
+            });
+            return control_params;
+        } else {
+            return [];
+        }
+        throw new NotImplementedException("createVnfrControlParam: non-template");
+    }
+}
+
+/*
+ * Creates a new VNFR base on the VNFD in the argument.
+ * This method is intended to not have side effects, otherwise
+ * just put this code in this.addVnfData
+ */
+DataModel.prototype.createVnfr = function(vnfd) {
+    //var vnfr_template = this.nextVnfrTemplate();
+    var vnfr_id = uuid.v1();
+
+    return {
+        id: vnfr_id,
+        // Hack: Copy the VNFD values but append '-Record' to end
+        name: vnfd.name + ' Record',
+        short_name: vnfd.short_name + '_REC',
+        vendor: vnfd.vendor,
+        description: vnfd.description,
+        version: vnfd.version,
+        vnfd_ref: vnfd.id,
+        internal_vlr: [],
+        // Even though this is in the Yang, it doesn't exist in the
+        // instantiated model:
+        // 'internal_connection_point_ref': [],
+        action_param: this.createVnfrActionParams(vnfd, vnfr_id),
+        //control_param: _.clone(vnfr_template['control_param'], true)
+        control_param: this.createVnfrControlParams(vnfd, vnfr_id)
+    };
+};
+
+
+/*
+ * Creates and adds a new VNFD and matching VNFR record to our data store
+ *
+ * TODO: Might need to be updated so we create a VNFR when a start VNFR is called
+ *
+ */
+DataModel.prototype.addVnfData = function(vnfd) {
+    // if the vnfd does not already exist:
+    if (this.descriptors['vnfd'][vnfd.id] == null) {
+        console.log("adding new vnfd with id %s", vnfd.id);
+        this.setDescriptor('vnfd', vnfd);
+        // create a vnfr record, but without monitoring-param
+        var vnfr = this.createVnfr(vnfd);
+
+        var sim_mp = this.generateMonitoringParams('vnfd', vnfd.id);
+        // save for using in update
+        this.monitoring_params['vnfr'][vnfr.id] = sim_mp;
+        vnfr.monitoring_param = sim_mp.map(function(obj) {
+            // not time stepping when we create them
+            return obj.values;
+        });
+        this.vnfr_records[vnfr.id] = vnfr;
+    } else {
+        // do nothing
+    }
+};
+
+
+DataModel.prototype.getVnfrs = function () {
+    records = [];
+    for (vnfr_id in this.vnfr_records) {
+        // When admin-status is implemented, then return only those 'ENABLED'
+        var vnfr_record = this.vnfr_records[vnfr_id];
+        vnfr_record.monitoring_param = this.updateMonitoringParams(
+                'vnfr', vnfr_id);
+        records.push(vnfr_record);
+    }
+    return records;
+}
+
+
+// Move the following to a new VnfrManager class
+
+DataModel.prototype.startVnfr = function(vnfr_id) {
+    console.log('Calling DataModel.startVnfr with id "%s"', vnfr_id);
+
+    console.log('Here are the VNFR ids we have:');
+    for (key in this.vnfr_records) {
+        console.log('id:%s"', key);
+    }
+    //console.log('vnfr_records = %s', JSON.stringify(this.vnfr_records));
+
+    if (!(vnfr_id in this.vnfr_records)) {
+        var errmsg = 'Cannot find vnfr record with id "'+vnfr_id+'"';
+        console.error('\n\n'+errmsg+'\n\n');
+        throw new DataModelException(errmsg);
+    }
+    // Just add/set it
+    this.opstate.vnfr[vnfr_id] = 'ON';
+    return this.vnfr_records[vnfr_id];
+}
+
+DataModel.prototype.stopVnfr = function(vnfr_id) {
+    console.log('Calling DataModel.stopVnfr with id "%s"', vnfr_id);
+    if (!(vnfr_id in this.vnfr_records)) {
+        var errmsg = 'Cannot find vnfr record with id "'+vnfr_id+'"';
+        console.error(errmsg);
+        throw new DataModelException(errmsg);
+    }
+    // Just add/set it
+    this.opstate.vnfr[vnfr_id] = 'OFF';
+    return this.vnfr_records[vnfr_id];
+}
+
+DataModel.prototype.vnfrRunningState = function(vnfr_id) {
+    if (!(vnfr_id in this.vnfr_records)) {
+        throw new DataModelException(
+                'DataModel.stopVnfr: Cannot find VNFR with id "%s"', vnfr_id);
+    }
+    if (vnfr_id in this.opstate.vnfr) {
+        return this.opstate.vnfr[vnfr_data];
+    } else {
+        // Assume we are 'ON'
+        return 'ON';
+    }
+}
+
+
+/* ==========================
+ * Debug and helper functions
+ * ==========================
+ */
+
+DataModel.prototype.prettyPrint = function (out) {
+    if (out == undefined) {
+        out = console.log;
+    }
+    out('Descriptors:');
+    for (descriptor_type in this.descriptors) {
+        out("Descriptor type: %s", descriptor_type);
+        for (descriptor_id in this.descriptors[descriptor_type]) {
+            out("data=%s",descriptor_id,
+                    JSON.stringify(this.descriptors[descriptor_type][descriptor_id]));
+        };
+    };
+
+    out('\nConfigRecords:');
+    for (record_type in this.config_records) {
+        out("Record type: %s", record_type);
+        for (record_id in this.config_records[record_type]) {
+            out("data=%s", record_id,
+                    JSON.stringify(this.config_records[record_type][record_id]));
+        };
+    };
+};
+
+
+module.exports = {
+    DataModelException: DataModelException,
+    NotImplementedException: NotImplementedException,
+    MonitoringParam: MonitoringParam,
+    DataModel: DataModel
+};
+
diff --git a/rwlaunchpad/mock/get_data.sh b/rwlaunchpad/mock/get_data.sh
new file mode 100755
index 0000000..508275c
--- /dev/null
+++ b/rwlaunchpad/mock/get_data.sh
@@ -0,0 +1,58 @@
+#!/bin/bash
+
+# 
+#   Copyright 2016 RIFT.IO Inc
+#
+#   Licensed under the Apache License, Version 2.0 (the "License");
+#   you may not use this file except in compliance with the License.
+#   You may obtain a copy of the License at
+#
+#       http://www.apache.org/licenses/LICENSE-2.0
+#
+#   Unless required by applicable law or agreed to in writing, software
+#   distributed under the License is distributed on an "AS IS" BASIS,
+#   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+#   See the License for the specific language governing permissions and
+#   limitations under the License.
+#
+
+#
+# This is a convenience script to get descriptors from the RESTConf server
+#
+# Provide the RESTConf hostname as the argument or default to localhost
+
+if [ $# -eq 0 ] ; then
+    HOST=localhost
+else
+    HOST=$1
+fi
+
+echo "Getting descriptor data from $IP"
+
+for descriptor in nsd vnfd vld
+do
+
+    printf "retrieving $descriptor:\n\n"
+
+    curl --user admin:admin \
+        -H "Content-Type: application/vnd.yang.data+json" \
+        -H "accept: application/vnd.yang.data+json" \
+        http://$HOST:8008/api/running/$descriptor-catalog/
+
+done
+
+rectype='ns'
+
+    curl --user admin:admin \
+        -H "Content-Type: application/vnd.yang.data+json" \
+        -H "accept: application/vnd.yang.data+json" \
+        http://$HOST:8008/api/running/$rectype-instance-config/
+
+
+    curl --user admin:admin \
+        -H "Content-Type: application/vnd.yang.data+json" \
+        -H "accept: application/vnd.yang.data+json" \
+        http://$HOST:8008/api/operational/$rectype-instance-opdata/
+
+
+
diff --git a/rwlaunchpad/mock/get_ns_instance_opdata.sh b/rwlaunchpad/mock/get_ns_instance_opdata.sh
new file mode 100755
index 0000000..582fec1
--- /dev/null
+++ b/rwlaunchpad/mock/get_ns_instance_opdata.sh
@@ -0,0 +1,34 @@
+#!/bin/bash
+
+# 
+#   Copyright 2016 RIFT.IO Inc
+#
+#   Licensed under the Apache License, Version 2.0 (the "License");
+#   you may not use this file except in compliance with the License.
+#   You may obtain a copy of the License at
+#
+#       http://www.apache.org/licenses/LICENSE-2.0
+#
+#   Unless required by applicable law or agreed to in writing, software
+#   distributed under the License is distributed on an "AS IS" BASIS,
+#   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+#   See the License for the specific language governing permissions and
+#   limitations under the License.
+#
+
+#
+# Provide the RESTConf hostname as the argument or default to localhost
+
+if [ $# -eq 0 ] ; then
+    HOST=localhost
+else
+    HOST=$1
+fi
+
+echo "Getting NS instance opdata from $IP"
+
+curl --user admin:admin \
+    -H "Content-Type: application/vnd.yang.data+json" \
+    -H "accept: application/vnd.yang.data+json" \
+    http://$HOST:8008/api/operational/ns-instance-opdata/
+
diff --git a/rwlaunchpad/mock/lp_mock_client.js b/rwlaunchpad/mock/lp_mock_client.js
new file mode 100644
index 0000000..6de0842
--- /dev/null
+++ b/rwlaunchpad/mock/lp_mock_client.js
@@ -0,0 +1,317 @@
+AUTOBAHN_DEBUG = true;
+var autobahn = require('autobahn');
+var uuid = require('node-uuid');
+var _ = require('lodash');
+
+// Our modules
+var dm = require('./data_model.js');
+
+
+var DUMP_RESULTS = false;
+
+// TODO: make the url be configurable via command line arg
+var connection = new autobahn.Connection({
+    url: 'ws://localhost:8090/ws',
+    realm: 'dts_mock'
+});
+
+// Instance of our data model/data store
+var dataModel = new dm.DataModel();
+
+var descriptor_module = (function () {
+
+    my = {};
+
+    /*
+     * This function sets descriptors in the dataModel
+     */
+    function on_config_descriptor_catalog(args) {
+        try {
+            var xpath = args[0];
+            var msg = args[1];
+
+            console.log("\n\n*** Got on_config_descriptor_catalog:\n    (xpath: %s)(msg: %j)", xpath, msg);
+
+            var descriptor_type = xpath.match(new RegExp(/(nsd|vnfd|vld)-catalog/))[1];
+
+            if (descriptor_type in msg) {
+                msg[descriptor_type].forEach(function(entry) {
+                    console.log('Assigning descriptor "%s" with id %s',
+                        descriptor_type, entry.id);
+                    if (descriptor_type == 'vnfd') {
+                        console.log('-- Adding VNFR data');
+                        dataModel.addVnfData(entry);
+                    } else {
+                        // Simply assign
+                        dataModel.setDescriptor(descriptor_type, entry);
+                    }
+                });
+            }
+        } catch(e) {
+            console.error("Caught exception: %s\n\n%s", e, e.stack);
+        }
+    }
+
+    my.register = function (session) {
+        console.log('Registering for descriptor handling');
+        session.subscribe('dts.config.nsd-catalog', on_config_descriptor_catalog);
+        session.subscribe('dts.config.vnfd-catalog', on_config_descriptor_catalog);
+        session.subscribe('dts.config.vld-catalog', on_config_descriptor_catalog);
+    };
+
+    return my;
+}());
+
+
+var instance_module = (function () {
+    my = {};
+
+   function on_config_config(args) {
+        try {
+            var xpath = args[0];
+            var msg = args[1];
+
+            console.log("\n\n*** Got on_config_config:\n    (xpath: %s)(msg: %j)", xpath, msg);
+
+            var record_type = xpath.match(new RegExp(/(ns|vnf|vl)-instance-config/))[1];
+            record_type += 'r';
+
+            console.log('record_type = %s', record_type);
+
+            if (record_type in msg) {
+                msg[record_type].forEach(function(entry) {
+                    console.log('Assigning record (%s) id=%s, descriptor: id=%s',
+                       record_type, entry.id, entry.nsd_ref);
+                    if (record_type == 'nsr') {
+                        dataModel.setNsInstanceConfig(entry);
+                    } else {
+                        // vnfd, vld, which don't have instance_config records yet
+                        dataModel.setConfigRecord(record_type, entry);
+                    }
+                });
+            }
+
+        } catch (e) {
+            console.error("Caught exception: %s\n\n%s", e, e.stack);
+        }
+    }
+
+    /*
+     * Get all nsr opdata records:
+     *   xpath: D,/nsr:ns-instance-opdata/nsr:nsr
+     *   msg: {"nsr":[{"ns_instance_config_ref":""}]}
+     *
+     * Get Ping Pong nsr opdata record:
+     *   xpath: D,/nsr:ns-instance-opdata/nsr:nsr[nsr:ns-instance-config-ref='f5f41f36-78f6-11e5-b9ba-6cb3113b406f']
+     *   msg: {"nsr":[{"ns_instance_config_ref":"f5f41f36-78f6-11e5-b9ba-6cb3113b406f"}]}
+     *
+     * Get monitoring param for nsr instance opdata record:
+     *   xpath: D,/nsr:ns-instance-opdata/nsr:nsr[nsr:ns-instance-config-ref='f5f41f36-78f6-11e5-b9ba-6cb3113b406f']
+     *   msg: {
+     *          "nsr":[{
+     *              "monitoring_param":[{"id":""}],
+     *              "ns_instance_config_ref":"f5f41f36-78f6-11e5-b9ba-6cb3113b406f"
+     *          }]}
+     *
+     * Note that the xpath arg is identical in getting the entire NSR and getting sub-elements in the NSR
+     * The message tells what values to get
+     */
+    function on_get_opdata(args) {
+        try {
+            var xpath = args[0];
+            var msg = args[1];
+            //console.log("\n\n*** Got on_get_opdata:\n   (xpath: %s)(msg: %j)", xpath, msg);
+            console.log("*** Got on_get_opdata:\n   (xpath: %s)(msg: %j)", xpath, msg);
+
+            var record_type = xpath.match(new RegExp(/(ns|vnf|vl)-instance-opdata/))[1];
+            record_type += 'r';
+
+            var gi_type_map = {
+                "nsr": "RwNsrYang.YangData_Nsr_NsInstanceOpdata",
+                "vnfr": "VnfrYang.YangData_Vnfr_VnfInstanceOpdata_Vnfr",
+                "vlr": "VlrYang.YangData_Vlr_VlInstanceOpdata_Vlr"
+            };
+
+            if (record_type == 'nsr') {
+                //console.log("###################\n   data model:\n\n");
+                //dataModel.prettyPrint();
+                var response = {
+                    'nsr': dataModel.getNsInstanceOpdata()
+                };
+                var respond_xpath = 'D,/nsr:ns-instance-opdata';
+            } else {
+                throw new dm.NotImplementedException(
+                        "record_type '%s' is not yet supported.", record_type);
+            }
+
+            var result = new autobahn.Result([
+                'RwNsrYang.YangData_Nsr_NsInstanceOpdata',
+                response
+            ], {"xpath": respond_xpath});
+
+            if (DUMP_RESULTS)
+                console.log("result=\n%s", JSON.stringify(result) );
+
+            return result;
+        } catch(e) {
+            console.error("Caught exception: %s\n\n%s", e, e.stack);
+        }
+    }
+
+    function on_get_vnfr_catalog(args) {
+        try {
+            var xpath = args[0];
+            var msg = args[1];
+            console.log("*** Got on_vnfr_catalog:\n   (xpath: %s)(msg: %j)", xpath, msg);
+
+            var response = {
+                'vnfr': dataModel.getVnfrs()
+            };
+            var respond_xpath = 'D,/vnfr:vnfr-catalog';
+
+            var result = new autobahn.Result([
+                'RwVnfrYang.YangData_Vnfr_VnfrCatalog',
+                response
+            ], {"xpath": respond_xpath});
+
+            if (DUMP_RESULTS)
+                console.log("result=\n%s", JSON.stringify(result) );
+
+            return result;
+        } catch(e) {
+            console.error("Caught exception: %s\n\n%s", e, e.stack);
+        }
+    }
+
+    my.register = function (session) {
+        console.log('Registering for record handling');
+        session.register('dts.data.ns-instance-opdata', on_get_opdata);
+        session.register('dts.data.vnfr-catalog', on_get_vnfr_catalog);
+        session.subscribe('dts.config.ns-instance-config', on_config_config);
+    }
+
+    return my;
+}());
+
+
+var action_module = (function() {
+    my = {};
+
+    /*
+     * Set the specified VNFR operating state
+     *
+     * (xpath: I,/lpmocklet:start-vnfr)
+     * (msg: {"id":"f26b90b0-8184-11e5-bc47-2b429643382b"})
+     */
+    function on_set_opstate(args) {
+        try {
+            var xpath = args[0];
+            var msg = args[1];
+
+            console.log("\n\n*** Got on_start_vnfr:\n    (xpath: %s)(msg: %j)",
+                xpath, msg);
+            var action_match = xpath.match(new RegExp(/lpmocklet:(\w+)-(\w+)/));
+            var action = action_match[1];
+            var obj_type = action_match[2];
+
+            var record_id = msg['id'];
+            console.log('action="%s", obj_type="%s", record_id="%s"',
+                    action, obj_type, record_id);
+
+            if (obj_type == 'vnfr') {
+                if (action == 'start') {
+                    dataModel.startVnfr(record_id);
+                }
+                else if (action == 'stop') {
+                    dataModel.stopVnfr(record_id);
+                }
+                else {
+                    console.error('Unsupported opstate action "%s"', action);
+                }
+            } else {
+                console.error('Unsupported opstate action object: "%s"',
+                        obj_type);
+            }
+
+            console.log('\n\nBuilding response....');
+
+            var response = {
+                id: uuid.v1(),
+                object_type: obj_type,
+                action: action,
+                status: 'SUCCESS' 
+            };
+            var respond_xpath = 'D,/lpmocklet:lpmocklet-action-status';
+            var result = new autobahn.Result([
+                    'LpmockletYang.YangData_Lpmocklet_LpmockletActionStatus',
+                    response
+                    ], {"xpath": respond_xpath});
+
+            console.log('Done running on_set_opdata');
+            return result;
+
+        } catch (e) {
+            console.error("Caught exception: %s\n\n%s", e, e.stack);
+        }
+    }
+
+    function on_set_control_param(args) {
+        try {
+            var xpath = args[0];
+            var msg = args[1];
+
+            console.log("\n\n*** Got on_set_control_param:\n    (xpath: %s)(msg: %j)",
+                xpath, msg);
+
+            // We can ignore xpath. We expect: "I,/lpmocklet:set-control-param"
+// msg: {"set":{"id":"f8d63b30-84b3-11e5-891c-61c6a71edd3c","obj_code":"VNFR","control_id":"ping-packet-size-1","value":10}}
+
+            var response_class = 'LpmockletYang.YangData_Lpmocklet_LpmockletActionStatus';
+            var status = dataModel.updateControlParam(
+                    msg.obj_code.toLowerCase(),
+                    msg.id,
+                    msg.control_id,
+                    msg.value);
+
+            var response = {
+                id: uuid.v1(),
+                object_type: msg.obj_code,
+                action: msg.control_id,
+                status: status
+            };
+
+            var respond_xpath = 'D,/lpmocklet:lpmocklet-action-status';
+            var result = new autobahn.Result([
+                    'LpmockletYang.YangData_Lpmocklet_LpmockletActionStatus',
+                    response
+                    ], {"xpath": respond_xpath});
+
+            console.log('Done running on_set_opdata');
+            return result;
+        } catch (e) {
+            console.error("Caught exception: %s\n\n%s", e, e.stack);
+        }
+    }
+
+    my.register = function(session) {
+        console.log('Registering for action handling');
+        session.register('dts.rpc.start-vnfr', on_set_opstate);
+        session.register('dts.rpc.stop-vnfr', on_set_opstate);
+        session.register('dts.rpc.set-control-param', on_set_control_param);
+    }
+
+    return my;
+
+}());
+
+
+connection.onopen = function (session) {
+    console.log('Connection to wamp server established!');
+    descriptor_module.register(session);
+    instance_module.register(session);
+    action_module.register(session);
+}
+
+console.log('Opening autobahn connection');
+connection.open();
+
diff --git a/rwlaunchpad/mock/package.json b/rwlaunchpad/mock/package.json
new file mode 100644
index 0000000..51e5d89
--- /dev/null
+++ b/rwlaunchpad/mock/package.json
@@ -0,0 +1,18 @@
+{
+  "name": "rw.lp.dts.mock",
+  "version": "1.0.0",
+  "description": "This is node js launchpad dts mock client.",
+  "main": "lp_mock_client.js",
+  "scripts": {
+    "start": "node lp_mock_client"
+  },
+  "author": "JohnBaldwin",
+  "license": "Apache-2.0",
+  "dependencies": {
+    "autobahn": "~0.9.6",
+    "lodash": "~3.10.1",
+    "node-uuid": "~1.4.3",
+    "mocha": "~2.3.3"
+  },
+  "devDependencies": {}
+}
diff --git a/rwlaunchpad/mock/plugins/CMakeLists.txt b/rwlaunchpad/mock/plugins/CMakeLists.txt
new file mode 100644
index 0000000..a10246d
--- /dev/null
+++ b/rwlaunchpad/mock/plugins/CMakeLists.txt
@@ -0,0 +1,25 @@
+
+# 
+#   Copyright 2016 RIFT.IO Inc
+#
+#   Licensed under the Apache License, Version 2.0 (the "License");
+#   you may not use this file except in compliance with the License.
+#   You may obtain a copy of the License at
+#
+#       http://www.apache.org/licenses/LICENSE-2.0
+#
+#   Unless required by applicable law or agreed to in writing, software
+#   distributed under the License is distributed on an "AS IS" BASIS,
+#   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+#   See the License for the specific language governing permissions and
+#   limitations under the License.
+#
+
+cmake_minimum_required(VERSION 2.0)
+
+set(subdirs
+    yang
+    )
+
+rift_add_subdirs(SUBDIR_LIST ${subdirs})
+
diff --git a/rwlaunchpad/mock/plugins/yang/CMakeLists.txt b/rwlaunchpad/mock/plugins/yang/CMakeLists.txt
new file mode 100644
index 0000000..2d8f2d9
--- /dev/null
+++ b/rwlaunchpad/mock/plugins/yang/CMakeLists.txt
@@ -0,0 +1,32 @@
+
+# 
+#   Copyright 2016 RIFT.IO Inc
+#
+#   Licensed under the Apache License, Version 2.0 (the "License");
+#   you may not use this file except in compliance with the License.
+#   You may obtain a copy of the License at
+#
+#       http://www.apache.org/licenses/LICENSE-2.0
+#
+#   Unless required by applicable law or agreed to in writing, software
+#   distributed under the License is distributed on an "AS IS" BASIS,
+#   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+#   See the License for the specific language governing permissions and
+#   limitations under the License.
+#
+
+
+include(rift_yang)
+include(rift_plugin)
+
+rift_add_yang_target(
+    TARGET
+        lpmocklet_yang
+    YANG_FILES
+        lpmocklet.yang
+    COMPONENT
+        ${PKG_LONG_NAME}
+    LIBRARIES
+        mano-types_yang_gen
+)
+
diff --git a/rwlaunchpad/mock/plugins/yang/lpmocklet.tailf.yang b/rwlaunchpad/mock/plugins/yang/lpmocklet.tailf.yang
new file mode 100644
index 0000000..0579add
--- /dev/null
+++ b/rwlaunchpad/mock/plugins/yang/lpmocklet.tailf.yang
@@ -0,0 +1,50 @@
+
+/*
+ * 
+ *   Copyright 2016 RIFT.IO Inc
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ *
+ */
+
+module lpmocklet-annotation
+{
+    namespace "http://riftio.com/ns/riftware-1.0/lpmocklet-annotation";
+    prefix "lpmocklet-ann";
+
+    import tailf-common {
+        prefix tailf;
+    }
+
+    import lpmocklet {
+        prefix lpmocklet;
+    }
+
+    tailf:annotate "/lpmocklet:lpmocklet-action-status" {
+        tailf:callpoint rw_callpoint;
+    }
+
+    tailf:annotate "/lpmocklet:set-control-param" {
+        tailf:actionpoint rw_actionpoint;
+    }
+
+    tailf:annotate "/lpmocklet:start-vnfr" {
+        tailf:actionpoint rw_actionpoint;
+    }
+
+    tailf:annotate "/lpmocklet:stop-vnfr" {
+        tailf:actionpoint rw_actionpoint;
+    }
+}
+
diff --git a/rwlaunchpad/mock/plugins/yang/lpmocklet.yang b/rwlaunchpad/mock/plugins/yang/lpmocklet.yang
new file mode 100644
index 0000000..819ee40
--- /dev/null
+++ b/rwlaunchpad/mock/plugins/yang/lpmocklet.yang
@@ -0,0 +1,111 @@
+
+/*
+ * 
+ *   Copyright 2016 RIFT.IO Inc
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ *
+ */
+
+module lpmocklet
+{
+    namespace "http://riftio.com/ns/riftware-1.0/lpmocklet";
+    prefix "lpmocklet";
+
+    import rw-pb-ext {
+        prefix "rwpb";
+    }
+
+    import ietf-inet-types {
+        prefix "inet";
+    }
+
+    import ietf-yang-types {
+        prefix "yang";
+    }
+
+    import mano-types {
+        prefix "manotypes";
+    }
+
+    // Used for LP Mocklet RPC action-param and control-param responses
+    container lpmocklet-action-status {
+        config false;
+        leaf id {
+            type yang:uuid;
+        }
+        // TODO: Make this consistent with 'set-control-param' 'obj-code'
+        leaf object_type {
+            type string;
+        }
+        leaf action {
+            type string;
+        }
+        leaf status {
+            type string;
+        }
+    }
+
+    rpc set-control-param {
+        input {
+            leaf id {
+                description "object id";
+                type yang:uuid;
+                mandatory true;
+            }
+            leaf obj-code {
+                description "Type of object: NS, VNF";
+                type string;
+                mandatory true;
+            }
+            leaf control-id {
+                type string;
+                mandatory true;
+            }
+            // The new vale to assign
+            leaf value {
+                type uint64;
+                mandatory true;
+            }
+        }
+    }
+
+    rpc start-vnfr {
+        input {
+            rwpb:msg-new "StartVnfrInput";
+            leaf id {
+                type yang:uuid;
+                mandatory true;
+            }
+        }
+        output {
+            rwpb:msg-new "StartVnfrOutput";
+            leaf status {
+                description "status of the start request";
+                type string;
+            }
+        }
+    }
+
+    rpc stop-vnfr {
+        input {
+            rwpb:msg-new "StopVnfr";
+            leaf id {
+                type yang:uuid;
+                mandatory true;
+            }
+        }
+    }
+}
+
diff --git a/rwlaunchpad/mock/set_data.sh b/rwlaunchpad/mock/set_data.sh
new file mode 100755
index 0000000..4a39c0a
--- /dev/null
+++ b/rwlaunchpad/mock/set_data.sh
@@ -0,0 +1,59 @@
+#!/bin/bash
+
+# 
+#   Copyright 2016 RIFT.IO Inc
+#
+#   Licensed under the Apache License, Version 2.0 (the "License");
+#   you may not use this file except in compliance with the License.
+#   You may obtain a copy of the License at
+#
+#       http://www.apache.org/licenses/LICENSE-2.0
+#
+#   Unless required by applicable law or agreed to in writing, software
+#   distributed under the License is distributed on an "AS IS" BASIS,
+#   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+#   See the License for the specific language governing permissions and
+#   limitations under the License.
+#
+
+#
+# This script posts descriptor data (NSD, VNFD, VLD) to the RESTConf server
+#
+# Provide the RESTConf hostname as the argument or default to localhost
+#
+
+if [ $# -eq 0 ] ; then
+    HOST=localhost
+else
+    HOST=$1
+fi
+
+echo "Posting descriptor data to $HOST"
+
+
+#for descriptor in nsd vnfd vld
+
+for descriptor in nsd vnfd
+do
+    echo "Assigning data to descriptor \"$descriptor\""
+
+    curl --user admin:admin \
+        -H "Content-Type: application/vnd.yang.data+json" \
+        -X POST \
+        -d @data/${descriptor}_catalog.json \
+        http://$HOST:8008/api/running/$descriptor-catalog/ -v
+
+done
+
+for rectype in ns
+do
+    echo "Assigning data to instance config \"$rectype\""
+
+    curl --user admin:admin \
+        -H "Content-Type: application/vnd.yang.data+json" \
+        -X POST \
+        -d @data/${rectype}-instance-config.json \
+        http://$HOST:8008/api/running/$rectype-instance-config/ -v
+
+done
+
diff --git a/rwlaunchpad/mock/set_ping_pong.sh b/rwlaunchpad/mock/set_ping_pong.sh
new file mode 100755
index 0000000..11126bd
--- /dev/null
+++ b/rwlaunchpad/mock/set_ping_pong.sh
@@ -0,0 +1,51 @@
+#!/bin/bash
+
+# 
+#   Copyright 2016 RIFT.IO Inc
+#
+#   Licensed under the Apache License, Version 2.0 (the "License");
+#   you may not use this file except in compliance with the License.
+#   You may obtain a copy of the License at
+#
+#       http://www.apache.org/licenses/LICENSE-2.0
+#
+#   Unless required by applicable law or agreed to in writing, software
+#   distributed under the License is distributed on an "AS IS" BASIS,
+#   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+#   See the License for the specific language governing permissions and
+#   limitations under the License.
+#
+
+#
+# This script posts descriptor data (NSD, VNFD, VLD) to the RESTConf server
+#
+# Provide the RESTConf hostname as the argument or default to localhost
+#
+
+if [ $# -eq 0 ] ; then
+    HOST=localhost
+else
+    HOST=$1
+fi
+
+echo "Posting descriptor data to $HOST"
+
+for rectype in vnfd nsd
+do
+    echo "Assigning data to instance config \"$rectype\""
+
+    curl --user admin:admin \
+        -H "Content-Type: application/vnd.yang.data+json" \
+        -X POST \
+        -d @data/ping-pong-${rectype}.json \
+        http://$HOST:8008/api/running/$rectype-catalog/ -v
+
+    # Add sleep here if vnfd is not ready on server
+done
+
+curl --user admin:admin \
+    -H "Content-Type: application/vnd.yang.data+json" \
+    -X POST \
+    -d @data/ping-pong-ns-instance-config.json \
+    http://$HOST:8008/api/running/ns-instance-config/ -v
+
diff --git a/rwlaunchpad/mock/simmp.js b/rwlaunchpad/mock/simmp.js
new file mode 100644
index 0000000..9d0628f
--- /dev/null
+++ b/rwlaunchpad/mock/simmp.js
@@ -0,0 +1,87 @@
+
+var _ = require('lodash');
+
+/*
+ * Args:
+ * rules - object with the monitoring param to simulator function mapping
+ *         see data/simmp.json
+ */
+SimMp = function(rules) {
+    this.rules = _.clone(rules, true);
+};
+
+//SimMp.prototype.map_rule = function(mp_id) {
+//    return this.rules['mp-mapper'][mp_id];
+//}
+
+// Use the monitoring param id for now
+SimMp.prototype.createSimMonitorFunc = function(mp) {
+
+    // Define our core simulation function here
+    //
+    // min, max inclusive
+    var rand_func = function(min, max) {
+        return Math.floor(Math.random() * (max-min+1)) + min;
+    }
+
+    var funcs = {
+        // transmit and receive rate
+        tx_rc_rate: function(value, elapsed_seconds) {
+            // Ignore elapsed time for first implementation of transmit and
+            // receive rate simulation.
+            // This is just a quick and dirty and simple implementation to make
+            // the monitoring params change, stay within bounds, and not swing
+            // wildly.
+            var min_val = mp.min_value;
+            var max_val = mp.max_value;
+            // Set an outer bound of maxmium change from current value
+            // Tweak bin_count to set how much the value can swing from the
+            // last value
+            var bin_count = 10;
+            // Set the range we can generate the new value based on a function
+            //  of the difference of the max and min values
+            var max_delta = (max_val - min_val) / bin_count;
+            console.log('Setting max_delta = %s', max_delta);
+            var new_val = rand_func(
+                    Math.max(min_val, value-max_delta),
+                    Math.min(max_val, value+max_delta));
+            //console.log("Generated value: %s", new_val);
+            return new_val;
+        },
+        packet_size: function(value, elapsed_seconds) {
+            // Stub method just returns value unchanged
+            // TODO: Figure out how we want to vary packet sizes
+            return value;
+        },
+        accumulate: function(value, elapsed_seconds) {
+            // NOT TESTED. Basic idea. Will want to add variablility
+            // how fast we accumulate
+            var accumulate_rate = 0.1;
+            var new_value = value + (elapsed_seconds * accumulate_rate);
+            return new_value;
+        }
+        // add growth function
+    };
+
+    // Declare our monitoring param id to sim function mapping here
+    // TODO: Move out to a yaml/json file and make this function belong to
+    // a 'Class'
+    //var mapper = {
+    //    'tx-rate-pp1': funcs['tx_rc_rate'],
+    //    'rc-rate-pp1': funcs['tx_rc_rate'] 
+    //};
+
+    var sim_func_name = this.rules['mp-mapper'][mp.id];
+    if (sim_func_name) {
+        return funcs[sim_func_name];
+    } else {
+        console.log('No time step sim function found for monitoring param with id "%s", using constant value', mp.id); 
+        return function(value, elapsed_seconds) {
+            return value;
+        }
+    }
+}
+
+module.exports = {
+    SimMp: SimMp
+};
diff --git a/rwlaunchpad/mock/test/test_simmp.js b/rwlaunchpad/mock/test/test_simmp.js
new file mode 100644
index 0000000..08833cf
--- /dev/null
+++ b/rwlaunchpad/mock/test/test_simmp.js
@@ -0,0 +1,28 @@
+var assert = require('assert');
+
+var simmp_module = require('../simmp.js');
+
+// This is an example test on SimMp. It is not a very good test, but shows
+// how to write a basic test in mocha
+describe('SimMp', function() {
+    describe('#createSimMonitorFunc()', function () {
+        it('should return tx_rc_rate', function () {
+            var mp = {
+                id: 'tx-rate-pp1',
+                min_value: 0,
+                max_value: 100,
+                current_value: 0
+            };
+            var simmp = new simmp_module.SimMp({
+                "mp-mapper": { "tx-rate-pp1": "tx_rc_rate" }
+            });
+            assert(simmp != null, 'Could not instantiate simmp');
+            var func = simmp.createSimMonitorFunc(mp);
+            var value = func(0);
+            assert(value >= mp.min_value, 'value less than min value);
+            assert(value <= mp.max_value, 'value greater than max value');
+
+       });
+    });
+});
+