CORD-1813 Document Service/Tenancy migration

Change-Id: I52f2ccdd0133c795a93ee0de6d6cf8152b9858c8
diff --git a/docs/migrate-4.0.md b/docs/migrate-4.0.md
new file mode 100644
index 0000000..ea7e698
--- /dev/null
+++ b/docs/migrate-4.0.md
@@ -0,0 +1,128 @@
+# CORD-4.0 Service Migration Guide
+
+## Service/Tenancy Model Migration
+
+CORD-4.0 makes the following changes:
+
+- Renames `Tenant` to `ServiceInstance`.
+- Replaces CORD-3.0's many-to-one tenancy links with a new many-to-many link object called `ServiceInstanceLink`. 
+- Introduces the concept of service interfaces using the `InterfaceType` and `ServiceInterface` models.
+- Makes `ServiceDependency` a separate model not directly related to Tenancy models. 
+
+Note that for the purposes of this document, we still refer to some R-CORD models using the suffix "Tenant" rather than "ServiceInstance". As time permits, those R-CORD models will be renamed. New services are recommended to use the suffix ServiceInstance rather than Tenant.  
+
+### Migrating existing Tenants
+
+The base class has been changed from `Tenant` to `ServiceInstance`. This may require an  `xproto` change, for example:
+
+    - message VTRTenant (Tenant){
+    + message VTRTenant (ServiceInstance){
+
+Note that `TenantWithContainer` has not yet been renamed (at some point in the future it may become `ServiceInstanceWithContainer`), so models inheriting from `TenantWithContainer` are fine for now.
+
+### Differences in ServiceInstance fields
+
+A few fields in ServiceInstance have been changed from what they were in `Tenant`:
+ 
+- `Tenant.provider_service` --> `ServiceInstance.owner` 
+
+### Creating links between Service Instances (`ServiceInstanceLink` objects)
+
+A common pattern in CORD-3.0 model policies is to create a new Tenant and link it to an existing model. For example,
+
+    t = VRouterTenant(provider_service=vrouter_service,
+                      subscriber_tenant=some_vsg_tenant)
+    t.save()
+
+In the above example, the relationship between the new VRouterTenant and `some_vsg_tenant` was captured by the field `subscriber_tenant`. This field no longer exists in CORD-4.0 and needs to be replaced with a link:
+
+    t = VRouterTenant(owner=vrouter_service)
+    t.save()
+    l = ServiceInstanceLink(provider_service_instance = t,
+                            subscriber_service_interface=some_vsg_tenant)
+    l.save()
+
+### Traversing links between Service Instances
+
+In CORD-3.0, it was possible to determine the subscriber of a Tenant by looking at the Tenant's `subscriber_*` properties. For example,
+
+    subscriber = some_vrouter_tenant.subscriber_tenant
+    vsg_tenant = VSGTenant.objects.get(id = subscriber.id)
+    # now, do something with vsg_tenant
+
+In CORD-4.0 you will need to traverse `ServiceInstanceLink` objects instead:
+
+    for link in some_vrouter_tenant.provided_links.all():
+        if link.subscriber_service_instance:
+            subscriber = link.subscriber_service_instance
+            vsg_tenant = subscriber.leaf_model
+            # now, do something with vsg_tenant
+
+You can also walk in the opposite direction:
+    
+    for link in some_vsg_tenant.subscribed_links.all():
+        if link.subscriber_service_instance:
+            provider = link.provider_service_instance
+            vrouter_tenant = provider.leaf_model
+            # now, do something with vrouter_tenant
+
+Note that since the service instance graph now supports true many-to-many relations, it's common to have to use for loops as described above to cover cases where an object may be linked to many providers or many subscribers. If it's a known constraint that only one object may be linked, then it may be reasonable to omit the for loop and use `provided_links.first()` or `subscribed_links.first()` instead of `.all()`. 
+
+Also note that `leaf_model` is a property that will automatically cast any base object to its descendant class. For example, if you have a generic `ServiceInstance` object, and that `ServiceInstance` is really a `VSGTenant`, then `leaf_model` will perform that conversion for you automatically.
+
+### Removing links between Service Instances
+
+Links are removed by deleting the `ServiceInstanceLink` object. For example,
+
+    # delete all links between some_vsg_tenant and some_vrouter_tenant
+    for link in ServiceInstanceLink.objects.filter(provider_service_instance_id=some_vsg_tenant.id, subscriber_service_instance_id=some_vrouter_instance.id):
+        link.delete() 
+
+### Creating ServiceInterfaces
+
+`ServiceInterfaces` allow you to type the links between `ServiceInstances`. For example, if one `ServiceInstance` provides a `WAN` interface and another `ServiceInstance` uses a `LAN` interface, you can explicitly connect those two interfaces. These are currently created in Tosca. For example,
+
+    in#lanside:
+      type: tosca.nodes.InterfaceType
+      properties:
+         direction: in
+
+    out#lanside:
+      type: tosca.nodes.InterfaceType
+      properties:
+         direction: out
+
+    volt_lanside:
+      type: tosca.nodes.ServiceInterface
+      requirements:
+        - service:
+            node: service#volt
+            relationship: tosca.relationships.MemberOfService
+        - interface:
+            node: out#lanside
+            relationship: tosca.relationships.IsType
+
+    vsg_lanside:
+      type: tosca.nodes.ServiceInterface
+      requirements:
+        - service:
+            node: service#vsg
+            relationship: tosca.relationships.MemberOfService
+        - interface:
+            node: in#lanside
+            relationship: tosca.relationships.IsType
+
+This example creates a `lanside` interface that is present in both the `VOLT` and `VSG` services. 
+
+Interfaces are currently optional, but may become mandatory in the next release. Until then, you can optionally associate links with interfaces. For example,
+
+    interface_type = InterfaceType.objects.get(name="lanside", direction="in")
+    interface = VSGService.Interfaces.get(interface_type=interface_type)
+    t = VSGTenant(owner=vsg_service)
+    t.save()
+    l = ServiceInstanceLink(provider_service_instance = t, 
+                            provider_service_interface = interface,
+                            subscriber_service_interface=some_volt_tenant)
+    l.save()
+
+As `ServiceInterface` are not mandatory, it's suggested that you perform the other migration steps, and leave `ServiceInterfaces` until everything else is working.
\ No newline at end of file