support for syncing service attributes with app
diff --git a/xos/configurations/cord/cord.yaml b/xos/configurations/cord/cord.yaml
index 02137ec..ea1425a 100644
--- a/xos/configurations/cord/cord.yaml
+++ b/xos/configurations/cord/cord.yaml
@@ -108,6 +108,21 @@
           kind: onos
           view_url: /admin/onos/onosservice/$id$/
           public_key: { get_artifact: [ SELF, pubkey, LOCAL_FILE] }
+#          rest_onos/v1/network/configuration/: >
+#            {
+#              "devices" : {
+#                "of:0000000000000001" : {
+#                  "accessDevice" : {
+#                    "uplink" : "2",
+#                    "vlan"   : "222",
+#                    "defaultVlan" : "1"
+#                  },
+#                  "basic" : {
+#                    "driver" : "default"
+#                  }
+#                }
+#              }
+#            }
       artifacts:
           pubkey: /opt/xos/observers/onos/onos_key.pub
 
diff --git a/xos/observers/onos/steps/sync_onosapp.py b/xos/observers/onos/steps/sync_onosapp.py
index 9b32298..97bb8a6 100644
--- a/xos/observers/onos/steps/sync_onosapp.py
+++ b/xos/observers/onos/steps/sync_onosapp.py
@@ -81,20 +81,25 @@
         if not os.path.exists(o.files_dir):
             os.makedirs(o.files_dir)
 
-        for attr in o.tenantattributes.all():
-            if attr.name.startswith("config_"):
-                fn = attr.name[7:] # .replace("_json",".json")
+        # Combine the service attributes with the tenant attributes. Tenant
+        # attribute can override service attributes.
+        attrs = o.provider_service.serviceattribute_dict
+        attrs.update(o.tenantattribute_dict)
+
+        for (name, value) in attrs.items():
+            if name.startswith("config_"):
+                fn = name[7:] # .replace("_json",".json")
                 o.config_fns.append(fn)
-                file(os.path.join(o.files_dir, fn),"w").write(attr.value)
-            if attr.name.startswith("rest_"):
-                fn = attr.name[5:].replace("/","_")
-                endpoint = attr.name[5:]
+                file(os.path.join(o.files_dir, fn),"w").write(value)
+            if name.startswith("rest_"):
+                fn = name[5:].replace("/","_")
+                endpoint = name[5:]
                 # Ansible goes out of it's way to make our life difficult. If
                 # 'lookup' sees a file that it thinks contains json, then it'll
                 # insist on parsing and return a json object. We just want
                 # a string, so prepend a space and then strip the space off
                 # later.
-                file(os.path.join(o.files_dir, fn),"w").write(" " +attr.value)
+                file(os.path.join(o.files_dir, fn),"w").write(" " +value)
                 o.rest_configs.append( {"endpoint": endpoint, "fn": fn} )
 
     def prepare_record(self, o):
diff --git a/xos/observers/onos/steps/sync_onosapp.yaml b/xos/observers/onos/steps/sync_onosapp.yaml
index 9ee2513..9105a2e 100644
--- a/xos/observers/onos/steps/sync_onosapp.yaml
+++ b/xos/observers/onos/steps/sync_onosapp.yaml
@@ -45,18 +45,6 @@
         {% endfor %}
 {% endif %}
 
-{% if rest_configs %}
-  - name: Add ONOS configuration values
-    uri:
-      url: http://localhost:8181/{{ '{{' }} item.endpoint {{ '}}' }} #http://localhost:8181/onos/v1/network/configuration/
-      body: "{{ '{{' }} item.body {{ '}}' }}"
-      body_format: raw
-      method: POST
-      user: karaf
-      password: karaf
-    with_items: "rest_configs"
-{% endif %}
-
   # Don't know how to check for this condition, just wait
   - name: Wait for ONOS to install the apps
     wait_for: timeout=15
@@ -71,3 +59,17 @@
         {% for dependency in dependencies %}
         - {{ dependency }}
         {% endfor %}
+
+{% if rest_configs %}
+# Do this after services have been activated, or it will cause an exception.
+# vOLT will re-read its net config; vbng may not.
+  - name: Add ONOS configuration values
+    uri:
+      url: http://localhost:8181/{{ '{{' }} item.endpoint {{ '}}' }} #http://localhost:8181/onos/v1/network/configuration/
+      body: "{{ '{{' }} item.body {{ '}}' }}"
+      body_format: raw
+      method: POST
+      user: karaf
+      password: karaf
+    with_items: "rest_configs"
+{% endif %}