Open Kilda Java Documentation
TestTopologyBuilder.java
Go to the documentation of this file.
1 /* Copyright 2017 Telstra Open Source
2  *
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  * http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 package org.openkilda.topo.builders;
17 
18 import static java.lang.String.format;
19 
20 import com.fasterxml.jackson.databind.ObjectMapper;
21 import com.google.common.primitives.Ints;
22 import org.openkilda.topo.Link;
24 import org.openkilda.topo.Port;
26 import org.openkilda.topo.Switch;
27 import org.openkilda.topo.Topology;
29 
30 import java.io.IOException;
31 import java.util.ArrayList;
32 import java.util.HashMap;
33 import java.util.Map;
34 
38 public class TestTopologyBuilder {
45  @SuppressWarnings("unchecked")
46  public static final Topology buildTopoFromTestJson(String jsonDoc) {
47  Map<String, Switch> switches = new HashMap<>();
48  Map<String, Switch> altSwitchId = new HashMap<>();
49  Map<String, Link> links = new HashMap<>();
50 
51  ObjectMapper mapper = new ObjectMapper();
52  Map<String,ArrayList<Map<String,String>>> root;
53 
54  try {
55  root = mapper.readValue(jsonDoc, Map.class);
56  } catch (IOException ex) {
57  throw new TopologyProcessingException(format("Unable to parse the topology '%s'.", jsonDoc), ex);
58  }
59 
60  // populate switches first
61  ArrayList<Map<String,String>> jsonSwitches = root.get("switches");
62  for (Map<String,String> s : jsonSwitches) {
63  String id = normalSwitchID(s.get("dpid"));
64  Switch newSwitch = new Switch(id);
65  switches.put(id, newSwitch);
66  if (s.get("name") != null)
67  altSwitchId.put(s.get("name"),newSwitch);
68  }
69 
70  // now populate links
71  ArrayList<Map<String,String>> jsonLinks = root.get("links");
72  for (Map<String,String> l : jsonLinks) {
73  String srcId = l.get("node1");
74  String dstId = l.get("node2");
75  Switch src = switches.get(srcId);
76  if (src == null) src = altSwitchId.get(srcId);
77  Switch dst = switches.get(dstId);
78  if (dst == null) dst = altSwitchId.get(dstId);
79 
80  Link link = new Link(
81  new LinkEndpoint(src,null,null),
82  new LinkEndpoint(dst,null,null)
83  );
84  links.put(link.getShortSlug(),link);
85  }
86 
87  return new Topology(switches, links);
88  }
89 
94  private static final String normalSwitchID(String id){
95  // normalize the ID ... I assume (mostly) the id is a valid mininet ID coming in.
96  // now, need to make it look like what mininet / topology engine generate.
97 
98  if (id.contains(":") == false){
99  StringBuilder sb = new StringBuilder(id.substring(0,2));
100  for (int i = 2; i < 16; i+=2) {
101  sb.append(":").append(id.substring(i,i+2));
102  }
103  id = sb.toString();
104  }
105  id = id.toLowerCase(); // mininet will do lower case ..
106  return id;
107  }
108 
114  public static final Topology buildLinearTopo(int numSwitches){
115  // Add Switches
116  Map<String, Switch> switches = new HashMap<>();
117  Map<String, Link> links = new HashMap<>();
118 
119  for (int i = 0; i < numSwitches; i++) {
120  String switchID = intToSwitchId(i+1);
121  switches.put(switchID, new Switch(switchID));
122  }
123 
124  // Add links between switches
125  int numLinks = numSwitches-1; // is A-->B = 2 switches, 1 link.
126  for (int i = 0; i < numLinks; i++) {
127  Switch s1 = switches.get(intToSwitchId(i+1));
128  Switch s2 = switches.get(intToSwitchId(i+2));
129  linkSwitches(links,s1,s2);
130  }
131  return new Topology(switches, links);
132  }
133 
134  public static String intToSwitchId(int i){
135  byte[] ib = Ints.toByteArray(i);
136  return String.format("DE:AD:BE:EF:%02x:%02x:%02x:%02x",ib[0],ib[1],ib[2],ib[3]);
137  }
138 
139  private static final void linkSwitches(Map<String, Link> links, Switch s1, Switch s2){
140  Port p1 = new Port(s1,String.format("PORTAA%03d",1));
141  Port p2 = new Port(s2,String.format("PORTBB%03d",1));;
142  PortQueue q1 = new PortQueue(p1, String.format("QUEUE%03d",1));
143  PortQueue q2 = new PortQueue(p2, String.format("QUEUE%03d",1));;
144 
145  LinkEndpoint e1 = new LinkEndpoint(q1);
146  LinkEndpoint e2 = new LinkEndpoint(q2);
147 
148  Link link1 = new Link(e1,e2);
149  Link link2 = new Link(e2,e1);
150  links.put(link1.getShortSlug(),link1);
151  links.put(link2.getShortSlug(),link2);
152  }
153 
155  public static final Topology buildTreeTopo(int depth, int fanout){
156  TreeBuilder tb = new TreeBuilder(fanout);
157  return tb.build(depth);
158  }
159 
160 
162  public static final Topology buildTorusTopo(){
163  throw new UnsupportedOperationException();
164  }
165 
170  static class TreeBuilder {
171  private int switchId = 1;
172  private int fanout;
173 
174  private Map<String, Switch> switches = new HashMap<>();
175  private Map<String, Link> links = new HashMap<>();
176 
177  TreeBuilder(int fanout){
178  this.fanout = fanout;
179  }
180 
181  Topology build(int depth) {
182  buildSwitch(depth);
183 
184  return new Topology(switches, links);
185  }
186 
188  private Switch buildSwitch(int depth){
189  String switchID = intToSwitchId(switchId++);
190  Switch s1 = new Switch(switchID);
191  switches.put(switchID, s1);
192  // the last level (depth == 1) is just a switch, so end the recursion.
193  if (depth > 1) {
194  for (int i = 0; i < fanout; i++) {
195  Switch s2 = buildSwitch(depth - 1);
196  linkSwitches(links,s1,s2);
197  }
198  }
199  return s1;
200  }
201  }
202 }
root
Definition: setup.py:12
s1
Definition: plan-c.py:44
id
Definition: nodes.py:55
static final Topology buildLinearTopo(int numSwitches)
static final Topology buildTopoFromTestJson(String jsonDoc)
def build()
Definition: plan-e.py:73
static final Topology buildTreeTopo(int depth, int fanout)