Implement spine leaf topology simulator

Change-Id: I13582cc838767a388b85a18c894eb6da58da3287
diff --git a/providers/null/src/main/java/org/onosproject/provider/nil/SpineLeafTopologySimulator.java b/providers/null/src/main/java/org/onosproject/provider/nil/SpineLeafTopologySimulator.java
index eec74f2..e42ae70 100644
--- a/providers/null/src/main/java/org/onosproject/provider/nil/SpineLeafTopologySimulator.java
+++ b/providers/null/src/main/java/org/onosproject/provider/nil/SpineLeafTopologySimulator.java
@@ -15,29 +15,65 @@
  */
 package org.onosproject.provider.nil;
 
+import static com.google.common.base.Preconditions.checkArgument;
+
 /**
  * Spine-leaf topology with hosts at the leaf devices.
  */
 public class SpineLeafTopologySimulator extends TopologySimulator {
+    private static final int DEFAULT_SPINE_COUNT = 2;
+    private static final int DEFAULT_LEAF_COUNT = 2;
+    private static final int DEFAULT_HOST_PER_LEAF = 2;
+    private int spineCount = DEFAULT_SPINE_COUNT;
+    private int leafCount = DEFAULT_LEAF_COUNT;
+    private int hostPerLeaf = DEFAULT_HOST_PER_LEAF;
 
     @Override
     protected void processTopoShape(String shape) {
         super.processTopoShape(shape);
-        // FIXME: implement this
+        // topology shape: spineleaf,[spine count],[leaf count],[host per leaf]
+
+        if (topoShape.length > 1) {
+            spineCount = Integer.parseInt(topoShape[1]);
+        }
+
+        if (topoShape.length > 2) {
+            leafCount = Integer.parseInt(topoShape[2]);
+        }
+
+        if (topoShape.length > 3) {
+            hostPerLeaf = Integer.parseInt(topoShape[3]);
+        }
     }
 
     @Override
     public void setUpTopology() {
-        // checkArgument(FIXME, "There must be at least one spine tier");
+        checkArgument(spineCount > 0, "There must be at least one spine");
+        checkArgument(leafCount > 0, "There must be at least one leaf");
+
+        deviceCount = spineCount + leafCount;
+        hostCount = hostPerLeaf;
+        log.info("Setup Spine-Leaf topology with {} spine(s), {} leaf(s), and {} host per leaf",
+                 spineCount, leafCount, hostPerLeaf);
+
         super.setUpTopology();
     }
 
     @Override
     protected void createLinks() {
+        for (int spineIndex = 0; spineIndex < spineCount; spineIndex++) {
+            for (int leafIndex = spineCount; leafIndex < spineCount + leafCount; leafIndex++) {
+                // Nth port of spine connect to Nth leaf, vice versa
+                createLink(spineIndex, leafIndex, leafIndex - spineCount + 1, spineIndex + 1);
+            }
+        }
     }
 
     @Override
     protected void createHosts() {
+        for (int i = spineCount; i < spineCount + leafCount; i++) {
+            createHosts(deviceIds.get(i), spineCount);
+        }
     }
 
 }